]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux...
authorRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 5 Dec 2011 23:20:17 +0000 (23:20 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 5 Dec 2011 23:20:17 +0000 (23:20 +0000)
Conflicts:
arch/arm/common/gic.c
arch/arm/plat-omap/include/plat/common.h

679 files changed:
Documentation/ABI/testing/sysfs-block
Documentation/DocBook/uio-howto.tmpl
Documentation/blockdev/cciss.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/filesystems/btrfs.txt
Documentation/i2c/ten-bit-addresses
Documentation/networking/ip-sysctl.txt
Documentation/power/devices.txt
Documentation/power/runtime_pm.txt
Documentation/serial/serial-rs485.txt
Documentation/sound/alsa/HD-Audio.txt
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/boot/Makefile
arch/arm/common/gic.c
arch/arm/common/pl330.c
arch/arm/configs/at91cap9_defconfig [moved from arch/arm/configs/at91cap9adk_defconfig with 93% similarity]
arch/arm/configs/at91rm9200_defconfig
arch/arm/configs/at91sam9260_defconfig [moved from arch/arm/configs/at91sam9260ek_defconfig with 86% similarity]
arch/arm/configs/at91sam9g20_defconfig [moved from arch/arm/configs/at91sam9g20ek_defconfig with 90% similarity]
arch/arm/configs/at91sam9g45_defconfig
arch/arm/configs/at91sam9rl_defconfig [moved from arch/arm/configs/at91sam9rlek_defconfig with 94% similarity]
arch/arm/configs/ezx_defconfig
arch/arm/configs/imote2_defconfig
arch/arm/configs/magician_defconfig
arch/arm/configs/omap1_defconfig
arch/arm/configs/u300_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/configs/zeus_defconfig
arch/arm/include/asm/cti.h [new file with mode: 0644]
arch/arm/include/asm/hardware/cache-l2x0.h
arch/arm/include/asm/mach/arch.h
arch/arm/include/asm/perf_event.h
arch/arm/include/asm/pmu.h
arch/arm/include/asm/topology.h
arch/arm/include/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/entry-armv.S
arch/arm/kernel/head.S
arch/arm/kernel/kprobes-arm.c
arch/arm/kernel/kprobes-test-arm.c
arch/arm/kernel/kprobes-test-thumb.c
arch/arm/kernel/kprobes-test.h
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/perf_event_v6.c
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/perf_event_xscale.c
arch/arm/kernel/pmu.c
arch/arm/kernel/process.c
arch/arm/kernel/setup.c
arch/arm/kernel/topology.c
arch/arm/lib/bitops.h
arch/arm/lib/changebit.S
arch/arm/lib/clearbit.S
arch/arm/lib/setbit.S
arch/arm/lib/testchangebit.S
arch/arm/lib/testclearbit.S
arch/arm/lib/testsetbit.S
arch/arm/mach-bcmring/core.c
arch/arm/mach-bcmring/dma.c
arch/arm/mach-exynos/cpuidle.c
arch/arm/mach-highbank/highbank.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/clock-imx6q.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mm-imx3.c
arch/arm/mach-imx/src.c
arch/arm/mach-mmp/gplugd.c
arch/arm/mach-mmp/include/mach/gpio-pxa.h
arch/arm/mach-mx5/cpu.c
arch/arm/mach-mx5/mm.c
arch/arm/mach-mxs/clock-mx28.c
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/clock.h
arch/arm/mach-omap1/clock_data.c
arch/arm/mach-omap1/devices.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/cpuidle34xx.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/display.h [new file with mode: 0644]
arch/arm/mach-omap2/io.h [deleted file]
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_2420_data.c
arch/arm/mach-omap2/omap_hwmod_2430_data.c
arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_common_data.c
arch/arm/mach-omap2/omap_hwmod_common_data.h
arch/arm/mach-omap2/omap_l3_noc.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/smartreflex.c
arch/arm/mach-omap2/twl-common.c
arch/arm/mach-omap2/twl-common.h
arch/arm/mach-pxa/balloon3.c
arch/arm/mach-pxa/colibri-pxa320.c
arch/arm/mach-pxa/gumstix.c
arch/arm/mach-pxa/include/mach/palm27x.h
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-pxa/vpac270.c
arch/arm/mach-s3c64xx/mach-crag6410-module.c
arch/arm/mach-shmobile/pm-sh7372.c
arch/arm/mach-w90x900/dev.c
arch/arm/mach-w90x900/include/mach/mfp.h
arch/arm/mach-w90x900/include/mach/nuc900_spi.h
arch/arm/mach-w90x900/mfp.c
arch/arm/mm/cache-l2x0.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/mmap.c
arch/arm/plat-mxc/include/mach/common.h
arch/arm/plat-mxc/include/mach/mxc.h
arch/arm/plat-mxc/include/mach/system.h
arch/arm/plat-mxc/system.c
arch/arm/plat-omap/include/plat/clock.h
arch/arm/plat-omap/include/plat/common.h
arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
arch/arm/plat-s5p/sysmmu.c
arch/arm/plat-samsung/include/plat/gpio-cfg.h
arch/arm/plat-samsung/pd.c
arch/arm/plat-samsung/pwm.c
arch/arm/tools/mach-types
arch/cris/arch-v10/drivers/Kconfig
arch/cris/arch-v32/drivers/Kconfig
arch/microblaze/include/asm/namei.h [deleted file]
arch/mips/cavium-octeon/flash_setup.c
arch/mips/cavium-octeon/smp.c
arch/mips/emma/common/prom.c
arch/mips/include/asm/mach-bcm47xx/gpio.h
arch/mips/include/asm/unistd.h
arch/mips/kernel/cevt-r4k.c
arch/mips/kernel/cpufreq/loongson2_clock.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/traps.c
arch/mips/lantiq/clk.c
arch/mips/lantiq/devices.c
arch/mips/lantiq/prom.c
arch/mips/lantiq/setup.c
arch/mips/lantiq/xway/clk-ase.c
arch/mips/lantiq/xway/clk-xway.c
arch/mips/lantiq/xway/devices.c
arch/mips/lantiq/xway/dma.c
arch/mips/lantiq/xway/gpio.c
arch/mips/lantiq/xway/gpio_ebu.c
arch/mips/lantiq/xway/gpio_stp.c
arch/mips/lantiq/xway/prom-ase.c
arch/mips/lantiq/xway/prom-xway.c
arch/mips/lantiq/xway/reset.c
arch/mips/nxp/pnx8550/common/pci.c [deleted file]
arch/mips/nxp/pnx8550/common/setup.c [deleted file]
arch/mips/pci/pci-alchemy.c
arch/mips/pci/pci-lantiq.c
arch/mips/pmc-sierra/yosemite/prom.c
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/dts/p1023rds.dts
arch/powerpc/configs/ppc44x_defconfig
arch/powerpc/include/asm/atomic.h
arch/powerpc/include/asm/bitops.h
arch/powerpc/include/asm/futex.h
arch/powerpc/include/asm/kvm.h
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/include/asm/sections.h
arch/powerpc/include/asm/synch.h
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/jump_label.c
arch/powerpc/kernel/kvm.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/traps.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/lib/feature-fixups.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/p3060_qds.c
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/ps3/interrupt.c
arch/powerpc/platforms/ps3/platform.h
arch/powerpc/platforms/ps3/smp.c
arch/powerpc/sysdev/ehv_pic.c
arch/powerpc/sysdev/fsl_lbc.c
arch/powerpc/sysdev/qe_lib/qe.c
arch/s390/Kconfig
arch/s390/crypto/crypt_s390.h
arch/s390/include/asm/kvm_host.h
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/setup.h
arch/s390/include/asm/timex.h
arch/s390/include/asm/unistd.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/early.c
arch/s390/kernel/setup.c
arch/s390/kernel/syscalls.S
arch/s390/kernel/topology.c
arch/s390/kernel/vmlinux.lds.S
arch/s390/kvm/diag.c
arch/s390/kvm/intercept.c
arch/s390/kvm/interrupt.c
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/priv.c
arch/s390/kvm/sigp.c
arch/s390/mm/fault.c
arch/sparc/include/asm/pgtable_32.h
arch/sparc/include/asm/pgtable_64.h
arch/sparc/kernel/entry.h
arch/sparc/kernel/module.c
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c
arch/sparc/kernel/sigutil_64.c
arch/sparc/mm/Makefile
arch/sparc/mm/generic_32.c [deleted file]
arch/sparc/mm/generic_64.c [deleted file]
arch/unicore32/Kconfig
arch/unicore32/Kconfig.debug
arch/unicore32/boot/compressed/Makefile
arch/unicore32/include/asm/bitops.h
arch/unicore32/include/asm/processor.h
arch/unicore32/kernel/ksyms.c
arch/unicore32/lib/findbit.S
arch/x86/include/asm/apic.h
arch/x86/include/asm/mach_traps.h
arch/x86/include/asm/mce.h
arch/x86/include/asm/mrst.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/alternative.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/cpu/mcheck/mce-inject.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/kvmclock.c
arch/x86/kernel/nmi.c
arch/x86/kernel/setup.c
arch/x86/kernel/x86_init.c
arch/x86/kvm/vmx.c
arch/x86/platform/mrst/mrst.c
arch/x86/um/asm/processor.h
arch/x86/xen/enlighten.c
arch/x86/xen/grant-table.c
block/blk-core.c
block/blk-map.c
block/genhd.c
drivers/acpi/apei/erst.c
drivers/ata/ahci_platform.c
drivers/ata/libata-sff.c
drivers/base/core.c
drivers/base/node.c
drivers/base/power/clock_ops.c
drivers/base/power/main.c
drivers/base/power/qos.c
drivers/block/cciss.c
drivers/block/cciss_scsi.c
drivers/block/loop.c
drivers/block/paride/pg.c
drivers/bluetooth/btusb.c
drivers/char/random.c
drivers/crypto/mv_cesa.c
drivers/devfreq/Kconfig
drivers/devfreq/devfreq.c
drivers/edac/mpc85xx_edac.c
drivers/firmware/dmi_scan.c
drivers/firmware/efivars.c
drivers/gpio/gpio-pca953x.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/exynos/exynos_drm_buf.c
drivers/gpu/drm/exynos/exynos_drm_buf.h
drivers/gpu/drm/exynos/exynos_drm_connector.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_crtc.h
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_encoder.c
drivers/gpu/drm/exynos/exynos_drm_encoder.h
drivers/gpu/drm/exynos/exynos_drm_fb.c
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/vga/vgaarb.c
drivers/hwmon/Kconfig
drivers/hwmon/ad7314.c
drivers/hwmon/ads7871.c
drivers/hwmon/exynos4_tmu.c
drivers/hwmon/gpio-fan.c
drivers/hwmon/jz4740-hwmon.c
drivers/hwmon/ntc_thermistor.c
drivers/hwmon/s3c-hwmon.c
drivers/hwmon/sch5627.c
drivers/hwmon/sch5636.c
drivers/hwmon/twl4030-madc-hwmon.c
drivers/hwmon/ultra45_env.c
drivers/hwmon/wm831x-hwmon.c
drivers/hwmon/wm8350-hwmon.c
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/busses/i2c-nuc900.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/ide/cy82c693.c
drivers/ide/icside.c
drivers/ide/piix.c
drivers/ide/triflex.c
drivers/infiniband/core/addr.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/cq.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/infiniband/hw/qib/qib_qsfp.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/input/mouse/elantech.c
drivers/input/serio/ams_delta_serio.c
drivers/input/serio/i8042-x86ia64io.h
drivers/leds/led-class.c
drivers/misc/Kconfig
drivers/misc/ad525x_dpot.h
drivers/misc/carma/carma-fpga-program.c
drivers/misc/carma/carma-fpga.c
drivers/misc/eeprom/Kconfig
drivers/misc/pch_phub.c
drivers/misc/spear13xx_pcie_gadget.c
drivers/net/Kconfig
drivers/net/bonding/bond_sysfs.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
drivers/net/ethernet/cadence/Kconfig
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/marvell/sky2.c
drivers/net/ethernet/marvell/sky2.h
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/nvidia/forcedeth.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
drivers/net/ethernet/rdc/r6040.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/sun/sunhme.c
drivers/net/ethernet/xilinx/ll_temac_main.c
drivers/net/hippi/Kconfig
drivers/net/usb/asix.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/lg-vl600.c
drivers/net/usb/smsc75xx.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/regd.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.h
drivers/net/wireless/brcm80211/brcmsmac/dma.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/wl12xx/scan.c
drivers/of/irq.c
drivers/pci/Kconfig
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_hpc.c
drivers/platform/x86/dell-laptop.c
drivers/regulator/aat2870-regulator.c
drivers/regulator/core.c
drivers/regulator/tps65910-regulator.c
drivers/regulator/twl-regulator.c
drivers/rtc/rtc-puv3.c
drivers/s390/char/zcore.c
drivers/s390/crypto/ap_bus.c
drivers/s390/net/Kconfig
drivers/s390/net/lcs.c
drivers/s390/net/netiucv.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l3_main.c
drivers/s390/net/qeth_l3_sys.c
drivers/scsi/aacraid/linit.c
drivers/scsi/hpsa.c
drivers/scsi/mpt2sas/mpt2sas_scsih.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_scan.c
drivers/spi/spi-nuc900.c
drivers/spi/spi-pl022.c
drivers/staging/et131x/Kconfig
drivers/staging/et131x/et131x.c
drivers/staging/iio/industrialio-core.c
drivers/staging/media/as102/as102_drv.c
drivers/staging/media/as102/as102_drv.h
drivers/staging/octeon/ethernet-tx.c
drivers/staging/slicoss/Kconfig
drivers/tty/hvc/hvc_dcc.c
drivers/tty/serial/Kconfig
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/crisv10.c
drivers/tty/serial/mfd.c
drivers/tty/serial/pch_uart.c
drivers/tty/tty_ldisc.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/hub.c
drivers/usb/core/quirks.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/ci13xxx_msm.c
drivers/usb/gadget/ci13xxx_udc.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/f_midi.c
drivers/usb/gadget/f_phonet.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/pch_udc.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/gadget/udc-core.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci-xls.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci.h
drivers/usb/host/pci-quirks.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/musb/Kconfig
drivers/usb/musb/am35x.c
drivers/usb/musb/da8xx.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_gadget.c
drivers/usb/renesas_usbhs/common.c
drivers/usb/renesas_usbhs/fifo.c
drivers/usb/renesas_usbhs/mod.h
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/renesas_usbhs/mod_host.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/storage/ene_ub6250.c
drivers/usb/storage/protocol.c
drivers/video/da8xx-fb.c
drivers/video/omap/dispc.c
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/hdmi.c
drivers/video/via/share.h
drivers/virtio/Kconfig
drivers/virtio/virtio_mmio.c
drivers/virtio/virtio_pci.c
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/adx_wdt.c [deleted file]
drivers/watchdog/s3c2410_wdt.c
drivers/watchdog/wm831x_wdt.c
drivers/xen/balloon.c
drivers/xen/gntalloc.c
drivers/xen/gntdev.c
drivers/xen/xenbus/xenbus_client.c
fs/bio.c
fs/btrfs/backref.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/scrub.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/volumes.h
fs/ceph/dir.c
fs/ceph/inode.c
fs/ceph/super.c
fs/dcache.c
fs/ecryptfs/crypto.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ext4/balloc.c
fs/ext4/inode.c
fs/ext4/super.c
fs/minix/bitmap.c
fs/minix/inode.c
fs/minix/minix.h
fs/namespace.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs3proc.c
fs/nfs/nfs4proc.c
fs/nfs/pnfs.c
fs/nfs/proc.c
fs/nfs/read.c
fs/nfs/super.c
fs/ocfs2/alloc.c
fs/ocfs2/aops.c
fs/ocfs2/aops.h
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/netdebug.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/cluster/tcp.h
fs/ocfs2/dir.c
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/dlm/dlmlock.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/dlm/dlmthread.c
fs/ocfs2/dlmglue.c
fs/ocfs2/extent_map.c
fs/ocfs2/extent_map.h
fs/ocfs2/file.c
fs/ocfs2/inode.c
fs/ocfs2/inode.h
fs/ocfs2/ioctl.c
fs/ocfs2/journal.c
fs/ocfs2/journal.h
fs/ocfs2/mmap.c
fs/ocfs2/move_extents.c
fs/ocfs2/ocfs2.h
fs/ocfs2/quota_local.c
fs/ocfs2/slot_map.c
fs/ocfs2/stack_o2cb.c
fs/ocfs2/super.c
fs/ocfs2/xattr.c
fs/pstore/platform.c
fs/xfs/xfs_qm.c
include/drm/drm_mode.h
include/drm/drm_pciids.h
include/drm/exynos_drm.h
include/drm/radeon_drm.h
include/linux/bio.h
include/linux/ceph/osd_client.h
include/linux/clocksource.h
include/linux/device.h
include/linux/fs.h
include/linux/genhd.h
include/linux/hugetlb.h
include/linux/i2c.h
include/linux/inet_diag.h
include/linux/init_task.h
include/linux/kvm.h
include/linux/mfd/tps65910.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h
include/linux/pci-ats.h
include/linux/pci.h
include/linux/pm.h
include/linux/pm_runtime.h
include/linux/pstore.h
include/linux/sched.h
include/linux/serial.h
include/linux/virtio_config.h
include/linux/virtio_mmio.h
include/linux/vmalloc.h
include/net/bluetooth/l2cap.h
include/net/cfg80211.h
include/video/omapdss.h
include/xen/platform_pci.h
kernel/cgroup_freezer.c
kernel/fork.c
kernel/hrtimer.c
kernel/irq/manage.c
kernel/irq/spurious.c
kernel/power/hibernate.c
kernel/power/main.c
kernel/time/clocksource.c
kernel/time/timekeeping.c
mm/backing-dev.c
mm/hugetlb.c
mm/nommu.c
mm/oom_kill.c
mm/page-writeback.c
mm/percpu-vm.c
mm/percpu.c
mm/slub.c
mm/vmalloc.c
net/bluetooth/hci_conn.c
net/bluetooth/l2cap_core.c
net/bridge/br_multicast.c
net/ceph/osd_client.c
net/ipv4/ah4.c
net/ipv4/inet_diag.c
net/ipv4/ip_options.c
net/ipv4/ping.c
net/ipv4/route.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv6/ah6.c
net/ipv6/ip6_input.c
net/ipv6/ip6_tunnel.c
net/l2tp/l2tp_core.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/util.c
net/rds/Kconfig
net/sunrpc/xprtsock.c
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/scan.c
security/keys/encrypted-keys/Makefile
security/keys/encrypted-keys/encrypted.c
security/keys/encrypted-keys/encrypted.h
security/keys/user_defined.c
security/smack/smackfs.c
sound/pci/cs5535audio/cs5535audio_pcm.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_cirrus.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/lx_core.c
sound/pci/lx6464es/lx_core.h
sound/pci/rme9652/hdspm.c
sound/soc/codecs/adau1373.c
sound/soc/codecs/cs4271.c
sound/soc/codecs/rt5631.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sta32x.c
sound/soc/codecs/sta32x.h
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8993.c
sound/soc/codecs/wm9081.c
sound/soc/codecs/wm9090.c
sound/soc/codecs/wm_hubs.c
sound/soc/fsl/fsl_ssi.c
sound/soc/nuc900/nuc900-ac97.c
tools/testing/ktest/ktest.pl

index 2b5d56127fce4d7f9a6f83b535cdfcf469f83e0b..c1eb41cb9876083d3df79a6a995b692762acd21b 100644 (file)
@@ -206,16 +206,3 @@ Description:
                when a discarded area is read the discard_zeroes_data
                parameter will be set to one. Otherwise it will be 0 and
                the result of reading a discarded area is undefined.
-What:          /sys/block/<disk>/alias
-Date:          Aug 2011
-Contact:       Nao Nishijima <nao.nishijima.xt@hitachi.com>
-Description:
-               A raw device name of a disk does not always point a same disk
-               each boot-up time. Therefore, users have to use persistent
-               device names, which udev creates when the kernel finds a disk,
-               instead of raw device name. However, kernel doesn't show those
-               persistent names on its messages (e.g. dmesg).
-               This file can store an alias of the disk and it would be
-               appeared in kernel messages if it is set. A disk can have an
-               alias which length is up to 255bytes. Users can use alphabets,
-               numbers, "-" and "_" in alias name. This file is writeonce.
index 54883de5d5f9b598ab981de82269c908dec86114..ac3d0018140cd34cd7dd242334de64713406c6b6 100644 (file)
@@ -520,6 +520,11 @@ Here's a description of the fields of <varname>struct uio_mem</varname>:
 </para>
 
 <itemizedlist>
+<listitem><para>
+<varname>const char *name</varname>: Optional. Set this to help identify
+the memory region, it will show up in the corresponding sysfs node.
+</para></listitem>
+
 <listitem><para>
 <varname>int memtype</varname>: Required if the mapping is used. Set this to
 <varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
@@ -553,7 +558,7 @@ instead to remember such an address.
 </itemizedlist>
 
 <para>
-Please do not touch the <varname>kobj</varname> element of
+Please do not touch the <varname>map</varname> element of
 <varname>struct uio_mem</varname>! It is used by the UIO framework
 to set up sysfs files for this mapping. Simply leave it alone.
 </para>
index 71464e09ec1841a39f031d972b281488e5d703af..b79d0a13e7cddf2512ef29069d60a54bf0399b02 100644 (file)
@@ -98,14 +98,12 @@ You must enable "SCSI tape drive support for Smart Array 5xxx" and
 "SCSI support" in your kernel configuration to be able to use SCSI
 tape drives with your Smart Array 5xxx controller.
 
-Additionally, note that the driver will not engage the SCSI core at init 
-time.  The driver must be directed to dynamically engage the SCSI core via 
-the /proc filesystem entry which the "block" side of the driver creates as 
-/proc/driver/cciss/cciss* at runtime.  This is because at driver init time, 
-the SCSI core may not yet be initialized (because the driver is a block 
-driver) and attempting to register it with the SCSI core in such a case 
-would cause a hang.  This is best done via an initialization script 
-(typically in /etc/init.d, but could vary depending on distribution). 
+Additionally, note that the driver will engage the SCSI core at init
+time if any tape drives or medium changers are detected.  The driver may
+also be directed to dynamically engage the SCSI core via the /proc filesystem
+entry which the "block" side of the driver creates as
+/proc/driver/cciss/cciss* at runtime.  This is best done via a script.
+
 For example:
 
        for x in /proc/driver/cciss/cciss[0-9]*
index e8552782b440af99ed14a6e851e3db5ed47d05fd..874921e97802d1d8c0e7cc2b694cca4bc3f18bf4 100644 (file)
@@ -33,6 +33,7 @@ qcom  Qualcomm, Inc.
 ramtron        Ramtron International
 samsung        Samsung Semiconductor
 schindler      Schindler
+sil    Silicon Image
 simtek
 sirf   SiRF Technology, Inc.
 stericsson     ST-Ericsson
index 64087c34327fe0ba11e790e0a41224b8e7c1d30c..7671352216f1369d8d3c7dd02f9ae06fd9f90c87 100644 (file)
@@ -63,8 +63,8 @@ IRC network.
 Userspace tools for creating and manipulating Btrfs file systems are
 available from the git repository at the following location:
 
- http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs-unstable.git
- git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs-unstable.git
+ http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs.git
+ git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs.git
 
 These include the following tools:
 
index e9890709c508b25ed9878ab979797d1fc58a7a4b..cdfe13901b99cb64a9bbc2484b13ca7cd174e878 100644 (file)
@@ -1,22 +1,24 @@
 The I2C protocol knows about two kinds of device addresses: normal 7 bit
 addresses, and an extended set of 10 bit addresses. The sets of addresses
 do not intersect: the 7 bit address 0x10 is not the same as the 10 bit
-address 0x10 (though a single device could respond to both of them). You
-select a 10 bit address by adding an extra byte after the address
-byte:
-  S Addr7 Rd/Wr ....
-becomes
-  S 11110 Addr10 Rd/Wr
-S is the start bit, Rd/Wr the read/write bit, and if you count the number
-of bits, you will see the there are 8 after the S bit for 7 bit addresses,
-and 16 after the S bit for 10 bit addresses.
+address 0x10 (though a single device could respond to both of them).
 
-WARNING! The current 10 bit address support is EXPERIMENTAL. There are
-several places in the code that will cause SEVERE PROBLEMS with 10 bit
-addresses, even though there is some basic handling and hooks. Also,
-almost no supported adapter handles the 10 bit addresses correctly.
+I2C messages to and from 10-bit address devices have a different format.
+See the I2C specification for the details.
 
-As soon as a real 10 bit address device is spotted 'in the wild', we
-can and will add proper support. Right now, 10 bit address devices
-are defined by the I2C protocol, but we have never seen a single device
-which supports them.
+The current 10 bit address support is minimal. It should work, however
+you can expect some problems along the way:
+* Not all bus drivers support 10-bit addresses. Some don't because the
+  hardware doesn't support them (SMBus doesn't require 10-bit address
+  support for example), some don't because nobody bothered adding the
+  code (or it's there but not working properly.) Software implementation
+  (i2c-algo-bit) is known to work.
+* Some optional features do not support 10-bit addresses. This is the
+  case of automatic detection and instantiation of devices by their,
+  drivers, for example.
+* Many user-space packages (for example i2c-tools) lack support for
+  10-bit addresses.
+
+Note that 10-bit address devices are still pretty rare, so the limitations
+listed above could stay for a long time, maybe even forever if nobody
+needs them to be fixed.
index cb7f3148035dbeaabbcc514ddf53705733321d66..f049a1ca186fbf6eb5e55ed9eb3a65bb8601b1f8 100644 (file)
@@ -20,7 +20,7 @@ ip_no_pmtu_disc - BOOLEAN
        default FALSE
 
 min_pmtu - INTEGER
-       default 562 - minimum discovered Path MTU
+       default 552 - minimum discovered Path MTU
 
 route/max_size - INTEGER
        Maximum number of routes allowed in the kernel.  Increase
index 646a89e0c07d50c682912ef0200dc087363cd37f..3139fb505dcec97cb609e02326110e8b5725a43a 100644 (file)
@@ -123,9 +123,10 @@ please refer directly to the source code for more information about it.
 Subsystem-Level Methods
 -----------------------
 The core methods to suspend and resume devices reside in struct dev_pm_ops
-pointed to by the pm member of struct bus_type, struct device_type and
-struct class.  They are mostly of interest to the people writing infrastructure
-for buses, like PCI or USB, or device type and device class drivers.
+pointed to by the ops member of struct dev_pm_domain, or by the pm member of
+struct bus_type, struct device_type and struct class.  They are mostly of
+interest to the people writing infrastructure for platforms and buses, like PCI
+or USB, or device type and device class drivers.
 
 Bus drivers implement these methods as appropriate for the hardware and the
 drivers using it; PCI works differently from USB, and so on.  Not many people
@@ -139,41 +140,57 @@ sequencing in the driver model tree.
 
 /sys/devices/.../power/wakeup files
 -----------------------------------
-All devices in the driver model have two flags to control handling of wakeup
-events (hardware signals that can force the device and/or system out of a low
-power state).  These flags are initialized by bus or device driver code using
+All device objects in the driver model contain fields that control the handling
+of system wakeup events (hardware signals that can force the system out of a
+sleep state).  These fields are initialized by bus or device driver code using
 device_set_wakeup_capable() and device_set_wakeup_enable(), defined in
 include/linux/pm_wakeup.h.
 
-The "can_wakeup" flag just records whether the device (and its driver) can
+The "power.can_wakeup" flag just records whether the device (and its driver) can
 physically support wakeup events.  The device_set_wakeup_capable() routine
-affects this flag.  The "should_wakeup" flag controls whether the device should
-try to use its wakeup mechanism.  device_set_wakeup_enable() affects this flag;
-for the most part drivers should not change its value.  The initial value of
-should_wakeup is supposed to be false for the majority of devices; the major
-exceptions are power buttons, keyboards, and Ethernet adapters whose WoL
-(wake-on-LAN) feature has been set up with ethtool.  It should also default
-to true for devices that don't generate wakeup requests on their own but merely
-forward wakeup requests from one bus to another (like PCI bridges).
+affects this flag.  The "power.wakeup" field is a pointer to an object of type
+struct wakeup_source used for controlling whether or not the device should use
+its system wakeup mechanism and for notifying the PM core of system wakeup
+events signaled by the device.  This object is only present for wakeup-capable
+devices (i.e. devices whose "can_wakeup" flags are set) and is created (or
+removed) by device_set_wakeup_capable().
 
 Whether or not a device is capable of issuing wakeup events is a hardware
 matter, and the kernel is responsible for keeping track of it.  By contrast,
 whether or not a wakeup-capable device should issue wakeup events is a policy
 decision, and it is managed by user space through a sysfs attribute: the
-power/wakeup file.  User space can write the strings "enabled" or "disabled" to
-set or clear the "should_wakeup" flag, respectively.  This file is only present
-for wakeup-capable devices (i.e. devices whose "can_wakeup" flags are set)
-and is created (or removed) by device_set_wakeup_capable().  Reads from the
-file will return the corresponding string.
-
-The device_may_wakeup() routine returns true only if both flags are set.
+"power/wakeup" file.  User space can write the strings "enabled" or "disabled"
+to it to indicate whether or not, respectively, the device is supposed to signal
+system wakeup.  This file is only present if the "power.wakeup" object exists
+for the given device and is created (or removed) along with that object, by
+device_set_wakeup_capable().  Reads from the file will return the corresponding
+string.
+
+The "power/wakeup" file is supposed to contain the "disabled" string initially
+for the majority of devices; the major exceptions are power buttons, keyboards,
+and Ethernet adapters whose WoL (wake-on-LAN) feature has been set up with
+ethtool.  It should also default to "enabled" for devices that don't generate
+wakeup requests on their own but merely forward wakeup requests from one bus to
+another (like PCI Express ports).
+
+The device_may_wakeup() routine returns true only if the "power.wakeup" object
+exists and the corresponding "power/wakeup" file contains the string "enabled".
 This information is used by subsystems, like the PCI bus type code, to see
 whether or not to enable the devices' wakeup mechanisms.  If device wakeup
 mechanisms are enabled or disabled directly by drivers, they also should use
 device_may_wakeup() to decide what to do during a system sleep transition.
-However for runtime power management, wakeup events should be enabled whenever
-the device and driver both support them, regardless of the should_wakeup flag.
-
+Device drivers, however, are not supposed to call device_set_wakeup_enable()
+directly in any case.
+
+It ought to be noted that system wakeup is conceptually different from "remote
+wakeup" used by runtime power management, although it may be supported by the
+same physical mechanism.  Remote wakeup is a feature allowing devices in
+low-power states to trigger specific interrupts to signal conditions in which
+they should be put into the full-power state.  Those interrupts may or may not
+be used to signal system wakeup events, depending on the hardware design.  On
+some systems it is impossible to trigger them from system sleep states.  In any
+case, remote wakeup should always be enabled for runtime power management for
+all devices and drivers that support it.
 
 /sys/devices/.../power/control files
 ------------------------------------
@@ -249,20 +266,31 @@ for every device before the next phase begins.  Not all busses or classes
 support all these callbacks and not all drivers use all the callbacks.  The
 various phases always run after tasks have been frozen and before they are
 unfrozen.  Furthermore, the *_noirq phases run at a time when IRQ handlers have
-been disabled (except for those marked with the IRQ_WAKEUP flag).
-
-All phases use bus, type, or class callbacks (that is, methods defined in
-dev->bus->pm, dev->type->pm, or dev->class->pm).  These callbacks are mutually
-exclusive, so if the device type provides a struct dev_pm_ops object pointed to
-by its pm field (i.e. both dev->type and dev->type->pm are defined), the
-callbacks included in that object (i.e. dev->type->pm) will be used.  Otherwise,
-if the class provides a struct dev_pm_ops object pointed to by its pm field
-(i.e. both dev->class and dev->class->pm are defined), the PM core will use the
-callbacks from that object (i.e. dev->class->pm).  Finally, if the pm fields of
-both the device type and class objects are NULL (or those objects do not exist),
-the callbacks provided by the bus (that is, the callbacks from dev->bus->pm)
-will be used (this allows device types to override callbacks provided by bus
-types or classes if necessary).
+been disabled (except for those marked with the IRQF_NO_SUSPEND flag).
+
+All phases use PM domain, bus, type, or class callbacks (that is, methods
+defined in dev->pm_domain->ops, dev->bus->pm, dev->type->pm, or dev->class->pm).
+These callbacks are regarded by the PM core as mutually exclusive.  Moreover,
+PM domain callbacks always take precedence over bus, type and class callbacks,
+while type callbacks take precedence over bus and class callbacks, and class
+callbacks take precedence over bus callbacks.  To be precise, the following
+rules are used to determine which callback to execute in the given phase:
+
+    1. If dev->pm_domain is present, the PM core will attempt to execute the
+       callback included in dev->pm_domain->ops.  If that callback is not
+       present, no action will be carried out for the given device.
+
+    2. Otherwise, if both dev->type and dev->type->pm are present, the callback
+       included in dev->type->pm will be executed.
+
+    3. Otherwise, if both dev->class and dev->class->pm are present, the
+       callback included in dev->class->pm will be executed.
+
+    4. Otherwise, if both dev->bus and dev->bus->pm are present, the callback
+       included in dev->bus->pm will be executed.
+
+This allows PM domains and device types to override callbacks provided by bus
+types or device classes if necessary.
 
 These callbacks may in turn invoke device- or driver-specific methods stored in
 dev->driver->pm, but they don't have to.
@@ -283,9 +311,8 @@ When the system goes into the standby or memory sleep state, the phases are:
 
        After the prepare callback method returns, no new children may be
        registered below the device.  The method may also prepare the device or
-       driver in some way for the upcoming system power transition (for
-       example, by allocating additional memory required for this purpose), but
-       it should not put the device into a low-power state.
+       driver in some way for the upcoming system power transition, but it
+       should not put the device into a low-power state.
 
     2. The suspend methods should quiesce the device to stop it from performing
        I/O.  They also may save the device registers and put it into the
index 5336149f831ba47d6215ccc1d9f9d3f66df370df..c2ae8bf77d46d6fbd12490a6a9aacc14c11c4931 100644 (file)
@@ -44,25 +44,33 @@ struct dev_pm_ops {
 };
 
 The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks
-are executed by the PM core for either the power domain, or the device type
-(if the device power domain's struct dev_pm_ops does not exist), or the class
-(if the device power domain's and type's struct dev_pm_ops object does not
-exist), or the bus type (if the device power domain's, type's and class'
-struct dev_pm_ops objects do not exist) of the given device, so the priority
-order of callbacks from high to low is that power domain callbacks, device
-type callbacks, class callbacks and bus type callbacks, and the high priority
-one will take precedence over low priority one. The bus type, device type and
-class callbacks are referred to as subsystem-level callbacks in what follows,
-and generally speaking, the power domain callbacks are used for representing
-power domains within a SoC.
+are executed by the PM core for the device's subsystem that may be either of
+the following:
+
+  1. PM domain of the device, if the device's PM domain object, dev->pm_domain,
+     is present.
+
+  2. Device type of the device, if both dev->type and dev->type->pm are present.
+
+  3. Device class of the device, if both dev->class and dev->class->pm are
+     present.
+
+  4. Bus type of the device, if both dev->bus and dev->bus->pm are present.
+
+The PM core always checks which callback to use in the order given above, so the
+priority order of callbacks from high to low is: PM domain, device type, class
+and bus type.  Moreover, the high-priority one will always take precedence over
+a low-priority one.  The PM domain, bus type, device type and class callbacks
+are referred to as subsystem-level callbacks in what follows.
 
 By default, the callbacks are always invoked in process context with interrupts
 enabled.  However, subsystems can use the pm_runtime_irq_safe() helper function
-to tell the PM core that a device's ->runtime_suspend() and ->runtime_resume()
-callbacks should be invoked in atomic context with interrupts disabled.
-This implies that these callback routines must not block or sleep, but it also
-means that the synchronous helper functions listed at the end of Section 4 can
-be used within an interrupt handler or in an atomic context.
+to tell the PM core that their ->runtime_suspend(), ->runtime_resume() and
+->runtime_idle() callbacks may be invoked in atomic context with interrupts
+disabled for a given device.  This implies that the callback routines in
+question must not block or sleep, but it also means that the synchronous helper
+functions listed at the end of Section 4 may be used for that device within an
+interrupt handler or generally in an atomic context.
 
 The subsystem-level suspend callback is _entirely_ _responsible_ for handling
 the suspend of the device as appropriate, which may, but need not include
index 079cb3df62cf6ff9908bebe493344d1cfdd99846..41c8378c0b2fb9ee86d3a781e8aaff6cad33ff9a 100644 (file)
 
        struct serial_rs485 rs485conf;
 
-       /* Set RS485 mode: */
+       /* Enable RS485 mode: */
        rs485conf.flags |= SER_RS485_ENABLED;
 
+       /* Set logical level for RTS pin equal to 1 when sending: */
+       rs485conf.flags |= SER_RS485_RTS_ON_SEND;
+       /* or, set logical level for RTS pin equal to 0 when sending: */
+       rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
+
+       /* Set logical level for RTS pin equal to 1 after sending: */
+       rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
+       /* or, set logical level for RTS pin equal to 0 after sending: */
+       rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
+
        /* Set rts delay before send, if needed: */
-       rs485conf.flags |= SER_RS485_RTS_BEFORE_SEND;
        rs485conf.delay_rts_before_send = ...;
 
        /* Set rts delay after send, if needed: */
-       rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
        rs485conf.delay_rts_after_send = ...;
 
        /* Set this flag if you want to receive data even whilst sending data */
index 03e2771ddeef53545357cc4bfbde29a378f9206d..91fee3b45fb80f75ac406dfbba093f1f49a418c1 100644 (file)
@@ -579,7 +579,7 @@ Development Tree
 ~~~~~~~~~~~~~~~~
 The latest development codes for HD-audio are found on sound git tree:
 
-- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
+- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 
 The master branch or for-next branches can be used as the main
 development branches in general while the HD-audio specific patches
@@ -594,7 +594,7 @@ is, installed via the usual spells: configure, make and make
 install(-modules).  See INSTALL in the package.  The snapshot tarballs
 are found at:
 
-- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/snapshot/
+- ftp://ftp.suse.com/pub/people/tiwai/snapshot/
 
 
 Sending a Bug Report
@@ -696,7 +696,7 @@ via hda-verb won't change the mixer value.
 
 The hda-verb program is found in the ftp directory:
 
-- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/misc/
+- ftp://ftp.suse.com/pub/people/tiwai/misc/
 
 Also a git repository is available:
 
@@ -764,7 +764,7 @@ operation, the jack plugging simulation, etc.
 
 The package is found in:
 
-- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/misc/
+- ftp://ftp.suse.com/pub/people/tiwai/misc/
 
 A git repository is available:
 
index 071a9967434750dffe00e68904832f5e374a6a6c..447560284996b3dfe8025180efdc87b1371906fd 100644 (file)
@@ -789,6 +789,7 @@ L:  linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 T:     git git://git.pengutronix.de/git/imx/linux-2.6.git
 F:     arch/arm/mach-mx*/
+F:     arch/arm/mach-imx/
 F:     arch/arm/plat-mxc/
 
 ARM/FREESCALE IMX51
@@ -804,6 +805,13 @@ S: Maintained
 T:     git git://git.linaro.org/people/shawnguo/linux-2.6.git
 F:     arch/arm/mach-imx/*imx6*
 
+ARM/FREESCALE MXS ARM ARCHITECTURE
+M:     Shawn Guo <shawn.guo@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+T:     git git://git.linaro.org/people/shawnguo/linux-2.6.git
+F:     arch/arm/mach-mxs/
+
 ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1789,6 +1797,14 @@ F:       include/net/cfg80211.h
 F:     net/wireless/*
 X:     net/wireless/wext*
 
+CHAR and MISC DRIVERS
+M:     Arnd Bergmann <arnd@arndb.de>
+M:     Greg Kroah-Hartman <greg@kroah.com>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
+S:     Maintained
+F:     drivers/char/*
+F:     drivers/misc/*
+
 CHECKPATCH
 M:     Andy Whitcroft <apw@canonical.com>
 S:     Supported
@@ -1927,9 +1943,11 @@ S:       Maintained
 F:     drivers/connector/
 
 CONTROL GROUPS (CGROUPS)
-M:     Paul Menage <paul@paulmenage.org>
+M:     Tejun Heo <tj@kernel.org>
 M:     Li Zefan <lizf@cn.fujitsu.com>
 L:     containers@lists.linux-foundation.org
+L:     cgroups@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git
 S:     Maintained
 F:     include/linux/cgroup*
 F:     kernel/cgroup*
@@ -2584,7 +2602,7 @@ S:        Maintained
 F:     drivers/net/ethernet/i825xx/eexpress.*
 
 ETHERNET BRIDGE
-M:     Stephen Hemminger <shemminger@linux-foundation.org>
+M:     Stephen Hemminger <shemminger@vyatta.com>
 L:     bridge@lists.linux-foundation.org
 L:     netdev@vger.kernel.org
 W:     http://www.linuxfoundation.org/en/Net:Bridge
@@ -3718,7 +3736,7 @@ F:        fs/jbd2/
 F:     include/linux/jbd2.h
 
 JSM Neo PCI based serial card
-M:     Breno Leitao <leitao@linux.vnet.ibm.com>
+M:     Lucas Tavares <lucaskt@linux.vnet.ibm.com>
 L:     linux-serial@vger.kernel.org
 S:     Maintained
 F:     drivers/tty/serial/jsm/
@@ -4304,6 +4322,7 @@ MEMORY RESOURCE CONTROLLER
 M:     Balbir Singh <bsingharora@gmail.com>
 M:     Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
 M:     KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+L:     cgroups@vger.kernel.org
 L:     linux-mm@kvack.org
 S:     Maintained
 F:     mm/memcontrol.c
@@ -4337,7 +4356,7 @@ MIPS
 M:     Ralf Baechle <ralf@linux-mips.org>
 L:     linux-mips@linux-mips.org
 W:     http://www.linux-mips.org/
-T:     git git://git.linux-mips.org/pub/scm/linux.git
+T:     git git://git.linux-mips.org/pub/scm/ralf/linux.git
 Q:     http://patchwork.linux-mips.org/project/linux-mips/list/
 S:     Supported
 F:     Documentation/mips/
@@ -4470,7 +4489,7 @@ S:        Supported
 F:     drivers/infiniband/hw/nes/
 
 NETEM NETWORK EMULATOR
-M:     Stephen Hemminger <shemminger@linux-foundation.org>
+M:     Stephen Hemminger <shemminger@vyatta.com>
 L:     netem@lists.linux-foundation.org
 S:     Maintained
 F:     net/sched/sch_netem.c
@@ -4947,7 +4966,7 @@ F:        drivers/char/ppdev.c
 F:     include/linux/ppdev.h
 
 PARAVIRT_OPS INTERFACE
-M:     Jeremy Fitzhardinge <jeremy@xensource.com>
+M:     Jeremy Fitzhardinge <jeremy@goop.org>
 M:     Chris Wright <chrisw@sous-sol.org>
 M:     Alok Kataria <akataria@vmware.com>
 M:     Rusty Russell <rusty@rustcorp.com.au>
@@ -5656,7 +5675,6 @@ F:        drivers/media/video/*7146*
 F:     include/media/*7146*
 
 SAMSUNG AUDIO (ASoC) DRIVERS
-M:     Jassi Brar <jassisinghbrar@gmail.com>
 M:     Sangbeom Kim <sbkim73@samsung.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
@@ -5985,7 +6003,7 @@ S:        Maintained
 F:     drivers/usb/misc/sisusbvga/
 
 SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
-M:     Stephen Hemminger <shemminger@linux-foundation.org>
+M:     Stephen Hemminger <shemminger@vyatta.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/marvell/sk*
@@ -7399,8 +7417,8 @@ S:        Maintained
 F:     arch/x86/kernel/cpu/mcheck/*
 
 XEN HYPERVISOR INTERFACE
-M:     Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
 M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+M:     Jeremy Fitzhardinge <jeremy@goop.org>
 L:     xen-devel@lists.xensource.com (moderated for non-subscribers)
 L:     virtualization@lists.linux-foundation.org
 S:     Supported
@@ -7433,7 +7451,8 @@ F:        drivers/xen/*swiotlb*
 
 XFS FILESYSTEM
 P:     Silicon Graphics Inc
-M:     Alex Elder <aelder@sgi.com>
+M:     Ben Myers <bpm@sgi.com>
+M:     Alex Elder <elder@kernel.org>
 M:     xfs-masters@oss.sgi.com
 L:     xfs@oss.sgi.com
 W:     http://oss.sgi.com/projects/xfs
index dab8610c4d6f63a2cc589764596e07229dd7c761..12aafc20efbd0d610430d3a88df4e6359093cfc1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 2
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc4
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
index 44789eff983f444c22cd967cbe418f7e50159358..e084b7e981e8ff301aaae64ef3a2dc7e66701247 100644 (file)
@@ -1231,7 +1231,7 @@ config ARM_ERRATA_742231
          capabilities of the processor.
 
 config PL310_ERRATA_588369
-       bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
+       bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
        depends on CACHE_L2X0
        help
           The PL310 L2 cache controller implements three types of Clean &
@@ -1256,7 +1256,7 @@ config ARM_ERRATA_720789
          entries regardless of the ASID.
 
 config PL310_ERRATA_727915
-       bool "Background Clean & Invalidate by Way operation can cause data corruption"
+       bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
        depends on CACHE_L2X0
        help
          PL310 implements the Clean & Invalidate by Way L2 cache maintenance
@@ -1289,8 +1289,8 @@ config ARM_ERRATA_751472
          operation is received by a CPU before the ICIALLUIS has completed,
          potentially leading to corrupted entries in the cache or TLB.
 
-config ARM_ERRATA_753970
-       bool "ARM errata: cache sync operation may be faulty"
+config PL310_ERRATA_753970
+       bool "PL310 errata: cache sync operation may be faulty"
        depends on CACHE_PL310
        help
          This option enables the workaround for the 753970 PL310 (r3p0) erratum.
@@ -1352,6 +1352,18 @@ config ARM_ERRATA_764369
          relevant cache maintenance functions and sets a specific bit
          in the diagnostic control register of the SCU.
 
+config PL310_ERRATA_769419
+       bool "PL310 errata: no automatic Store Buffer drain"
+       depends on CACHE_L2X0
+       help
+         On revisions of the PL310 prior to r3p2, the Store Buffer does
+         not automatically drain. This can cause normal, non-cacheable
+         writes to be retained when the memory system is idle, leading
+         to suboptimal I/O performance for drivers using coherent DMA.
+         This option adds a write barrier to the cpu_idle loop so that,
+         on systems with an outer cache, the store buffer is drained
+         explicitly.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
index 176062ac7f07305014357372c42285ff07a09c68..5df26a9976a26c10ddfcf0f788302dd2caeb8769 100644 (file)
@@ -65,6 +65,8 @@ $(obj)/%.dtb: $(src)/dts/%.dts
 
 $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
 
+clean-files := *.dtb
+
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
                   -C none -a $(LOADADDR) -e $(STARTADDR) \
index a1feb6b4f9f545f6d53d6e78bf1d04d62b6d4bdd..b2dc2dd7f1df6d25fbba306e0822563883b18859 100644 (file)
@@ -612,7 +612,8 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
                sizeof(u32));
        BUG_ON(!gic->saved_ppi_conf);
 
-       cpu_pm_register_notifier(&gic_notifier_block);
+       if (gic == &gic_data[0])
+               cpu_pm_register_notifier(&gic_notifier_block);
 }
 #else
 static void __init gic_pm_init(struct gic_chip_data *gic)
@@ -696,12 +697,14 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
         * For primary GICs, skip over SGIs.
         * For secondary GICs, skip over PPIs, too.
         */
+       domain->hwirq_base = 32;
        if (gic_nr == 0) {
-               domain->hwirq_base = 16;
-               if (irq_start > 0)
-                       irq_start = (irq_start & ~31) + 16;
-       } else
-               domain->hwirq_base = 32;
+               if ((irq_start & 31) > 0) {
+                       domain->hwirq_base = 16;
+                       if (irq_start != -1)
+                               irq_start = (irq_start & ~31) + 16;
+               }
+       }
 
        /*
         * Find out how many interrupts are supported.
index 7129cfbdacd6887920cf28994625be7b35f65503..f407a6b35d3dd1e6ad1e72afec38837dcfdd796a 100644 (file)
@@ -1211,8 +1211,8 @@ static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc)
        ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT);
        ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT);
 
-       ccr |= (rqc->dcctl << CC_SRCCCTRL_SHFT);
-       ccr |= (rqc->scctl << CC_DSTCCTRL_SHFT);
+       ccr |= (rqc->scctl << CC_SRCCCTRL_SHFT);
+       ccr |= (rqc->dcctl << CC_DSTCCTRL_SHFT);
 
        ccr |= (rqc->swap << CC_SWAP_SHFT);
 
@@ -1623,6 +1623,11 @@ static inline int _alloc_event(struct pl330_thread *thrd)
        return -1;
 }
 
+static bool _chan_ns(const struct pl330_info *pi, int i)
+{
+       return pi->pcfg.irq_ns & (1 << i);
+}
+
 /* Upon success, returns IdentityToken for the
  * allocated channel, NULL otherwise.
  */
@@ -1647,7 +1652,8 @@ void *pl330_request_channel(const struct pl330_info *pi)
 
        for (i = 0; i < chans; i++) {
                thrd = &pl330->channels[i];
-               if (thrd->free) {
+               if ((thrd->free) && (!_manager_ns(thrd) ||
+                                       _chan_ns(pi, i))) {
                        thrd->ev = _alloc_event(thrd);
                        if (thrd->ev >= 0) {
                                thrd->free = false;
similarity index 93%
rename from arch/arm/configs/at91cap9adk_defconfig
rename to arch/arm/configs/at91cap9_defconfig
index ffb1edd933633b6f5cc661df0347ba2f4416b9fc..8826eb218e73f861a1dc36a1dc875c4430b28a50 100644 (file)
@@ -38,7 +38,6 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -52,16 +51,12 @@ CONFIG_MTD_NAND_ATMEL=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_MACB=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
@@ -81,7 +76,6 @@ CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_FB=y
 CONFIG_FB_ATMEL=y
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
@@ -99,7 +93,6 @@ CONFIG_MMC_AT91=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT91SAM9=y
 CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
index 38cb7c98542623a92cc7791a89f701e9fe5adf48..bbe4e1a1f5d86f81464e393e2fd2ab228e34542c 100644 (file)
@@ -5,7 +5,6 @@ CONFIG_SYSVIPC=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_MODULES=y
 CONFIG_MODULE_FORCE_LOAD=y
@@ -56,7 +55,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
@@ -75,18 +73,8 @@ CONFIG_IPV6_TUNNEL=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_AFS_PARTS=y
 CONFIG_MTD_CHAR=y
@@ -108,8 +96,6 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_TCLIB=y
-CONFIG_EEPROM_LEGACY=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_BLK_DEV_SR=m
@@ -119,14 +105,23 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_TUN=m
+CONFIG_ARM_AT91_ETHER=y
 CONFIG_PHYLIB=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_SMSC_PHY=y
 CONFIG_MICREL_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=y
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
 CONFIG_USB_CATC=m
 CONFIG_USB_KAWETH=m
 CONFIG_USB_PEGASUS=m
@@ -139,18 +134,6 @@ CONFIG_USB_NET_RNDIS_HOST=m
 CONFIG_USB_ALI_M5632=y
 CONFIG_USB_AN2720=y
 CONFIG_USB_EPSON2888=y
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
@@ -158,9 +141,9 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_LEGACY_PTY_COUNT=32
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=32
 CONFIG_HW_RANDOM=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
@@ -290,7 +273,6 @@ CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
-CONFIG_SMB_FS=m
 CONFIG_CIFS=m
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_MAC_PARTITION=y
@@ -335,7 +317,6 @@ CONFIG_NLS_UTF8=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_CRYPTO_PCBC=y
 CONFIG_CRYPTO_SHA1=y
similarity index 86%
rename from arch/arm/configs/at91sam9260ek_defconfig
rename to arch/arm/configs/at91sam9260_defconfig
index f8a9226413bfe59735be5a6c9538a3c200bc5b0a..505b3765f87ebfb269184a11b9b096dc4fff8fea 100644 (file)
@@ -12,11 +12,23 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_AT91=y
 CONFIG_ARCH_AT91SAM9260=y
+CONFIG_ARCH_AT91SAM9260_SAM9XE=y
 CONFIG_MACH_AT91SAM9260EK=y
+CONFIG_MACH_CAM60=y
+CONFIG_MACH_SAM9_L9260=y
+CONFIG_MACH_AFEB9260=y
+CONFIG_MACH_USB_A9260=y
+CONFIG_MACH_QIL_A9260=y
+CONFIG_MACH_CPU9260=y
+CONFIG_MACH_FLEXIBITY=y
+CONFIG_MACH_SNAPPER_9260=y
+CONFIG_MACH_AT91SAM_DT=y
 CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 # CONFIG_ARM_THUMB is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
 CONFIG_FPE_NWFPE=y
 CONFIG_NET=y
@@ -33,12 +45,10 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_MACB=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
@@ -55,7 +65,6 @@ CONFIG_I2C_GPIO=y
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_AT91SAM9X_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
 # CONFIG_USB_HID is not set
 CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
@@ -71,7 +80,6 @@ CONFIG_USB_G_SERIAL=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT91SAM9=y
 CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_CRAMFS=y
similarity index 90%
rename from arch/arm/configs/at91sam9g20ek_defconfig
rename to arch/arm/configs/at91sam9g20_defconfig
index 9e90e6d792973042ec81faf2f78433e416a2752d..9123568d9a8db424f34fceaa66aa69d5fb4374fe 100644 (file)
@@ -14,6 +14,15 @@ CONFIG_ARCH_AT91=y
 CONFIG_ARCH_AT91SAM9G20=y
 CONFIG_MACH_AT91SAM9G20EK=y
 CONFIG_MACH_AT91SAM9G20EK_2MMC=y
+CONFIG_MACH_CPU9G20=y
+CONFIG_MACH_ACMENETUSFOXG20=y
+CONFIG_MACH_PORTUXG20=y
+CONFIG_MACH_STAMP9G20=y
+CONFIG_MACH_PCONTROL_G20=y
+CONFIG_MACH_GSIA18S=y
+CONFIG_MACH_USB_A9G20=y
+CONFIG_MACH_SNAPPER_9260=y
+CONFIG_MACH_AT91SAM_DT=y
 CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 # CONFIG_ARM_THUMB is not set
 CONFIG_AEABI=y
@@ -21,9 +30,10 @@ CONFIG_LEDS=y
 CONFIG_LEDS_CPU=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
 CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -37,8 +47,6 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -48,17 +56,13 @@ CONFIG_MTD_NAND_ATMEL=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_MACB=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
@@ -66,15 +70,14 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
+CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_HW_RANDOM=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
 CONFIG_SPI_SPIDEV=y
 # CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SEQUENCER=y
@@ -82,7 +85,6 @@ CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_VERBOSE_PROCFS is not set
-CONFIG_SND_AT73C213=y
 CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
@@ -105,7 +107,6 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT91SAM9=y
 CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
index c5876d244f4b2d667db3d4753bdc1bdab1203064..606d48f3b8f81c10370b718d7b2b3475818b9a03 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_AT91=y
 CONFIG_ARCH_AT91SAM9G45=y
 CONFIG_MACH_AT91SAM9M10G45EK=y
+CONFIG_MACH_AT91SAM_DT=y
 CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 CONFIG_AT91_SLOW_CLOCK=y
 CONFIG_AEABI=y
@@ -73,11 +74,8 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_MII=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
 CONFIG_MACB=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_DAVICOM_PHY=y
 CONFIG_LIBERTAS_THINFIRM=m
 CONFIG_LIBERTAS_THINFIRM_USB=m
 CONFIG_AT76C50X_USB=m
@@ -131,7 +129,6 @@ CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
 # CONFIG_HWMON is not set
-# CONFIG_MFD_SUPPORT is not set
 CONFIG_FB=y
 CONFIG_FB_ATMEL=y
 CONFIG_FB_UDL=m
similarity index 94%
rename from arch/arm/configs/at91sam9rlek_defconfig
rename to arch/arm/configs/at91sam9rl_defconfig
index 75621e4d03fc2992d6f02e022aed4ccd7a021e29..ad562ee64209cd08e57f9b31160c089b810d7c11 100644 (file)
@@ -23,8 +23,6 @@ CONFIG_NET=y
 CONFIG_UNIX=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -35,7 +33,6 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=4
 CONFIG_BLK_DEV_RAM_SIZE=24576
-CONFIG_ATMEL_SSC=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
@@ -62,13 +59,11 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_AT91SAM9X_WATCHDOG=y
 CONFIG_FB=y
 CONFIG_FB_ATMEL=y
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_MMC=y
 CONFIG_MMC_AT91=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT91SAM9=y
 CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
index 227a477346edb44a2a83ba49a0f9b7cd2b165ec0..d95763d5f0d83df6543364e3ea648c2ad88994bf 100644 (file)
@@ -287,7 +287,7 @@ CONFIG_USB=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_MMC=y
index 176ec22af0342f215b59a2778144d69ef0f4c806..fd996bb13022879dee93c308c8e8ad154918ec20 100644 (file)
@@ -263,7 +263,7 @@ CONFIG_USB=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_MMC=y
index a88e64d4e9a5862c28160c9d1b7d3cd01edf0550..443675d317e6de326c576caf47ae9ff179a0814c 100644 (file)
@@ -132,7 +132,7 @@ CONFIG_USB_MON=m
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_USB_GADGETFS=m
index 7b63462b349d7de9965b13bec7c1c85e57c25fcd..a7e77758137881bf52067b145ae220f0447b7fdc 100644 (file)
@@ -48,7 +48,6 @@ CONFIG_MACH_SX1=y
 CONFIG_MACH_NOKIA770=y
 CONFIG_MACH_AMS_DELTA=y
 CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
 CONFIG_OMAP_ARM_216MHZ=y
 CONFIG_OMAP_ARM_195MHZ=y
 CONFIG_OMAP_ARM_192MHZ=y
index 4a5a12681be2038c908318ffc953c3ad7a9bd431..374000ec4e4e9a66bbf07304abd75dced85a0b66 100644 (file)
@@ -14,8 +14,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_U300=y
 CONFIG_MACH_U300=y
 CONFIG_MACH_U300_BS335=y
-CONFIG_MACH_U300_DUAL_RAM=y
-CONFIG_U300_DEBUG=y
 CONFIG_MACH_U300_SPIDUMMY=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -26,19 +24,21 @@ CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072"
 CONFIG_CPU_IDLE=y
 CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
 # CONFIG_SUSPEND is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_MISC_DEVICES is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 # CONFIG_HWMON is not set
@@ -51,6 +51,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_MMC=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_ARMMMCI=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_HCTOSYS is not set
@@ -65,10 +66,8 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_PREEMPT is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_CRC32 is not set
index 97d31a4663daf0c6186cd948a05abf35687686d3..2d7b6e7b72713cba72df0349462c29dbe38a67ba 100644 (file)
@@ -10,7 +10,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_U8500=y
 CONFIG_UX500_SOC_DB5500=y
 CONFIG_UX500_SOC_DB8500=y
-CONFIG_MACH_U8500=y
+CONFIG_MACH_HREFV60=y
 CONFIG_MACH_SNOWBALL=y
 CONFIG_MACH_U5500=y
 CONFIG_NO_HZ=y
@@ -24,6 +24,7 @@ CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_VFP=y
 CONFIG_NEON=y
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -41,11 +42,8 @@ CONFIG_MISC_DEVICES=y
 CONFIG_AB8500_PWM=y
 CONFIG_SENSORS_BH1780=y
 CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
 CONFIG_SMSC911X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_SMSC_PHY=y
 # CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_EVDEV=y
@@ -72,15 +70,12 @@ CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_TC3589X=y
-# CONFIG_HWMON is not set
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_TC3589X=y
+CONFIG_AB5500_CORE=y
 CONFIG_AB8500_CORE=y
 CONFIG_REGULATOR_AB8500=y
 # CONFIG_HID_SUPPORT is not set
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
-CONFIG_MUSB_PIO_ONLY=y
 CONFIG_USB_GADGET=y
 CONFIG_AB8500_USB=y
 CONFIG_MMC=y
@@ -97,6 +92,7 @@ CONFIG_DMADEVICES=y
 CONFIG_STE_DMA40=y
 CONFIG_STAGING=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
+CONFIG_HSEM_U8500=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
index 59577ad3f4efdfda65e65753054673a32614e80f..547a3c1e59dbcd88ea9da77505691110508f9daf 100644 (file)
@@ -140,7 +140,7 @@ CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_GADGET=m
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h
new file mode 100644 (file)
index 0000000..a0ada3e
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef __ASMARM_CTI_H
+#define __ASMARM_CTI_H
+
+#include       <asm/io.h>
+
+/* The registers' definition is from section 3.2 of
+ * Embedded Cross Trigger Revision: r0p0
+ */
+#define                CTICONTROL              0x000
+#define                CTISTATUS               0x004
+#define                CTILOCK                 0x008
+#define                CTIPROTECTION           0x00C
+#define                CTIINTACK               0x010
+#define                CTIAPPSET               0x014
+#define                CTIAPPCLEAR             0x018
+#define                CTIAPPPULSE             0x01c
+#define                CTIINEN                 0x020
+#define                CTIOUTEN                0x0A0
+#define                CTITRIGINSTATUS         0x130
+#define                CTITRIGOUTSTATUS        0x134
+#define                CTICHINSTATUS           0x138
+#define                CTICHOUTSTATUS          0x13c
+#define                CTIPERIPHID0            0xFE0
+#define                CTIPERIPHID1            0xFE4
+#define                CTIPERIPHID2            0xFE8
+#define                CTIPERIPHID3            0xFEC
+#define                CTIPCELLID0             0xFF0
+#define                CTIPCELLID1             0xFF4
+#define                CTIPCELLID2             0xFF8
+#define                CTIPCELLID3             0xFFC
+
+/* The below are from section 3.6.4 of
+ * CoreSight v1.0 Architecture Specification
+ */
+#define                LOCKACCESS              0xFB0
+#define                LOCKSTATUS              0xFB4
+
+/* write this value to LOCKACCESS will unlock the module, and
+ * other value will lock the module
+ */
+#define                LOCKCODE                0xC5ACCE55
+
+/**
+ * struct cti - cross trigger interface struct
+ * @base: mapped virtual address for the cti base
+ * @irq: irq number for the cti
+ * @trig_out_for_irq: triger out number which will cause
+ *     the @irq happen
+ *
+ * cti struct used to operate cti registers.
+ */
+struct cti {
+       void __iomem *base;
+       int irq;
+       int trig_out_for_irq;
+};
+
+/**
+ * cti_init - initialize the cti instance
+ * @cti: cti instance
+ * @base: mapped virtual address for the cti base
+ * @irq: irq number for the cti
+ * @trig_out: triger out number which will cause
+ *     the @irq happen
+ *
+ * called by machine code to pass the board dependent
+ * @base, @irq and @trig_out to cti.
+ */
+static inline void cti_init(struct cti *cti,
+       void __iomem *base, int irq, int trig_out)
+{
+       cti->base = base;
+       cti->irq  = irq;
+       cti->trig_out_for_irq = trig_out;
+}
+
+/**
+ * cti_map_trigger - use the @chan to map @trig_in to @trig_out
+ * @cti: cti instance
+ * @trig_in: trigger in number
+ * @trig_out: trigger out number
+ * @channel: channel number
+ *
+ * This function maps one trigger in of @trig_in to one trigger
+ * out of @trig_out using the channel @chan.
+ */
+static inline void cti_map_trigger(struct cti *cti,
+       int trig_in, int trig_out, int chan)
+{
+       void __iomem *base = cti->base;
+       unsigned long val;
+
+       val = __raw_readl(base + CTIINEN + trig_in * 4);
+       val |= BIT(chan);
+       __raw_writel(val, base + CTIINEN + trig_in * 4);
+
+       val = __raw_readl(base + CTIOUTEN + trig_out * 4);
+       val |= BIT(chan);
+       __raw_writel(val, base + CTIOUTEN + trig_out * 4);
+}
+
+/**
+ * cti_enable - enable the cti module
+ * @cti: cti instance
+ *
+ * enable the cti module
+ */
+static inline void cti_enable(struct cti *cti)
+{
+       __raw_writel(0x1, cti->base + CTICONTROL);
+}
+
+/**
+ * cti_disable - disable the cti module
+ * @cti: cti instance
+ *
+ * enable the cti module
+ */
+static inline void cti_disable(struct cti *cti)
+{
+       __raw_writel(0, cti->base + CTICONTROL);
+}
+
+/**
+ * cti_irq_ack - clear the cti irq
+ * @cti: cti instance
+ *
+ * clear the cti irq
+ */
+static inline void cti_irq_ack(struct cti *cti)
+{
+       void __iomem *base = cti->base;
+       unsigned long val;
+
+       val = __raw_readl(base + CTIINTACK);
+       val |= BIT(cti->trig_out_for_irq);
+       __raw_writel(val, base + CTIINTACK);
+}
+
+/**
+ * cti_unlock - unlock cti module
+ * @cti: cti instance
+ *
+ * unlock the cti module, or else any writes to the cti
+ * module is not allowed.
+ */
+static inline void cti_unlock(struct cti *cti)
+{
+       void __iomem *base = cti->base;
+       unsigned long val;
+
+       val = __raw_readl(base + LOCKSTATUS);
+
+       if (val & 1) {
+               val = LOCKCODE;
+               __raw_writel(val, base + LOCKACCESS);
+       }
+}
+
+/**
+ * cti_lock - lock cti module
+ * @cti: cti instance
+ *
+ * lock the cti module, so any writes to the cti
+ * module will be not allowed.
+ */
+static inline void cti_lock(struct cti *cti)
+{
+       void __iomem *base = cti->base;
+       unsigned long val;
+
+       val = __raw_readl(base + LOCKSTATUS);
+
+       if (!(val & 1)) {
+               val = ~LOCKCODE;
+               __raw_writel(val, base + LOCKACCESS);
+       }
+}
+#endif
index 1db1143a94838cb92419040c40009f17d1ee2f97..7df239bcdf2745b6a3d20e5a90ed3bac27d73ecc 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __ASM_ARM_HARDWARE_L2X0_H
 #define __ASM_ARM_HARDWARE_L2X0_H
 
+#include <linux/errno.h>
+
 #define L2X0_CACHE_ID                  0x000
 #define L2X0_CACHE_TYPE                        0x004
 #define L2X0_CTRL                      0x100
index 6fe6cf0895c94e7c191a8592a2218c91bd916005..bcb0c883e21ed06aa18c9f48354314c877523a8b 100644 (file)
@@ -13,6 +13,7 @@
 struct tag;
 struct meminfo;
 struct sys_timer;
+struct pt_regs;
 
 struct machine_desc {
        unsigned int            nr;             /* architecture number  */
index 0f8e3827a89b314aa47ea827e9d109cbeb8406d9..99cfe36079893101b382acf9a5fefd6279f206aa 100644 (file)
@@ -32,7 +32,4 @@ enum arm_perf_pmu_ids {
 extern enum arm_perf_pmu_ids
 armpmu_get_pmu_id(void);
 
-extern int
-armpmu_get_max_events(void);
-
 #endif /* __ARM_PERF_EVENT_H__ */
index 71d99b83cdb980178aac275e487c2db081c041fc..b5a5be2536c1158acf5a9c979eccb0f5588bb97c 100644 (file)
@@ -27,13 +27,22 @@ enum arm_pmu_type {
 /*
  * struct arm_pmu_platdata - ARM PMU platform data
  *
- * @handle_irq: an optional handler which will be called from the interrupt and
- * passed the address of the low level handler, and can be used to implement
- * any platform specific handling before or after calling it.
+ * @handle_irq: an optional handler which will be called from the
+ *     interrupt and passed the address of the low level handler,
+ *     and can be used to implement any platform specific handling
+ *     before or after calling it.
+ * @enable_irq: an optional handler which will be called after
+ *     request_irq and be used to handle some platform specific
+ *     irq enablement
+ * @disable_irq: an optional handler which will be called before
+ *     free_irq and be used to handle some platform specific
+ *     irq disablement
  */
 struct arm_pmu_platdata {
        irqreturn_t (*handle_irq)(int irq, void *dev,
                                  irq_handler_t pmu_handler);
+       void (*enable_irq)(int irq);
+       void (*disable_irq)(int irq);
 };
 
 #ifdef CONFIG_CPU_HAS_PMU
@@ -55,16 +64,6 @@ reserve_pmu(enum arm_pmu_type type);
 extern void
 release_pmu(enum arm_pmu_type type);
 
-/**
- * init_pmu() - Initialise the PMU.
- *
- * Initialise the system ready for PMU enabling. This should typically set the
- * IRQ affinity and nothing else. The users (oprofile/perf events etc) will do
- * the actual hardware initialisation.
- */
-extern int
-init_pmu(enum arm_pmu_type type);
-
 #else /* CONFIG_CPU_HAS_PMU */
 
 #include <linux/err.h>
index a7e457ed27c31e1185ebe3a0eaa745d88c35029d..58b8b84adcd2cf5f295e6869b68350f9dcadc798 100644 (file)
@@ -25,7 +25,7 @@ extern struct cputopo_arm cpu_topology[NR_CPUS];
 
 void init_cpu_topology(void);
 void store_cpu_topology(unsigned int cpuid);
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+const struct cpumask *cpu_coregroup_mask(int cpu);
 
 #else
 
index c60a2944f95b82a0cc9d5bfea32d88c65ecb202f..4a1123783806b79ef559ed51a093353feb67070e 100644 (file)
 #define __NR_syncfs                    (__NR_SYSCALL_BASE+373)
 #define __NR_sendmmsg                  (__NR_SYSCALL_BASE+374)
 #define __NR_setns                     (__NR_SYSCALL_BASE+375)
+#define __NR_process_vm_readv          (__NR_SYSCALL_BASE+376)
+#define __NR_process_vm_writev         (__NR_SYSCALL_BASE+377)
 
 /*
  * The following SWIs are ARM private.
index 9943e9e74a1bda0b17bc6e1ee93ca3ab2b80f970..463ff4a0ec8acaa69372b8abd40a39260ee91736 100644 (file)
                CALL(sys_syncfs)
                CALL(sys_sendmmsg)
 /* 375 */      CALL(sys_setns)
+               CALL(sys_process_vm_readv)
+               CALL(sys_process_vm_writev)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index bd49a6a2a17dba0c60ed4de46735123c453d23c6..3a456c6c70056f9267f592792193d2176c045802 100644 (file)
@@ -496,7 +496,7 @@ ENDPROC(__und_usr)
        .popsection
        .pushsection __ex_table,"a"
        .long   1b, 4b
-#if __LINUX_ARM_ARCH__ >= 7
+#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
        .long   2b, 4b
        .long   3b, 4b
 #endif
index 566c54c2a1fef28bffea090e89bcec998b73ede6..08c82fd844a8683533216048b54ff2f210729fb6 100644 (file)
@@ -360,7 +360,7 @@ __secondary_data:
  *  r13 = *virtual* address to jump to upon completion
  */
 __enable_mmu:
-#ifdef CONFIG_ALIGNMENT_TRAP
+#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
        orr     r0, r0, #CR_A
 #else
        bic     r0, r0, #CR_A
index 9fe8910308af922eda3c17ffee908c99652c1a1f..8a30c89da70ec104d4c1499f3a88a1dc4721e6e0 100644 (file)
@@ -519,10 +519,12 @@ static const union decode_item arm_cccc_0000_____1001_table[] = {
 static const union decode_item arm_cccc_0001_____1001_table[] = {
        /* Synchronization primitives                                   */
 
+#if __LINUX_ARM_ARCH__ < 6
+       /* Deprecated on ARMv6 and may be UNDEFINED on v7               */
        /* SMP/SWPB             cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
        DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
                                                 REGS(NOPC, NOPC, 0, 0, NOPC)),
-
+#endif
        /* LDREX/STREX{,D,B,H}  cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
        /* And unallocated instructions...                              */
        DECODE_END
index fc82de8bdcce1081801cece62fa3d97480d520e1..ba32b393b3f0c514c83799687348d52655bfe1da 100644 (file)
@@ -427,18 +427,25 @@ void kprobe_arm_test_cases(void)
 
        TEST_GROUP("Synchronization primitives")
 
-       /*
-        * Use hard coded constants for SWP instructions to avoid warnings
-        * about deprecated instructions.
-        */
-       TEST_RP( ".word 0xe108e097 @ swp        lr, r",7,VAL2,", [r",8,0,"]")
-       TEST_R(  ".word 0x610d0091 @ swpvs      r0, r",1,VAL1,", [sp]")
-       TEST_RP( ".word 0xe10cd09e @ swp        sp, r",14,VAL2,", [r",12,13*4,"]")
+#if __LINUX_ARM_ARCH__ < 6
+       TEST_RP("swp    lr, r",7,VAL2,", [r",8,0,"]")
+       TEST_R( "swpvs  r0, r",1,VAL1,", [sp]")
+       TEST_RP("swp    sp, r",14,VAL2,", [r",12,13*4,"]")
+#else
+       TEST_UNSUPPORTED(".word 0xe108e097 @ swp        lr, r7, [r8]")
+       TEST_UNSUPPORTED(".word 0x610d0091 @ swpvs      r0, r1, [sp]")
+       TEST_UNSUPPORTED(".word 0xe10cd09e @ swp        sp, r14 [r12]")
+#endif
        TEST_UNSUPPORTED(".word 0xe102f091 @ swp pc, r1, [r2]")
        TEST_UNSUPPORTED(".word 0xe102009f @ swp r0, pc, [r2]")
        TEST_UNSUPPORTED(".word 0xe10f0091 @ swp r0, r1, [pc]")
-       TEST_RP( ".word 0xe148e097 @ swpb       lr, r",7,VAL2,", [r",8,0,"]")
-       TEST_R(  ".word 0x614d0091 @ swpvsb     r0, r",1,VAL1,", [sp]")
+#if __LINUX_ARM_ARCH__ < 6
+       TEST_RP("swpb   lr, r",7,VAL2,", [r",8,0,"]")
+       TEST_R( "swpvsb r0, r",1,VAL1,", [sp]")
+#else
+       TEST_UNSUPPORTED(".word 0xe148e097 @ swpb       lr, r7, [r8]")
+       TEST_UNSUPPORTED(".word 0x614d0091 @ swpvsb     r0, r1, [sp]")
+#endif
        TEST_UNSUPPORTED(".word 0xe142f091 @ swpb pc, r1, [r2]")
 
        TEST_UNSUPPORTED(".word 0xe1100090") /* Unallocated space */
@@ -550,7 +557,7 @@ void kprobe_arm_test_cases(void)
        TEST_RPR(  "strccd      r",8, VAL2,", [r",13,0, ", r",12,48,"]")
        TEST_RPR(  "strd        r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
        TEST_RPR(  "strcsd      r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
-       TEST_RPR(  "strd        r",2, VAL1,", [r",3, 24,"], r",4,48,"")
+       TEST_RPR(  "strd        r",2, VAL1,", [r",5, 24,"], r",4,48,"")
        TEST_RPR(  "strd        r",10,VAL2,", [r",9, 48,"], -r",7,24,"")
        TEST_UNSUPPORTED(".word 0xe1afc0fa      @ strd r12, [pc, r10]!")
 
index 5e726c31c45aef5084a7e7ddf07bb1762ed4c403..5d8b857922220b4be4e9babf6e050c94625a56eb 100644 (file)
@@ -222,8 +222,8 @@ void kprobe_thumb16_test_cases(void)
 DONT_TEST_IN_ITBLOCK(
        TEST_BF_R(  "cbnz       r",0,0, ", 2f")
        TEST_BF_R(  "cbz        r",2,-1,", 2f")
-       TEST_BF_RX( "cbnz       r",4,1, ", 2f",0x20)
-       TEST_BF_RX( "cbz        r",7,0, ", 2f",0x40)
+       TEST_BF_RX( "cbnz       r",4,1, ", 2f", SPACE_0x20)
+       TEST_BF_RX( "cbz        r",7,0, ", 2f", SPACE_0x40)
 )
        TEST_R("sxth    r0, r",7, HH1,"")
        TEST_R("sxth    r7, r",0, HH2,"")
@@ -246,7 +246,7 @@ DONT_TEST_IN_ITBLOCK(
        TESTCASE_START(code)            \
        TEST_ARG_PTR(13, offset)        \
        TEST_ARG_END("")                \
-       TEST_BRANCH_F(code,0)           \
+       TEST_BRANCH_F(code)             \
        TESTCASE_END
 
        TEST("push      {r0}")
@@ -319,8 +319,8 @@ CONDITION_INSTRUCTIONS(8,
 
        TEST_BF(  "b    2f")
        TEST_BB(  "b    2b")
-       TEST_BF_X("b    2f", 0x400)
-       TEST_BB_X("b    2b", 0x400)
+       TEST_BF_X("b    2f", SPACE_0x400)
+       TEST_BB_X("b    2b", SPACE_0x400)
 
        TEST_GROUP("Testing instructions in IT blocks")
 
@@ -746,7 +746,7 @@ CONDITION_INSTRUCTIONS(22,
        TEST_BB("bne.w  2b")
        TEST_BF("bgt.w  2f")
        TEST_BB("blt.w  2b")
-       TEST_BF_X("bpl.w        2f",0x1000)
+       TEST_BF_X("bpl.w        2f", SPACE_0x1000)
 )
 
        TEST_UNSUPPORTED("msr   cpsr, r0")
@@ -786,11 +786,11 @@ CONDITION_INSTRUCTIONS(22,
 
        TEST_BF(  "b.w  2f")
        TEST_BB(  "b.w  2b")
-       TEST_BF_X("b.w  2f", 0x1000)
+       TEST_BF_X("b.w  2f", SPACE_0x1000)
 
        TEST_BF(  "bl.w 2f")
        TEST_BB(  "bl.w 2b")
-       TEST_BB_X("bl.w 2b", 0x1000)
+       TEST_BB_X("bl.w 2b", SPACE_0x1000)
 
        TEST_X( "blx    __dummy_arm_subroutine",
                ".arm                           \n\t"
index 0dc5d77b9356bcd86b4b0c087bf642bc6396e06e..e28a869b1ae4b7be5abfb7d088c3214bfe2caab7 100644 (file)
@@ -149,23 +149,31 @@ struct test_arg_end {
        "1:     "instruction"                           \n\t"   \
        "       nop                                     \n\t"
 
-#define TEST_BRANCH_F(instruction, xtra_dist)                  \
+#define TEST_BRANCH_F(instruction)                             \
        TEST_INSTRUCTION(instruction)                           \
-       ".if "#xtra_dist"                               \n\t"   \
        "       b       99f                             \n\t"   \
-       ".space "#xtra_dist"                            \n\t"   \
-       ".endif                                         \n\t"   \
+       "2:     nop                                     \n\t"
+
+#define TEST_BRANCH_B(instruction)                             \
+       "       b       50f                             \n\t"   \
+       "       b       99f                             \n\t"   \
+       "2:     nop                                     \n\t"   \
+       "       b       99f                             \n\t"   \
+       TEST_INSTRUCTION(instruction)
+
+#define TEST_BRANCH_FX(instruction, codex)                     \
+       TEST_INSTRUCTION(instruction)                           \
+       "       b       99f                             \n\t"   \
+       codex"                                          \n\t"   \
        "       b       99f                             \n\t"   \
        "2:     nop                                     \n\t"
 
-#define TEST_BRANCH_B(instruction, xtra_dist)                  \
+#define TEST_BRANCH_BX(instruction, codex)                     \
        "       b       50f                             \n\t"   \
        "       b       99f                             \n\t"   \
        "2:     nop                                     \n\t"   \
        "       b       99f                             \n\t"   \
-       ".if "#xtra_dist"                               \n\t"   \
-       ".space "#xtra_dist"                            \n\t"   \
-       ".endif                                         \n\t"   \
+       codex"                                          \n\t"   \
        TEST_INSTRUCTION(instruction)
 
 #define TESTCASE_END                                           \
@@ -301,47 +309,60 @@ struct test_arg_end {
        TESTCASE_START(code1 #reg1 code2)       \
        TEST_ARG_PTR(reg1, val1)                \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_F(code1 #reg1 code2, 0)     \
+       TEST_BRANCH_F(code1 #reg1 code2)        \
        TESTCASE_END
 
-#define TEST_BF_X(code, xtra_dist)             \
+#define TEST_BF(code)                          \
        TESTCASE_START(code)                    \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_F(code, xtra_dist)          \
+       TEST_BRANCH_F(code)                     \
        TESTCASE_END
 
-#define TEST_BB_X(code, xtra_dist)             \
+#define TEST_BB(code)                          \
        TESTCASE_START(code)                    \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_B(code, xtra_dist)          \
+       TEST_BRANCH_B(code)                     \
        TESTCASE_END
 
-#define TEST_BF_RX(code1, reg, val, code2, xtra_dist)  \
-       TESTCASE_START(code1 #reg code2)                \
-       TEST_ARG_REG(reg, val)                          \
-       TEST_ARG_END("")                                \
-       TEST_BRANCH_F(code1 #reg code2, xtra_dist)      \
+#define TEST_BF_R(code1, reg, val, code2)      \
+       TESTCASE_START(code1 #reg code2)        \
+       TEST_ARG_REG(reg, val)                  \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_F(code1 #reg code2)         \
        TESTCASE_END
 
-#define TEST_BB_RX(code1, reg, val, code2, xtra_dist)  \
-       TESTCASE_START(code1 #reg code2)                \
-       TEST_ARG_REG(reg, val)                          \
-       TEST_ARG_END("")                                \
-       TEST_BRANCH_B(code1 #reg code2, xtra_dist)      \
+#define TEST_BB_R(code1, reg, val, code2)      \
+       TESTCASE_START(code1 #reg code2)        \
+       TEST_ARG_REG(reg, val)                  \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_B(code1 #reg code2)         \
        TESTCASE_END
 
-#define TEST_BF(code)  TEST_BF_X(code, 0)
-#define TEST_BB(code)  TEST_BB_X(code, 0)
-
-#define TEST_BF_R(code1, reg, val, code2) TEST_BF_RX(code1, reg, val, code2, 0)
-#define TEST_BB_R(code1, reg, val, code2) TEST_BB_RX(code1, reg, val, code2, 0)
-
 #define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3)        \
        TESTCASE_START(code1 #reg1 code2 #reg2 code3)           \
        TEST_ARG_REG(reg1, val1)                                \
        TEST_ARG_REG(reg2, val2)                                \
        TEST_ARG_END("")                                        \
-       TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3, 0)         \
+       TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3)            \
+       TESTCASE_END
+
+#define TEST_BF_X(code, codex)                 \
+       TESTCASE_START(code)                    \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_FX(code, codex)             \
+       TESTCASE_END
+
+#define TEST_BB_X(code, codex)                 \
+       TESTCASE_START(code)                    \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_BX(code, codex)             \
+       TESTCASE_END
+
+#define TEST_BF_RX(code1, reg, val, code2, codex)      \
+       TESTCASE_START(code1 #reg code2)                \
+       TEST_ARG_REG(reg, val)                          \
+       TEST_ARG_END("")                                \
+       TEST_BRANCH_FX(code1 #reg code2, codex)         \
        TESTCASE_END
 
 #define TEST_X(code, codex)                    \
@@ -372,6 +393,25 @@ struct test_arg_end {
        TESTCASE_END
 
 
+/*
+ * Macros for defining space directives spread over multiple lines.
+ * These are required so the compiler guesses better the length of inline asm
+ * code and will spill the literal pool early enough to avoid generating PC
+ * relative loads with out of range offsets.
+ */
+#define TWICE(x)       x x
+#define SPACE_0x8      TWICE(".space 4\n\t")
+#define SPACE_0x10     TWICE(SPACE_0x8)
+#define SPACE_0x20     TWICE(SPACE_0x10)
+#define SPACE_0x40     TWICE(SPACE_0x20)
+#define SPACE_0x80     TWICE(SPACE_0x40)
+#define SPACE_0x100    TWICE(SPACE_0x80)
+#define SPACE_0x200    TWICE(SPACE_0x100)
+#define SPACE_0x400    TWICE(SPACE_0x200)
+#define SPACE_0x800    TWICE(SPACE_0x400)
+#define SPACE_0x1000   TWICE(SPACE_0x800)
+
+
 /* Various values used in test cases... */
 #define N(val) (val ^ 0xffffffff)
 #define VAL1   0x12345678
index cc40b965d42a5b2d9c19e8dd5bd086412b4cca43..29620b632ed945366605b46424df24eb7f369815 100644 (file)
@@ -32,24 +32,6 @@ static atomic_t waiting_for_crash_ipi;
 
 int machine_kexec_prepare(struct kimage *image)
 {
-       unsigned long page_list;
-       void *reboot_code_buffer;
-       page_list = image->head & PAGE_MASK;
-
-       reboot_code_buffer = page_address(image->control_code_page);
-
-       /* Prepare parameters for reboot_code_buffer*/
-       kexec_start_address = image->start;
-       kexec_indirection_page = page_list;
-       kexec_mach_type = machine_arch_type;
-       kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
-
-       /* copy our kernel relocation code to the control code page */
-       memcpy(reboot_code_buffer,
-              relocate_new_kernel, relocate_new_kernel_size);
-
-       flush_icache_range((unsigned long) reboot_code_buffer,
-                          (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
        return 0;
 }
 
@@ -100,14 +82,31 @@ void (*kexec_reinit)(void);
 
 void machine_kexec(struct kimage *image)
 {
+       unsigned long page_list;
        unsigned long reboot_code_buffer_phys;
        void *reboot_code_buffer;
 
+
+       page_list = image->head & PAGE_MASK;
+
        /* we need both effective and real address here */
        reboot_code_buffer_phys =
            page_to_pfn(image->control_code_page) << PAGE_SHIFT;
        reboot_code_buffer = page_address(image->control_code_page);
 
+       /* Prepare parameters for reboot_code_buffer*/
+       kexec_start_address = image->start;
+       kexec_indirection_page = page_list;
+       kexec_mach_type = machine_arch_type;
+       kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
+
+       /* copy our kernel relocation code to the control code page */
+       memcpy(reboot_code_buffer,
+              relocate_new_kernel, relocate_new_kernel_size);
+
+
+       flush_icache_range((unsigned long) reboot_code_buffer,
+                          (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
        printk(KERN_INFO "Bye!\n");
 
        if (kexec_reinit)
index 24e2347be6b1043ad7cf87f70ab88fe6e9a270c9..172101ac97de5a1125a014a02f1c1d71922a1640 100644 (file)
@@ -59,8 +59,7 @@ armpmu_get_pmu_id(void)
 }
 EXPORT_SYMBOL_GPL(armpmu_get_pmu_id);
 
-int
-armpmu_get_max_events(void)
+int perf_num_counters(void)
 {
        int max_events = 0;
 
@@ -69,12 +68,6 @@ armpmu_get_max_events(void)
 
        return max_events;
 }
-EXPORT_SYMBOL_GPL(armpmu_get_max_events);
-
-int perf_num_counters(void)
-{
-       return armpmu_get_max_events();
-}
 EXPORT_SYMBOL_GPL(perf_num_counters);
 
 #define HW_OP_UNSUPPORTED              0xFFFF
@@ -343,8 +336,14 @@ validate_group(struct perf_event *event)
 {
        struct perf_event *sibling, *leader = event->group_leader;
        struct pmu_hw_events fake_pmu;
+       DECLARE_BITMAP(fake_used_mask, ARMPMU_MAX_HWEVENTS);
 
-       memset(&fake_pmu, 0, sizeof(fake_pmu));
+       /*
+        * Initialise the fake PMU. We only need to populate the
+        * used_mask for the purposes of validation.
+        */
+       memset(fake_used_mask, 0, sizeof(fake_used_mask));
+       fake_pmu.used_mask = fake_used_mask;
 
        if (!validate_event(&fake_pmu, leader))
                return -ENOSPC;
@@ -374,6 +373,8 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 {
        int i, irq, irqs;
        struct platform_device *pmu_device = armpmu->plat_device;
+       struct arm_pmu_platdata *plat =
+               dev_get_platdata(&pmu_device->dev);
 
        irqs = min(pmu_device->num_resources, num_possible_cpus());
 
@@ -381,8 +382,11 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
                if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
                        continue;
                irq = platform_get_irq(pmu_device, i);
-               if (irq >= 0)
+               if (irq >= 0) {
+                       if (plat && plat->disable_irq)
+                               plat->disable_irq(irq);
                        free_irq(irq, armpmu);
+               }
        }
 
        release_pmu(armpmu->type);
@@ -396,6 +400,9 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
        int i, err, irq, irqs;
        struct platform_device *pmu_device = armpmu->plat_device;
 
+       if (!pmu_device)
+               return -ENODEV;
+
        err = reserve_pmu(armpmu->type);
        if (err) {
                pr_warning("unable to reserve pmu\n");
@@ -439,7 +446,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
                                irq);
                        armpmu_release_hardware(armpmu);
                        return err;
-               }
+               } else if (plat && plat->enable_irq)
+                       plat->enable_irq(irq);
 
                cpumask_set_cpu(i, &armpmu->active_irqs);
        }
index e63d8115c01b2fc9cabef9a23749cdc60e9ad0e7..533be9930ec22f803e672a2e57217b8c65bfc40b 100644 (file)
@@ -65,13 +65,15 @@ enum armv6_counters {
  * accesses/misses in hardware.
  */
 static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
-       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV6_PERFCTR_CPU_CYCLES,
-       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV6_PERFCTR_INSTR_EXEC,
-       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
-       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV6_PERFCTR_BR_MISPREDICT,
-       [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CPU_CYCLES]              = ARMV6_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = ARMV6_PERFCTR_INSTR_EXEC,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]            = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = ARMV6_PERFCTR_BR_EXEC,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = ARMV6_PERFCTR_BR_MISPREDICT,
+       [PERF_COUNT_HW_BUS_CYCLES]              = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6_PERFCTR_IBUF_STALL,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = ARMV6_PERFCTR_LSU_FULL_STALL,
 };
 
 static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
@@ -218,13 +220,15 @@ enum armv6mpcore_perf_types {
  * accesses/misses in hardware.
  */
 static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
-       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
-       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
-       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
-       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
-       [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CPU_CYCLES]              = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]            = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = ARMV6MPCORE_PERFCTR_BR_EXEC,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
+       [PERF_COUNT_HW_BUS_CYCLES]              = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6MPCORE_PERFCTR_IBUF_STALL,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = ARMV6MPCORE_PERFCTR_LSU_FULL_STALL,
 };
 
 static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
index 1ef6d0034b85d1172c8efe1d1659e82dbced1032..460bbbb6b88536ba18ded4983b6ee18baf1a4bf4 100644 (file)
@@ -28,165 +28,87 @@ static struct arm_pmu armv7pmu;
  * they are not available.
  */
 enum armv7_perf_types {
-       ARMV7_PERFCTR_PMNC_SW_INCR              = 0x00,
-       ARMV7_PERFCTR_IFETCH_MISS               = 0x01,
-       ARMV7_PERFCTR_ITLB_MISS                 = 0x02,
-       ARMV7_PERFCTR_DCACHE_REFILL             = 0x03, /* L1 */
-       ARMV7_PERFCTR_DCACHE_ACCESS             = 0x04, /* L1 */
-       ARMV7_PERFCTR_DTLB_REFILL               = 0x05,
-       ARMV7_PERFCTR_DREAD                     = 0x06,
-       ARMV7_PERFCTR_DWRITE                    = 0x07,
-       ARMV7_PERFCTR_INSTR_EXECUTED            = 0x08,
-       ARMV7_PERFCTR_EXC_TAKEN                 = 0x09,
-       ARMV7_PERFCTR_EXC_EXECUTED              = 0x0A,
-       ARMV7_PERFCTR_CID_WRITE                 = 0x0B,
-       /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
+       ARMV7_PERFCTR_PMNC_SW_INCR                      = 0x00,
+       ARMV7_PERFCTR_L1_ICACHE_REFILL                  = 0x01,
+       ARMV7_PERFCTR_ITLB_REFILL                       = 0x02,
+       ARMV7_PERFCTR_L1_DCACHE_REFILL                  = 0x03,
+       ARMV7_PERFCTR_L1_DCACHE_ACCESS                  = 0x04,
+       ARMV7_PERFCTR_DTLB_REFILL                       = 0x05,
+       ARMV7_PERFCTR_MEM_READ                          = 0x06,
+       ARMV7_PERFCTR_MEM_WRITE                         = 0x07,
+       ARMV7_PERFCTR_INSTR_EXECUTED                    = 0x08,
+       ARMV7_PERFCTR_EXC_TAKEN                         = 0x09,
+       ARMV7_PERFCTR_EXC_EXECUTED                      = 0x0A,
+       ARMV7_PERFCTR_CID_WRITE                         = 0x0B,
+
+       /*
+        * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
         * It counts:
-        *  - all branch instructions,
+        *  - all (taken) branch instructions,
         *  - instructions that explicitly write the PC,
         *  - exception generating instructions.
         */
-       ARMV7_PERFCTR_PC_WRITE                  = 0x0C,
-       ARMV7_PERFCTR_PC_IMM_BRANCH             = 0x0D,
-       ARMV7_PERFCTR_PC_PROC_RETURN            = 0x0E,
-       ARMV7_PERFCTR_UNALIGNED_ACCESS          = 0x0F,
+       ARMV7_PERFCTR_PC_WRITE                          = 0x0C,
+       ARMV7_PERFCTR_PC_IMM_BRANCH                     = 0x0D,
+       ARMV7_PERFCTR_PC_PROC_RETURN                    = 0x0E,
+       ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS              = 0x0F,
+       ARMV7_PERFCTR_PC_BRANCH_MIS_PRED                = 0x10,
+       ARMV7_PERFCTR_CLOCK_CYCLES                      = 0x11,
+       ARMV7_PERFCTR_PC_BRANCH_PRED                    = 0x12,
 
        /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
-       ARMV7_PERFCTR_PC_BRANCH_MIS_PRED        = 0x10,
-       ARMV7_PERFCTR_CLOCK_CYCLES              = 0x11,
-       ARMV7_PERFCTR_PC_BRANCH_PRED            = 0x12,
-       ARMV7_PERFCTR_MEM_ACCESS                = 0x13,
-       ARMV7_PERFCTR_L1_ICACHE_ACCESS          = 0x14,
-       ARMV7_PERFCTR_L1_DCACHE_WB              = 0x15,
-       ARMV7_PERFCTR_L2_DCACHE_ACCESS          = 0x16,
-       ARMV7_PERFCTR_L2_DCACHE_REFILL          = 0x17,
-       ARMV7_PERFCTR_L2_DCACHE_WB              = 0x18,
-       ARMV7_PERFCTR_BUS_ACCESS                = 0x19,
-       ARMV7_PERFCTR_MEMORY_ERROR              = 0x1A,
-       ARMV7_PERFCTR_INSTR_SPEC                = 0x1B,
-       ARMV7_PERFCTR_TTBR_WRITE                = 0x1C,
-       ARMV7_PERFCTR_BUS_CYCLES                = 0x1D,
-
-       ARMV7_PERFCTR_CPU_CYCLES                = 0xFF
+       ARMV7_PERFCTR_MEM_ACCESS                        = 0x13,
+       ARMV7_PERFCTR_L1_ICACHE_ACCESS                  = 0x14,
+       ARMV7_PERFCTR_L1_DCACHE_WB                      = 0x15,
+       ARMV7_PERFCTR_L2_CACHE_ACCESS                   = 0x16,
+       ARMV7_PERFCTR_L2_CACHE_REFILL                   = 0x17,
+       ARMV7_PERFCTR_L2_CACHE_WB                       = 0x18,
+       ARMV7_PERFCTR_BUS_ACCESS                        = 0x19,
+       ARMV7_PERFCTR_MEM_ERROR                         = 0x1A,
+       ARMV7_PERFCTR_INSTR_SPEC                        = 0x1B,
+       ARMV7_PERFCTR_TTBR_WRITE                        = 0x1C,
+       ARMV7_PERFCTR_BUS_CYCLES                        = 0x1D,
+
+       ARMV7_PERFCTR_CPU_CYCLES                        = 0xFF
 };
 
 /* ARMv7 Cortex-A8 specific event types */
 enum armv7_a8_perf_types {
-       ARMV7_PERFCTR_WRITE_BUFFER_FULL         = 0x40,
-       ARMV7_PERFCTR_L2_STORE_MERGED           = 0x41,
-       ARMV7_PERFCTR_L2_STORE_BUFF             = 0x42,
-       ARMV7_PERFCTR_L2_ACCESS                 = 0x43,
-       ARMV7_PERFCTR_L2_CACH_MISS              = 0x44,
-       ARMV7_PERFCTR_AXI_READ_CYCLES           = 0x45,
-       ARMV7_PERFCTR_AXI_WRITE_CYCLES          = 0x46,
-       ARMV7_PERFCTR_MEMORY_REPLAY             = 0x47,
-       ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY   = 0x48,
-       ARMV7_PERFCTR_L1_DATA_MISS              = 0x49,
-       ARMV7_PERFCTR_L1_INST_MISS              = 0x4A,
-       ARMV7_PERFCTR_L1_DATA_COLORING          = 0x4B,
-       ARMV7_PERFCTR_L1_NEON_DATA              = 0x4C,
-       ARMV7_PERFCTR_L1_NEON_CACH_DATA         = 0x4D,
-       ARMV7_PERFCTR_L2_NEON                   = 0x4E,
-       ARMV7_PERFCTR_L2_NEON_HIT               = 0x4F,
-       ARMV7_PERFCTR_L1_INST                   = 0x50,
-       ARMV7_PERFCTR_PC_RETURN_MIS_PRED        = 0x51,
-       ARMV7_PERFCTR_PC_BRANCH_FAILED          = 0x52,
-       ARMV7_PERFCTR_PC_BRANCH_TAKEN           = 0x53,
-       ARMV7_PERFCTR_PC_BRANCH_EXECUTED        = 0x54,
-       ARMV7_PERFCTR_OP_EXECUTED               = 0x55,
-       ARMV7_PERFCTR_CYCLES_INST_STALL         = 0x56,
-       ARMV7_PERFCTR_CYCLES_INST               = 0x57,
-       ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL    = 0x58,
-       ARMV7_PERFCTR_CYCLES_NEON_INST_STALL    = 0x59,
-       ARMV7_PERFCTR_NEON_CYCLES               = 0x5A,
-
-       ARMV7_PERFCTR_PMU0_EVENTS               = 0x70,
-       ARMV7_PERFCTR_PMU1_EVENTS               = 0x71,
-       ARMV7_PERFCTR_PMU_EVENTS                = 0x72,
+       ARMV7_A8_PERFCTR_L2_CACHE_ACCESS                = 0x43,
+       ARMV7_A8_PERFCTR_L2_CACHE_REFILL                = 0x44,
+       ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS               = 0x50,
+       ARMV7_A8_PERFCTR_STALL_ISIDE                    = 0x56,
 };
 
 /* ARMv7 Cortex-A9 specific event types */
 enum armv7_a9_perf_types {
-       ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC     = 0x40,
-       ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC     = 0x41,
-       ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC       = 0x42,
-
-       ARMV7_PERFCTR_COHERENT_LINE_MISS        = 0x50,
-       ARMV7_PERFCTR_COHERENT_LINE_HIT         = 0x51,
-
-       ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES   = 0x60,
-       ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES   = 0x61,
-       ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
-       ARMV7_PERFCTR_STREX_EXECUTED_PASSED     = 0x63,
-       ARMV7_PERFCTR_STREX_EXECUTED_FAILED     = 0x64,
-       ARMV7_PERFCTR_DATA_EVICTION             = 0x65,
-       ARMV7_PERFCTR_ISSUE_STAGE_NO_INST       = 0x66,
-       ARMV7_PERFCTR_ISSUE_STAGE_EMPTY         = 0x67,
-       ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE  = 0x68,
-
-       ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
-
-       ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST   = 0x70,
-       ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
-       ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST  = 0x72,
-       ARMV7_PERFCTR_FP_EXECUTED_INST          = 0x73,
-       ARMV7_PERFCTR_NEON_EXECUTED_INST        = 0x74,
-
-       ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
-       ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES  = 0x81,
-       ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES        = 0x82,
-       ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES        = 0x83,
-       ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES  = 0x84,
-       ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES  = 0x85,
-       ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES      = 0x86,
-
-       ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES  = 0x8A,
-       ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
-
-       ARMV7_PERFCTR_ISB_INST                  = 0x90,
-       ARMV7_PERFCTR_DSB_INST                  = 0x91,
-       ARMV7_PERFCTR_DMB_INST                  = 0x92,
-       ARMV7_PERFCTR_EXT_INTERRUPTS            = 0x93,
-
-       ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED     = 0xA0,
-       ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED       = 0xA1,
-       ARMV7_PERFCTR_PLE_FIFO_FLUSH            = 0xA2,
-       ARMV7_PERFCTR_PLE_RQST_COMPLETED        = 0xA3,
-       ARMV7_PERFCTR_PLE_FIFO_OVERFLOW         = 0xA4,
-       ARMV7_PERFCTR_PLE_RQST_PROG             = 0xA5
+       ARMV7_A9_PERFCTR_INSTR_CORE_RENAME              = 0x68,
+       ARMV7_A9_PERFCTR_STALL_ICACHE                   = 0x60,
+       ARMV7_A9_PERFCTR_STALL_DISPATCH                 = 0x66,
 };
 
 /* ARMv7 Cortex-A5 specific event types */
 enum armv7_a5_perf_types {
-       ARMV7_PERFCTR_IRQ_TAKEN                 = 0x86,
-       ARMV7_PERFCTR_FIQ_TAKEN                 = 0x87,
-
-       ARMV7_PERFCTR_EXT_MEM_RQST              = 0xc0,
-       ARMV7_PERFCTR_NC_EXT_MEM_RQST           = 0xc1,
-       ARMV7_PERFCTR_PREFETCH_LINEFILL         = 0xc2,
-       ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP    = 0xc3,
-       ARMV7_PERFCTR_ENTER_READ_ALLOC          = 0xc4,
-       ARMV7_PERFCTR_READ_ALLOC                = 0xc5,
-
-       ARMV7_PERFCTR_STALL_SB_FULL             = 0xc9,
+       ARMV7_A5_PERFCTR_PREFETCH_LINEFILL              = 0xc2,
+       ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP         = 0xc3,
 };
 
 /* ARMv7 Cortex-A15 specific event types */
 enum armv7_a15_perf_types {
-       ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS     = 0x40,
-       ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS    = 0x41,
-       ARMV7_PERFCTR_L1_DCACHE_READ_REFILL     = 0x42,
-       ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL    = 0x43,
+       ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ         = 0x40,
+       ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE        = 0x41,
+       ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ         = 0x42,
+       ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE        = 0x43,
 
-       ARMV7_PERFCTR_L1_DTLB_READ_REFILL       = 0x4C,
-       ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL      = 0x4D,
+       ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ           = 0x4C,
+       ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE          = 0x4D,
 
-       ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS     = 0x50,
-       ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS    = 0x51,
-       ARMV7_PERFCTR_L2_DCACHE_READ_REFILL     = 0x52,
-       ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL    = 0x53,
+       ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ          = 0x50,
+       ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE         = 0x51,
+       ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ          = 0x52,
+       ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE         = 0x53,
 
-       ARMV7_PERFCTR_SPEC_PC_WRITE             = 0x76,
+       ARMV7_A15_PERFCTR_PC_WRITE_SPEC                 = 0x76,
 };
 
 /*
@@ -197,13 +119,15 @@ enum armv7_a15_perf_types {
  * accesses/misses in hardware.
  */
 static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
-       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
-       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV7_PERFCTR_INSTR_EXECUTED,
-       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
-       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-       [PERF_COUNT_HW_BUS_CYCLES]          = ARMV7_PERFCTR_CLOCK_CYCLES,
+       [PERF_COUNT_HW_CPU_CYCLES]              = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+       [PERF_COUNT_HW_CACHE_MISSES]            = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = ARMV7_PERFCTR_PC_WRITE,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]              = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = HW_OP_UNSUPPORTED,
 };
 
 static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
@@ -217,12 +141,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                 * combined.
                 */
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_DCACHE_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DCACHE_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_DCACHE_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DCACHE_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -231,12 +155,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        },
        [C(L1I)] = {
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_INST,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_INST_MISS,
+                       [C(RESULT_ACCESS)]      = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_INST,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_INST_MISS,
+                       [C(RESULT_ACCESS)]      = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -245,12 +169,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        },
        [C(LL)] = {
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L2_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L2_CACH_MISS,
+                       [C(RESULT_ACCESS)]      = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L2_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L2_CACH_MISS,
+                       [C(RESULT_ACCESS)]      = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -274,11 +198,11 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        [C(ITLB)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -287,14 +211,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        },
        [C(BPU)] = {
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_WRITE,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_WRITE,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -321,14 +243,15 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  * Cortex-A9 HW events mapping
  */
 static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
-       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
-       [PERF_COUNT_HW_INSTRUCTIONS]        =
-                                       ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
-       [PERF_COUNT_HW_CACHE_REFERENCES]    = ARMV7_PERFCTR_DCACHE_ACCESS,
-       [PERF_COUNT_HW_CACHE_MISSES]        = ARMV7_PERFCTR_DCACHE_REFILL,
-       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
-       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-       [PERF_COUNT_HW_BUS_CYCLES]          = ARMV7_PERFCTR_CLOCK_CYCLES,
+       [PERF_COUNT_HW_CPU_CYCLES]              = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+       [PERF_COUNT_HW_CACHE_MISSES]            = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = ARMV7_PERFCTR_PC_WRITE,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]              = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = ARMV7_A9_PERFCTR_STALL_DISPATCH,
 };
 
 static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
@@ -342,12 +265,12 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                 * combined.
                 */
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_DCACHE_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DCACHE_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_DCACHE_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DCACHE_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -357,11 +280,11 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        [C(L1I)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -399,11 +322,11 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        [C(ITLB)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -412,14 +335,12 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        },
        [C(BPU)] = {
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_WRITE,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_WRITE,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -446,13 +367,15 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  * Cortex-A5 HW events mapping
  */
 static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
-       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
-       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV7_PERFCTR_INSTR_EXECUTED,
-       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
-       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-       [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CPU_CYCLES]              = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+       [PERF_COUNT_HW_CACHE_MISSES]            = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = ARMV7_PERFCTR_PC_WRITE,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]              = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = HW_OP_UNSUPPORTED,
 };
 
 static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
@@ -460,42 +383,34 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                                        [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
        [C(L1D)] = {
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]
-                                       = ARMV7_PERFCTR_DCACHE_ACCESS,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_DCACHE_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]
-                                       = ARMV7_PERFCTR_DCACHE_ACCESS,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_DCACHE_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
                },
                [C(OP_PREFETCH)] = {
-                       [C(RESULT_ACCESS)]
-                                       = ARMV7_PERFCTR_PREFETCH_LINEFILL,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+                       [C(RESULT_ACCESS)]      = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
+                       [C(RESULT_MISS)]        = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
                },
        },
        [C(L1I)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
                },
                /*
                 * The prefetch counters don't differentiate between the I
                 * side and the D side.
                 */
                [C(OP_PREFETCH)] = {
-                       [C(RESULT_ACCESS)]
-                                       = ARMV7_PERFCTR_PREFETCH_LINEFILL,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+                       [C(RESULT_ACCESS)]      = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
+                       [C(RESULT_MISS)]        = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
                },
        },
        [C(LL)] = {
@@ -529,11 +444,11 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        [C(ITLB)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -543,13 +458,11 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        [C(BPU)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -562,13 +475,15 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  * Cortex-A15 HW events mapping
  */
 static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
-       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
-       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV7_PERFCTR_INSTR_EXECUTED,
-       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE,
-       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
-       [PERF_COUNT_HW_BUS_CYCLES]          = ARMV7_PERFCTR_BUS_CYCLES,
+       [PERF_COUNT_HW_CPU_CYCLES]              = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+       [PERF_COUNT_HW_CACHE_MISSES]            = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]              = ARMV7_PERFCTR_BUS_CYCLES,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = HW_OP_UNSUPPORTED,
 };
 
 static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
@@ -576,16 +491,12 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                                        [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
        [C(L1D)] = {
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]
-                                       = ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_L1_DCACHE_READ_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
+                       [C(RESULT_MISS)]        = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]
-                                       = ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
+                       [C(RESULT_MISS)]        = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -601,11 +512,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                 */
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -614,16 +525,12 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        },
        [C(LL)] = {
                [C(OP_READ)] = {
-                       [C(RESULT_ACCESS)]
-                                       = ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_L2_DCACHE_READ_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
+                       [C(RESULT_MISS)]        = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
                },
                [C(OP_WRITE)] = {
-                       [C(RESULT_ACCESS)]
-                                       = ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL,
+                       [C(RESULT_ACCESS)]      = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
+                       [C(RESULT_MISS)]        = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -633,13 +540,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        [C(DTLB)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_L1_DTLB_READ_REFILL,
+                       [C(RESULT_MISS)]        = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL,
+                       [C(RESULT_MISS)]        = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -649,11 +554,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        [C(ITLB)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
-                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
@@ -663,13 +568,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        [C(BPU)] = {
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
                },
                [C(OP_WRITE)] = {
                        [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
-                       [C(RESULT_MISS)]
-                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
                },
                [C(OP_PREFETCH)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
index e0cca10a8411d51d6a7cf1fadef714213a76de81..3b99d8269829b971db3d8f0618629c77d8317c5a 100644 (file)
@@ -48,13 +48,15 @@ enum xscale_counters {
 };
 
 static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
-       [PERF_COUNT_HW_CPU_CYCLES]          = XSCALE_PERFCTR_CCNT,
-       [PERF_COUNT_HW_INSTRUCTIONS]        = XSCALE_PERFCTR_INSTRUCTION,
-       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
-       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
-       [PERF_COUNT_HW_BRANCH_MISSES]       = XSCALE_PERFCTR_BRANCH_MISS,
-       [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CPU_CYCLES]              = XSCALE_PERFCTR_CCNT,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = XSCALE_PERFCTR_INSTRUCTION,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]            = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = XSCALE_PERFCTR_BRANCH,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = XSCALE_PERFCTR_BRANCH_MISS,
+       [PERF_COUNT_HW_BUS_CYCLES]              = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = XSCALE_PERFCTR_ICACHE_NO_DELIVER,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = HW_OP_UNSUPPORTED,
 };
 
 static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
index 2c3407ee857675242c874f49adaf9d26339f79bf..2334bf8a650a16a35d5849a4b6c309d5f19eb1f1 100644 (file)
@@ -33,3 +33,4 @@ release_pmu(enum arm_pmu_type type)
 {
        clear_bit_unlock(type, pmu_lock);
 }
+EXPORT_SYMBOL_GPL(release_pmu);
index 1e8b3e2de7a3b0ead2cfd2aaa87de146d3fc8325..eeb3e16c60465616067d7681a47b35f8752c4d78 100644 (file)
@@ -191,6 +191,9 @@ void cpu_idle(void)
 #endif
 
                        local_irq_disable();
+#ifdef CONFIG_PL310_ERRATA_769419
+                       wmb();
+#endif
                        if (hlt_counter) {
                                local_irq_enable();
                                cpu_relax();
index a753880e984b9c74822763963a0ec43e5db8d60a..6c2b0db5d1e92e10bb5a00f15671e908ccbf24b4 100644 (file)
@@ -461,8 +461,10 @@ static void __init setup_processor(void)
               cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
               proc_arch[cpu_architecture()], cr_alignment);
 
-       sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
-       sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
+       snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
+                list->arch_name, ENDIANNESS);
+       snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c",
+                list->elf_name, ENDIANNESS);
        elf_hwcap = list->elf_hwcap;
 #ifndef CONFIG_ARM_THUMB
        elf_hwcap &= ~HWCAP_THUMB;
index 1040c00405d0f362916c77030249fff754eda5e8..8200deaa14f680b553bdea41652fac0aaa58e23a 100644 (file)
@@ -43,7 +43,7 @@
 
 struct cputopo_arm cpu_topology[NR_CPUS];
 
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+const struct cpumask *cpu_coregroup_mask(int cpu)
 {
        return &cpu_topology[cpu].core_sibling;
 }
index 10d868a5a48135840278022e153f3610b0b7a640..d6408d1ee543fe5e3ceabbcda01b25efb07676ba 100644 (file)
@@ -1,5 +1,9 @@
+#include <asm/unwind.h>
+
 #if __LINUX_ARM_ARCH__ >= 6
-       .macro  bitop, instr
+       .macro  bitop, name, instr
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        mov     r2, #1
        cmp     r0, #0
        bne     1b
        bx      lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 
-       .macro  testop, instr, store
+       .macro  testop, name, instr, store
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        mov     r2, #1
        cmp     r0, #0
        movne   r0, #1
 2:     bx      lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 #else
-       .macro  bitop, instr
+       .macro  bitop, name, instr
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        and     r2, r0, #31
@@ -49,6 +61,8 @@
        str     r2, [r1, r0, lsl #2]
        restore_irqs ip
        mov     pc, lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 
 /**
@@ -59,7 +73,9 @@
  * Note: we can trivially conditionalise the store instruction
  * to avoid dirtying the data cache.
  */
-       .macro  testop, instr, store
+       .macro  testop, name, instr, store
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        and     r3, r0, #31
@@ -73,5 +89,7 @@
        moveq   r0, #0
        restore_irqs ip
        mov     pc, lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 #endif
index 68ed5b62e83976d906bad4409fdabda385caaf96..f4027862172f8a4f1082ae06d7568615f3e5ad45 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_change_bit)
-       bitop   eor
-ENDPROC(_change_bit)
+bitop  _change_bit, eor
index 4c04c3b51eeb0d11bc3b755044b0a63ca6f0db1b..f6b75fb64d30557c5b22655adec3ba2bd34b0c07 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_clear_bit)
-       bitop   bic
-ENDPROC(_clear_bit)
+bitop  _clear_bit, bic
index bbee5c66a23e177494875e5db4fc19da97ed0d73..618fedae4b370aac8b65c2a39ae51046b0ff711a 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                .text
 
-ENTRY(_set_bit)
-       bitop   orr
-ENDPROC(_set_bit)
+bitop  _set_bit, orr
index 15a4d431f229440979aaf179fd423eb647b8da0f..4becdc3a59cbb60717bae345ec7b3f58243abdb6 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_change_bit)
-       testop  eor, str
-ENDPROC(_test_and_change_bit)
+testop _test_and_change_bit, eor, str
index 521b66b5b95da197fa661f142547414399a0af59..918841dcce7ad57ef5e880f1c09547404070fbe5 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_clear_bit)
-       testop  bicne, strne
-ENDPROC(_test_and_clear_bit)
+testop _test_and_clear_bit, bicne, strne
index 1c98cc2185bb0885ae0cac805193f52d34345608..8d1b2fe9e4873ba8d53ba75773a7e30e92292b7c 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_set_bit)
-       testop  orreq, streq
-ENDPROC(_test_and_set_bit)
+testop _test_and_set_bit, orreq, streq
index 43eadbcc29ede940fd5c4035c2b6abacbcdb2a3b..430da120a297fe08620eaba672c65e283171bd99 100644 (file)
@@ -235,7 +235,7 @@ void __init bcmring_init_timer(void)
         */
        bcmring_clocksource_init();
 
-       sp804_clockevents_register(TIMER0_VA_BASE, IRQ_TIMER0, "timer0");
+       sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMER0, "timer0");
 }
 
 struct sys_timer bcmring_timer = {
index b52b8de91bde72c2a4847c1a37a44f425974612d..f4d4d6d174d06e9c049756de6089e02e790abe8a 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/mm.h>
 #include <linux/pfn.h>
 #include <linux/atomic.h>
+#include <linux/sched.h>
 #include <mach/dma.h>
 
 /* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
index 35f6502144ae14c9ffa989066f51add9ee084375..4ebb382c597918e1053a221b35bd52a9e9d1b39a 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/init.h>
 #include <linux/cpuidle.h>
 #include <linux/io.h>
+#include <linux/export.h>
+#include <linux/time.h>
 
 #include <asm/proc-fns.h>
 
index 89bdf0039f7bf25458236de67b14b3c8e3c30e64..7266dd510f1a4ed9dd495c3268f6430a776b3dc4 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
+#include <linux/smp.h>
 
 #include <asm/cacheflush.h>
 #include <asm/unified.h>
@@ -72,6 +73,9 @@ static void __init highbank_map_io(void)
 
 void highbank_set_cpu_jump(int cpu, void *jump_addr)
 {
+#ifdef CONFIG_SMP
+       cpu = cpu_logical_map(cpu);
+#endif
        writel(BSYM(virt_to_phys(jump_addr)), HB_JUMP_TABLE_VIRT(cpu));
        __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16);
        outer_clean_range(HB_JUMP_TABLE_PHYS(cpu),
index 5f7f9c2a34aec39cdd4f312c326cd0005d5ea027..c44aa974e79c473d123631236269bdb8c2daa8a3 100644 (file)
@@ -10,11 +10,6 @@ config HAVE_IMX_MMDC
 config HAVE_IMX_SRC
        bool
 
-#
-# ARCH_MX31 and ARCH_MX35 are left for compatibility
-# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
-# To easily distinguish good and reviewed from unreviewed usages new (and IMHO
-# more sensible) names are used: SOC_IMX31 and SOC_IMX35
 config ARCH_MX1
        bool
 
@@ -27,12 +22,6 @@ config ARCH_MX25
 config MACH_MX27
        bool
 
-config ARCH_MX31
-       bool
-
-config ARCH_MX35
-       bool
-
 config SOC_IMX1
        bool
        select ARCH_MX1
@@ -72,7 +61,6 @@ config SOC_IMX31
        select CPU_V6
        select IMX_HAVE_PLATFORM_MXC_RNGA
        select ARCH_MXC_AUDMUX_V2
-       select ARCH_MX31
        select MXC_AVIC
        select SMP_ON_UP if SMP
 
@@ -82,7 +70,6 @@ config SOC_IMX35
        select ARCH_MXC_IOMUX_V3
        select ARCH_MXC_AUDMUX_V2
        select HAVE_EPIT
-       select ARCH_MX35
        select MXC_AVIC
        select SMP_ON_UP if SMP
 
index 613a1b993bff9f7fbf9f71595b5ffa8c74922d4d..039a7abb165a35f4afc10ae08dbb7cc62f1121f7 100644 (file)
@@ -1953,14 +1953,17 @@ static struct map_desc imx6q_clock_desc[] = {
        imx_map_entry(MX6Q, ANATOP, MT_DEVICE),
 };
 
+void __init imx6q_clock_map_io(void)
+{
+       iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
+}
+
 int __init mx6q_clocks_init(void)
 {
        struct device_node *np;
        void __iomem *base;
        int i, irq;
 
-       iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
-
        /* retrieve the freqency of fixed clocks from device tree */
        for_each_compatible_node(np, NULL, "fixed-clock") {
                u32 rate;
index 8bf5fa349484e2da42a4c6deea64bc042b1263e3..9cd860a27af5f797cff2b9e5ceaf1798e09e8777 100644 (file)
@@ -34,6 +34,7 @@ static void __init imx6q_map_io(void)
 {
        imx_lluart_map_io();
        imx_scu_map_io();
+       imx6q_clock_map_io();
 }
 
 static void __init imx6q_gpio_add_irq_domain(struct device_node *np,
index 9f0e82ec3398dfcf7e83c8df246e54cdf53b9503..31807d2a8b7bf1a65d57c8f4cb748bb9e6697934 100644 (file)
 static void imx3_idle(void)
 {
        unsigned long reg = 0;
-       __asm__ __volatile__(
-               /* disable I and D cache */
-               "mrc p15, 0, %0, c1, c0, 0\n"
-               "bic %0, %0, #0x00001000\n"
-               "bic %0, %0, #0x00000004\n"
-               "mcr p15, 0, %0, c1, c0, 0\n"
-               /* invalidate I cache */
-               "mov %0, #0\n"
-               "mcr p15, 0, %0, c7, c5, 0\n"
-               /* clear and invalidate D cache */
-               "mov %0, #0\n"
-               "mcr p15, 0, %0, c7, c14, 0\n"
-               /* WFI */
-               "mov %0, #0\n"
-               "mcr p15, 0, %0, c7, c0, 4\n"
-               "nop\n" "nop\n" "nop\n" "nop\n"
-               "nop\n" "nop\n" "nop\n"
-               /* enable I and D cache */
-               "mrc p15, 0, %0, c1, c0, 0\n"
-               "orr %0, %0, #0x00001000\n"
-               "orr %0, %0, #0x00000004\n"
-               "mcr p15, 0, %0, c1, c0, 0\n"
-               : "=r" (reg));
+
+       if (!need_resched())
+               __asm__ __volatile__(
+                       /* disable I and D cache */
+                       "mrc p15, 0, %0, c1, c0, 0\n"
+                       "bic %0, %0, #0x00001000\n"
+                       "bic %0, %0, #0x00000004\n"
+                       "mcr p15, 0, %0, c1, c0, 0\n"
+                       /* invalidate I cache */
+                       "mov %0, #0\n"
+                       "mcr p15, 0, %0, c7, c5, 0\n"
+                       /* clear and invalidate D cache */
+                       "mov %0, #0\n"
+                       "mcr p15, 0, %0, c7, c14, 0\n"
+                       /* WFI */
+                       "mov %0, #0\n"
+                       "mcr p15, 0, %0, c7, c0, 4\n"
+                       "nop\n" "nop\n" "nop\n" "nop\n"
+                       "nop\n" "nop\n" "nop\n"
+                       /* enable I and D cache */
+                       "mrc p15, 0, %0, c1, c0, 0\n"
+                       "orr %0, %0, #0x00001000\n"
+                       "orr %0, %0, #0x00000004\n"
+                       "mcr p15, 0, %0, c1, c0, 0\n"
+                       : "=r" (reg));
+       local_irq_enable();
 }
 
 static void __iomem *imx3_ioremap(unsigned long phys_addr, size_t size,
@@ -108,6 +111,7 @@ void imx3_init_l2x0(void)
        l2x0_init(l2x0_base, 0x00030024, 0x00000000);
 }
 
+#ifdef CONFIG_SOC_IMX31
 static struct map_desc mx31_io_desc[] __initdata = {
        imx_map_entry(MX31, X_MEMC, MT_DEVICE),
        imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
@@ -126,33 +130,11 @@ void __init mx31_map_io(void)
        iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
 }
 
-static struct map_desc mx35_io_desc[] __initdata = {
-       imx_map_entry(MX35, X_MEMC, MT_DEVICE),
-       imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
-       imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
-       imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
-       imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
-};
-
-void __init mx35_map_io(void)
-{
-       iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
-}
-
 void __init imx31_init_early(void)
 {
        mxc_set_cpu_type(MXC_CPU_MX31);
        mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
-       imx_idle = imx3_idle;
-       imx_ioremap = imx3_ioremap;
-}
-
-void __init imx35_init_early(void)
-{
-       mxc_set_cpu_type(MXC_CPU_MX35);
-       mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
-       mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
-       imx_idle = imx3_idle;
+       pm_idle = imx3_idle;
        imx_ioremap = imx3_ioremap;
 }
 
@@ -161,11 +143,6 @@ void __init mx31_init_irq(void)
        mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
 }
 
-void __init mx35_init_irq(void)
-{
-       mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
-}
-
 static struct sdma_script_start_addrs imx31_to1_sdma_script __initdata = {
        .per_2_per_addr = 1677,
 };
@@ -199,6 +176,35 @@ void __init imx31_soc_init(void)
 
        imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
 }
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+static struct map_desc mx35_io_desc[] __initdata = {
+       imx_map_entry(MX35, X_MEMC, MT_DEVICE),
+       imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
+       imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
+       imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
+       imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
+};
+
+void __init mx35_map_io(void)
+{
+       iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
+}
+
+void __init imx35_init_early(void)
+{
+       mxc_set_cpu_type(MXC_CPU_MX35);
+       mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
+       mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
+       pm_idle = imx3_idle;
+       imx_ioremap = imx3_ioremap;
+}
+
+void __init mx35_init_irq(void)
+{
+       mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
+}
 
 static struct sdma_script_start_addrs imx35_to1_sdma_script __initdata = {
        .ap_2_ap_addr = 642,
@@ -254,3 +260,4 @@ void __init imx35_soc_init(void)
 
        imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
 }
+#endif /* ifdef CONFIG_SOC_IMX35 */
index 36cacbd0dcc2fa8c5d98bd5cb1e141a9d30e3503..a8e33681b73251f498a7cfee463f20c3f6d0e1ff 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/smp.h>
 #include <asm/unified.h>
 
 #define SRC_SCR                                0x000
 
 static void __iomem *src_base;
 
+#ifndef CONFIG_SMP
+#define cpu_logical_map(cpu)           0
+#endif
+
 void imx_enable_cpu(int cpu, bool enable)
 {
        u32 mask, val;
 
+       cpu = cpu_logical_map(cpu);
        mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
        val = readl_relaxed(src_base + SRC_SCR);
        val = enable ? val | mask : val & ~mask;
@@ -35,6 +41,7 @@ void imx_enable_cpu(int cpu, bool enable)
 
 void imx_set_cpu_jump(int cpu, void *jump_addr)
 {
+       cpu = cpu_logical_map(cpu);
        writel_relaxed(BSYM(virt_to_phys(jump_addr)),
                       src_base + SRC_GPR1 + cpu * 8);
 }
index 69156568bc41f95891df3c17ca06836a9c3bf5bb..4665767a4f79ee918ec1fd24053d296ce13d0806 100644 (file)
@@ -182,7 +182,7 @@ static void __init gplugd_init(void)
 
        /* on-chip devices */
        pxa168_add_uart(3);
-       pxa168_add_ssp(0);
+       pxa168_add_ssp(1);
        pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
 
        pxa168_add_eth(&gplugd_eth_platform_data);
index d14eeaf163226d3b2ff53c394976be090b1e4d62..99b4ce1b6562cebf64651b9a0039599d624593d6 100644 (file)
@@ -7,7 +7,7 @@
 #define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000)
 
 #define BANK_OFF(n)    (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
-#define GPIO_REG(x)    (GPIO_REGS_VIRT + (x))
+#define GPIO_REG(x)    (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
 
 #define NR_BUILTIN_GPIO                IRQ_GPIO_NUM
 
index 5c5328257dca2f5560ccaa33bf98a27b80582b27..5e2e7a8438606f43015d90115046e555eee1a3c5 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static int mx5_cpu_rev = -1;
 
@@ -67,7 +67,8 @@ static int __init mx51_neon_fixup(void)
        if (!cpu_is_mx51())
                return 0;
 
-       if (mx51_revision() < IMX_CHIP_REVISION_3_0 && (elf_hwcap & HWCAP_NEON)) {
+       if (mx51_revision() < IMX_CHIP_REVISION_3_0 &&
+                       (elf_hwcap & HWCAP_NEON)) {
                elf_hwcap &= ~HWCAP_NEON;
                pr_info("Turning off NEON support, detected broken NEON implementation\n");
        }
index 26eacc9d0d90fbf88930bd6a009c58efe6914c70..df4a508f240a04a47ce8bb5abbf6074f843c8aae 100644 (file)
@@ -23,7 +23,9 @@
 
 static void imx5_idle(void)
 {
-       mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+       if (!need_resched())
+               mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+       local_irq_enable();
 }
 
 /*
@@ -89,7 +91,7 @@ void __init imx51_init_early(void)
        mxc_set_cpu_type(MXC_CPU_MX51);
        mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
        mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
-       imx_idle = imx5_idle;
+       pm_idle = imx5_idle;
 }
 
 void __init imx53_init_early(void)
index 229ae3494216da2920bddb5164d66ce523a6ddeb..da6e4aad177c2097b12515b2ddd2572e8b397ea2 100644 (file)
@@ -404,7 +404,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)             \
        reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);         \
        reg &= ~BM_CLKCTRL_##dr##_DIV;                                  \
        reg |= div << BP_CLKCTRL_##dr##_DIV;                            \
-       if (reg | (1 << clk->enable_shift)) {                           \
+       if (reg & (1 << clk->enable_shift)) {                           \
                pr_err("%s: clock is gated\n", __func__);               \
                return -EINVAL;                                         \
        }                                                               \
index e0a028161ddee89a4119014ed83420bd0a21ad4e..73f287d6429b629d57f7c093645962ce48cee318 100644 (file)
@@ -171,14 +171,6 @@ config MACH_OMAP_GENERIC
 comment "OMAP CPU Speed"
        depends on ARCH_OMAP1
 
-config OMAP_CLOCKS_SET_BY_BOOTLOADER
-       bool "OMAP clocks set by bootloader"
-       depends on ARCH_OMAP1
-       help
-         Enable this option to prevent the kernel from overriding the clock
-         frequencies programmed by bootloader for MPU, DSP, MMUs, TC,
-         internal LCD controller and MPU peripherals.
-
 config OMAP_ARM_216MHZ
        bool "OMAP ARM 216 MHz CPU (1710 only)"
         depends on ARCH_OMAP1 && ARCH_OMAP16XX
index 1b374009b1a3efa2402bb4432d382de27ec5b22e..af7911963c0dc53429b33eb039aaec9d80152453 100644 (file)
@@ -302,8 +302,6 @@ static void __init ams_delta_init(void)
        omap_cfg_reg(J19_1610_CAM_D6);
        omap_cfg_reg(J18_1610_CAM_D7);
 
-       iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
-
        omap_board_config = ams_delta_config;
        omap_board_config_size = ARRAY_SIZE(ams_delta_config);
        omap_serial_init();
@@ -373,10 +371,16 @@ static int __init ams_delta_modem_init(void)
 }
 arch_initcall(ams_delta_modem_init);
 
+static void __init ams_delta_map_io(void)
+{
+       omap15xx_map_io();
+       iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
+}
+
 MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
        /* Maintainer: Jonathan McDowell <noodles@earth.li> */
        .atag_offset    = 0x100,
-       .map_io         = omap15xx_map_io,
+       .map_io         = ams_delta_map_io,
        .init_early     = omap1_init_early,
        .reserve        = omap_reserve,
        .init_irq       = omap1_init_irq,
index eaf09efb91caec613eeb73e961e7fbd77a93cf21..16b1423b454a32dea7197460a393b12a4bd4e2b0 100644 (file)
@@ -17,7 +17,8 @@
 
 #include <plat/clock.h>
 
-extern int __init omap1_clk_init(void);
+int omap1_clk_init(void);
+void omap1_clk_late_init(void);
 extern int omap1_clk_enable(struct clk *clk);
 extern void omap1_clk_disable(struct clk *clk);
 extern long omap1_clk_round_rate(struct clk *clk, unsigned long rate);
index 92400b9eb69f10c419c7e1295e238d56d5ef6110..1297bb58869cf72dcda88e7329b9f83f5cd3da13 100644 (file)
@@ -767,6 +767,15 @@ static struct clk_functions omap1_clk_functions = {
        .clk_disable_unused     = omap1_clk_disable_unused,
 };
 
+static void __init omap1_show_rates(void)
+{
+       pr_notice("Clocking rate (xtal/DPLL1/MPU): "
+                       "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
+               ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
+               ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
+               arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
+}
+
 int __init omap1_clk_init(void)
 {
        struct omap_clk *c;
@@ -835,9 +844,12 @@ int __init omap1_clk_init(void)
        /* We want to be in syncronous scalable mode */
        omap_writew(0x1000, ARM_SYSST);
 
-#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
-       /* Use values set by bootloader. Determine PLL rate and recalculate
-        * dependent clocks as if kernel had changed PLL or divisors.
+
+       /*
+        * Initially use the values set by bootloader. Determine PLL rate and
+        * recalculate dependent clocks as if kernel had changed PLL or
+        * divisors. See also omap1_clk_late_init() that can reprogram dpll1
+        * after the SRAM is initialized.
         */
        {
                unsigned pll_ctl_val = omap_readw(DPLL_CTL);
@@ -862,25 +874,10 @@ int __init omap1_clk_init(void)
                        }
                }
        }
-#else
-       /* Find the highest supported frequency and enable it */
-       if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
-               printk(KERN_ERR "System frequencies not set. Check your config.\n");
-               /* Guess sane values (60MHz) */
-               omap_writew(0x2290, DPLL_CTL);
-               omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL);
-               ck_dpll1.rate = 60000000;
-       }
-#endif
        propagate_rate(&ck_dpll1);
        /* Cache rates for clocks connected to ck_ref (not dpll1) */
        propagate_rate(&ck_ref);
-       printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
-               "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
-              ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
-              ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
-              arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
-
+       omap1_show_rates();
        if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
                /* Select slicer output as OMAP input clock */
                omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1,
@@ -925,3 +922,21 @@ int __init omap1_clk_init(void)
 
        return 0;
 }
+
+#define OMAP1_DPLL1_SANE_VALUE 60000000
+
+void __init omap1_clk_late_init(void)
+{
+       if (ck_dpll1.rate >= OMAP1_DPLL1_SANE_VALUE)
+               return;
+
+       /* Find the highest supported frequency and enable it */
+       if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
+               pr_err("System frequencies not set, using default. Check your config.\n");
+               omap_writew(0x2290, DPLL_CTL);
+               omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL);
+               ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE;
+       }
+       propagate_rate(&ck_dpll1);
+       omap1_show_rates();
+}
index 9d47ca7f80fae989d098f3170f0ab77bbe9e0801..1d76a63c098362742773ac89298c1a8cf0980e6f 100644 (file)
@@ -30,6 +30,8 @@
 #include <plat/omap7xx.h>
 #include <plat/mcbsp.h>
 
+#include "clock.h"
+
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
@@ -293,6 +295,7 @@ static int __init omap1_init_devices(void)
                return -ENODEV;
 
        omap_sram_init();
+       omap1_clk_late_init();
 
        /* please keep these calls, and their implementations above,
         * in alphabetical order so they're easier to sort through.
index 22f7c97a27288f6a2faddfe39cf8898f79347967..b6625130831d3f5378a4a0cf3d422dcc3e9c0870 100644 (file)
@@ -336,6 +336,7 @@ config MACH_OMAP4_PANDA
 config OMAP3_EMU
        bool "OMAP3 debugging peripherals"
        depends on ARCH_OMAP3
+       select ARM_AMBA
        select OC_ETM
        help
          Say Y here to enable debugging hardware of omap3
index 69ab1c069134ccee42da01c015aea9d219408f4a..b009f17dee5606de2acbb1b7ba25c8938d0c5adb 100644 (file)
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
-        common.o gpio.o dma.o wd_timer.o
+        common.o gpio.o dma.o wd_timer.o display.o
 
 omap-2-3-common                                = irq.o sdrc.o
 hwmod-common                           = omap_hwmod.o \
@@ -264,7 +264,4 @@ smsc911x-$(CONFIG_SMSC911X)         := gpmc-smsc911x.o
 obj-y                                  += $(smsc911x-m) $(smsc911x-y)
 obj-$(CONFIG_ARCH_OMAP4)               += hwspinlock.o
 
-disp-$(CONFIG_OMAP2_DSS)               := display.o
-obj-y                                  += $(disp-m) $(disp-y)
-
 obj-y                                  += common-board-devices.o twl-common.o
index 876f647797356c1c2117d60d01724ece41d66a25..e20332f4abdc57e891231bb39503b4dcb4d1aa18 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
+#include <linux/export.h>
 
 #include <plat/prcm.h>
 #include <plat/irqs.h>
index adb2756e242f104bc8dd35e969ba4957d3407b7a..dce9905d64bb6e1af6c0b80d012142ffdfca49ee 100644 (file)
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 #include <plat/omap-pm.h>
+#include <plat/common.h>
 
 #include "control.h"
+#include "display.h"
+
+#define DISPC_CONTROL          0x0040
+#define DISPC_CONTROL2         0x0238
+#define DISPC_IRQSTATUS                0x0018
+
+#define DSS_SYSCONFIG          0x10
+#define DSS_SYSSTATUS          0x14
+#define DSS_CONTROL            0x40
+#define DSS_SDI_CONTROL                0x44
+#define DSS_PLL_CONTROL                0x48
+
+#define LCD_EN_MASK            (0x1 << 0)
+#define DIGIT_EN_MASK          (0x1 << 1)
+
+#define FRAMEDONE_IRQ_SHIFT    0
+#define EVSYNC_EVEN_IRQ_SHIFT  2
+#define EVSYNC_ODD_IRQ_SHIFT   3
+#define FRAMEDONE2_IRQ_SHIFT   22
+#define FRAMEDONETV_IRQ_SHIFT  24
+
+/*
+ * FRAMEDONE_IRQ_TIMEOUT: how long (in milliseconds) to wait during DISPC
+ *     reset before deciding that something has gone wrong
+ */
+#define FRAMEDONE_IRQ_TIMEOUT          100
 
 static struct platform_device omap_display_device = {
        .name          = "omapdss",
@@ -172,3 +199,135 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
 
        return r;
 }
+
+static void dispc_disable_outputs(void)
+{
+       u32 v, irq_mask = 0;
+       bool lcd_en, digit_en, lcd2_en = false;
+       int i;
+       struct omap_dss_dispc_dev_attr *da;
+       struct omap_hwmod *oh;
+
+       oh = omap_hwmod_lookup("dss_dispc");
+       if (!oh) {
+               WARN(1, "display: could not disable outputs during reset - could not find dss_dispc hwmod\n");
+               return;
+       }
+
+       if (!oh->dev_attr) {
+               pr_err("display: could not disable outputs during reset due to missing dev_attr\n");
+               return;
+       }
+
+       da = (struct omap_dss_dispc_dev_attr *)oh->dev_attr;
+
+       /* store value of LCDENABLE and DIGITENABLE bits */
+       v = omap_hwmod_read(oh, DISPC_CONTROL);
+       lcd_en = v & LCD_EN_MASK;
+       digit_en = v & DIGIT_EN_MASK;
+
+       /* store value of LCDENABLE for LCD2 */
+       if (da->manager_count > 2) {
+               v = omap_hwmod_read(oh, DISPC_CONTROL2);
+               lcd2_en = v & LCD_EN_MASK;
+       }
+
+       if (!(lcd_en | digit_en | lcd2_en))
+               return; /* no managers currently enabled */
+
+       /*
+        * If any manager was enabled, we need to disable it before
+        * DSS clocks are disabled or DISPC module is reset
+        */
+       if (lcd_en)
+               irq_mask |= 1 << FRAMEDONE_IRQ_SHIFT;
+
+       if (digit_en) {
+               if (da->has_framedonetv_irq) {
+                       irq_mask |= 1 << FRAMEDONETV_IRQ_SHIFT;
+               } else {
+                       irq_mask |= 1 << EVSYNC_EVEN_IRQ_SHIFT |
+                               1 << EVSYNC_ODD_IRQ_SHIFT;
+               }
+       }
+
+       if (lcd2_en)
+               irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT;
+
+       /*
+        * clear any previous FRAMEDONE, FRAMEDONETV,
+        * EVSYNC_EVEN/ODD or FRAMEDONE2 interrupts
+        */
+       omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS);
+
+       /* disable LCD and TV managers */
+       v = omap_hwmod_read(oh, DISPC_CONTROL);
+       v &= ~(LCD_EN_MASK | DIGIT_EN_MASK);
+       omap_hwmod_write(v, oh, DISPC_CONTROL);
+
+       /* disable LCD2 manager */
+       if (da->manager_count > 2) {
+               v = omap_hwmod_read(oh, DISPC_CONTROL2);
+               v &= ~LCD_EN_MASK;
+               omap_hwmod_write(v, oh, DISPC_CONTROL2);
+       }
+
+       i = 0;
+       while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) !=
+              irq_mask) {
+               i++;
+               if (i > FRAMEDONE_IRQ_TIMEOUT) {
+                       pr_err("didn't get FRAMEDONE1/2 or TV interrupt\n");
+                       break;
+               }
+               mdelay(1);
+       }
+}
+
+#define MAX_MODULE_SOFTRESET_WAIT      10000
+int omap_dss_reset(struct omap_hwmod *oh)
+{
+       struct omap_hwmod_opt_clk *oc;
+       int c = 0;
+       int i, r;
+
+       if (!(oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)) {
+               pr_err("dss_core: hwmod data doesn't contain reset data\n");
+               return -EINVAL;
+       }
+
+       for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+               if (oc->_clk)
+                       clk_enable(oc->_clk);
+
+       dispc_disable_outputs();
+
+       /* clear SDI registers */
+       if (cpu_is_omap3430()) {
+               omap_hwmod_write(0x0, oh, DSS_SDI_CONTROL);
+               omap_hwmod_write(0x0, oh, DSS_PLL_CONTROL);
+       }
+
+       /*
+        * clear DSS_CONTROL register to switch DSS clock sources to
+        * PRCM clock, if any
+        */
+       omap_hwmod_write(0x0, oh, DSS_CONTROL);
+
+       omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs)
+                               & SYSS_RESETDONE_MASK),
+                       MAX_MODULE_SOFTRESET_WAIT, c);
+
+       if (c == MAX_MODULE_SOFTRESET_WAIT)
+               pr_warning("dss_core: waiting for reset to finish failed\n");
+       else
+               pr_debug("dss_core: softreset done\n");
+
+       for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+               if (oc->_clk)
+                       clk_disable(oc->_clk);
+
+       r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
+
+       return r;
+}
diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h
new file mode 100644 (file)
index 0000000..b871b01
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * display.h - OMAP2+ integration-specific DSS header
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_DISPLAY_H
+#define __ARCH_ARM_MACH_OMAP2_DISPLAY_H
+
+#include <linux/kernel.h>
+
+struct omap_dss_dispc_dev_attr {
+       u8      manager_count;
+       bool    has_framedonetv_irq;
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/io.h b/arch/arm/mach-omap2/io.h
deleted file mode 100644 (file)
index e69de29..0000000
index 00fcd2c311ea652e4117eae2ebb74eb462d9304f..529142aff76699a85082179eb3e455d13a97959b 100644 (file)
@@ -749,7 +749,7 @@ static int _count_mpu_irqs(struct omap_hwmod *oh)
                ohii = &oh->mpu_irqs[i++];
        } while (ohii->irq != -1);
 
-       return i;
+       return i-1;
 }
 
 /**
@@ -772,7 +772,7 @@ static int _count_sdma_reqs(struct omap_hwmod *oh)
                ohdi = &oh->sdma_reqs[i++];
        } while (ohdi->dma_req != -1);
 
-       return i;
+       return i-1;
 }
 
 /**
@@ -795,7 +795,7 @@ static int _count_ocp_if_addr_spaces(struct omap_hwmod_ocp_if *os)
                mem = &os->addr[i++];
        } while (mem->pa_start != mem->pa_end);
 
-       return i;
+       return i-1;
 }
 
 /**
index 6d7206213525d03ac830d8ca6092ce4317863f37..a5409ce3f3233eaac531ed070fc1f9cf74e8398f 100644 (file)
@@ -875,6 +875,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_slaves[] = {
 };
 
 static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+       /*
+        * The DSS HW needs all DSS clocks enabled during reset. The dss_core
+        * driver does not use these clocks.
+        */
        { .role = "tv_clk", .clk = "dss_54m_fck" },
        { .role = "sys_clk", .clk = "dss2_fck" },
 };
@@ -899,7 +903,7 @@ static struct omap_hwmod omap2420_dss_core_hwmod = {
        .slaves_cnt     = ARRAY_SIZE(omap2420_dss_slaves),
        .masters        = omap2420_dss_masters,
        .masters_cnt    = ARRAY_SIZE(omap2420_dss_masters),
-       .flags          = HWMOD_NO_IDLEST,
+       .flags          = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET,
 };
 
 /* l4_core -> dss_dispc */
@@ -939,6 +943,7 @@ static struct omap_hwmod omap2420_dss_dispc_hwmod = {
        .slaves         = omap2420_dss_dispc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2420_dss_dispc_slaves),
        .flags          = HWMOD_NO_IDLEST,
+       .dev_attr       = &omap2_3_dss_dispc_dev_attr
 };
 
 /* l4_core -> dss_rfbi */
@@ -961,6 +966,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_rfbi_slaves[] = {
        &omap2420_l4_core__dss_rfbi,
 };
 
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+       { .role = "ick", .clk = "dss_ick" },
+};
+
 static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
        .name           = "dss_rfbi",
        .class          = &omap2_rfbi_hwmod_class,
@@ -972,6 +981,8 @@ static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
                        .module_offs = CORE_MOD,
                },
        },
+       .opt_clks       = dss_rfbi_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_rfbi_opt_clks),
        .slaves         = omap2420_dss_rfbi_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2420_dss_rfbi_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -981,7 +992,7 @@ static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
 static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = {
        .master         = &omap2420_l4_core_hwmod,
        .slave          = &omap2420_dss_venc_hwmod,
-       .clk            = "dss_54m_fck",
+       .clk            = "dss_ick",
        .addr           = omap2_dss_venc_addrs,
        .fw = {
                .omap2 = {
@@ -1001,7 +1012,7 @@ static struct omap_hwmod_ocp_if *omap2420_dss_venc_slaves[] = {
 static struct omap_hwmod omap2420_dss_venc_hwmod = {
        .name           = "dss_venc",
        .class          = &omap2_venc_hwmod_class,
-       .main_clk       = "dss1_fck",
+       .main_clk       = "dss_54m_fck",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
index a2580d01c3ff98b25a57b6508bd959d0e58c700f..c4f56cb60d7d676ddda36e232c8b385a58fef6ba 100644 (file)
@@ -942,6 +942,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_slaves[] = {
 };
 
 static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+       /*
+        * The DSS HW needs all DSS clocks enabled during reset. The dss_core
+        * driver does not use these clocks.
+        */
        { .role = "tv_clk", .clk = "dss_54m_fck" },
        { .role = "sys_clk", .clk = "dss2_fck" },
 };
@@ -966,7 +970,7 @@ static struct omap_hwmod omap2430_dss_core_hwmod = {
        .slaves_cnt     = ARRAY_SIZE(omap2430_dss_slaves),
        .masters        = omap2430_dss_masters,
        .masters_cnt    = ARRAY_SIZE(omap2430_dss_masters),
-       .flags          = HWMOD_NO_IDLEST,
+       .flags          = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET,
 };
 
 /* l4_core -> dss_dispc */
@@ -1000,6 +1004,7 @@ static struct omap_hwmod omap2430_dss_dispc_hwmod = {
        .slaves         = omap2430_dss_dispc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2430_dss_dispc_slaves),
        .flags          = HWMOD_NO_IDLEST,
+       .dev_attr       = &omap2_3_dss_dispc_dev_attr
 };
 
 /* l4_core -> dss_rfbi */
@@ -1016,6 +1021,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_rfbi_slaves[] = {
        &omap2430_l4_core__dss_rfbi,
 };
 
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+       { .role = "ick", .clk = "dss_ick" },
+};
+
 static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
        .name           = "dss_rfbi",
        .class          = &omap2_rfbi_hwmod_class,
@@ -1027,6 +1036,8 @@ static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
                        .module_offs = CORE_MOD,
                },
        },
+       .opt_clks       = dss_rfbi_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_rfbi_opt_clks),
        .slaves         = omap2430_dss_rfbi_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2430_dss_rfbi_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -1036,7 +1047,7 @@ static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
 static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = {
        .master         = &omap2430_l4_core_hwmod,
        .slave          = &omap2430_dss_venc_hwmod,
-       .clk            = "dss_54m_fck",
+       .clk            = "dss_ick",
        .addr           = omap2_dss_venc_addrs,
        .flags          = OCPIF_SWSUP_IDLE,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
@@ -1050,7 +1061,7 @@ static struct omap_hwmod_ocp_if *omap2430_dss_venc_slaves[] = {
 static struct omap_hwmod omap2430_dss_venc_hwmod = {
        .name           = "dss_venc",
        .class          = &omap2_venc_hwmod_class,
-       .main_clk       = "dss1_fck",
+       .main_clk       = "dss_54m_fck",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
index c451729d289adfd17090c3be58c53937626835fe..c11273da5dcc33f046e94babfdb6f34c1d6f2778 100644 (file)
@@ -11,6 +11,7 @@
 #include <plat/omap_hwmod.h>
 #include <plat/serial.h>
 #include <plat/dma.h>
+#include <plat/common.h>
 
 #include <mach/irqs.h>
 
@@ -43,13 +44,15 @@ static struct omap_hwmod_class_sysconfig omap2_dss_sysc = {
        .rev_offs       = 0x0000,
        .sysc_offs      = 0x0010,
        .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+       .sysc_flags     = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+                          SYSS_HAS_RESET_STATUS),
        .sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
 struct omap_hwmod_class omap2_dss_hwmod_class = {
        .name   = "dss",
        .sysc   = &omap2_dss_sysc,
+       .reset  = omap_dss_reset,
 };
 
 /*
index bc9035ec87fc59aa08410cdbc24156619c87c7a1..7f8915ad50990b1af2e877ed169c32cd0d15cd02 100644 (file)
@@ -1369,9 +1369,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = {
 };
 
 static struct omap_hwmod_opt_clk dss_opt_clks[] = {
-       { .role = "tv_clk", .clk = "dss_tv_fck" },
-       { .role = "video_clk", .clk = "dss_96m_fck" },
+       /*
+        * The DSS HW needs all DSS clocks enabled during reset. The dss_core
+        * driver does not use these clocks.
+        */
        { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+       { .role = "tv_clk", .clk = "dss_tv_fck" },
+       /* required only on OMAP3430 */
+       { .role = "tv_dac_clk", .clk = "dss_96m_fck" },
 };
 
 static struct omap_hwmod omap3430es1_dss_core_hwmod = {
@@ -1394,11 +1399,12 @@ static struct omap_hwmod omap3430es1_dss_core_hwmod = {
        .slaves_cnt     = ARRAY_SIZE(omap3430es1_dss_slaves),
        .masters        = omap3xxx_dss_masters,
        .masters_cnt    = ARRAY_SIZE(omap3xxx_dss_masters),
-       .flags          = HWMOD_NO_IDLEST,
+       .flags          = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET,
 };
 
 static struct omap_hwmod omap3xxx_dss_core_hwmod = {
        .name           = "dss_core",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .class          = &omap2_dss_hwmod_class,
        .main_clk       = "dss1_alwon_fck", /* instead of dss_fck */
        .sdma_reqs      = omap3xxx_dss_sdma_chs,
@@ -1456,6 +1462,7 @@ static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
        .slaves         = omap3xxx_dss_dispc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_dss_dispc_slaves),
        .flags          = HWMOD_NO_IDLEST,
+       .dev_attr       = &omap2_3_dss_dispc_dev_attr
 };
 
 /*
@@ -1486,6 +1493,7 @@ static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = {
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap3xxx_dss_dsi1_hwmod,
+       .clk            = "dss_ick",
        .addr           = omap3xxx_dss_dsi1_addrs,
        .fw = {
                .omap2 = {
@@ -1502,6 +1510,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = {
        &omap3xxx_l4_core__dss_dsi1,
 };
 
+static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = {
+       { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+};
+
 static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
        .name           = "dss_dsi1",
        .class          = &omap3xxx_dsi_hwmod_class,
@@ -1514,6 +1526,8 @@ static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
                        .module_offs = OMAP3430_DSS_MOD,
                },
        },
+       .opt_clks       = dss_dsi1_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_dsi1_opt_clks),
        .slaves         = omap3xxx_dss_dsi1_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_dss_dsi1_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -1540,6 +1554,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_rfbi_slaves[] = {
        &omap3xxx_l4_core__dss_rfbi,
 };
 
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+       { .role = "ick", .clk = "dss_ick" },
+};
+
 static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
        .name           = "dss_rfbi",
        .class          = &omap2_rfbi_hwmod_class,
@@ -1551,6 +1569,8 @@ static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
                        .module_offs = OMAP3430_DSS_MOD,
                },
        },
+       .opt_clks       = dss_rfbi_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_rfbi_opt_clks),
        .slaves         = omap3xxx_dss_rfbi_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_dss_rfbi_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -1560,7 +1580,7 @@ static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap3xxx_dss_venc_hwmod,
-       .clk            = "dss_tv_fck",
+       .clk            = "dss_ick",
        .addr           = omap2_dss_venc_addrs,
        .fw = {
                .omap2 = {
@@ -1578,10 +1598,15 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_venc_slaves[] = {
        &omap3xxx_l4_core__dss_venc,
 };
 
+static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = {
+       /* required only on OMAP3430 */
+       { .role = "tv_dac_clk", .clk = "dss_96m_fck" },
+};
+
 static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
        .name           = "dss_venc",
        .class          = &omap2_venc_hwmod_class,
-       .main_clk       = "dss1_alwon_fck",
+       .main_clk       = "dss_tv_fck",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
@@ -1589,6 +1614,8 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
                        .module_offs = OMAP3430_DSS_MOD,
                },
        },
+       .opt_clks       = dss_venc_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_venc_opt_clks),
        .slaves         = omap3xxx_dss_venc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_dss_venc_slaves),
        .flags          = HWMOD_NO_IDLEST,
index 7695e5d43316686429158ec56aafacbc7d25a6a7..daaf165af696f212c6dcadb4db7ac3539d54dcd6 100644 (file)
@@ -30,6 +30,7 @@
 #include <plat/mmc.h>
 #include <plat/i2c.h>
 #include <plat/dmtimer.h>
+#include <plat/common.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -1187,6 +1188,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = {
 static struct omap_hwmod_class omap44xx_dss_hwmod_class = {
        .name   = "dss",
        .sysc   = &omap44xx_dss_sysc,
+       .reset  = omap_dss_reset,
 };
 
 /* dss */
@@ -1240,12 +1242,12 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = {
 static struct omap_hwmod_opt_clk dss_opt_clks[] = {
        { .role = "sys_clk", .clk = "dss_sys_clk" },
        { .role = "tv_clk", .clk = "dss_tv_clk" },
-       { .role = "dss_clk", .clk = "dss_dss_clk" },
-       { .role = "video_clk", .clk = "dss_48mhz_clk" },
+       { .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
 };
 
 static struct omap_hwmod omap44xx_dss_hwmod = {
        .name           = "dss_core",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .class          = &omap44xx_dss_hwmod_class,
        .clkdm_name     = "l3_dss_clkdm",
        .main_clk       = "dss_dss_clk",
@@ -1325,6 +1327,11 @@ static struct omap_hwmod_addr_space omap44xx_dss_dispc_addrs[] = {
        { }
 };
 
+static struct omap_dss_dispc_dev_attr omap44xx_dss_dispc_dev_attr = {
+       .manager_count          = 3,
+       .has_framedonetv_irq    = 1
+};
+
 /* l4_per -> dss_dispc */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = {
        .master         = &omap44xx_l4_per_hwmod,
@@ -1340,12 +1347,6 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = {
        &omap44xx_l4_per__dss_dispc,
 };
 
-static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = {
-       { .role = "sys_clk", .clk = "dss_sys_clk" },
-       { .role = "tv_clk", .clk = "dss_tv_clk" },
-       { .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
-};
-
 static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
        .name           = "dss_dispc",
        .class          = &omap44xx_dispc_hwmod_class,
@@ -1359,10 +1360,9 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
                        .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
                },
        },
-       .opt_clks       = dss_dispc_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(dss_dispc_opt_clks),
        .slaves         = omap44xx_dss_dispc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap44xx_dss_dispc_slaves),
+       .dev_attr       = &omap44xx_dss_dispc_dev_attr
 };
 
 /*
@@ -1624,7 +1624,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
        .clkdm_name     = "l3_dss_clkdm",
        .mpu_irqs       = omap44xx_dss_hdmi_irqs,
        .sdma_reqs      = omap44xx_dss_hdmi_sdma_reqs,
-       .main_clk       = "dss_dss_clk",
+       .main_clk       = "dss_48mhz_clk",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
@@ -1785,7 +1785,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
        .name           = "dss_venc",
        .class          = &omap44xx_venc_hwmod_class,
        .clkdm_name     = "l3_dss_clkdm",
-       .main_clk       = "dss_dss_clk",
+       .main_clk       = "dss_tv_clk",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
index de832ebc93a98c8d2556675de6ae3bfd7a5b2342..51e5418899fb446cd2317efe2622e3683860eec4 100644 (file)
@@ -49,3 +49,7 @@ struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = {
        .srst_shift     = SYSC_TYPE2_SOFTRESET_SHIFT,
 };
 
+struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr = {
+       .manager_count          = 2,
+       .has_framedonetv_irq    = 0
+};
index 39a7c37f45870446a9f61d682eb5cc333cbac94c..ad5d8f04c0b8803edeac09dff53686c156365b91 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <plat/omap_hwmod.h>
 
+#include "display.h"
+
 /* Common address space across OMAP2xxx */
 extern struct omap_hwmod_addr_space omap2xxx_uart1_addr_space[];
 extern struct omap_hwmod_addr_space omap2xxx_uart2_addr_space[];
@@ -111,4 +113,6 @@ extern struct omap_hwmod_class omap2xxx_dma_hwmod_class;
 extern struct omap_hwmod_class omap2xxx_mailbox_hwmod_class;
 extern struct omap_hwmod_class omap2xxx_mcspi_class;
 
+extern struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr;
+
 #endif
index 6a66aa5e2a5b368f702f646366cb7175e6c2ad52..d15225ff5c4969b3ddde9cc79ece7caf725001eb 100644 (file)
@@ -237,7 +237,7 @@ static int __devexit omap4_l3_remove(struct platform_device *pdev)
 static const struct of_device_id l3_noc_match[] = {
        {.compatible = "ti,omap4-l3-noc", },
        {},
-}
+};
 MODULE_DEVICE_TABLE(of, l3_noc_match);
 #else
 #define l3_noc_match NULL
index e7bee5ca407ca94e3f163f0928e9212b43726bb5..1881fe9151495ba4fd542146fcee7c208565cb63 100644 (file)
@@ -24,6 +24,7 @@
 #include "powerdomain.h"
 #include "clockdomain.h"
 #include "pm.h"
+#include "twl-common.h"
 
 static struct omap_device_pm_latency *pm_lats;
 
@@ -226,11 +227,8 @@ postcore_initcall(omap2_common_pm_init);
 
 static int __init omap2_common_pm_late_init(void)
 {
-       /* Init the OMAP TWL parameters */
-       omap3_twl_init();
-       omap4_twl_init();
-
        /* Init the voltage layer */
+       omap_pmic_late_init();
        omap_voltage_late_init();
 
        /* Initialize the voltages */
index 919d827ed7079157a6399bd193c909f7a8583923..9dd93453e563eaa666b2640663d529dc9102c928 100644 (file)
@@ -139,7 +139,7 @@ static irqreturn_t sr_interrupt(int irq, void *data)
                sr_write_reg(sr_info, ERRCONFIG_V1, status);
        } else if (sr_info->ip_type == SR_TYPE_V2) {
                /* Read the status bits */
-               sr_read_reg(sr_info, IRQSTATUS);
+               status = sr_read_reg(sr_info, IRQSTATUS);
 
                /* Clear them by writing back */
                sr_write_reg(sr_info, IRQSTATUS, status);
index 5224357721686dc41d5a703a3ba02ae1e1e7bf6a..10b20c652e5dc390026bc1eec5042ff351c387f4 100644 (file)
@@ -30,6 +30,7 @@
 #include <plat/usb.h>
 
 #include "twl-common.h"
+#include "pm.h"
 
 static struct i2c_board_info __initdata pmic_i2c_board_info = {
        .addr           = 0x48,
@@ -48,6 +49,16 @@ void __init omap_pmic_init(int bus, u32 clkrate,
        omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
 }
 
+void __init omap_pmic_late_init(void)
+{
+       /* Init the OMAP TWL parameters (if PMIC has been registerd) */
+       if (!pmic_i2c_board_info.irq)
+               return;
+
+       omap3_twl_init();
+       omap4_twl_init();
+}
+
 #if defined(CONFIG_ARCH_OMAP3)
 static struct twl4030_usb_data omap3_usb_pdata = {
        .usb_mode       = T2_USB_MODE_ULPI,
index 5e83a5bd37fb719dd06ea8deac01e0c3c2922e80..275dde8cb27aa789ce4d9bfa89c8ed92fb122711 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __OMAP_PMIC_COMMON__
 #define __OMAP_PMIC_COMMON__
 
+#include <plat/irqs.h>
+
 #define TWL_COMMON_PDATA_USB           (1 << 0)
 #define TWL_COMMON_PDATA_BCI           (1 << 1)
 #define TWL_COMMON_PDATA_MADC          (1 << 2)
@@ -30,6 +32,7 @@ struct twl4030_platform_data;
 
 void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
                    struct twl4030_platform_data *pmic_data);
+void omap_pmic_late_init(void);
 
 static inline void omap2_pmic_init(const char *pmic_type,
                                   struct twl4030_platform_data *pmic_data)
index fc0b8544e17455f27fb020cee143dbaee16123b2..4b81f59a4cbaf5aebbac8c1d55980d9b4dd45618 100644 (file)
@@ -307,7 +307,7 @@ static inline void balloon3_mmc_init(void) {}
 /******************************************************************************
  * USB Gadget
  ******************************************************************************/
-#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
 static void balloon3_udc_command(int cmd)
 {
        if (cmd == PXA2XX_UDC_CMD_CONNECT)
index 692e1ffc558628526105f3b378f6ce745650480e..d23b92b80488257db2ef2bf4af458fc4060feaf8 100644 (file)
@@ -146,7 +146,7 @@ static void __init colibri_pxa320_init_eth(void)
 static inline void __init colibri_pxa320_init_eth(void) {}
 #endif /* CONFIG_AX88796 */
 
-#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
 static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = {
        .gpio_vbus              = mfp_to_gpio(MFP_PIN_GPIO96),
        .gpio_pullup            = -1,
index 9c8208ca04150e4a3bbb2d41cccb28287a0efe99..ffdd70dad327dd135f1a2d5fc36a3cde45f2f86b 100644 (file)
@@ -106,7 +106,7 @@ static void __init gumstix_mmc_init(void)
 }
 #endif
 
-#ifdef CONFIG_USB_GADGET_PXA25X
+#ifdef CONFIG_USB_PXA25X
 static struct gpio_vbus_mach_info gumstix_udc_info = {
        .gpio_vbus              = GPIO_GUMSTIX_USB_GPIOn,
        .gpio_pullup            = GPIO_GUMSTIX_USB_GPIOx,
index f80bbe246afe5812b17db200d709b13f6160f72c..d4eac3d6ffb5ecd04df4abeb0ed45b32a2882705 100644 (file)
@@ -37,8 +37,8 @@ extern void __init palm27x_lcd_init(int power,
 #define palm27x_lcd_init(power, mode)  do {} while (0)
 #endif
 
-#if    defined(CONFIG_USB_GADGET_PXA27X) || \
-       defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if    defined(CONFIG_USB_PXA27X) || \
+       defined(CONFIG_USB_PXA27X_MODULE)
 extern void __init palm27x_udc_init(int vbus, int pullup,
                                        int vbus_inverted);
 #else
index 325c245c0a0dd3916129b2875caaec931758137e..fbc10d7b95d1e8ef7ceec5dd03d512c7c2d314bf 100644 (file)
@@ -164,8 +164,8 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode)
 /******************************************************************************
  * USB Gadget
  ******************************************************************************/
-#if    defined(CONFIG_USB_GADGET_PXA27X) || \
-       defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if    defined(CONFIG_USB_PXA27X) || \
+       defined(CONFIG_USB_PXA27X_MODULE)
 static struct gpio_vbus_mach_info palm27x_udc_info = {
        .gpio_vbus_inverted     = 1,
 };
index 6ec7caefb37c8219d02f45fc0088249295006fa5..2c24c67fd92b6d863fc2e534b6ad9f15b7daaaf7 100644 (file)
@@ -338,7 +338,7 @@ static inline void palmtc_mkp_init(void) {}
 /******************************************************************************
  * UDC
  ******************************************************************************/
-#if defined(CONFIG_USB_GADGET_PXA25X)||defined(CONFIG_USB_GADGET_PXA25X_MODULE)
+#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE)
 static struct gpio_vbus_mach_info palmtc_udc_info = {
        .gpio_vbus              = GPIO_NR_PALMTC_USB_DETECT_N,
        .gpio_vbus_inverted     = 1,
index a7539a6ed1ff2a5d1ce4a460183a17fe28900e45..ca0c6615028c42aa0414cc2e76de4a0a29c83918 100644 (file)
@@ -343,7 +343,7 @@ static inline void vpac270_uhc_init(void) {}
 /******************************************************************************
  * USB Gadget
  ******************************************************************************/
-#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
 static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = {
        .gpio_vbus              = GPIO41_VPAC270_UDC_DETECT,
        .gpio_pullup            = -1,
index 66668565ee75e6694c086030504bf5d01fc59bef..f208154b1382d0492898ebba6b6d7c14079ad80d 100644 (file)
@@ -8,7 +8,7 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 
index 0a5b22942fd3555d38591dd7e24c0a556079b9e9..34bbcbfb1706f1b74d4d5c92965e491d32204e21 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/bitrev.h>
+#include <linux/console.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/tlbflush.h>
@@ -106,9 +107,8 @@ static int pd_power_down(struct generic_pm_domain *genpd)
        return 0;
 }
 
-static int pd_power_up(struct generic_pm_domain *genpd)
+static int __pd_power_up(struct sh7372_pm_domain *sh7372_pd, bool do_resume)
 {
-       struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd);
        unsigned int mask = 1 << sh7372_pd->bit_shift;
        unsigned int retry_count;
        int ret = 0;
@@ -123,13 +123,13 @@ static int pd_power_up(struct generic_pm_domain *genpd)
 
        for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
                if (!(__raw_readl(SWUCR) & mask))
-                       goto out;
+                       break;
                if (retry_count > PSTR_RETRIES)
                        udelay(PSTR_DELAY_US);
                else
                        cpu_relax();
        }
-       if (__raw_readl(SWUCR) & mask)
+       if (!retry_count)
                ret = -EIO;
 
        if (!sh7372_pd->no_debug)
@@ -137,12 +137,17 @@ static int pd_power_up(struct generic_pm_domain *genpd)
                         mask, __raw_readl(PSTR));
 
  out:
-       if (ret == 0 && sh7372_pd->resume)
+       if (ret == 0 && sh7372_pd->resume && do_resume)
                sh7372_pd->resume();
 
        return ret;
 }
 
+static int pd_power_up(struct generic_pm_domain *genpd)
+{
+        return __pd_power_up(to_sh7372_pd(genpd), true);
+}
+
 static void sh7372_a4r_suspend(void)
 {
        sh7372_intcs_suspend();
@@ -174,7 +179,7 @@ void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
        genpd->active_wakeup = pd_active_wakeup;
        genpd->power_off = pd_power_down;
        genpd->power_on = pd_power_up;
-       genpd->power_on(&sh7372_pd->genpd);
+       __pd_power_up(sh7372_pd, false);
 }
 
 void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd,
@@ -227,11 +232,23 @@ struct sh7372_pm_domain sh7372_a3sp = {
        .no_debug = true,
 };
 
+static void sh7372_a3sp_init(void)
+{
+       /* serial consoles make use of SCIF hardware located in A3SP,
+        * keep such power domain on if "no_console_suspend" is set.
+        */
+       sh7372_a3sp.stay_on = !console_suspend_enabled;
+}
+
 struct sh7372_pm_domain sh7372_a3sg = {
        .bit_shift = 13,
 };
 
-#endif /* CONFIG_PM */
+#else /* !CONFIG_PM */
+
+static inline void sh7372_a3sp_init(void) {}
+
+#endif /* !CONFIG_PM */
 
 #if defined(CONFIG_SUSPEND) || defined(CONFIG_CPU_IDLE)
 static int sh7372_do_idle_core_standby(unsigned long unused)
@@ -465,6 +482,8 @@ void __init sh7372_pm_init(void)
        /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */
        __raw_writel(0, PDNSEL);
 
+       sh7372_a3sp_init();
+
        sh7372_suspend_init();
        sh7372_cpuidle_init();
 }
index 7a1fa6adb7c32d5645b1f0e608b1e61794081afc..5b0c38abacc107a7eae8bd35ec8f03666f3422e7 100644 (file)
@@ -422,7 +422,7 @@ struct platform_device nuc900_device_kpi = {
 
 /* LCD controller*/
 
-static struct nuc900fb_display __initdata nuc900_lcd_info[] = {
+static struct nuc900fb_display nuc900_lcd_info[] = {
        /* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
        [0] = {
                .type           = LCM_DCCS_VA_SRC_RGB565,
@@ -445,7 +445,7 @@ static struct nuc900fb_display __initdata nuc900_lcd_info[] = {
        },
 };
 
-static struct nuc900fb_mach_info nuc900_fb_info __initdata = {
+static struct nuc900fb_mach_info nuc900_fb_info = {
 #if defined(CONFIG_GPM1040A0_320X240)
        .displays               = &nuc900_lcd_info[0],
 #else
index 94c0e71617c6c3487aaf20a4f1b7bfd34023e580..23ef1f573abd3395ac872ab6b39be6bc29090a8d 100644 (file)
@@ -19,6 +19,7 @@
 extern void mfp_set_groupf(struct device *dev);
 extern void mfp_set_groupc(struct device *dev);
 extern void mfp_set_groupi(struct device *dev);
-extern void mfp_set_groupg(struct device *dev);
+extern void mfp_set_groupg(struct device *dev, const char *subname);
+extern void mfp_set_groupd(struct device *dev, const char *subname);
 
 #endif /* __ASM_ARCH_MFP_H */
index bd94819e314fed7f67173c016a00bbcfbacc38c6..2c4e0c1285010fdfee53bebeaff4cd638c50a56f 100644 (file)
@@ -14,7 +14,7 @@
 #ifndef __ASM_ARCH_SPI_H
 #define __ASM_ARCH_SPI_H
 
-extern void mfp_set_groupg(struct device *dev);
+extern void mfp_set_groupg(struct device *dev, const char *subname);
 
 struct nuc900_spi_info {
        unsigned int num_cs;
index fb7fb627b1a564ca920fdb747080988f3fb75551..9dd74612bb8707560abd06e6adc250f7ecd54bf2 100644 (file)
 #define REG_MFSEL      (W90X900_VA_GCR + 0xC)
 
 #define GPSELF         (0x01 << 1)
-
 #define GPSELC         (0x03 << 2)
-#define ENKPI          (0x02 << 2)
-#define ENNAND         (0x01 << 2)
+#define GPSELD         (0x0f << 4)
 
 #define GPSELEI0       (0x01 << 26)
 #define GPSELEI1       (0x01 << 27)
 #define GPIOG0TO1      (0x03 << 14)
 #define GPIOG2TO3      (0x03 << 16)
 #define GPIOG22TO23    (0x03 << 22)
+#define GPIOG18TO20    (0x07 << 18)
 
 #define ENSPI          (0x0a << 14)
 #define ENI2C0         (0x01 << 14)
 #define ENI2C1         (0x01 << 16)
 #define ENAC97         (0x02 << 22)
+#define ENSD1          (0x02 << 18)
+#define ENSD0          (0x0a << 4)
+#define ENKPI          (0x02 << 2)
+#define ENNAND         (0x01 << 2)
 
 static DEFINE_MUTEX(mfp_mutex);
 
@@ -127,16 +130,19 @@ void mfp_set_groupi(struct device *dev)
 }
 EXPORT_SYMBOL(mfp_set_groupi);
 
-void mfp_set_groupg(struct device *dev)
+void mfp_set_groupg(struct device *dev, const char *subname)
 {
        unsigned long mfpen;
        const char *dev_id;
 
-       BUG_ON(!dev);
+       BUG_ON((!dev) && (!subname));
 
        mutex_lock(&mfp_mutex);
 
-       dev_id = dev_name(dev);
+       if (subname != NULL)
+               dev_id = subname;
+       else
+               dev_id = dev_name(dev);
 
        mfpen = __raw_readl(REG_MFSEL);
 
@@ -152,6 +158,9 @@ void mfp_set_groupg(struct device *dev)
        } else if (strcmp(dev_id, "nuc900-audio") == 0) {
                mfpen &= ~(GPIOG22TO23);
                mfpen |= ENAC97;/*enable AC97*/
+       } else if (strcmp(dev_id, "nuc900-mmc-port1") == 0) {
+               mfpen &= ~(GPIOG18TO20);
+               mfpen |= (ENSD1 | 0x01);/*enable sd1*/
        } else {
                mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
        }
@@ -162,3 +171,30 @@ void mfp_set_groupg(struct device *dev)
 }
 EXPORT_SYMBOL(mfp_set_groupg);
 
+void mfp_set_groupd(struct device *dev, const char *subname)
+{
+       unsigned long mfpen;
+       const char *dev_id;
+
+       BUG_ON((!dev) && (!subname));
+
+       mutex_lock(&mfp_mutex);
+
+       if (subname != NULL)
+               dev_id = subname;
+       else
+               dev_id = dev_name(dev);
+
+       mfpen = __raw_readl(REG_MFSEL);
+
+       if (strcmp(dev_id, "nuc900-mmc-port0") == 0) {
+               mfpen &= ~GPSELD;/*enable sd0*/
+               mfpen |= ENSD0;
+       } else
+               mfpen &= (~GPSELD);
+
+       __raw_writel(mfpen, REG_MFSEL);
+
+       mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupd);
index 8ac9e9f84790bb946716016607478ad97711376d..b1e192ba8c2450cb75a8118f86f8b650be284c82 100644 (file)
@@ -61,7 +61,7 @@ static inline void cache_sync(void)
 {
        void __iomem *base = l2x0_base;
 
-#ifdef CONFIG_ARM_ERRATA_753970
+#ifdef CONFIG_PL310_ERRATA_753970
        /* write to an unmmapped register */
        writel_relaxed(0, base + L2X0_DUMMY_REG);
 #else
index e4e7f6cba1ab4823fdbf0fe7ab2109bf6df89ed7..1aa664a1999fce45c2548726b50b6fa924608ec2 100644 (file)
@@ -168,7 +168,7 @@ static int __init consistent_init(void)
        pte_t *pte;
        int i = 0;
        unsigned long base = consistent_base;
-       unsigned long num_ptes = (CONSISTENT_END - base) >> PGDIR_SHIFT;
+       unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT;
 
        consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
        if (!consistent_pte) {
@@ -332,6 +332,15 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
        struct page *page;
        void *addr;
 
+       /*
+        * Following is a work-around (a.k.a. hack) to prevent pages
+        * with __GFP_COMP being passed to split_page() which cannot
+        * handle them.  The real problem is that this flag probably
+        * should be 0 on ARM as it is not supported on this
+        * platform; see CONFIG_HUGETLBFS.
+        */
+       gfp &= ~(__GFP_COMP);
+
        *handle = ~0;
        size = PAGE_ALIGN(size);
 
index 74be05f3e03ac58be921aff208c6f6aa460ab683..44b628e4d6ea9c0121acf892ffbcfb30d0fc40ad 100644 (file)
@@ -9,8 +9,7 @@
 #include <linux/io.h>
 #include <linux/personality.h>
 #include <linux/random.h>
-#include <asm/cputype.h>
-#include <asm/system.h>
+#include <asm/cachetype.h>
 
 #define COLOUR_ALIGN(addr,pgoff)               \
        ((((addr)+SHMLBA-1)&~(SHMLBA-1)) +      \
@@ -32,25 +31,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        unsigned long start_addr;
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
-       unsigned int cache_type;
-       int do_align = 0, aliasing = 0;
+       int do_align = 0;
+       int aliasing = cache_is_vipt_aliasing();
 
        /*
         * We only need to do colour alignment if either the I or D
-        * caches alias.  This is indicated by bits 9 and 21 of the
-        * cache type register.
+        * caches alias.
         */
-       cache_type = read_cpuid_cachetype();
-       if (cache_type != read_cpuid_id()) {
-               aliasing = (cache_type | cache_type >> 12) & (1 << 11);
-               if (aliasing)
-                       do_align = filp || flags & MAP_SHARED;
-       }
-#else
-#define do_align 0
-#define aliasing 0
-#endif
+       if (aliasing)
+               do_align = filp || (flags & MAP_SHARED);
 
        /*
         * We enforce the MAP_FIXED case.
index 14b4703e6e467f8ce1033ace2029324030435117..6698cae942f78e21072a8fea8719c181313a16fd 100644 (file)
@@ -85,7 +85,6 @@ enum mxc_cpu_pwr_mode {
 };
 
 extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
-extern void (*imx_idle)(void);
 extern void imx_print_silicon_rev(const char *cpu, int srev);
 
 void avic_handle_irq(struct pt_regs *);
@@ -132,4 +131,5 @@ extern void imx53_qsb_common_init(void);
 extern void imx53_smd_common_init(void);
 extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
 extern void imx6q_pm_init(void);
+extern void imx6q_clock_map_io(void);
 #endif
index 00a78193c681ae16f5ed61f1b587f3ecf9e777f8..a4d36d601d55a5ed493f9191929850c6530f804f 100644 (file)
 #define IMX_CHIP_REVISION_3_3          0x33
 #define IMX_CHIP_REVISION_UNKNOWN      0xff
 
-#define IMX_CHIP_REVISION_1_0_STRING           "1.0"
-#define IMX_CHIP_REVISION_1_1_STRING           "1.1"
-#define IMX_CHIP_REVISION_1_2_STRING           "1.2"
-#define IMX_CHIP_REVISION_1_3_STRING           "1.3"
-#define IMX_CHIP_REVISION_2_0_STRING           "2.0"
-#define IMX_CHIP_REVISION_2_1_STRING           "2.1"
-#define IMX_CHIP_REVISION_2_2_STRING           "2.2"
-#define IMX_CHIP_REVISION_2_3_STRING           "2.3"
-#define IMX_CHIP_REVISION_3_0_STRING           "3.0"
-#define IMX_CHIP_REVISION_3_1_STRING           "3.1"
-#define IMX_CHIP_REVISION_3_2_STRING           "3.2"
-#define IMX_CHIP_REVISION_3_3_STRING           "3.3"
-#define IMX_CHIP_REVISION_UNKNOWN_STRING       "unknown"
-
 #ifndef __ASSEMBLY__
 extern unsigned int __mxc_cpu_type;
 #endif
index cf88b3593fba794d1a2de0c871f278ec03988da5..b9895d250167cf6b384d5cb1320e00e855537019 100644 (file)
 #ifndef __ASM_ARCH_MXC_SYSTEM_H__
 #define __ASM_ARCH_MXC_SYSTEM_H__
 
-extern void (*imx_idle)(void);
-
 static inline void arch_idle(void)
 {
-       if (imx_idle != NULL)
-               (imx_idle)();
-       else
-               cpu_do_idle();
+       cpu_do_idle();
 }
 
 void arch_reset(char mode, const char *cmd);
index b1cfc6a49715f96a1aa663a3f338f3a23af4756a..7e5c76ea4466a425a49ba8e64f450403f58733ab 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 #include <mach/hardware.h>
 #include <mach/common.h>
@@ -28,8 +29,8 @@
 #include <asm/system.h>
 #include <asm/mach-types.h>
 
-void (*imx_idle)(void) = NULL;
 void __iomem *(*imx_ioremap)(unsigned long, size_t, unsigned int) = NULL;
+EXPORT_SYMBOL_GPL(imx_ioremap);
 
 static void __iomem *wdog_base;
 
index 197ca03c3f7d8490a109a9b576b2e2f9c9c420e6..eb73ab40e9556ee03f36e63fa7c06b9e77b4b1d3 100644 (file)
@@ -165,8 +165,8 @@ struct dpll_data {
        u8                      auto_recal_bit;
        u8                      recal_en_bit;
        u8                      recal_st_bit;
-       u8                      flags;
 #  endif
+       u8                      flags;
 };
 
 #endif
index 346098fb92190320c2c21e21b276175362e6b1b2..257f9770b2da2faa38d3de32550963f0124d611c 100644 (file)
 #define __ARCH_ARM_MACH_OMAP_COMMON_H
 
 #include <plat/i2c.h>
+#include <plat/omap_hwmod.h>
 
 extern int __init omap_init_clocksource_32k(void);
 extern unsigned long long notrace omap_32k_sched_clock(void);
 
 extern void omap_reserve(void);
+extern int omap_dss_reset(struct omap_hwmod *);
+
 void omap_sram_init(void);
 
 #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
index a9276667c2fb0e59c21e643aab28aef2debdee84..c7adad0e8de091ad42d021958bb1fc3b3c8cff03 100644 (file)
@@ -12,7 +12,7 @@
 */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
index e1cbc728c7759b1e1f54923f11120b3ea4647cb2..c8bec9c7655d417ebbcb78096f16a7cbeddcf54d 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/export.h>
 
 #include <asm/pgtable.h>
 
index d48245bb02b3bbf6178a45e7e6ae48ad3ec8d7f6..df8155b9d4d19e550b881abf22df4dbbeab3315c 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef __PLAT_GPIO_CFG_H
 #define __PLAT_GPIO_CFG_H __FILE__
 
+#include<linux/types.h>
+
 typedef unsigned int __bitwise__ samsung_gpio_pull_t;
 typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
 
index efe1d564473e02c6195774fbc47c51a23a97fad4..312b510d86b76bf0b96feba92de8aae8163380c3 100644 (file)
@@ -11,7 +11,7 @@
 */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
index dc1185dcf80d559757d289f4490723888786c2fa..c559d8438c70ee2d873afc43a7d14ee1fc2002c2 100644 (file)
@@ -11,7 +11,7 @@
  * the Free Software Foundation; either version 2 of the License.
 */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
index 5bdeef9698470b354dc3f144caadabda08dae00d..ccbe16f47227e2ebb171032b2a5de66289014cd0 100644 (file)
@@ -1123,5 +1123,6 @@ blissc                    MACH_BLISSC             BLISSC                  3491
 thales_adc             MACH_THALES_ADC         THALES_ADC              3492
 ubisys_p9d_evp         MACH_UBISYS_P9D_EVP     UBISYS_P9D_EVP          3493
 atdgp318               MACH_ATDGP318           ATDGP318                3494
+m28evk                 MACH_M28EVK             M28EVK                  3613
 smdk4212               MACH_SMDK4212           SMDK4212                3638
 smdk4412               MACH_SMDK4412           SMDK4412                3765
index 32d90867a9841098177b1fd5969af784ef88ac19..5f2cdb3e428cd979601b6b15d5e04a24042c7a8e 100644 (file)
@@ -3,7 +3,7 @@ if ETRAX_ARCH_V10
 config ETRAX_ETHERNET
        bool "Ethernet support"
        depends on ETRAX_ARCH_V10
-       select NET_ETHERNET
+       select ETHERNET
        select NET_CORE
        select MII
        help
index e47e9c3401b08bbbde729c13e626b9a91823ec18..de43aadcdbc47963cdaa63e0e522cdc171e3d432 100644 (file)
@@ -3,7 +3,7 @@ if ETRAX_ARCH_V32
 config ETRAX_ETHERNET
        bool "Ethernet support"
        depends on ETRAX_ARCH_V32
-       select NET_ETHERNET
+       select ETHERNET
        select NET_CORE
        select MII
        help
diff --git a/arch/microblaze/include/asm/namei.h b/arch/microblaze/include/asm/namei.h
deleted file mode 100644 (file)
index 61d60b8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_NAMEI_H
-#define _ASM_MICROBLAZE_NAMEI_H
-
-#ifdef __KERNEL__
-
-/* This dummy routine maybe changed to something useful
- * for /usr/gnemul/ emulation stuff.
- * Look at asm-sparc/namei.h for details.
- */
-#define __emul_prefix() NULL
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_MICROBLAZE_NAMEI_H */
index 975c20327bb152e4774f24f05a273bc4bbeb3a28..0a430e06f5e5e11f3989265a1f49336d1b10abee 100644 (file)
@@ -17,8 +17,6 @@
 
 static struct map_info flash_map;
 static struct mtd_info *mymtd;
-static int nr_parts;
-static struct mtd_partition *parts;
 static const char *part_probe_types[] = {
        "cmdlinepart",
 #ifdef CONFIG_MTD_REDBOOT_PARTS
@@ -61,11 +59,8 @@ static int __init flash_init(void)
                mymtd = do_map_probe("cfi_probe", &flash_map);
                if (mymtd) {
                        mymtd->owner = THIS_MODULE;
-
-                       nr_parts = parse_mtd_partitions(mymtd,
-                                                       part_probe_types,
-                                                       &parts, 0);
-                       mtd_device_register(mymtd, parts, nr_parts);
+                       mtd_device_parse_register(mymtd, part_probe_types,
+                                                 0, NULL, 0);
                } else {
                        pr_err("Failed to register MTD device for flash\n");
                }
index 8b606423bbd7f84dcacd4b043297844fc59200d4..efcfff4d4627c55f4238bfd3361fe937be25465e 100644 (file)
@@ -207,8 +207,9 @@ void octeon_prepare_cpus(unsigned int max_cpus)
         * the other bits alone.
         */
        cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff);
-       if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
-                       "SMP-IPI", mailbox_interrupt)) {
+       if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt,
+                       IRQF_PERCPU | IRQF_NO_THREAD, "SMP-IPI",
+                       mailbox_interrupt)) {
                panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
        }
 }
index 708f08761406fe3bfdbd308822f163a2ae7c9822..cae42259d6da9cc49efd4ceb8bccdbad941fe3d0 100644 (file)
@@ -50,7 +50,7 @@ void __init prom_init(void)
 
        /* arg[0] is "g", the rest is boot parameters */
        for (i = 1; i < argc; i++) {
-               if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+               if (strlen(arcs_cmdline) + strlen(arg[i]) + 1
                    >= sizeof(arcs_cmdline))
                        break;
                strcat(arcs_cmdline, arg[i]);
index 76961cabeedfe1cdac4caaef7e9989ca04a345be..2ef17e8df40346f07aea6e01431186686214a1f7 100644 (file)
@@ -36,6 +36,8 @@ static inline int gpio_get_value(unsigned gpio)
        return -EINVAL;
 }
 
+#define gpio_get_value_cansleep        gpio_get_value
+
 static inline void gpio_set_value(unsigned gpio, int value)
 {
        switch (bcm47xx_bus_type) {
@@ -54,6 +56,19 @@ static inline void gpio_set_value(unsigned gpio, int value)
        }
 }
 
+#define gpio_set_value_cansleep gpio_set_value
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+       return 0;
+}
+
+static inline int gpio_is_valid(unsigned gpio)
+{
+       return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
+}
+
+
 static inline int gpio_direction_input(unsigned gpio)
 {
        switch (bcm47xx_bus_type) {
@@ -137,7 +152,4 @@ static inline int gpio_polarity(unsigned gpio, int value)
 }
 
 
-/* cansleep wrappers */
-#include <asm-generic/gpio.h>
-
 #endif /* __BCM47XX_GPIO_H */
index ecea7871dec28f6e4e44e1652a2d10b87e8a87b1..d8dad5340ea30d22eac825883012a14341fbf157 100644 (file)
 #define __NR_syncfs                    (__NR_Linux + 342)
 #define __NR_sendmmsg                  (__NR_Linux + 343)
 #define __NR_setns                     (__NR_Linux + 344)
+#define __NR_process_vm_readv          (__NR_Linux + 345)
+#define __NR_process_vm_writev         (__NR_Linux + 346)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls            344
+#define __NR_Linux_syscalls            346
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux                 4000
-#define __NR_O32_Linux_syscalls                344
+#define __NR_O32_Linux_syscalls                346
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 #define __NR_syncfs                    (__NR_Linux + 301)
 #define __NR_sendmmsg                  (__NR_Linux + 302)
 #define __NR_setns                     (__NR_Linux + 303)
+#define __NR_process_vm_readv          (__NR_Linux + 304)
+#define __NR_process_vm_writev         (__NR_Linux + 305)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            303
+#define __NR_Linux_syscalls            305
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         303
+#define __NR_64_Linux_syscalls         305
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
 #define __NR_syncfs                    (__NR_Linux + 306)
 #define __NR_sendmmsg                  (__NR_Linux + 307)
 #define __NR_setns                     (__NR_Linux + 308)
+#define __NR_process_vm_readv          (__NR_Linux + 309)
+#define __NR_process_vm_writev         (__NR_Linux + 310)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls            308
+#define __NR_Linux_syscalls            310
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux                 6000
-#define __NR_N32_Linux_syscalls                308
+#define __NR_N32_Linux_syscalls                310
 
 #ifdef __KERNEL__
 
index 98c5a9737c14d2c200a161640122f9a8af053e88..e2d8e199be323345a6feaf3eb03a738e515dd5f5 100644 (file)
@@ -103,19 +103,10 @@ static int c0_compare_int_pending(void)
 
 /*
  * Compare interrupt can be routed and latched outside the core,
- * so a single execution hazard barrier may not be enough to give
- * it time to clear as seen in the Cause register.  4 time the
- * pipeline depth seems reasonably conservative, and empirically
- * works better in configurations with high CPU/bus clock ratios.
+ * so wait up to worst case number of cycle counter ticks for timer interrupt
+ * changes to propagate to the cause register.
  */
-
-#define compare_change_hazard() \
-       do { \
-               irq_disable_hazard(); \
-               irq_disable_hazard(); \
-               irq_disable_hazard(); \
-               irq_disable_hazard(); \
-       } while (0)
+#define COMPARE_INT_SEEN_TICKS 50
 
 int c0_compare_int_usable(void)
 {
@@ -126,8 +117,12 @@ int c0_compare_int_usable(void)
         * IP7 already pending?  Try to clear it by acking the timer.
         */
        if (c0_compare_int_pending()) {
-               write_c0_compare(read_c0_count());
-               compare_change_hazard();
+               cnt = read_c0_count();
+               write_c0_compare(cnt);
+               back_to_back_c0_hazard();
+               while (read_c0_count() < (cnt  + COMPARE_INT_SEEN_TICKS))
+                       if (!c0_compare_int_pending())
+                               break;
                if (c0_compare_int_pending())
                        return 0;
        }
@@ -136,7 +131,7 @@ int c0_compare_int_usable(void)
                cnt = read_c0_count();
                cnt += delta;
                write_c0_compare(cnt);
-               compare_change_hazard();
+               back_to_back_c0_hazard();
                if ((int)(read_c0_count() - cnt) < 0)
                    break;
                /* increase delta if the timer was already expired */
@@ -145,12 +140,17 @@ int c0_compare_int_usable(void)
        while ((int)(read_c0_count() - cnt) <= 0)
                ;       /* Wait for expiry  */
 
-       compare_change_hazard();
+       while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
+               if (c0_compare_int_pending())
+                       break;
        if (!c0_compare_int_pending())
                return 0;
-
-       write_c0_compare(read_c0_count());
-       compare_change_hazard();
+       cnt = read_c0_count();
+       write_c0_compare(cnt);
+       back_to_back_c0_hazard();
+       while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
+               if (!c0_compare_int_pending())
+                       break;
        if (c0_compare_int_pending())
                return 0;
 
index cefc6e259bafd3acd986588af2c87a6e3ce0f32d..5426779d9fdb77700d05b897e7af3acff8d753e1 100644 (file)
@@ -7,6 +7,7 @@
  * for more details.
  */
 
+#include <linux/module.h>
 #include <linux/cpufreq.h>
 #include <linux/platform_device.h>
 
index 47920657968d2e65368edd0c2cbd39c6a5052ef2..a632bc144efa1b9ca977a582864530e33ee039cb 100644 (file)
@@ -591,6 +591,8 @@ einval:     li      v0, -ENOSYS
        sys     sys_syncfs              1
        sys     sys_sendmmsg            4
        sys     sys_setns               2
+       sys     sys_process_vm_readv    6       /* 4345 */
+       sys     sys_process_vm_writev   6
        .endm
 
        /* We pre-compute the number of _instruction_ bytes needed to
index fb7334bea7316aedd8071ff41d63178539504cc8..3b5a5e9ae49c132640c95a87037e48ac95e5b932 100644 (file)
@@ -430,4 +430,6 @@ sys_call_table:
        PTR     sys_syncfs
        PTR     sys_sendmmsg
        PTR     sys_setns
+       PTR     sys_process_vm_readv
+       PTR     sys_process_vm_writev           /* 5305 */
        .size   sys_call_table,.-sys_call_table
index 6de1f598346e3bfd527f1d3cad321160aedb3c02..6be6f7020923f1224260a0bf4df420a2d951db7a 100644 (file)
@@ -430,4 +430,6 @@ EXPORT(sysn32_call_table)
        PTR     sys_syncfs
        PTR     compat_sys_sendmmsg
        PTR     sys_setns
+       PTR     compat_sys_process_vm_readv
+       PTR     compat_sys_process_vm_writev    /* 6310 */
        .size   sysn32_call_table,.-sysn32_call_table
index 1d813169e453ea3709b0410521b8526638d96a98..54228553691d60903559706c00bc8a0d16a05b86 100644 (file)
@@ -548,4 +548,6 @@ sys_call_table:
        PTR     sys_syncfs
        PTR     compat_sys_sendmmsg
        PTR     sys_setns
+       PTR     compat_sys_process_vm_readv     /* 4345 */
+       PTR     compat_sys_process_vm_writev
        .size   sys_call_table,.-sys_call_table
index 261ccbc0774016aa6d055eb19dd82067f7ad65e8..5c8a49d55054dffce696066bad88d1863c5e7f35 100644 (file)
@@ -1596,7 +1596,8 @@ void __cpuinit per_cpu_trap_init(void)
        }
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-       cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
+       if (!cpu_data[cpu].asid_cache)
+               cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
 
        atomic_inc(&init_mm.mm_count);
        current->active_mm = &init_mm;
index 7e9c0ffc11a51c42bd58b1f465d54481aab6023c..77ed70fc2fe5953cd9bf31aa2514820b41e2bbd6 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  */
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
index 44a36771c819bebcb03732744566764c6d60b574..de1cb2bcd79a167e36b9602d14d6fa889e9a2b1d 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
index 56ba007bf1e59ee37d5a7a2627d603d635df447d..e34fcfd0d5ca5763983c2b0a248352275b40f49b 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
index 9b8af77ed0f9868baf4d1873121213cc6a8c556c..1ff6c9d6cb93eb6e21109f9a8c0a3f3941cba4a5 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <asm/bootinfo.h>
index 22d823acd536a3bcfee7708c90a593f57835d143..652258309c9c14220ebdbcaa5a43ac1faa01b7cc 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 
index ddd39593c581453237b26e831716f853cd349a9d..696b1a3e06421d605097535384427ba7632e3396 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 
index d0e32ab2ea074b9fa75ebd56e2c77ff1a15c994a..d614aa7ff07f48f89789694236aadf90b5f30004 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/mtd/physmap.h>
index 4278a459d6c483afd2f371fb856bff8eb1851714..cbb6ae5747b97f81c67c8d77916bd10bad34e125 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 
 #include <lantiq_soc.h>
 #include <xway_dma.h>
index a321451a54554bc0cba17a0458e61436ce62801e..d2fa98f3c78d8185d6bfec384b88e23720829b88 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/ioport.h>
index a479355abdb92755759366fa1b50325474d93810..b91c7f17f10f043ae906c322e12669438e7f562a 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
index 67d59d69034063ab37dcffa6e4f135c7a531396b..ff9991cddeaa8c3fd6e44048730b09b6d24efb1f 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
index abe49f4db57f1ad670b6c6c6a6709bea6dcfe1e6..ae4959ae865c464cddd5da9393664f148fc448ca 100644 (file)
@@ -6,7 +6,7 @@
  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
index 1686692ac24d52eee2338feaebd3cdf943bb22e3..2228133ca3566a0e6a192a9191625f7f2078db28 100644 (file)
@@ -6,7 +6,7 @@
  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
index a1be36d0e490481b9fcdfdf6579e576ee115c111..3d41f0bb5bf73f0d84108129a979642770e632f7 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/pm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/reboot.h>
 
 #include <lantiq_soc.h>
diff --git a/arch/mips/nxp/pnx8550/common/pci.c b/arch/mips/nxp/pnx8550/common/pci.c
deleted file mode 100644 (file)
index 98e86dd..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *
- * Author: source@mvista.com
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms 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, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <pci.h>
-#include <glb.h>
-#include <nand.h>
-
-static struct resource pci_io_resource = {
-       .start  = PNX8550_PCIIO + 0x1000,       /* reserve regacy I/O space */
-       .end    = PNX8550_PCIIO + PNX8550_PCIIO_SIZE,
-       .name   = "pci IO space",
-       .flags  = IORESOURCE_IO
-};
-
-static struct resource pci_mem_resource = {
-       .start  = PNX8550_PCIMEM,
-       .end    = PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1,
-       .name   = "pci memory space",
-       .flags  = IORESOURCE_MEM
-};
-
-extern struct pci_ops pnx8550_pci_ops;
-
-static struct pci_controller pnx8550_controller = {
-       .pci_ops        = &pnx8550_pci_ops,
-       .io_map_base    = PNX8550_PORT_BASE,
-       .io_resource    = &pci_io_resource,
-       .mem_resource   = &pci_mem_resource,
-};
-
-/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
-static inline unsigned long get_system_mem_size(void)
-{
-       /* Read IP2031_RANK0_ADDR_LO */
-       unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
-       /* Read IP2031_RANK1_ADDR_HI */
-       unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
-
-       return dram_r1_hi - dram_r0_lo + 1;
-}
-
-static int __init pnx8550_pci_setup(void)
-{
-       int pci_mem_code;
-       int mem_size = get_system_mem_size() >> 20;
-
-       /* Clear the Global 2 Register, PCI Inta Output Enable Registers
-          Bit 1:Enable DAC Powerdown
-         -> 0:DACs are enabled and are working normally
-            1:DACs are powerdown
-          Bit 0:Enable of PCI inta output
-         -> 0 = Disable PCI inta output
-            1 = Enable PCI inta output
-       */
-       PNX8550_GLB2_ENAB_INTA_O = 0;
-
-       /* Calc the PCI mem size code */
-       if (mem_size >= 128)
-               pci_mem_code = SIZE_128M;
-       else if (mem_size >= 64)
-               pci_mem_code = SIZE_64M;
-       else if (mem_size >= 32)
-               pci_mem_code = SIZE_32M;
-       else
-               pci_mem_code = SIZE_16M;
-
-       /* Set PCI_XIO registers */
-       outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
-       outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
-       outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
-       outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
-
-       /* Send memory transaction via PCI_BASE2 */
-       outl(0x00000001, PCI_BASE | PCI_IO);
-
-       /* Unlock the setup register */
-       outl(0xca, PCI_BASE | PCI_UNLOCKREG);
-
-       /*
-        * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
-        * to work, and in order for bus_to_baddr to work without any
-        * hacks.
-        */
-       outl(0x00000000, PCI_BASE | PCI_BASE10);
-
-       /*
-        *These two bars are set by default or the boot code.
-        * However, it's safer to set them here so we're not boot
-        * code dependent.
-        */
-       outl(0x1be00000, PCI_BASE | PCI_BASE14);  /* PNX MMIO */
-       outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18);  /* XIO      */
-
-       outl(PCI_EN_TA |
-            PCI_EN_PCI2MMI |
-            PCI_EN_XIO |
-            PCI_SETUP_BASE18_SIZE(SIZE_32M) |
-            PCI_SETUP_BASE18_EN |
-            PCI_SETUP_BASE14_EN |
-            PCI_SETUP_BASE10_PREF |
-            PCI_SETUP_BASE10_SIZE(pci_mem_code) |
-            PCI_SETUP_CFGMANAGE_EN |
-            PCI_SETUP_PCIARB_EN,
-            PCI_BASE |
-            PCI_SETUP);        /* PCI_SETUP */
-       outl(0x00000000, PCI_BASE | PCI_CTRL);  /* PCI_CONTROL */
-
-       register_pci_controller(&pnx8550_controller);
-
-       return 0;
-}
-
-arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c
deleted file mode 100644 (file)
index 71adac3..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- *
- * 2.6 port, Embedded Alley Solutions, Inc
- *
- *  Based on Per Hallsmark, per.hallsmark@mvista.com
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms 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, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/serial_pnx8xxx.h>
-#include <linux/pm.h>
-
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/reboot.h>
-#include <asm/pgtable.h>
-#include <asm/time.h>
-
-#include <glb.h>
-#include <int.h>
-#include <pci.h>
-#include <uart.h>
-#include <nand.h>
-
-extern void __init board_setup(void);
-extern void pnx8550_machine_restart(char *);
-extern void pnx8550_machine_halt(void);
-extern void pnx8550_machine_power_off(void);
-extern struct resource ioport_resource;
-extern struct resource iomem_resource;
-extern char *prom_getcmdline(void);
-
-struct resource standard_io_resources[] = {
-       {
-               .start  = 0x00,
-               .end    = 0x1f,
-               .name   = "dma1",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0x40,
-               .end    = 0x5f,
-               .name   = "timer",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0x80,
-               .end    = 0x8f,
-               .name   = "dma page reg",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0xc0,
-               .end    = 0xdf,
-               .name   = "dma2",
-               .flags  = IORESOURCE_BUSY
-       },
-};
-
-#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
-
-extern struct resource pci_io_resource;
-extern struct resource pci_mem_resource;
-
-/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
-unsigned long get_system_mem_size(void)
-{
-       /* Read IP2031_RANK0_ADDR_LO */
-       unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
-       /* Read IP2031_RANK1_ADDR_HI */
-       unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
-
-       return dram_r1_hi - dram_r0_lo + 1;
-}
-
-int pnx8550_console_port = -1;
-
-void __init plat_mem_setup(void)
-{
-       int i;
-       char* argptr;
-
-       board_setup();  /* board specific setup */
-
-        _machine_restart = pnx8550_machine_restart;
-        _machine_halt = pnx8550_machine_halt;
-        pm_power_off = pnx8550_machine_power_off;
-
-       /* Clear the Global 2 Register, PCI Inta Output Enable Registers
-          Bit 1:Enable DAC Powerdown
-         -> 0:DACs are enabled and are working normally
-            1:DACs are powerdown
-          Bit 0:Enable of PCI inta output
-         -> 0 = Disable PCI inta output
-            1 = Enable PCI inta output
-       */
-       PNX8550_GLB2_ENAB_INTA_O = 0;
-
-       /* IO/MEM resources. */
-       set_io_port_base(PNX8550_PORT_BASE);
-       ioport_resource.start = 0;
-       ioport_resource.end = ~0;
-       iomem_resource.start = 0;
-       iomem_resource.end = ~0;
-
-       /* Request I/O space for devices on this board */
-       for (i = 0; i < STANDARD_IO_RESOURCES; i++)
-               request_resource(&ioport_resource, standard_io_resources + i);
-
-       /* Place the Mode Control bit for GPIO pin 16 in primary function */
-       /* Pin 16 is used by UART1, UA1_TX                                */
-       outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
-                       (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
-                       PNX8550_GPIO_MC1);
-
-       argptr = prom_getcmdline();
-       if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
-               argptr += strlen("console=ttyS");
-               pnx8550_console_port = *argptr == '0' ? 0 : 1;
-
-               /* We must initialize the UART (console) before early printk */
-               /* Set LCR to 8-bit and BAUD to 38400 (no 5)                */
-               ip3106_lcr(UART_BASE, pnx8550_console_port) =
-                       PNX8XXX_UART_LCR_8BIT;
-               ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
-       }
-}
index 4ee57104e47bb78ef4b8957480e04de5ee8198b9..b5ce041cdafb54667b7c11738892ab7e9020000a 100644 (file)
@@ -7,6 +7,7 @@
  * Support for all devices (greater than 16) added by David Gathright.
  */
 
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
index 8656388b34bd4fac95d7dadf6584d9fe6cdbceb6..be1e1afe12c3ce3aa527b4142d8f8b7aee17143e 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 
 #include <asm/pci.h>
index cf4c868715acaaba37e9aec317d0224ca5b6d060..dcc926e06fcec573a4478b2359b2218d5ca942cf 100644 (file)
@@ -102,7 +102,7 @@ void __init prom_init(void)
 
        /* Get the boot parameters */
        for (i = 1; i < argc; i++) {
-               if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >=
+               if (strlen(arcs_cmdline) + strlen(arg[i]) + 1 >=
                    sizeof(arcs_cmdline))
                        break;
 
index b177caa56d95c5880f9a7d0732f1736dbb908598..951e18f5335b268965d3880881d900bed63e7356 100644 (file)
@@ -345,7 +345,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
 
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !47x)) && EXPERIMENTAL
+       depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !PPC_47x)) && EXPERIMENTAL
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
index 57af16edc19231ad0b4511f30174607a57711494..70ba0c0a1223d475cd2d2c2cdfddbf5b901a7527 100644 (file)
@@ -255,12 +255,6 @@ checkbin:
                echo 'disable kernel modules' ; \
                false ; \
        fi
-       @if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \
-               echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \
-               echo 'correctly with old versions of binutils.' ; \
-               echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \
-               false ; \
-       fi
 
 CLEAN_FILES += $(TOUT)
 
index d9b776740a6739707d26a9ad836a39533bc8718c..d3b478242ea9586b793f9def431a6d9a4ea00c80 100644 (file)
                        interrupt-parent = <&mpic>;
                        interrupts = <16 2>;
                        interrupt-map-mask = <0xf800 0 0 7>;
+                       /* IRQ[0:3] are pulled up on board, set to active-low */
                        interrupt-map = <
                                /* IDSEL 0x0 */
                                0000 0 0 1 &mpic 0 1
                        interrupt-parent = <&mpic>;
                        interrupts = <16 2>;
                        interrupt-map-mask = <0xf800 0 0 7>;
+                       /*
+                        * IRQ[4:6] only for PCIe, set to active-high,
+                        * IRQ[7] is pulled up on board, set to active-low
+                        */
                        interrupt-map = <
                                /* IDSEL 0x0 */
-                               0000 0 0 1 &mpic 4 1
-                               0000 0 0 2 &mpic 5 1
-                               0000 0 0 3 &mpic 6 1
+                               0000 0 0 1 &mpic 4 2
+                               0000 0 0 2 &mpic 5 2
+                               0000 0 0 3 &mpic 6 2
                                0000 0 0 4 &mpic 7 1
                                >;
                        ranges = <0x2000000 0x0 0xa0000000
                        interrupt-parent = <&mpic>;
                        interrupts = <16 2>;
                        interrupt-map-mask = <0xf800 0 0 7>;
+                       /*
+                        * IRQ[8:10] are pulled up on board, set to active-low
+                        * IRQ[11] only for PCIe, set to active-high,
+                        */
                        interrupt-map = <
                                /* IDSEL 0x0 */
                                0000 0 0 1 &mpic 8 1
                                0000 0 0 2 &mpic 9 1
                                0000 0 0 3 &mpic 10 1
-                               0000 0 0 4 &mpic 11 1
+                               0000 0 0 4 &mpic 11 2
                                >;
                        ranges = <0x2000000 0x0 0x80000000
                                  0x2000000 0x0 0x80000000
index 6cdf1c0d2c8a10acc43796c20af80d52f7b78d64..3b98d735434142bb9240a6a2d4906d0b882a3ab2 100644 (file)
@@ -52,6 +52,8 @@ CONFIG_MTD_CFI=y
 CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_NDFC=m
 CONFIG_MTD_UBI=m
 CONFIG_MTD_UBI_GLUEBI=m
 CONFIG_PROC_DEVICETREE=y
index e2a4c26ad37793874dce3902d561dd749c78681d..02e41b53488d8d8574f42c6a4e0ce1f99df9aaa8 100644 (file)
@@ -49,13 +49,13 @@ static __inline__ int atomic_add_return(int a, atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%2         # atomic_add_return\n\
        add     %0,%1,%0\n"
        PPC405_ERR77(0,%2)
 "      stwcx.  %0,0,%2 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (a), "r" (&v->counter)
        : "cc", "memory");
@@ -85,13 +85,13 @@ static __inline__ int atomic_sub_return(int a, atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%2         # atomic_sub_return\n\
        subf    %0,%1,%0\n"
        PPC405_ERR77(0,%2)
 "      stwcx.  %0,0,%2 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (a), "r" (&v->counter)
        : "cc", "memory");
@@ -119,13 +119,13 @@ static __inline__ int atomic_inc_return(atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%1         # atomic_inc_return\n\
        addic   %0,%0,1\n"
        PPC405_ERR77(0,%1)
 "      stwcx.  %0,0,%1 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (&v->counter)
        : "cc", "xer", "memory");
@@ -163,13 +163,13 @@ static __inline__ int atomic_dec_return(atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%1         # atomic_dec_return\n\
        addic   %0,%0,-1\n"
        PPC405_ERR77(0,%1)
 "      stwcx.  %0,0,%1\n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (&v->counter)
        : "cc", "xer", "memory");
@@ -194,7 +194,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
        int t;
 
        __asm__ __volatile__ (
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%1         # __atomic_add_unless\n\
        cmpw    0,%0,%3 \n\
        beq-    2f \n\
@@ -202,7 +202,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
        PPC405_ERR77(0,%2)
 "      stwcx.  %0,0,%1 \n\
        bne-    1b \n"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
 "      subf    %0,%2,%0 \n\
 2:"
        : "=&r" (t)
@@ -226,7 +226,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%1         # atomic_dec_if_positive\n\
        cmpwi   %0,1\n\
        addi    %0,%0,-1\n\
@@ -234,7 +234,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
        PPC405_ERR77(0,%1)
 "      stwcx.  %0,0,%1\n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        "\n\
 2:"    : "=&b" (t)
        : "r" (&v->counter)
@@ -285,12 +285,12 @@ static __inline__ long atomic64_add_return(long a, atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%2         # atomic64_add_return\n\
        add     %0,%1,%0\n\
        stdcx.  %0,0,%2 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (a), "r" (&v->counter)
        : "cc", "memory");
@@ -319,12 +319,12 @@ static __inline__ long atomic64_sub_return(long a, atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%2         # atomic64_sub_return\n\
        subf    %0,%1,%0\n\
        stdcx.  %0,0,%2 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (a), "r" (&v->counter)
        : "cc", "memory");
@@ -351,12 +351,12 @@ static __inline__ long atomic64_inc_return(atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%1         # atomic64_inc_return\n\
        addic   %0,%0,1\n\
        stdcx.  %0,0,%1 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (&v->counter)
        : "cc", "xer", "memory");
@@ -393,12 +393,12 @@ static __inline__ long atomic64_dec_return(atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%1         # atomic64_dec_return\n\
        addic   %0,%0,-1\n\
        stdcx.  %0,0,%1\n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (&v->counter)
        : "cc", "xer", "memory");
@@ -418,13 +418,13 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%1         # atomic64_dec_if_positive\n\
        addic.  %0,%0,-1\n\
        blt-    2f\n\
        stdcx.  %0,0,%1\n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        "\n\
 2:"    : "=&r" (t)
        : "r" (&v->counter)
@@ -450,14 +450,14 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
        long t;
 
        __asm__ __volatile__ (
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%1         # __atomic_add_unless\n\
        cmpd    0,%0,%3 \n\
        beq-    2f \n\
        add     %0,%2,%0 \n"
 "      stdcx.  %0,0,%1 \n\
        bne-    1b \n"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
 "      subf    %0,%2,%0 \n\
 2:"
        : "=&r" (t)
index e137afcc10fae89cb0987bbe982af5653916e9e1..efdc92618b38ddfa7da075a53fb3ba93e9c71dae 100644 (file)
@@ -124,14 +124,14 @@ static __inline__ unsigned long fn(                       \
        return (old & mask);                            \
 }
 
-DEFINE_TESTOP(test_and_set_bits, or, PPC_RELEASE_BARRIER,
-             PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_set_bits, or, PPC_ATOMIC_ENTRY_BARRIER,
+             PPC_ATOMIC_EXIT_BARRIER, 0)
 DEFINE_TESTOP(test_and_set_bits_lock, or, "",
              PPC_ACQUIRE_BARRIER, 1)
-DEFINE_TESTOP(test_and_clear_bits, andc, PPC_RELEASE_BARRIER,
-             PPC_ACQUIRE_BARRIER, 0)
-DEFINE_TESTOP(test_and_change_bits, xor, PPC_RELEASE_BARRIER,
-             PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_clear_bits, andc, PPC_ATOMIC_ENTRY_BARRIER,
+             PPC_ATOMIC_EXIT_BARRIER, 0)
+DEFINE_TESTOP(test_and_change_bits, xor, PPC_ATOMIC_ENTRY_BARRIER,
+             PPC_ATOMIC_EXIT_BARRIER, 0)
 
 static __inline__ int test_and_set_bit(unsigned long nr,
                                       volatile unsigned long *addr)
index c94e4a3fe2ef3de09decfd1aa47bda3b77342f53..2a9cf845473bb51a4aea7d5317dde0a4b5ab37ed 100644 (file)
 
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
   __asm__ __volatile ( \
-       PPC_RELEASE_BARRIER \
+       PPC_ATOMIC_ENTRY_BARRIER \
 "1:    lwarx   %0,0,%2\n" \
        insn \
        PPC405_ERR77(0, %2) \
 "2:    stwcx.  %1,0,%2\n" \
        "bne-   1b\n" \
+       PPC_ATOMIC_EXIT_BARRIER \
        "li     %1,0\n" \
 "3:    .section .fixup,\"ax\"\n" \
 "4:    li      %1,%3\n" \
@@ -92,14 +93,14 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
                return -EFAULT;
 
         __asm__ __volatile__ (
-        PPC_RELEASE_BARRIER
+        PPC_ATOMIC_ENTRY_BARRIER
 "1:     lwarx   %1,0,%3         # futex_atomic_cmpxchg_inatomic\n\
         cmpw    0,%1,%4\n\
         bne-    3f\n"
         PPC405_ERR77(0,%3)
 "2:     stwcx.  %5,0,%3\n\
         bne-    1b\n"
-        PPC_ACQUIRE_BARRIER
+        PPC_ATOMIC_EXIT_BARRIER
 "3:    .section .fixup,\"ax\"\n\
 4:     li      %0,%6\n\
        b       3b\n\
index 08fe69edcd103f7882a3e172b7c5a55764009550..0ad432bc81d66259d82e4e94f691c46e4c765555 100644 (file)
@@ -148,12 +148,6 @@ struct kvm_regs {
 #define KVM_SREGS_E_UPDATE_DEC         (1 << 2)
 #define KVM_SREGS_E_UPDATE_DBSR                (1 << 3)
 
-/*
- * Book3S special bits to indicate contents in the struct by maintaining
- * backwards compatibility with older structs. If adding a new field,
- * please make sure to add a flag for that new field */
-#define KVM_SREGS_S_HIOR               (1 << 0)
-
 /*
  * In KVM_SET_SREGS, reserved/pad fields must be left untouched from a
  * previous KVM_GET_REGS.
@@ -179,8 +173,6 @@ struct kvm_sregs {
                                __u64 ibat[8]; 
                                __u64 dbat[8]; 
                        } ppc32;
-                       __u64 flags; /* KVM_SREGS_S_ */
-                       __u64 hior;
                } s;
                struct {
                        union {
index a384ffdf33de0af850ca03f18aab3e6c36515540..d4df013ad77964353fdf5a59c8ed6afde4ed1ce2 100644 (file)
@@ -90,8 +90,6 @@ struct kvmppc_vcpu_book3s {
 #endif
        int context_id[SID_CONTEXTS];
 
-       bool hior_sregs;                /* HIOR is set by SREGS, not PVR */
-
        struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE];
        struct hlist_head hpte_hash_pte_long[HPTEG_HASH_NUM_PTE_LONG];
        struct hlist_head hpte_hash_vpte[HPTEG_HASH_NUM_VPTE];
index 28cdbd9f399c70fb5b9a9adf80863ca9758e390f..03c48e819c8e3ff3bc600242dc85ef9111aca478 100644 (file)
@@ -31,7 +31,7 @@
 
 #define MSR_           MSR_ME | MSR_CE
 #define MSR_KERNEL     MSR_ | MSR_64BIT
-#define MSR_USER32     MSR_ | MSR_PR | MSR_EE | MSR_DE
+#define MSR_USER32     MSR_ | MSR_PR | MSR_EE
 #define MSR_USER64     MSR_USER32 | MSR_64BIT
 #elif defined (CONFIG_40x)
 #define MSR_KERNEL     (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE)
index 6fbce725c710f97453079205e190c02c7365cd0b..a0f358d4a00cd57ba3b22fbbf1024c7daba65fa4 100644 (file)
@@ -8,7 +8,7 @@
 
 #ifdef __powerpc64__
 
-extern char _end[];
+extern char __end_interrupts[];
 
 static inline int in_kernel_text(unsigned long addr)
 {
index d7cab44643c51d90f1f79509939e3c734b735eba..e682a7143edb767826705243df3613cc85e305ab 100644 (file)
@@ -13,6 +13,7 @@
 extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
 extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
                             void *fixup_end);
+extern void do_final_fixups(void);
 
 static inline void eieio(void)
 {
@@ -41,11 +42,15 @@ static inline void isync(void)
        START_LWSYNC_SECTION(97);                       \
        isync;                                          \
        MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
-#define PPC_ACQUIRE_BARRIER    "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
-#define PPC_RELEASE_BARRIER    stringify_in_c(LWSYNC) "\n"
+#define PPC_ACQUIRE_BARRIER     "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
+#define PPC_RELEASE_BARRIER     stringify_in_c(LWSYNC) "\n"
+#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(LWSYNC) "\n"
+#define PPC_ATOMIC_EXIT_BARRIER         "\n" stringify_in_c(sync) "\n"
 #else
 #define PPC_ACQUIRE_BARRIER
 #define PPC_RELEASE_BARRIER
+#define PPC_ATOMIC_ENTRY_BARRIER
+#define PPC_ATOMIC_EXIT_BARRIER
 #endif
 
 #endif /* __KERNEL__ */
index 56212bc0ab087c4b40bb21df3496c89849a01f06..4f80cf1ce77b84c30e905bcb8cb8d660c005c22b 100644 (file)
@@ -215,7 +215,22 @@ reenable_mmu:                              /* re-enable mmu so we can */
        stw     r9,8(r1)
        stw     r11,12(r1)
        stw     r3,ORIG_GPR3(r1)
+       /*
+        * The trace_hardirqs_off will use CALLER_ADDR0 and CALLER_ADDR1.
+        * If from user mode there is only one stack frame on the stack, and
+        * accessing CALLER_ADDR1 will cause oops. So we need create a dummy
+        * stack frame to make trace_hardirqs_off happy.
+        */
+       andi.   r12,r12,MSR_PR
+       beq     11f
+       stwu    r1,-16(r1)
+       bl      trace_hardirqs_off
+       addi    r1,r1,16
+       b       12f
+
+11:
        bl      trace_hardirqs_off
+12:
        lwz     r0,GPR0(r1)
        lwz     r3,ORIG_GPR3(r1)
        lwz     r4,GPR4(r1)
index 368d158d665d5e44942f403d5a3710413ece52d2..a1ed8a8c7cb42c83fc61c674735f1f7d6bbe3842 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/jump_label.h>
 #include <asm/code-patching.h>
 
+#ifdef HAVE_JUMP_LABEL
 void arch_jump_label_transform(struct jump_entry *entry,
                               enum jump_label_type type)
 {
@@ -21,3 +22,4 @@ void arch_jump_label_transform(struct jump_entry *entry,
        else
                patch_instruction(addr, PPC_INST_NOP);
 }
+#endif
index 35f27646c4ff5af053313054c953000d0be64031..2985338d0e10164e3b77ab12fcc3bb755a1a6fb3 100644 (file)
@@ -132,7 +132,6 @@ static void kvm_patch_ins_b(u32 *inst, int addr)
        /* On relocatable kernels interrupts handlers and our code
           can be in different regions, so we don't patch them */
 
-       extern u32 __end_interrupts;
        if ((ulong)inst < (ulong)&__end_interrupts)
                return;
 #endif
index f7d760ab5ca1fd6851502352a7a958759c429c7f..7cd07b42ca1a505c9a9bfbb3802277336537a514 100644 (file)
@@ -738,7 +738,7 @@ relocate_new_kernel:
        mr      r5, r31
 
        li      r0, 0
-#elif defined(CONFIG_44x)  && !defined(CONFIG_47x)
+#elif defined(CONFIG_44x)  && !defined(CONFIG_PPC_47x)
 
 /*
  * Code for setting up 1:1 mapping for PPC440x for KEXEC
index 9054ca9ab4f93bcd6100cc0fcb03c7d5f4caf857..6457574c0b2f32fbaa800b11eeed0cbd8877a77e 100644 (file)
@@ -486,28 +486,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
        new_thread = &new->thread;
        old_thread = &current->thread;
 
-#if defined(CONFIG_PPC_BOOK3E_64)
-       /* XXX Current Book3E code doesn't deal with kernel side DBCR0,
-        * we always hold the user values, so we set it now.
-        *
-        * However, we ensure the kernel MSR:DE is appropriately cleared too
-        * to avoid spurrious single step exceptions in the kernel.
-        *
-        * This will have to change to merge with the ppc32 code at some point,
-        * but I don't like much what ppc32 is doing today so there's some
-        * thinking needed there
-        */
-       if ((new_thread->dbcr0 | old_thread->dbcr0) & DBCR0_IDM) {
-               u32 dbcr0;
-
-               mtmsr(mfmsr() & ~MSR_DE);
-               isync();
-               dbcr0 = mfspr(SPRN_DBCR0);
-               dbcr0 = (dbcr0 & DBCR0_EDM) | new_thread->dbcr0;
-               mtspr(SPRN_DBCR0, dbcr0);
-       }
-#endif /* CONFIG_PPC64_BOOK3E */
-
 #ifdef CONFIG_PPC64
        /*
         * Collect processor utilization data per process
@@ -657,7 +635,7 @@ void show_regs(struct pt_regs * regs)
        if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
                printk("CFAR: "REG"\n", regs->orig_gpr3);
        if (trap == 0x300 || trap == 0x600)
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
                printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
 #else
                printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr);
index b4fa66127495286aa6d4e7030480492f2b6bf90b..cc584865b3df537d7c50cfb2bda9d87a6ed24f85 100644 (file)
@@ -1579,10 +1579,8 @@ static void __init prom_instantiate_rtas(void)
                return;
 
        base = alloc_down(size, PAGE_SIZE, 0);
-       if (base == 0) {
-               prom_printf("RTAS allocation failed !\n");
-               return;
-       }
+       if (base == 0)
+               prom_panic("Could not allocate memory for RTAS\n");
 
        rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
        if (!IHANDLE_VALID(rtas_inst)) {
index c1ce86357ecb4a3a47411c18e6fe88cfd5c07d8b..ac761081511355ee68854ee02ade12f17ef93e18 100644 (file)
@@ -107,6 +107,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
                         PTRRELOC(&__start___lwsync_fixup),
                         PTRRELOC(&__stop___lwsync_fixup));
 
+       do_final_fixups();
+
        return KERNELBASE + offset;
 }
 
index 1a9dea80a69b46a42b9df6ed4ce4d45f385abb85..fb9bb46e7e881a584c1532a6768622395a5045be 100644 (file)
@@ -359,6 +359,7 @@ void __init setup_system(void)
                          &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
        do_lwsync_fixups(cur_cpu_spec->cpu_features,
                         &__start___lwsync_fixup, &__stop___lwsync_fixup);
+       do_final_fixups();
 
        /*
         * Unflatten the device-tree passed by prom_init or kexec
index 78b76dc54dfb27847a24228e1bac2e2ef804354a..836a5a19eb2c3a3e45d5cab542fdb7138a8142bd 100644 (file)
@@ -97,7 +97,7 @@ static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
        compat_sigset_t cset;
 
        switch (_NSIG_WORDS) {
-       case 4: cset.sig[5] = set->sig[3] & 0xffffffffull;
+       case 4: cset.sig[6] = set->sig[3] & 0xffffffffull;
                cset.sig[7] = set->sig[3] >> 32;
        case 3: cset.sig[4] = set->sig[2] & 0xffffffffull;
                cset.sig[5] = set->sig[2] >> 32;
index 4e5908264d1a98819a6713fe23f4d5a23032db41..5459d148a0f6d792fd457bd55e2105788057169b 100644 (file)
@@ -1298,14 +1298,12 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 
                if (user_mode(regs)) {
                        current->thread.dbcr0 &= ~DBCR0_IC;
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
                        if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
                                               current->thread.dbcr1))
                                regs->msr |= MSR_DE;
                        else
                                /* Make sure the IDM bit is off */
                                current->thread.dbcr0 &= ~DBCR0_IDM;
-#endif
                }
 
                _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
index 0cdbc07cec14e1cd9900a5b1eddc62e476dcdf98..0cb137a9b0381f1175d5962c67aac18f566af662 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/processor.h>
 #include <asm/cputhreads.h>
 #include <asm/page.h>
+#include <asm/hvcall.h>
 #include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
index bc4d50dec78b8f420f789d722c38c66d42a87ab6..3c791e1eb675299c96e7b428b499e7bec4e5f434 100644 (file)
@@ -151,16 +151,14 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
 #ifdef CONFIG_PPC_BOOK3S_64
        if ((pvr >= 0x330000) && (pvr < 0x70330000)) {
                kvmppc_mmu_book3s_64_init(vcpu);
-               if (!to_book3s(vcpu)->hior_sregs)
-                       to_book3s(vcpu)->hior = 0xfff00000;
+               to_book3s(vcpu)->hior = 0xfff00000;
                to_book3s(vcpu)->msr_mask = 0xffffffffffffffffULL;
                vcpu->arch.cpu_type = KVM_CPU_3S_64;
        } else
 #endif
        {
                kvmppc_mmu_book3s_32_init(vcpu);
-               if (!to_book3s(vcpu)->hior_sregs)
-                       to_book3s(vcpu)->hior = 0;
+               to_book3s(vcpu)->hior = 0;
                to_book3s(vcpu)->msr_mask = 0xffffffffULL;
                vcpu->arch.cpu_type = KVM_CPU_3S_32;
        }
@@ -797,9 +795,6 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
                }
        }
 
-       if (sregs->u.s.flags & KVM_SREGS_S_HIOR)
-               sregs->u.s.hior = to_book3s(vcpu)->hior;
-
        return 0;
 }
 
@@ -836,11 +831,6 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
        /* Flush the MMU after messing with the segments */
        kvmppc_mmu_pte_flush(vcpu, 0, 0);
 
-       if (sregs->u.s.flags & KVM_SREGS_S_HIOR) {
-               to_book3s(vcpu)->hior_sregs = true;
-               to_book3s(vcpu)->hior = sregs->u.s.hior;
-       }
-
        return 0;
 }
 
index efbf9ad872035dee6a364867c5e5e50cdd52da99..607fbdf24b8484c173cc03593ffc71d968b689fe 100644 (file)
@@ -208,7 +208,6 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_PPC_BOOKE_SREGS:
 #else
        case KVM_CAP_PPC_SEGSTATE:
-       case KVM_CAP_PPC_HIOR:
        case KVM_CAP_PPC_PAPR:
 #endif
        case KVM_CAP_PPC_UNSET_IRQ:
index 0d08d0171392a4e7ec72e21226737cc458e3a98f..7a8a7487cee8dde9d06aa86fff3bd32bdd54433e 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/init.h>
 #include <asm/cputable.h>
 #include <asm/code-patching.h>
+#include <asm/page.h>
+#include <asm/sections.h>
 
 
 struct fixup_entry {
@@ -128,6 +130,27 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
        }
 }
 
+void do_final_fixups(void)
+{
+#if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE)
+       int *src, *dest;
+       unsigned long length;
+
+       if (PHYSICAL_START == 0)
+               return;
+
+       src = (int *)(KERNELBASE + PHYSICAL_START);
+       dest = (int *)KERNELBASE;
+       length = (__end_interrupts - _stext) / sizeof(int);
+
+       while (length--) {
+               patch_instruction(dest, *src);
+               src++;
+               dest++;
+       }
+#endif
+}
+
 #ifdef CONFIG_FTR_FIXUP_SELFTEST
 
 #define check(x)       \
index 5964371303ac4a5941eb2a0ccceca27cf6330354..8558b572e55d3e6ba2ee7b5656b9eb9f9e39b5c3 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/of_fdt.h>
 #include <linux/memblock.h>
 #include <linux/bootmem.h>
+#include <linux/moduleparam.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
index 45023e26aea369685d88c752aa52814ac07dd27a..d7946be298b6fc1f842eaff3e14b4ae502924f3c 100644 (file)
@@ -203,7 +203,7 @@ config P3060_QDS
        select PPC_E500MC
        select PHYS_64BIT
        select SWIOTLB
-       select MPC8xxx_GPIO
+       select GPIO_MPC8XXX
        select HAS_RAPIDIO
        select PPC_EPAPR_HV_PIC
        help
index 01dcf44871e9a4c79273d14efd1fcde0b60b6ba9..081cf4ac188161b4f4bb535d0d57209bc14fd03c 100644 (file)
@@ -70,7 +70,7 @@ define_machine(p3060_qds) {
        .power_save             = e500_idle,
 };
 
-machine_device_initcall(p3060_qds, declare_of_platform_devices);
+machine_device_initcall(p3060_qds, corenet_ds_publish_devices);
 
 #ifdef CONFIG_SWIOTLB
 machine_arch_initcall(p3060_qds, swiotlb_setup_bus_notifier);
index e4588721ef344da86b4cc001179e2e778bbde4cd..3fe6d927ad70e928d302192d275fd0b69220af05 100644 (file)
@@ -347,7 +347,7 @@ config SIMPLE_GPIO
 
 config MCU_MPC8349EMITX
        bool "MPC8349E-mITX MCU driver"
-       depends on I2C && PPC_83xx
+       depends on I2C=y && PPC_83xx
        select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
        help
index 404bc52b7806e1f769455439626bb62ac0afbcf9..1d6f4f478fe293ebd06313aa1077c1019507473d 100644 (file)
@@ -88,6 +88,7 @@ struct ps3_private {
        struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
        u64 ppe_id;
        u64 thread_id;
+       unsigned long ipi_mask;
 };
 
 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
@@ -144,7 +145,11 @@ static void ps3_chip_unmask(struct irq_data *d)
 static void ps3_chip_eoi(struct irq_data *d)
 {
        const struct ps3_private *pd = irq_data_get_irq_chip_data(d);
-       lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
+
+       /* non-IPIs are EOIed here. */
+
+       if (!test_bit(63 - d->irq, &pd->ipi_mask))
+               lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
 }
 
 /**
@@ -691,6 +696,16 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
                cpu, virq, pd->bmp.ipi_debug_brk_mask);
 }
 
+void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq)
+{
+       struct ps3_private *pd = &per_cpu(ps3_private, cpu);
+
+       set_bit(63 - virq, &pd->ipi_mask);
+
+       DBG("%s:%d: cpu %u, virq %u, ipi_mask %lxh\n", __func__, __LINE__,
+               cpu, virq, pd->ipi_mask);
+}
+
 static unsigned int ps3_get_irq(void)
 {
        struct ps3_private *pd = &__get_cpu_var(ps3_private);
@@ -720,6 +735,12 @@ static unsigned int ps3_get_irq(void)
                BUG();
        }
 #endif
+
+       /* IPIs are EOIed here. */
+
+       if (test_bit(63 - plug, &pd->ipi_mask))
+               lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, plug);
+
        return plug;
 }
 
index 9a196a88eda794d6d07f50abefaebc7a21902427..1a633ed0fe98744d8994d7e6367180a11ab59a96 100644 (file)
@@ -43,6 +43,7 @@ void ps3_mm_shutdown(void);
 void ps3_init_IRQ(void);
 void ps3_shutdown_IRQ(int cpu);
 void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq);
+void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq);
 
 /* smp */
 
index 4c44794faac0b344ac50663ed12122519c37b53d..efc1cd8c034ac7f47135f7af1e1582d9e722984b 100644 (file)
@@ -59,46 +59,49 @@ static void ps3_smp_message_pass(int cpu, int msg)
 
 static int ps3_smp_probe(void)
 {
-       return 2;
-}
+       int cpu;
 
-static void __init ps3_smp_setup_cpu(int cpu)
-{
-       int result;
-       unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
-       int i;
+       for (cpu = 0; cpu < 2; cpu++) {
+               int result;
+               unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
+               int i;
 
-       DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
+               DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
 
-       /*
-        * Check assumptions on ps3_ipi_virqs[] indexing. If this
-        * check fails, then a different mapping of PPC_MSG_
-        * to index needs to be setup.
-        */
+               /*
+               * Check assumptions on ps3_ipi_virqs[] indexing. If this
+               * check fails, then a different mapping of PPC_MSG_
+               * to index needs to be setup.
+               */
 
-       BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION    != 0);
-       BUILD_BUG_ON(PPC_MSG_RESCHEDULE       != 1);
-       BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2);
-       BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK   != 3);
+               BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION    != 0);
+               BUILD_BUG_ON(PPC_MSG_RESCHEDULE       != 1);
+               BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2);
+               BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK   != 3);
 
-       for (i = 0; i < MSG_COUNT; i++) {
-               result = ps3_event_receive_port_setup(cpu, &virqs[i]);
+               for (i = 0; i < MSG_COUNT; i++) {
+                       result = ps3_event_receive_port_setup(cpu, &virqs[i]);
 
-               if (result)
-                       continue;
+                       if (result)
+                               continue;
 
-               DBG("%s:%d: (%d, %d) => virq %u\n",
-                       __func__, __LINE__, cpu, i, virqs[i]);
+                       DBG("%s:%d: (%d, %d) => virq %u\n",
+                               __func__, __LINE__, cpu, i, virqs[i]);
 
-               result = smp_request_message_ipi(virqs[i], i);
+                       result = smp_request_message_ipi(virqs[i], i);
 
-               if (result)
-                       virqs[i] = NO_IRQ;
-       }
+                       if (result)
+                               virqs[i] = NO_IRQ;
+                       else
+                               ps3_register_ipi_irq(cpu, virqs[i]);
+               }
 
-       ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);
+               ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);
 
-       DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
+               DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
+       }
+
+       return 2;
 }
 
 void ps3_smp_cleanup_cpu(int cpu)
@@ -121,7 +124,6 @@ static struct smp_ops_t ps3_smp_ops = {
        .probe          = ps3_smp_probe,
        .message_pass   = ps3_smp_message_pass,
        .kick_cpu       = smp_generic_kick_cpu,
-       .setup_cpu      = ps3_smp_setup_cpu,
 };
 
 void smp_init_ps3(void)
index af1a5df46b3e54ff75bb392b97ff26e8f1e72b4f..b6731e4a6646e16e81c62de273d8a6cd579b1ca7 100644 (file)
@@ -280,6 +280,7 @@ void __init ehv_pic_init(void)
 
        if (!ehv_pic->irqhost) {
                of_node_put(np);
+               kfree(ehv_pic);
                return;
        }
 
index c4d96fa32ba557a68512b133400fef585e799eb4..d5c3c90ee6981a14d40da0175f3d3ddc0c0f77f4 100644 (file)
@@ -328,6 +328,7 @@ static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev)
 err:
        iounmap(fsl_lbc_ctrl_dev->regs);
        kfree(fsl_lbc_ctrl_dev);
+       fsl_lbc_ctrl_dev = NULL;
        return ret;
 }
 
index 3363fbc964f86c1d42676116f813a2ac71b9e0e2..ceb09cbd2329e782fe00a5c3e1326d217ab3e92b 100644 (file)
@@ -216,7 +216,7 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
        /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
           that the BRG divisor must be even if you're not using divide-by-16
           mode. */
-       if (!div16 && (divisor & 1))
+       if (!div16 && (divisor & 1) && (divisor > 3))
                divisor++;
 
        tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
index a9fbd43395f71814d85a284a63900dc5a7dcc018..373679b3744a7992c7009281c1747b3aeb38157a 100644 (file)
@@ -572,6 +572,7 @@ config KEXEC
 config CRASH_DUMP
        bool "kernel crash dumps"
        depends on 64BIT
+       select KEXEC
        help
          Generate crash dump after being started by kexec.
          Crash dump kernels are loaded in the main kernel with kexec-tools
index 49676771bd66a278e73db7a2430612a57a1cf6a1..ffd1ac255f19444d838e58b2fb2ef2b716b02f77 100644 (file)
@@ -368,9 +368,12 @@ static inline int crypt_s390_func_available(int func,
 
        if (facility_mask & CRYPT_S390_MSA && !test_facility(17))
                return 0;
-       if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76))
+
+       if (facility_mask & CRYPT_S390_MSA3 &&
+           (!test_facility(2) || !test_facility(76)))
                return 0;
-       if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77))
+       if (facility_mask & CRYPT_S390_MSA4 &&
+           (!test_facility(2) || !test_facility(77)))
                return 0;
 
        switch (func & CRYPT_S390_OP_MASK) {
index 24e18473d926548ec3e54732093902178a6838e9..b0c235cb6ad5c79d42414a863508e0c37db8337d 100644 (file)
@@ -47,7 +47,7 @@ struct sca_block {
 #define KVM_HPAGE_MASK(x)      (~(KVM_HPAGE_SIZE(x) - 1))
 #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
 
-#define CPUSTAT_HOST       0x80000000
+#define CPUSTAT_STOPPED    0x80000000
 #define CPUSTAT_WAIT       0x10000000
 #define CPUSTAT_ECALL_PEND 0x08000000
 #define CPUSTAT_STOP_INT   0x04000000
@@ -139,6 +139,7 @@ struct kvm_vcpu_stat {
        u32 instruction_stfl;
        u32 instruction_tprot;
        u32 instruction_sigp_sense;
+       u32 instruction_sigp_sense_running;
        u32 instruction_sigp_external_call;
        u32 instruction_sigp_emergency;
        u32 instruction_sigp_stop;
index 34ede0ea85a9d0ae6d03a8c52b3bb3f43cb4e1ac..524d23b8610ceb65c42661a97e79226125dbadf3 100644 (file)
@@ -593,6 +593,8 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
        unsigned long address, bits;
        unsigned char skey;
 
+       if (!pte_present(*ptep))
+               return pgste;
        address = pte_val(*ptep) & PAGE_MASK;
        skey = page_get_storage_key(address);
        bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
@@ -625,6 +627,8 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
 #ifdef CONFIG_PGSTE
        int young;
 
+       if (!pte_present(*ptep))
+               return pgste;
        young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK);
        /* Transfer page referenced bit to pte software bit (host view) */
        if (young || (pgste_val(pgste) & RCP_HR_BIT))
@@ -638,13 +642,15 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
 
 }
 
-static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste)
+static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste, pte_t entry)
 {
 #ifdef CONFIG_PGSTE
        unsigned long address;
        unsigned long okey, nkey;
 
-       address = pte_val(*ptep) & PAGE_MASK;
+       if (!pte_present(entry))
+               return;
+       address = pte_val(entry) & PAGE_MASK;
        okey = nkey = page_get_storage_key(address);
        nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
        /* Set page access key and fetch protection bit from pgste */
@@ -712,7 +718,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 
        if (mm_has_pgste(mm)) {
                pgste = pgste_get_lock(ptep);
-               pgste_set_pte(ptep, pgste);
+               pgste_set_pte(ptep, pgste, entry);
                *ptep = entry;
                pgste_set_unlock(ptep, pgste);
        } else
index 5a099714df0459b9470e3d158e0b163bf8ce770b..097183c70407a81e9147697a37c880a6008b4ed1 100644 (file)
@@ -82,6 +82,7 @@ extern unsigned int user_mode;
 #define MACHINE_FLAG_LPAR      (1UL << 12)
 #define MACHINE_FLAG_SPP       (1UL << 13)
 #define MACHINE_FLAG_TOPOLOGY  (1UL << 14)
+#define MACHINE_FLAG_STCKF     (1UL << 15)
 
 #define MACHINE_IS_VM          (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
 #define MACHINE_IS_KVM         (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
@@ -100,6 +101,7 @@ extern unsigned int user_mode;
 #define MACHINE_HAS_PFMF       (0)
 #define MACHINE_HAS_SPP                (0)
 #define MACHINE_HAS_TOPOLOGY   (0)
+#define MACHINE_HAS_STCKF      (0)
 #else /* __s390x__ */
 #define MACHINE_HAS_IEEE       (1)
 #define MACHINE_HAS_CSP                (1)
@@ -111,6 +113,7 @@ extern unsigned int user_mode;
 #define MACHINE_HAS_PFMF       (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
 #define MACHINE_HAS_SPP                (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
 #define MACHINE_HAS_TOPOLOGY   (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
+#define MACHINE_HAS_STCKF      (S390_lowcore.machine_flags & MACHINE_FLAG_STCKF)
 #endif /* __s390x__ */
 
 #define ZFCPDUMP_HSA_SIZE      (32UL<<20)
index d610bef9c5e91a425ad01a683525f46ba0c055e1..c447a27a7fdb109be95edf0d6884026df6e895ce 100644 (file)
@@ -90,7 +90,7 @@ static inline unsigned long long get_clock_fast(void)
 {
        unsigned long long clk;
 
-       if (test_facility(25))
+       if (MACHINE_HAS_STCKF)
                asm volatile(".insn     s,0xb27c0000,%0" : "=Q" (clk) : : "cc");
        else
                clk = get_clock();
index 404bdb9671b4f5c8d03d2391e93abf26e5b38a59..58de4c91c333358000779b283efdad2de1ebe445 100644 (file)
 #define __NR_clock_adjtime     337
 #define __NR_syncfs            338
 #define __NR_setns             339
-#define NR_syscalls 340
+#define __NR_process_vm_readv  340
+#define __NR_process_vm_writev 341
+#define NR_syscalls 342
 
 /* 
  * There are some system calls that are not present on 64 bit, some
index 5006a1d9f5d0ed6d3abd95f3cca652d87689dcef..18c51df9fe06c5ed98f785fb6af86655c025e887 100644 (file)
@@ -1627,3 +1627,23 @@ ENTRY(sys_setns_wrapper)
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
        jg      sys_setns
+
+ENTRY(compat_sys_process_vm_readv_wrapper)
+       lgfr    %r2,%r2                 # compat_pid_t
+       llgtr   %r3,%r3                 # struct compat_iovec __user *
+       llgfr   %r4,%r4                 # unsigned long
+       llgtr   %r5,%r5                 # struct compat_iovec __user *
+       llgfr   %r6,%r6                 # unsigned long
+       llgf    %r0,164(%r15)           # unsigned long
+       stg     %r0,160(%r15)
+       jg      sys_process_vm_readv
+
+ENTRY(compat_sys_process_vm_writev_wrapper)
+       lgfr    %r2,%r2                 # compat_pid_t
+       llgtr   %r3,%r3                 # struct compat_iovec __user *
+       llgfr   %r4,%r4                 # unsigned long
+       llgtr   %r5,%r5                 # struct compat_iovec __user *
+       llgfr   %r6,%r6                 # unsigned long
+       llgf    %r0,164(%r15)           # unsigned long
+       stg     %r0,160(%r15)
+       jg      sys_process_vm_writev
index 37394b3413e2776dfd24586f0578045e488bd054..c9ffe002519715d64ddc16d2a2caafcbf47cb8b2 100644 (file)
@@ -390,6 +390,8 @@ static __init void detect_machine_facilities(void)
                S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
        if (test_facility(40))
                S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
+       if (test_facility(25))
+               S390_lowcore.machine_flags |= MACHINE_FLAG_STCKF;
 #endif
 }
 
index 8ac6bfa2786cbe139d9964b1f4ab374e4302e2e8..e58a462949b164ea90c5697696b9ccec47bb7ff4 100644 (file)
@@ -211,6 +211,8 @@ static void __init setup_zfcpdump(unsigned int console_devno)
 
        if (ipl_info.type != IPL_TYPE_FCP_DUMP)
                return;
+       if (OLDMEM_BASE)
+               return;
        if (console_devno != -1)
                sprintf(str, " cio_ignore=all,!0.0.%04x,!0.0.%04x",
                        ipl_info.data.fcp.dev_id.devno, console_devno);
@@ -482,7 +484,7 @@ static void __init setup_memory_end(void)
 
 
 #ifdef CONFIG_ZFCPDUMP
-       if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
+       if (ipl_info.type == IPL_TYPE_FCP_DUMP && !OLDMEM_BASE) {
                memory_end = ZFCPDUMP_HSA_SIZE;
                memory_end_set = 1;
        }
index 73eb08c874fb450ef6ba0464d4aa4ca845bb6911..bcab2f04ba581f7648426a1790485d53626d8fda 100644 (file)
@@ -348,3 +348,5 @@ SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at
 SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper)
 SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper)
 SYSCALL(sys_setns,sys_setns,sys_setns_wrapper)
+SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wrapper) /* 340 */
+SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper)
index 77b8942b9a153af398cf9cf0e2dfd8eb7c5629ef..fdb5b8cb260f683e1f4559f95c006a7838690f60 100644 (file)
@@ -68,8 +68,10 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
        return mask;
 }
 
-static void add_cpus_to_mask(struct topology_cpu *tl_cpu,
-                            struct mask_info *book, struct mask_info *core)
+static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
+                                         struct mask_info *book,
+                                         struct mask_info *core,
+                                         int z10)
 {
        unsigned int cpu;
 
@@ -88,10 +90,16 @@ static void add_cpus_to_mask(struct topology_cpu *tl_cpu,
                        cpu_book_id[lcpu] = book->id;
 #endif
                        cpumask_set_cpu(lcpu, &core->mask);
-                       cpu_core_id[lcpu] = core->id;
+                       if (z10) {
+                               cpu_core_id[lcpu] = rcpu;
+                               core = core->next;
+                       } else {
+                               cpu_core_id[lcpu] = core->id;
+                       }
                        smp_cpu_polarization[lcpu] = tl_cpu->pp;
                }
        }
+       return core;
 }
 
 static void clear_masks(void)
@@ -123,18 +131,41 @@ static void tl_to_cores(struct sysinfo_15_1_x *info)
 {
 #ifdef CONFIG_SCHED_BOOK
        struct mask_info *book = &book_info;
+       struct cpuid cpu_id;
 #else
        struct mask_info *book = NULL;
 #endif
        struct mask_info *core = &core_info;
        union topology_entry *tle, *end;
+       int z10 = 0;
 
-
+#ifdef CONFIG_SCHED_BOOK
+       get_cpu_id(&cpu_id);
+       z10 = cpu_id.machine == 0x2097 || cpu_id.machine == 0x2098;
+#endif
        spin_lock_irq(&topology_lock);
        clear_masks();
        tle = info->tle;
        end = (union topology_entry *)((unsigned long)info + info->length);
        while (tle < end) {
+#ifdef CONFIG_SCHED_BOOK
+               if (z10) {
+                       switch (tle->nl) {
+                       case 1:
+                               book = book->next;
+                               book->id = tle->container.id;
+                               break;
+                       case 0:
+                               core = add_cpus_to_mask(&tle->cpu, book, core, z10);
+                               break;
+                       default:
+                               clear_masks();
+                               goto out;
+                       }
+                       tle = next_tle(tle);
+                       continue;
+               }
+#endif
                switch (tle->nl) {
 #ifdef CONFIG_SCHED_BOOK
                case 2:
@@ -147,7 +178,7 @@ static void tl_to_cores(struct sysinfo_15_1_x *info)
                        core->id = tle->container.id;
                        break;
                case 0:
-                       add_cpus_to_mask(&tle->cpu, book, core);
+                       add_cpus_to_mask(&tle->cpu, book, core, z10);
                        break;
                default:
                        clear_masks();
@@ -328,8 +359,8 @@ void __init s390_init_cpu_topology(void)
        for (i = 0; i < TOPOLOGY_NR_MAG; i++)
                printk(" %d", info->mag[i]);
        printk(" / %d\n", info->mnest);
-       alloc_masks(info, &core_info, 2);
+       alloc_masks(info, &core_info, 1);
 #ifdef CONFIG_SCHED_BOOK
-       alloc_masks(info, &book_info, 3);
+       alloc_masks(info, &book_info, 2);
 #endif
 }
index 56fe6bc81fee45804a61c37fb189ccf73a0b72e8..e4c79ebb40e628850fd230fc94a0c7fdc77aaeb1 100644 (file)
@@ -43,6 +43,8 @@ SECTIONS
 
        NOTES :text :note
 
+       .dummy : { *(.dummy) } :data
+
        RODATA
 
 #ifdef CONFIG_SHARED_KERNEL
index 87cedd61be0467fdd4085308e55967acb9210ef3..8943e82cd4d94248ef8708839d6c7e0d99e324f9 100644 (file)
@@ -70,7 +70,7 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
                return -EOPNOTSUPP;
        }
 
-       atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
+       atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
        vcpu->run->s390_reset_flags |= KVM_S390_RESET_SUBSYSTEM;
        vcpu->run->s390_reset_flags |= KVM_S390_RESET_IPL;
        vcpu->run->s390_reset_flags |= KVM_S390_RESET_CPU_INIT;
index c7c51898984ef78e64b761ad8c6f9256fa71f30b..02434543eabbede6e5e2fbc17f8e649f5a19871a 100644 (file)
@@ -132,7 +132,6 @@ static int handle_stop(struct kvm_vcpu *vcpu)
        int rc = 0;
 
        vcpu->stat.exit_stop_request++;
-       atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
        spin_lock_bh(&vcpu->arch.local_int.lock);
        if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) {
                vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP;
@@ -149,6 +148,8 @@ static int handle_stop(struct kvm_vcpu *vcpu)
        }
 
        if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
+               atomic_set_mask(CPUSTAT_STOPPED,
+                               &vcpu->arch.sie_block->cpuflags);
                vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
                VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
                rc = -EOPNOTSUPP;
index 87c16705b381396f796e7fbacbb079d62cab8d9d..278ee009ce6570a9d4049a095def51b17fb164d5 100644 (file)
@@ -252,6 +252,7 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
                        offsetof(struct _lowcore, restart_psw), sizeof(psw_t));
                if (rc == -EFAULT)
                        exception = 1;
+               atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
                break;
 
        case KVM_S390_PROGRAM_INT:
index 0bd3bea1e4cdfc40069a474d37f74459903803ce..d1c445732451b6d1bd1c4b95db3d6467ff629c68 100644 (file)
@@ -65,6 +65,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "instruction_stfl", VCPU_STAT(instruction_stfl) },
        { "instruction_tprot", VCPU_STAT(instruction_tprot) },
        { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
+       { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
        { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
        { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
        { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
@@ -127,6 +128,7 @@ int kvm_dev_ioctl_check_extension(long ext)
        switch (ext) {
        case KVM_CAP_S390_PSW:
        case KVM_CAP_S390_GMAP:
+       case KVM_CAP_SYNC_MMU:
                r = 1;
                break;
        default:
@@ -270,10 +272,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        restore_fp_regs(&vcpu->arch.guest_fpregs);
        restore_access_regs(vcpu->arch.guest_acrs);
        gmap_enable(vcpu->arch.gmap);
+       atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+       atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
        gmap_disable(vcpu->arch.gmap);
        save_fp_regs(&vcpu->arch.guest_fpregs);
        save_access_regs(vcpu->arch.guest_acrs);
@@ -301,7 +305,9 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
 
 int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
-       atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM);
+       atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
+                                                   CPUSTAT_SM |
+                                                   CPUSTAT_STOPPED);
        vcpu->arch.sie_block->ecb   = 6;
        vcpu->arch.sie_block->eca   = 0xC1002001U;
        vcpu->arch.sie_block->fac   = (int) (long) facilities;
@@ -428,7 +434,7 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
 {
        int rc = 0;
 
-       if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
+       if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
                rc = -EBUSY;
        else {
                vcpu->run->psw_mask = psw.mask;
@@ -501,7 +507,7 @@ rerun_vcpu:
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
 
-       atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
+       atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
 
        BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
 
index 391626361084e363cfd2f0f4251dd652ebc16a58..d02638959922aba41712d16d6dfb20f86f87ec8b 100644 (file)
@@ -336,6 +336,7 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
        u64 address1 = disp1 + base1 ? vcpu->arch.guest_gprs[base1] : 0;
        u64 address2 = disp2 + base2 ? vcpu->arch.guest_gprs[base2] : 0;
        struct vm_area_struct *vma;
+       unsigned long user_address;
 
        vcpu->stat.instruction_tprot++;
 
@@ -349,9 +350,14 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
                return -EOPNOTSUPP;
 
 
+       /* we must resolve the address without holding the mmap semaphore.
+        * This is ok since the userspace hypervisor is not supposed to change
+        * the mapping while the guest queries the memory. Otherwise the guest
+        * might crash or get wrong info anyway. */
+       user_address = (unsigned long) __guestaddr_to_user(vcpu, address1);
+
        down_read(&current->mm->mmap_sem);
-       vma = find_vma(current->mm,
-                       (unsigned long) __guestaddr_to_user(vcpu, address1));
+       vma = find_vma(current->mm, user_address);
        if (!vma) {
                up_read(&current->mm->mmap_sem);
                return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
index f815118835f3c3221932c5e01c86847cc1ec9ba8..0a7941d74bc68b30b9121090aeb96111c86058b7 100644 (file)
 #define SIGP_SET_PREFIX        0x0d
 #define SIGP_STORE_STATUS_ADDR 0x0e
 #define SIGP_SET_ARCH          0x12
+#define SIGP_SENSE_RUNNING     0x15
 
 /* cpu status bits */
 #define SIGP_STAT_EQUIPMENT_CHECK   0x80000000UL
+#define SIGP_STAT_NOT_RUNNING      0x00000400UL
 #define SIGP_STAT_INCORRECT_STATE   0x00000200UL
 #define SIGP_STAT_INVALID_PARAMETER 0x00000100UL
 #define SIGP_STAT_EXT_CALL_PENDING  0x00000080UL
@@ -57,8 +59,8 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
        spin_lock(&fi->lock);
        if (fi->local_int[cpu_addr] == NULL)
                rc = 3; /* not operational */
-       else if (atomic_read(fi->local_int[cpu_addr]->cpuflags)
-                & CPUSTAT_RUNNING) {
+       else if (!(atomic_read(fi->local_int[cpu_addr]->cpuflags)
+                 & CPUSTAT_STOPPED)) {
                *reg &= 0xffffffff00000000UL;
                rc = 1; /* status stored */
        } else {
@@ -251,7 +253,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
 
        spin_lock_bh(&li->lock);
        /* cpu must be in stopped state */
-       if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) {
+       if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
                rc = 1; /* incorrect state */
                *reg &= SIGP_STAT_INCORRECT_STATE;
                kfree(inti);
@@ -275,6 +277,38 @@ out_fi:
        return rc;
 }
 
+static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
+                               unsigned long *reg)
+{
+       int rc;
+       struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
+
+       if (cpu_addr >= KVM_MAX_VCPUS)
+               return 3; /* not operational */
+
+       spin_lock(&fi->lock);
+       if (fi->local_int[cpu_addr] == NULL)
+               rc = 3; /* not operational */
+       else {
+               if (atomic_read(fi->local_int[cpu_addr]->cpuflags)
+                   & CPUSTAT_RUNNING) {
+                       /* running */
+                       rc = 1;
+               } else {
+                       /* not running */
+                       *reg &= 0xffffffff00000000UL;
+                       *reg |= SIGP_STAT_NOT_RUNNING;
+                       rc = 0;
+               }
+       }
+       spin_unlock(&fi->lock);
+
+       VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x", cpu_addr,
+                  rc);
+
+       return rc;
+}
+
 int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
 {
        int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
@@ -331,6 +365,11 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
                rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
                                       &vcpu->arch.guest_gprs[r1]);
                break;
+       case SIGP_SENSE_RUNNING:
+               vcpu->stat.instruction_sigp_sense_running++;
+               rc = __sigp_sense_running(vcpu, cpu_addr,
+                                         &vcpu->arch.guest_gprs[r1]);
+               break;
        case SIGP_RESTART:
                vcpu->stat.instruction_sigp_restart++;
                /* user space must know about restart */
index 1766def5bc3fc7f4717904313c69b2a7879b6d86..a9a301866b3c1846f37792aa371620e2b3004415 100644 (file)
@@ -587,8 +587,13 @@ static void pfault_interrupt(unsigned int ext_int_code,
                } else {
                        /* Completion interrupt was faster than initial
                         * interrupt. Set pfault_wait to -1 so the initial
-                        * interrupt doesn't put the task to sleep. */
-                       tsk->thread.pfault_wait = -1;
+                        * interrupt doesn't put the task to sleep.
+                        * If the task is not running, ignore the completion
+                        * interrupt since it must be a leftover of a PFAULT
+                        * CANCEL operation which didn't remove all pending
+                        * completion interrupts. */
+                       if (tsk->state == TASK_RUNNING)
+                               tsk->thread.pfault_wait = -1;
                }
                put_task_struct(tsk);
        } else {
index 5b31a8e89823699fbe5f99ebf6eb8d34bac8cb46..a790cc657476320831f9753ad0fd2aff9264ca0a 100644 (file)
@@ -431,10 +431,6 @@ extern unsigned long *sparc_valid_addr_bitmap;
 #define kern_addr_valid(addr) \
        (test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))
 
-extern int io_remap_pfn_range(struct vm_area_struct *vma,
-                             unsigned long from, unsigned long pfn,
-                             unsigned long size, pgprot_t prot);
-
 /*
  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
  * its high 4 bits.  These macros/functions put it there or get it from there.
@@ -443,6 +439,22 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma,
 #define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)                   (pfn & 0x0fffffffUL)
 
+extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
+                          unsigned long, pgprot_t);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+                                    unsigned long from, unsigned long pfn,
+                                    unsigned long size, pgprot_t prot)
+{
+       unsigned long long offset, space, phys_base;
+
+       offset = ((unsigned long long) GET_PFN(pfn)) << PAGE_SHIFT;
+       space = GET_IOSPACE(pfn);
+       phys_base = offset | (space << 32ULL);
+
+       return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
+}
+
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
 ({                                                                       \
index adf89329af59a653f8694f05df291f2c91475506..38ebb2c601374a386192c061b50ea171c4f83373 100644 (file)
@@ -757,10 +757,6 @@ static inline bool kern_addr_valid(unsigned long addr)
 
 extern int page_in_phys_avail(unsigned long paddr);
 
-extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-                              unsigned long pfn,
-                              unsigned long size, pgprot_t prot);
-
 /*
  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
  * its high 4 bits.  These macros/functions put it there or get it from there.
@@ -769,6 +765,22 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
 #define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)                   (pfn & 0x0fffffffffffffffUL)
 
+extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
+                          unsigned long, pgprot_t);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+                                    unsigned long from, unsigned long pfn,
+                                    unsigned long size, pgprot_t prot)
+{
+       unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+       int space = GET_IOSPACE(pfn);
+       unsigned long phys_base;
+
+       phys_base = offset | (((unsigned long) space) << 32UL);
+
+       return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
+}
+
 #include <asm-generic/pgtable.h>
 
 /* We provide our own get_unmapped_area to cope with VA holes and
index e27f8ea8656e3e4b9b1c799a6d170cc9739e2cb2..0c218e4c0881fba70c1748e6a4c295e0db280652 100644 (file)
@@ -42,6 +42,9 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
 extern void fpload(unsigned long *fpregs, unsigned long *fsr);
 
 #else /* CONFIG_SPARC32 */
+
+#include <asm/trap_block.h>
+
 struct popc_3insn_patch_entry {
        unsigned int    addr;
        unsigned int    insns[3];
@@ -57,6 +60,10 @@ extern struct popc_6insn_patch_entry __popc_6insn_patch,
        __popc_6insn_patch_end;
 
 extern void __init per_cpu_patch(void);
+extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
+                                   struct sun4v_1insn_patch_entry *);
+extern void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
+                                   struct sun4v_2insn_patch_entry *);
 extern void __init sun4v_patch(void);
 extern void __init boot_cpu_id_too_large(int cpu);
 extern unsigned int dcache_parity_tl1_occurred;
index da0c6c70ccb2c0a783043c151bd82d3dc289d86a..e5519870c3d9ab43b516c5994568af974664d616 100644 (file)
@@ -17,6 +17,8 @@
 #include <asm/processor.h>
 #include <asm/spitfire.h>
 
+#include "entry.h"
+
 #ifdef CONFIG_SPARC64
 
 #include <linux/jump_label.h>
@@ -203,6 +205,29 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
 }
 
 #ifdef CONFIG_SPARC64
+static void do_patch_sections(const Elf_Ehdr *hdr,
+                             const Elf_Shdr *sechdrs)
+{
+       const Elf_Shdr *s, *sun4v_1insn = NULL, *sun4v_2insn = NULL;
+       char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+       for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
+               if (!strcmp(".sun4v_1insn_patch", secstrings + s->sh_name))
+                       sun4v_1insn = s;
+               if (!strcmp(".sun4v_2insn_patch", secstrings + s->sh_name))
+                       sun4v_2insn = s;
+       }
+
+       if (sun4v_1insn && tlb_type == hypervisor) {
+               void *p = (void *) sun4v_1insn->sh_addr;
+               sun4v_patch_1insn_range(p, p + sun4v_1insn->sh_size);
+       }
+       if (sun4v_2insn && tlb_type == hypervisor) {
+               void *p = (void *) sun4v_2insn->sh_addr;
+               sun4v_patch_2insn_range(p, p + sun4v_2insn->sh_size);
+       }
+}
+
 int module_finalize(const Elf_Ehdr *hdr,
                    const Elf_Shdr *sechdrs,
                    struct module *me)
@@ -210,6 +235,8 @@ int module_finalize(const Elf_Ehdr *hdr,
        /* make jump label nops */
        jump_label_apply_nops(me);
 
+       do_patch_sections(hdr, sechdrs);
+
        /* Cheetah's I-cache is fully coherent.  */
        if (tlb_type == spitfire) {
                unsigned long va;
index c965595aa7e968c8a28e0cfce8f8cd9158db3e0f..a854a1c240ffe1eff016a3324ecfccd1dd63ce4c 100644 (file)
@@ -234,40 +234,50 @@ void __init per_cpu_patch(void)
        }
 }
 
-void __init sun4v_patch(void)
+void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *start,
+                            struct sun4v_1insn_patch_entry *end)
 {
-       extern void sun4v_hvapi_init(void);
-       struct sun4v_1insn_patch_entry *p1;
-       struct sun4v_2insn_patch_entry *p2;
-
-       if (tlb_type != hypervisor)
-               return;
+       while (start < end) {
+               unsigned long addr = start->addr;
 
-       p1 = &__sun4v_1insn_patch;
-       while (p1 < &__sun4v_1insn_patch_end) {
-               unsigned long addr = p1->addr;
-
-               *(unsigned int *) (addr +  0) = p1->insn;
+               *(unsigned int *) (addr +  0) = start->insn;
                wmb();
                __asm__ __volatile__("flush     %0" : : "r" (addr +  0));
 
-               p1++;
+               start++;
        }
+}
 
-       p2 = &__sun4v_2insn_patch;
-       while (p2 < &__sun4v_2insn_patch_end) {
-               unsigned long addr = p2->addr;
+void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
+                            struct sun4v_2insn_patch_entry *end)
+{
+       while (start < end) {
+               unsigned long addr = start->addr;
 
-               *(unsigned int *) (addr +  0) = p2->insns[0];
+               *(unsigned int *) (addr +  0) = start->insns[0];
                wmb();
                __asm__ __volatile__("flush     %0" : : "r" (addr +  0));
 
-               *(unsigned int *) (addr +  4) = p2->insns[1];
+               *(unsigned int *) (addr +  4) = start->insns[1];
                wmb();
                __asm__ __volatile__("flush     %0" : : "r" (addr +  4));
 
-               p2++;
+               start++;
        }
+}
+
+void __init sun4v_patch(void)
+{
+       extern void sun4v_hvapi_init(void);
+
+       if (tlb_type != hypervisor)
+               return;
+
+       sun4v_patch_1insn_range(&__sun4v_1insn_patch,
+                               &__sun4v_1insn_patch_end);
+
+       sun4v_patch_2insn_range(&__sun4v_2insn_patch,
+                               &__sun4v_2insn_patch_end);
 
        sun4v_hvapi_init();
 }
index 2caa556db86dc44818521233c5ba7aad226ca186..023b8860dc9704330391b1db6a8eaf2ea117d32e 100644 (file)
@@ -822,21 +822,23 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-void do_signal32(sigset_t *oldset, struct pt_regs * regs,
-                int restart_syscall, unsigned long orig_i0)
+void do_signal32(sigset_t *oldset, struct pt_regs * regs)
 {
        struct k_sigaction ka;
+       unsigned long orig_i0;
+       int restart_syscall;
        siginfo_t info;
        int signr;
        
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 
-       /* If the debugger messes with the program counter, it clears
-        * the "in syscall" bit, directing us to not perform a syscall
-        * restart.
-        */
-       if (restart_syscall && !pt_regs_is_syscall(regs))
-               restart_syscall = 0;
+       restart_syscall = 0;
+       orig_i0 = 0;
+       if (pt_regs_is_syscall(regs) &&
+           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
+               restart_syscall = 1;
+               orig_i0 = regs->u_regs[UREG_G6];
+       }
 
        if (signr > 0) {
                if (restart_syscall)
index 8ce247ac04cc0d905abd7d7e1d5de20073ce654a..d54c6e53aba00323fda9f01c95aae0f001352fb9 100644 (file)
@@ -519,10 +519,26 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
        siginfo_t info;
        int signr;
 
+       /* It's a lot of work and synchronization to add a new ptrace
+        * register for GDB to save and restore in order to get
+        * orig_i0 correct for syscall restarts when debugging.
+        *
+        * Although it should be the case that most of the global
+        * registers are volatile across a system call, glibc already
+        * depends upon that fact that we preserve them.  So we can't
+        * just use any global register to save away the orig_i0 value.
+        *
+        * In particular %g2, %g3, %g4, and %g5 are all assumed to be
+        * preserved across a system call trap by various pieces of
+        * code in glibc.
+        *
+        * %g7 is used as the "thread register".   %g6 is not used in
+        * any fixed manner.  %g6 is used as a scratch register and
+        * a compiler temporary, but it's value is never used across
+        * a system call.  Therefore %g6 is usable for orig_i0 storage.
+        */
        if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
-               restart_syscall = 1;
-       else
-               restart_syscall = 0;
+               regs->u_regs[UREG_G6] = orig_i0;
 
        if (test_thread_flag(TIF_RESTORE_SIGMASK))
                oldset = &current->saved_sigmask;
@@ -535,8 +551,12 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
         * the software "in syscall" bit, directing us to not perform
         * a syscall restart.
         */
-       if (restart_syscall && !pt_regs_is_syscall(regs))
-               restart_syscall = 0;
+       restart_syscall = 0;
+       if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) {
+               restart_syscall = 1;
+               orig_i0 = regs->u_regs[UREG_G6];
+       }
+
 
        if (signr > 0) {
                if (restart_syscall)
index a2b81598d90562695abefa70b8c66ea11832341c..f0836cd0e2f243ffb3c1df37ff02cc31488850b7 100644 (file)
@@ -529,11 +529,27 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
        siginfo_t info;
        int signr;
        
+       /* It's a lot of work and synchronization to add a new ptrace
+        * register for GDB to save and restore in order to get
+        * orig_i0 correct for syscall restarts when debugging.
+        *
+        * Although it should be the case that most of the global
+        * registers are volatile across a system call, glibc already
+        * depends upon that fact that we preserve them.  So we can't
+        * just use any global register to save away the orig_i0 value.
+        *
+        * In particular %g2, %g3, %g4, and %g5 are all assumed to be
+        * preserved across a system call trap by various pieces of
+        * code in glibc.
+        *
+        * %g7 is used as the "thread register".   %g6 is not used in
+        * any fixed manner.  %g6 is used as a scratch register and
+        * a compiler temporary, but it's value is never used across
+        * a system call.  Therefore %g6 is usable for orig_i0 storage.
+        */
        if (pt_regs_is_syscall(regs) &&
-           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
-               restart_syscall = 1;
-       } else
-               restart_syscall = 0;
+           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
+               regs->u_regs[UREG_G6] = orig_i0;
 
        if (current_thread_info()->status & TS_RESTORE_SIGMASK)
                oldset = &current->saved_sigmask;
@@ -542,22 +558,20 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 
 #ifdef CONFIG_COMPAT
        if (test_thread_flag(TIF_32BIT)) {
-               extern void do_signal32(sigset_t *, struct pt_regs *,
-                                       int restart_syscall,
-                                       unsigned long orig_i0);
-               do_signal32(oldset, regs, restart_syscall, orig_i0);
+               extern void do_signal32(sigset_t *, struct pt_regs *);
+               do_signal32(oldset, regs);
                return;
        }
 #endif 
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 
-       /* If the debugger messes with the program counter, it clears
-        * the software "in syscall" bit, directing us to not perform
-        * a syscall restart.
-        */
-       if (restart_syscall && !pt_regs_is_syscall(regs))
-               restart_syscall = 0;
+       restart_syscall = 0;
+       if (pt_regs_is_syscall(regs) &&
+           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
+               restart_syscall = 1;
+               orig_i0 = regs->u_regs[UREG_G6];
+       }
 
        if (signr > 0) {
                if (restart_syscall)
index e7dc508c38eb47dd1f77bee9a125687287c2856a..b19570d41a39eab11e7b60d2146aec678d0c8621 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/types.h>
 #include <linux/thread_info.h>
 #include <linux/uaccess.h>
+#include <linux/errno.h>
 
 #include <asm/sigcontext.h>
 #include <asm/fpumacro.h>
index e3cda21b5ee994200b7d09e7e14c33704363e67c..301421c11291c6a0c8ef01a1af18da17453c9d35 100644 (file)
@@ -8,7 +8,6 @@ obj-$(CONFIG_SPARC64)   += ultra.o tlb.o tsb.o gup.o
 obj-y                   += fault_$(BITS).o
 obj-y                   += init_$(BITS).o
 obj-$(CONFIG_SPARC32)   += loadmmu.o
-obj-y                   += generic_$(BITS).o
 obj-$(CONFIG_SPARC32)   += extable.o btfixup.o srmmu.o iommu.o io-unit.o
 obj-$(CONFIG_SPARC32)   += hypersparc.o viking.o tsunami.o swift.o
 obj-$(CONFIG_SPARC_LEON)+= leon_mm.o
diff --git a/arch/sparc/mm/generic_32.c b/arch/sparc/mm/generic_32.c
deleted file mode 100644 (file)
index 6ca39a6..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * generic.c: Generic Sparc mm routines that are not dependent upon
- *            MMU type but are Sparc specific.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/pagemap.h>
-#include <linux/export.h>
-
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-
-/* Remap IO memory, the same way as remap_pfn_range(), but use
- * the obio memory space.
- *
- * They use a pgprot that sets PAGE_IO and does not check the
- * mem_map table as this is independent of normal memory.
- */
-static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, unsigned long address, unsigned long size,
-       unsigned long offset, pgprot_t prot, int space)
-{
-       unsigned long end;
-
-       address &= ~PMD_MASK;
-       end = address + size;
-       if (end > PMD_SIZE)
-               end = PMD_SIZE;
-       do {
-               set_pte_at(mm, address, pte, mk_pte_io(offset, prot, space));
-               address += PAGE_SIZE;
-               offset += PAGE_SIZE;
-               pte++;
-       } while (address < end);
-}
-
-static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
-       unsigned long offset, pgprot_t prot, int space)
-{
-       unsigned long end;
-
-       address &= ~PGDIR_MASK;
-       end = address + size;
-       if (end > PGDIR_SIZE)
-               end = PGDIR_SIZE;
-       offset -= address;
-       do {
-               pte_t *pte = pte_alloc_map(mm, NULL, pmd, address);
-               if (!pte)
-                       return -ENOMEM;
-               io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space);
-               address = (address + PMD_SIZE) & PMD_MASK;
-               pmd++;
-       } while (address < end);
-       return 0;
-}
-
-int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-                      unsigned long pfn, unsigned long size, pgprot_t prot)
-{
-       int error = 0;
-       pgd_t * dir;
-       unsigned long beg = from;
-       unsigned long end = from + size;
-       struct mm_struct *mm = vma->vm_mm;
-       int space = GET_IOSPACE(pfn);
-       unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
-
-       /* See comment in mm/memory.c remap_pfn_range */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
-       vma->vm_pgoff = (offset >> PAGE_SHIFT) |
-               ((unsigned long)space << 28UL);
-
-       offset -= from;
-       dir = pgd_offset(mm, from);
-       flush_cache_range(vma, beg, end);
-
-       while (from < end) {
-               pmd_t *pmd = pmd_alloc(mm, dir, from);
-               error = -ENOMEM;
-               if (!pmd)
-                       break;
-               error = io_remap_pmd_range(mm, pmd, from, end - from, offset + from, prot, space);
-               if (error)
-                       break;
-               from = (from + PGDIR_SIZE) & PGDIR_MASK;
-               dir++;
-       }
-
-       flush_tlb_range(vma, beg, end);
-       return error;
-}
-EXPORT_SYMBOL(io_remap_pfn_range);
diff --git a/arch/sparc/mm/generic_64.c b/arch/sparc/mm/generic_64.c
deleted file mode 100644 (file)
index 9b357dd..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * generic.c: Generic Sparc mm routines that are not dependent upon
- *            MMU type but are Sparc specific.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/export.h>
-#include <linux/pagemap.h>
-
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/tlbflush.h>
-
-/* Remap IO memory, the same way as remap_pfn_range(), but use
- * the obio memory space.
- *
- * They use a pgprot that sets PAGE_IO and does not check the
- * mem_map table as this is independent of normal memory.
- */
-static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte,
-                                     unsigned long address,
-                                     unsigned long size,
-                                     unsigned long offset, pgprot_t prot,
-                                     int space)
-{
-       unsigned long end;
-
-       /* clear hack bit that was used as a write_combine side-effect flag */
-       offset &= ~0x1UL;
-       address &= ~PMD_MASK;
-       end = address + size;
-       if (end > PMD_SIZE)
-               end = PMD_SIZE;
-       do {
-               pte_t entry;
-               unsigned long curend = address + PAGE_SIZE;
-               
-               entry = mk_pte_io(offset, prot, space, PAGE_SIZE);
-               if (!(address & 0xffff)) {
-                       if (PAGE_SIZE < (4 * 1024 * 1024) &&
-                           !(address & 0x3fffff) &&
-                           !(offset & 0x3ffffe) &&
-                           end >= address + 0x400000) {
-                               entry = mk_pte_io(offset, prot, space,
-                                                 4 * 1024 * 1024);
-                               curend = address + 0x400000;
-                               offset += 0x400000;
-                       } else if (PAGE_SIZE < (512 * 1024) &&
-                                  !(address & 0x7ffff) &&
-                                  !(offset & 0x7fffe) &&
-                                  end >= address + 0x80000) {
-                               entry = mk_pte_io(offset, prot, space,
-                                                 512 * 1024 * 1024);
-                               curend = address + 0x80000;
-                               offset += 0x80000;
-                       } else if (PAGE_SIZE < (64 * 1024) &&
-                                  !(offset & 0xfffe) &&
-                                  end >= address + 0x10000) {
-                               entry = mk_pte_io(offset, prot, space,
-                                                 64 * 1024);
-                               curend = address + 0x10000;
-                               offset += 0x10000;
-                       } else
-                               offset += PAGE_SIZE;
-               } else
-                       offset += PAGE_SIZE;
-
-               if (pte_write(entry))
-                       entry = pte_mkdirty(entry);
-               do {
-                       BUG_ON(!pte_none(*pte));
-                       set_pte_at(mm, address, pte, entry);
-                       address += PAGE_SIZE;
-                       pte_val(entry) += PAGE_SIZE;
-                       pte++;
-               } while (address < curend);
-       } while (address < end);
-}
-
-static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
-       unsigned long offset, pgprot_t prot, int space)
-{
-       unsigned long end;
-
-       address &= ~PGDIR_MASK;
-       end = address + size;
-       if (end > PGDIR_SIZE)
-               end = PGDIR_SIZE;
-       offset -= address;
-       do {
-               pte_t *pte = pte_alloc_map(mm, NULL, pmd, address);
-               if (!pte)
-                       return -ENOMEM;
-               io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space);
-               pte_unmap(pte);
-               address = (address + PMD_SIZE) & PMD_MASK;
-               pmd++;
-       } while (address < end);
-       return 0;
-}
-
-static inline int io_remap_pud_range(struct mm_struct *mm, pud_t * pud, unsigned long address, unsigned long size,
-       unsigned long offset, pgprot_t prot, int space)
-{
-       unsigned long end;
-
-       address &= ~PUD_MASK;
-       end = address + size;
-       if (end > PUD_SIZE)
-               end = PUD_SIZE;
-       offset -= address;
-       do {
-               pmd_t *pmd = pmd_alloc(mm, pud, address);
-               if (!pud)
-                       return -ENOMEM;
-               io_remap_pmd_range(mm, pmd, address, end - address, address + offset, prot, space);
-               address = (address + PUD_SIZE) & PUD_MASK;
-               pud++;
-       } while (address < end);
-       return 0;
-}
-
-int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-               unsigned long pfn, unsigned long size, pgprot_t prot)
-{
-       int error = 0;
-       pgd_t * dir;
-       unsigned long beg = from;
-       unsigned long end = from + size;
-       struct mm_struct *mm = vma->vm_mm;
-       int space = GET_IOSPACE(pfn);
-       unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
-       unsigned long phys_base;
-
-       phys_base = offset | (((unsigned long) space) << 32UL);
-
-       /* See comment in mm/memory.c remap_pfn_range */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
-       vma->vm_pgoff = phys_base >> PAGE_SHIFT;
-
-       offset -= from;
-       dir = pgd_offset(mm, from);
-       flush_cache_range(vma, beg, end);
-
-       while (from < end) {
-               pud_t *pud = pud_alloc(mm, dir, from);
-               error = -ENOMEM;
-               if (!pud)
-                       break;
-               error = io_remap_pud_range(mm, pud, from, end - from, offset + from, prot, space);
-               if (error)
-                       break;
-               from = (from + PGDIR_SIZE) & PGDIR_MASK;
-               dir++;
-       }
-
-       flush_tlb_range(vma, beg, end);
-       return error;
-}
-EXPORT_SYMBOL(io_remap_pfn_range);
index e57dcce9bfda4da6ea6be362a542bf891289f0c0..942ed6174f1d073e565d52e5dc074c7e84d3b533 100644 (file)
@@ -237,13 +237,13 @@ menu "PKUnity NetBook-0916 Features"
 
 config I2C_BATTERY_BQ27200
        tristate "I2C Battery BQ27200 Support"
-       select PUV3_I2C
+       select I2C_PUV3
        select POWER_SUPPLY
        select BATTERY_BQ27x00
 
 config I2C_EEPROM_AT24
        tristate "I2C EEPROMs AT24 support"
-       select PUV3_I2C
+       select I2C_PUV3
        select MISC_DEVICES
        select EEPROM_AT24
 
index ae2ec334c3c61473ffa6b7b5cf8695c8d64c322b..1a36262398435ff9f9f224cab74da1a3d2bb0233 100644 (file)
@@ -44,18 +44,4 @@ config DEBUG_OCD
          Say Y here if you want the debug print routines to direct their
          output to the UniCore On-Chip-Debugger channel using CP #1.
 
-config DEBUG_OCD_BREAKPOINT
-       bool "Breakpoint support via On-Chip-Debugger"
-       depends on DEBUG_OCD
-
-config DEBUG_UART
-       int "Kernel low-level debugging messages via serial port"
-       depends on DEBUG_LL
-       range 0 1
-       default "0"
-       help
-         Choice for UART for kernel low-level using PKUnity UARTS,
-         should be between zero and one. The port must have been
-         initialised by the boot-loader before use.
-
 endmenu
index b0954a2d23cfaf5b4db0bbe1b6e95493d75ebc03..950a9afa38f8632239df166ac21ffe094229217e 100644 (file)
@@ -10,8 +10,8 @@
 # Copyright (C) 2001~2010 GUAN Xue-tao
 #
 
-EXTRA_CFLAGS   := -fpic -fno-builtin
-EXTRA_AFLAGS   := -Wa,-march=all
+ccflags-y      := -fpic -fno-builtin
+asflags-y      := -Wa,-march=all
 
 OBJS           := misc.o
 
index 1628a63289946218c12cebed99246c87087e8a18..401f597bc38cfcdf102ff6188f8bd3c27f46dde5 100644 (file)
 #ifndef __UNICORE_BITOPS_H__
 #define __UNICORE_BITOPS_H__
 
-#define find_next_bit          __uc32_find_next_bit
-#define find_next_zero_bit     __uc32_find_next_zero_bit
-
-#define find_first_bit         __uc32_find_first_bit
-#define find_first_zero_bit    __uc32_find_first_zero_bit
-
 #define _ASM_GENERIC_BITOPS_FLS_H_
 #define _ASM_GENERIC_BITOPS___FLS_H_
 #define _ASM_GENERIC_BITOPS_FFS_H_
@@ -44,4 +38,10 @@ static inline int fls(int x)
 
 #include <asm-generic/bitops.h>
 
+/* following definitions: to avoid using codes in lib/find_*.c */
+#define find_next_bit          find_next_bit
+#define find_next_zero_bit     find_next_zero_bit
+#define find_first_bit         find_first_bit
+#define find_first_zero_bit    find_first_zero_bit
+
 #endif /* __UNICORE_BITOPS_H__ */
index e11cb07865782c81b82e4dd90d1977b8f4495245..f0d780a51f9b5dec74a5310fe0f1fd2c4fdc7b28 100644 (file)
@@ -53,7 +53,6 @@ struct thread_struct {
 #define start_thread(regs, pc, sp)                                     \
 ({                                                                     \
        unsigned long *stack = (unsigned long *)sp;                     \
-       set_fs(USER_DS);                                                \
        memset(regs->uregs, 0, sizeof(regs->uregs));                    \
        regs->UCreg_asr = USER_MODE;                                    \
        regs->UCreg_pc = pc & ~1;       /* pc */                        \
index a8970809428a65985873e42ffd417782c0f47ae9..d98bd812cae1ea17efcb314a1cccee9639636b37 100644 (file)
@@ -24,8 +24,8 @@
 
 #include "ksyms.h"
 
-EXPORT_SYMBOL(__uc32_find_next_zero_bit);
-EXPORT_SYMBOL(__uc32_find_next_bit);
+EXPORT_SYMBOL(find_next_zero_bit);
+EXPORT_SYMBOL(find_next_bit);
 
 EXPORT_SYMBOL(__backtrace);
 
index c360ce905d8b7bcb0d9b84b796089987c5cf967b..c77746247d3698856f26e27531c7454382178a6e 100644 (file)
@@ -17,7 +17,7 @@
  * Purpose  : Find a 'zero' bit
  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  */
-__uc32_find_first_zero_bit:
+ENTRY(find_first_zero_bit)
                cxor.a  r1, #0
                beq     3f
                mov     r2, #0
@@ -29,13 +29,14 @@ __uc32_find_first_zero_bit:
                bub     1b
 3:             mov     r0, r1                  @ no free bits
                mov     pc, lr
+ENDPROC(find_first_zero_bit)
 
 /*
  * Purpose  : Find next 'zero' bit
  * Prototype: int find_next_zero_bit
  *             (void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(__uc32_find_next_zero_bit)
+ENTRY(find_next_zero_bit)
                cxor.a  r1, #0
                beq     3b
                and.a   ip, r2, #7
@@ -47,14 +48,14 @@ ENTRY(__uc32_find_next_zero_bit)
                or      r2, r2, #7              @ if zero, then no bits here
                add     r2, r2, #1              @ align bit pointer
                b       2b                      @ loop for next bit
-ENDPROC(__uc32_find_next_zero_bit)
+ENDPROC(find_next_zero_bit)
 
 /*
  * Purpose  : Find a 'one' bit
  * Prototype: int find_first_bit
  *             (const unsigned long *addr, unsigned int maxbit);
  */
-__uc32_find_first_bit:
+ENTRY(find_first_bit)
                cxor.a  r1, #0
                beq     3f
                mov     r2, #0
@@ -66,13 +67,14 @@ __uc32_find_first_bit:
                bub     1b
 3:             mov     r0, r1                  @ no free bits
                mov     pc, lr
+ENDPROC(find_first_bit)
 
 /*
  * Purpose  : Find next 'one' bit
  * Prototype: int find_next_zero_bit
  *             (void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(__uc32_find_next_bit)
+ENTRY(find_next_bit)
                cxor.a  r1, #0
                beq     3b
                and.a   ip, r2, #7
@@ -83,7 +85,7 @@ ENTRY(__uc32_find_next_bit)
                or      r2, r2, #7              @ if zero, then no bits here
                add     r2, r2, #1              @ align bit pointer
                b       2b                      @ loop for next bit
-ENDPROC(__uc32_find_next_bit)
+ENDPROC(find_next_bit)
 
 /*
  * One or more bits in the LSB of r3 are assumed to be set.
index 9b7273cb21937e8a884a08b45b3024af1bf3cfbc..1a6c09af048fbd587613c750502677d7cbb1c052 100644 (file)
@@ -49,6 +49,7 @@ extern unsigned int apic_verbosity;
 extern int local_apic_timer_c2_ok;
 
 extern int disable_apic;
+extern unsigned int lapic_timer_frequency;
 
 #ifdef CONFIG_SMP
 extern void __inquire_remote_apic(int apicid);
index 72a8b52e7dfd0de3fa4271284fdd4a76da7fb31b..a01e7ec7d2377aaede271b6ad4ddd546ef5238a5 100644 (file)
@@ -17,7 +17,7 @@
 #define NMI_REASON_CLEAR_IOCHK 0x08
 #define NMI_REASON_CLEAR_MASK  0x0f
 
-static inline unsigned char get_nmi_reason(void)
+static inline unsigned char default_get_nmi_reason(void)
 {
        return inb(NMI_REASON_PORT);
 }
index c9321f34e55b3fa2cdb9fd4afeaa332dac345add..0e8ae57d3656c4576498b545826a5880214fe9e5 100644 (file)
@@ -201,7 +201,10 @@ int mce_notify_irq(void);
 void mce_notify_process(void);
 
 DECLARE_PER_CPU(struct mce, injectm);
-extern struct file_operations mce_chrdev_ops;
+
+extern void register_mce_write_callback(ssize_t (*)(struct file *filp,
+                                   const char __user *ubuf,
+                                   size_t usize, loff_t *off));
 
 /*
  * Exception handler
index 719f00b28ff5358caf87d736ed5b4100dafdce9e..e6283129c821014eba1afcbbb1bdd042b6b73e04 100644 (file)
@@ -44,6 +44,13 @@ enum mrst_timer_options {
 
 extern enum mrst_timer_options mrst_timer_options;
 
+/*
+ * Penwell uses spread spectrum clock, so the freq number is not exactly
+ * the same as reported by MSR based on SDM.
+ */
+#define PENWELL_FSB_FREQ_83SKU         83200
+#define PENWELL_FSB_FREQ_100SKU        99840
+
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX   8
 
index d3d859035af9e1968d0ad9d4a39000331c27c8f1..1971e652d24be5fc0674633c1edb3717645306e7 100644 (file)
@@ -152,6 +152,7 @@ struct x86_cpuinit_ops {
 /**
  * struct x86_platform_ops - platform specific runtime functions
  * @calibrate_tsc:             calibrate TSC
+ * @wallclock_init:            init the wallclock device
  * @get_wallclock:             get time from HW clock like RTC etc.
  * @set_wallclock:             set time back to HW clock
  * @is_untracked_pat_range     exclude from PAT logic
@@ -160,11 +161,13 @@ struct x86_cpuinit_ops {
  */
 struct x86_platform_ops {
        unsigned long (*calibrate_tsc)(void);
+       void (*wallclock_init)(void);
        unsigned long (*get_wallclock)(void);
        int (*set_wallclock)(unsigned long nowtime);
        void (*iommu_shutdown)(void);
        bool (*is_untracked_pat_range)(u64 start, u64 end);
        void (*nmi_init)(void);
+       unsigned char (*get_nmi_reason)(void);
        int (*i8042_detect)(void);
 };
 
index c63822816249e8c41fa47643d3204bde8a758a42..1f84794f0759327c387d602cddccb3d479188f92 100644 (file)
@@ -738,5 +738,5 @@ void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n)
 
        atomic_set(&stop_machine_first, 1);
        wrote_text = 0;
-       __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
+       __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask);
 }
index a2fd72e0ab35bbff6703836f82540a0f71588e85..f98d84caf94cfdc43cedda4cb411ebea5213e4b7 100644 (file)
@@ -186,7 +186,7 @@ static struct resource lapic_resource = {
        .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
 };
 
-static unsigned int calibration_result;
+unsigned int lapic_timer_frequency = 0;
 
 static void apic_pm_activate(void);
 
@@ -454,7 +454,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
        case CLOCK_EVT_MODE_ONESHOT:
-               __setup_APIC_LVTT(calibration_result,
+               __setup_APIC_LVTT(lapic_timer_frequency,
                                  mode != CLOCK_EVT_MODE_PERIODIC, 1);
                break;
        case CLOCK_EVT_MODE_UNUSED:
@@ -638,6 +638,25 @@ static int __init calibrate_APIC_clock(void)
        long delta, deltatsc;
        int pm_referenced = 0;
 
+       /**
+        * check if lapic timer has already been calibrated by platform
+        * specific routine, such as tsc calibration code. if so, we just fill
+        * in the clockevent structure and return.
+        */
+
+       if (lapic_timer_frequency) {
+               apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n",
+                               lapic_timer_frequency);
+               lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
+                                       TICK_NSEC, lapic_clockevent.shift);
+               lapic_clockevent.max_delta_ns =
+                       clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
+               lapic_clockevent.min_delta_ns =
+                       clockevent_delta2ns(0xF, &lapic_clockevent);
+               lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
+               return 0;
+       }
+
        local_irq_disable();
 
        /* Replace the global interrupt handler */
@@ -679,12 +698,12 @@ static int __init calibrate_APIC_clock(void)
        lapic_clockevent.min_delta_ns =
                clockevent_delta2ns(0xF, &lapic_clockevent);
 
-       calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
+       lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
 
        apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
        apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);
        apic_printk(APIC_VERBOSE, "..... calibration result: %u\n",
-                   calibration_result);
+                   lapic_timer_frequency);
 
        if (cpu_has_tsc) {
                apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
@@ -695,13 +714,13 @@ static int __init calibrate_APIC_clock(void)
 
        apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
                    "%u.%04u MHz.\n",
-                   calibration_result / (1000000 / HZ),
-                   calibration_result % (1000000 / HZ));
+                   lapic_timer_frequency / (1000000 / HZ),
+                   lapic_timer_frequency % (1000000 / HZ));
 
        /*
         * Do a sanity check on the APIC calibration result
         */
-       if (calibration_result < (1000000 / HZ)) {
+       if (lapic_timer_frequency < (1000000 / HZ)) {
                local_irq_enable();
                pr_warning("APIC frequency too slow, disabling apic timer\n");
                return -1;
index 3c31fa98af6dcb23a9298fae4c0ea29495167d0f..6d939d7847e293901538cfe32ae1b95d1d82551a 100644 (file)
@@ -193,10 +193,8 @@ int __init arch_early_irq_init(void)
        struct irq_cfg *cfg;
        int count, node, i;
 
-       if (!legacy_pic->nr_legacy_irqs) {
-               nr_irqs_gsi = 0;
+       if (!legacy_pic->nr_legacy_irqs)
                io_apic_irqs = ~0UL;
-       }
 
        for (i = 0; i < nr_ioapics; i++) {
                ioapics[i].saved_registers =
@@ -1696,6 +1694,7 @@ __apicdebuginit(void) print_IO_APICs(void)
        int ioapic_idx;
        struct irq_cfg *cfg;
        unsigned int irq;
+       struct irq_chip *chip;
 
        printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
        for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
@@ -1716,6 +1715,10 @@ __apicdebuginit(void) print_IO_APICs(void)
        for_each_active_irq(irq) {
                struct irq_pin_list *entry;
 
+               chip = irq_get_chip(irq);
+               if (chip != &ioapic_chip)
+                       continue;
+
                cfg = irq_get_chip_data(irq);
                if (!cfg)
                        continue;
index 6199232161cffa181d6cf80605adb38dfbb51a61..319882ef848d3cd43c0a4dcfa41ea14cd09502ab 100644 (file)
@@ -208,7 +208,7 @@ static int inject_init(void)
        if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL))
                return -ENOMEM;
        printk(KERN_INFO "Machine check injector initialized\n");
-       mce_chrdev_ops.write = mce_write;
+       register_mce_write_callback(mce_write);
        register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0,
                                "mce_notify");
        return 0;
index 362056aefeb474c86b165c4f9c77d213b40fdbfa..2af127d4c3d1dc2ebdab3e0e2ff95d2d07595a46 100644 (file)
@@ -1634,16 +1634,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd,
        }
 }
 
-/* Modified in mce-inject.c, so not static or const */
-struct file_operations mce_chrdev_ops = {
+static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf,
+                           size_t usize, loff_t *off);
+
+void register_mce_write_callback(ssize_t (*fn)(struct file *filp,
+                            const char __user *ubuf,
+                            size_t usize, loff_t *off))
+{
+       mce_write = fn;
+}
+EXPORT_SYMBOL_GPL(register_mce_write_callback);
+
+ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
+                        size_t usize, loff_t *off)
+{
+       if (mce_write)
+               return mce_write(filp, ubuf, usize, off);
+       else
+               return -EINVAL;
+}
+
+static const struct file_operations mce_chrdev_ops = {
        .open                   = mce_chrdev_open,
        .release                = mce_chrdev_release,
        .read                   = mce_chrdev_read,
+       .write                  = mce_chrdev_write,
        .poll                   = mce_chrdev_poll,
        .unlocked_ioctl         = mce_chrdev_ioctl,
        .llseek                 = no_llseek,
 };
-EXPORT_SYMBOL_GPL(mce_chrdev_ops);
 
 static struct miscdevice mce_chrdev_device = {
        MISC_MCELOG_MINOR,
index c1a0188e29aef61d22706c8d0f2b99f843cf8fc7..44842d756b29fa9b2705fb8c57189fe5d28b5732 100644 (file)
@@ -74,9 +74,10 @@ static cycle_t kvm_clock_read(void)
        struct pvclock_vcpu_time_info *src;
        cycle_t ret;
 
-       src = &get_cpu_var(hv_clock);
+       preempt_disable_notrace();
+       src = &__get_cpu_var(hv_clock);
        ret = pvclock_clocksource_read(src);
-       put_cpu_var(hv_clock);
+       preempt_enable_notrace();
        return ret;
 }
 
index b9c8628974af3ae4eeb7cc73891140618df589b2..e88f37b58dddeeaecfb8951649db799986b7e247 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/traps.h>
 #include <asm/mach_traps.h>
 #include <asm/nmi.h>
+#include <asm/x86_init.h>
 
 #define NMI_MAX_NAMELEN        16
 struct nmiaction {
@@ -348,7 +349,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
 
        /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */
        raw_spin_lock(&nmi_reason_lock);
-       reason = get_nmi_reason();
+       reason = x86_platform.get_nmi_reason();
 
        if (reason & NMI_REASON_MASK) {
                if (reason & NMI_REASON_SERR)
index afaf38447ef5fc42c53e78168492fa9eb89a032b..cf0ef986cb6dff51348c17c691491f6f48c61a60 100644 (file)
@@ -1045,6 +1045,8 @@ void __init setup_arch(char **cmdline_p)
 
        x86_init.timers.wallclock_init();
 
+       x86_platform.wallclock_init();
+
        mcheck_init();
 
        arch_init_ideal_nops();
index 6f164bd5e14d167d417b2f86e5fc8580047ed371..c1d6cd549397ad54dbcb32526c9170e1f590a759 100644 (file)
 #include <asm/pat.h>
 #include <asm/tsc.h>
 #include <asm/iommu.h>
+#include <asm/mach_traps.h>
 
 void __cpuinit x86_init_noop(void) { }
 void __init x86_init_uint_noop(unsigned int unused) { }
 void __init x86_init_pgd_noop(pgd_t *unused) { }
 int __init iommu_init_noop(void) { return 0; }
 void iommu_shutdown_noop(void) { }
+void wallclock_init_noop(void) { }
 
 /*
  * The platform setup functions are preset with the default functions
@@ -97,11 +99,13 @@ static int default_i8042_detect(void) { return 1; };
 
 struct x86_platform_ops x86_platform = {
        .calibrate_tsc                  = native_calibrate_tsc,
+       .wallclock_init                 = wallclock_init_noop,
        .get_wallclock                  = mach_get_cmos_time,
        .set_wallclock                  = mach_set_rtc_mmss,
        .iommu_shutdown                 = iommu_shutdown_noop,
        .is_untracked_pat_range         = is_ISA_range,
        .nmi_init                       = default_nmi_init,
+       .get_nmi_reason                 = default_get_nmi_reason,
        .i8042_detect                   = default_i8042_detect
 };
 
index a0d6bd9ad442f1746bfa66eaabe86641470b7d0f..579a0b51696ac560b1768ae445bb8f2084172f8c 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/mce.h>
 #include <asm/i387.h>
 #include <asm/xcr.h>
+#include <asm/perf_event.h>
 
 #include "trace.h"
 
@@ -118,7 +119,7 @@ module_param(ple_gap, int, S_IRUGO);
 static int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW;
 module_param(ple_window, int, S_IRUGO);
 
-#define NR_AUTOLOAD_MSRS 1
+#define NR_AUTOLOAD_MSRS 8
 #define VMCS02_POOL_SIZE 1
 
 struct vmcs {
@@ -622,6 +623,7 @@ static unsigned long *vmx_msr_bitmap_legacy;
 static unsigned long *vmx_msr_bitmap_longmode;
 
 static bool cpu_has_load_ia32_efer;
+static bool cpu_has_load_perf_global_ctrl;
 
 static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS);
 static DEFINE_SPINLOCK(vmx_vpid_lock);
@@ -1191,15 +1193,34 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
        vmcs_write32(EXCEPTION_BITMAP, eb);
 }
 
+static void clear_atomic_switch_msr_special(unsigned long entry,
+               unsigned long exit)
+{
+       vmcs_clear_bits(VM_ENTRY_CONTROLS, entry);
+       vmcs_clear_bits(VM_EXIT_CONTROLS, exit);
+}
+
 static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
 {
        unsigned i;
        struct msr_autoload *m = &vmx->msr_autoload;
 
-       if (msr == MSR_EFER && cpu_has_load_ia32_efer) {
-               vmcs_clear_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER);
-               vmcs_clear_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER);
-               return;
+       switch (msr) {
+       case MSR_EFER:
+               if (cpu_has_load_ia32_efer) {
+                       clear_atomic_switch_msr_special(VM_ENTRY_LOAD_IA32_EFER,
+                                       VM_EXIT_LOAD_IA32_EFER);
+                       return;
+               }
+               break;
+       case MSR_CORE_PERF_GLOBAL_CTRL:
+               if (cpu_has_load_perf_global_ctrl) {
+                       clear_atomic_switch_msr_special(
+                                       VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
+                                       VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
+                       return;
+               }
+               break;
        }
 
        for (i = 0; i < m->nr; ++i)
@@ -1215,25 +1236,55 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
        vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr);
 }
 
+static void add_atomic_switch_msr_special(unsigned long entry,
+               unsigned long exit, unsigned long guest_val_vmcs,
+               unsigned long host_val_vmcs, u64 guest_val, u64 host_val)
+{
+       vmcs_write64(guest_val_vmcs, guest_val);
+       vmcs_write64(host_val_vmcs, host_val);
+       vmcs_set_bits(VM_ENTRY_CONTROLS, entry);
+       vmcs_set_bits(VM_EXIT_CONTROLS, exit);
+}
+
 static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,
                                  u64 guest_val, u64 host_val)
 {
        unsigned i;
        struct msr_autoload *m = &vmx->msr_autoload;
 
-       if (msr == MSR_EFER && cpu_has_load_ia32_efer) {
-               vmcs_write64(GUEST_IA32_EFER, guest_val);
-               vmcs_write64(HOST_IA32_EFER, host_val);
-               vmcs_set_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER);
-               vmcs_set_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER);
-               return;
+       switch (msr) {
+       case MSR_EFER:
+               if (cpu_has_load_ia32_efer) {
+                       add_atomic_switch_msr_special(VM_ENTRY_LOAD_IA32_EFER,
+                                       VM_EXIT_LOAD_IA32_EFER,
+                                       GUEST_IA32_EFER,
+                                       HOST_IA32_EFER,
+                                       guest_val, host_val);
+                       return;
+               }
+               break;
+       case MSR_CORE_PERF_GLOBAL_CTRL:
+               if (cpu_has_load_perf_global_ctrl) {
+                       add_atomic_switch_msr_special(
+                                       VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
+                                       VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL,
+                                       GUEST_IA32_PERF_GLOBAL_CTRL,
+                                       HOST_IA32_PERF_GLOBAL_CTRL,
+                                       guest_val, host_val);
+                       return;
+               }
+               break;
        }
 
        for (i = 0; i < m->nr; ++i)
                if (m->guest[i].index == msr)
                        break;
 
-       if (i == m->nr) {
+       if (i == NR_AUTOLOAD_MSRS) {
+               printk_once(KERN_WARNING"Not enough mst switch entries. "
+                               "Can't add msr %x\n", msr);
+               return;
+       } else if (i == m->nr) {
                ++m->nr;
                vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->nr);
                vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr);
@@ -2455,6 +2506,42 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
                && allow_1_setting(MSR_IA32_VMX_EXIT_CTLS,
                                   VM_EXIT_LOAD_IA32_EFER);
 
+       cpu_has_load_perf_global_ctrl =
+               allow_1_setting(MSR_IA32_VMX_ENTRY_CTLS,
+                               VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
+               && allow_1_setting(MSR_IA32_VMX_EXIT_CTLS,
+                                  VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
+
+       /*
+        * Some cpus support VM_ENTRY_(LOAD|SAVE)_IA32_PERF_GLOBAL_CTRL
+        * but due to arrata below it can't be used. Workaround is to use
+        * msr load mechanism to switch IA32_PERF_GLOBAL_CTRL.
+        *
+        * VM Exit May Incorrectly Clear IA32_PERF_GLOBAL_CTRL [34:32]
+        *
+        * AAK155             (model 26)
+        * AAP115             (model 30)
+        * AAT100             (model 37)
+        * BC86,AAY89,BD102   (model 44)
+        * BA97               (model 46)
+        *
+        */
+       if (cpu_has_load_perf_global_ctrl && boot_cpu_data.x86 == 0x6) {
+               switch (boot_cpu_data.x86_model) {
+               case 26:
+               case 30:
+               case 37:
+               case 44:
+               case 46:
+                       cpu_has_load_perf_global_ctrl = false;
+                       printk_once(KERN_WARNING"kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL "
+                                       "does not work properly. Using workaround\n");
+                       break;
+               default:
+                       break;
+               }
+       }
+
        return 0;
 }
 
@@ -5968,6 +6055,24 @@ static void vmx_cancel_injection(struct kvm_vcpu *vcpu)
        vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);
 }
 
+static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
+{
+       int i, nr_msrs;
+       struct perf_guest_switch_msr *msrs;
+
+       msrs = perf_guest_get_msrs(&nr_msrs);
+
+       if (!msrs)
+               return;
+
+       for (i = 0; i < nr_msrs; i++)
+               if (msrs[i].host == msrs[i].guest)
+                       clear_atomic_switch_msr(vmx, msrs[i].msr);
+               else
+                       add_atomic_switch_msr(vmx, msrs[i].msr, msrs[i].guest,
+                                       msrs[i].host);
+}
+
 #ifdef CONFIG_X86_64
 #define R "r"
 #define Q "q"
@@ -6017,6 +6122,8 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
        if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
                vmx_set_interrupt_shadow(vcpu, 0);
 
+       atomic_switch_perf_msrs(vmx);
+
        vmx->__launched = vmx->loaded_vmcs->launched;
        asm(
                /* Store host registers */
index 541020df0da6713f485b313829def31dab03b334..b1489a06a49dbc5ac0f4acd5eeaddc6136f05c1a 100644 (file)
@@ -187,11 +187,34 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table)
 static unsigned long __init mrst_calibrate_tsc(void)
 {
        unsigned long flags, fast_calibrate;
-
-       local_irq_save(flags);
-       fast_calibrate = apbt_quick_calibrate();
-       local_irq_restore(flags);
-
+       if (__mrst_cpu_chip == MRST_CPU_CHIP_PENWELL) {
+               u32 lo, hi, ratio, fsb;
+
+               rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+               pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi);
+               ratio = (hi >> 8) & 0x1f;
+               pr_debug("ratio is %d\n", ratio);
+               if (!ratio) {
+                       pr_err("read a zero ratio, should be incorrect!\n");
+                       pr_err("force tsc ratio to 16 ...\n");
+                       ratio = 16;
+               }
+               rdmsr(MSR_FSB_FREQ, lo, hi);
+               if ((lo & 0x7) == 0x7)
+                       fsb = PENWELL_FSB_FREQ_83SKU;
+               else
+                       fsb = PENWELL_FSB_FREQ_100SKU;
+               fast_calibrate = ratio * fsb;
+               pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
+               lapic_timer_frequency = fsb * 1000 / HZ;
+               /* mark tsc clocksource as reliable */
+               set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
+       } else {
+               local_irq_save(flags);
+               fast_calibrate = apbt_quick_calibrate();
+               local_irq_restore(flags);
+       }
+       
        if (fast_calibrate)
                return fast_calibrate;
 
@@ -253,6 +276,17 @@ static void mrst_reboot(void)
        intel_scu_ipc_simple_command(0xf1, 0);
 }
 
+/*
+ * Moorestown does not have external NMI source nor port 0x61 to report
+ * NMI status. The possible NMI sources are from pmu as a result of NMI
+ * watchdog or lock debug. Reading io port 0x61 results in 0xff which
+ * misled NMI handler.
+ */
+static unsigned char mrst_get_nmi_reason(void)
+{
+       return 0;
+}
+
 /*
  * Moorestown specific x86_init function overrides and early setup
  * calls.
@@ -274,6 +308,8 @@ void __init x86_mrst_early_setup(void)
        x86_platform.calibrate_tsc = mrst_calibrate_tsc;
        x86_platform.i8042_detect = mrst_i8042_detect;
        x86_init.timers.wallclock_init = mrst_rtc_init;
+       x86_platform.get_nmi_reason = mrst_get_nmi_reason;
+
        x86_init.pci.init = pci_mrst_init;
        x86_init.pci.fixup_irqs = x86_init_noop;
 
index 118c143a9cb49ca03ced909f1a0744902889d701..2c32df6fe23167a6ca3955fdac07444f6f2fbc34 100644 (file)
@@ -11,7 +11,7 @@
 #endif
 
 #define KSTK_EIP(tsk) KSTK_REG(tsk, HOST_IP)
-#define KSTK_ESP(tsk) KSTK_REG(tsk, HOST_IP)
+#define KSTK_ESP(tsk) KSTK_REG(tsk, HOST_SP)
 #define KSTK_EBP(tsk) KSTK_REG(tsk, HOST_BP)
 
 #define ARCH_IS_STACKGROW(address) \
index da8afd576a6b7d161e3e81f2997912a73fec3d31..1f928659c338e6e5cfcf6386446f087f41f1e22f 100644 (file)
@@ -1356,7 +1356,7 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
        int cpu = (long)hcpu;
        switch (action) {
        case CPU_UP_PREPARE:
-               per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
+               xen_vcpu_setup(cpu);
                if (xen_have_vector_callback)
                        xen_init_lock_cpu(cpu);
                break;
@@ -1386,7 +1386,6 @@ static void __init xen_hvm_guest_init(void)
        xen_hvm_smp_init();
        register_cpu_notifier(&xen_hvm_cpu_notifier);
        xen_unplug_emulated_devices();
-       have_vcpu_info_placement = 0;
        x86_init.irqs.intr_init = xen_init_IRQ;
        xen_hvm_init_time_ops();
        xen_hvm_init_mmu_ops();
index 6bbfd7ac5e814b10c96b925407c18cfaabb32453..5a40d24ba3316b85b42e5ef5d00280b89a2033b9 100644 (file)
@@ -71,7 +71,7 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
 
        if (shared == NULL) {
                struct vm_struct *area =
-                       alloc_vm_area(PAGE_SIZE * max_nr_gframes);
+                       alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);
                BUG_ON(area == NULL);
                shared = area->addr;
                *__shared = shared;
index f43c8a5840ae488131dbf395d5eaf96e2fea876d..ea70e6c80cd34f0c2b563ceabcc7189027fc5182 100644 (file)
@@ -1379,15 +1379,19 @@ get_rq:
                 */
                if (list_empty(&plug->list))
                        trace_block_plug(q);
-               else if (!plug->should_sort) {
-                       struct request *__rq;
+               else {
+                       if (!plug->should_sort) {
+                               struct request *__rq;
 
-                       __rq = list_entry_rq(plug->list.prev);
-                       if (__rq->q != q)
-                               plug->should_sort = 1;
+                               __rq = list_entry_rq(plug->list.prev);
+                               if (__rq->q != q)
+                                       plug->should_sort = 1;
+                       }
+                       if (request_count >= BLK_MAX_REQUEST_COUNT) {
+                               blk_flush_plug_list(plug, false);
+                               trace_block_plug(q);
+                       }
                }
-               if (request_count >= BLK_MAX_REQUEST_COUNT)
-                       blk_flush_plug_list(plug, false);
                list_add_tail(&req->queuelist, &plug->list);
                drive_stat_acct(req, 1);
        } else {
index e663ac2d8e68f70ff17ce274f3cebec16c1dd18c..164cd0059706214e53c01b780b353fca98d9b829 100644 (file)
@@ -204,10 +204,11 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
                if (!iov[i].iov_len)
                        return -EINVAL;
 
-               if (uaddr & queue_dma_alignment(q)) {
+               /*
+                * Keep going so we check length of all segments
+                */
+               if (uaddr & queue_dma_alignment(q))
                        unaligned = 1;
-                       break;
-               }
        }
 
        if (unaligned || (q->dma_pad_mask & len) || map_data)
index 9253839714ff95b4acc6da413bd87f610ddce44c..02e9fca808256f762e0af44e8a1055c322b51b40 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mutex.h>
 #include <linux/idr.h>
 #include <linux/log2.h>
-#include <linux/ctype.h>
 
 #include "blk.h"
 
@@ -916,74 +915,6 @@ static int __init genhd_device_init(void)
 
 subsys_initcall(genhd_device_init);
 
-static ssize_t alias_show(struct device *dev,
-                              struct device_attribute *attr, char *buf)
-{
-       struct gendisk *disk = dev_to_disk(dev);
-       ssize_t ret = 0;
-
-       if (disk->alias)
-               ret = snprintf(buf, ALIAS_LEN, "%s\n", disk->alias);
-       return ret;
-}
-
-static ssize_t alias_store(struct device *dev, struct device_attribute *attr,
-                          const char *buf, size_t count)
-{
-       struct gendisk *disk = dev_to_disk(dev);
-       char *alias;
-       char *envp[] = { NULL, NULL };
-       unsigned char c;
-       int i;
-       ssize_t ret = count;
-
-       if (!count)
-               return -EINVAL;
-
-       if (count >= ALIAS_LEN) {
-               printk(KERN_ERR "alias: alias is too long\n");
-               return -EINVAL;
-       }
-
-       /* Validation check */
-       for (i = 0; i < count; i++) {
-               c = buf[i];
-               if (i == count - 1 && c == '\n')
-                       break;
-               if (!isalnum(c) && c != '_' && c != '-') {
-                       printk(KERN_ERR "alias: invalid alias\n");
-                       return -EINVAL;
-               }
-       }
-
-       if (disk->alias) {
-               printk(KERN_INFO "alias: %s is already assigned (%s)\n",
-                      disk->disk_name, disk->alias);
-               return -EINVAL;
-       }
-
-       alias = kasprintf(GFP_KERNEL, "%s", buf);
-       if (!alias)
-               return -ENOMEM;
-
-       if (alias[count - 1] == '\n')
-               alias[count - 1] = '\0';
-
-       envp[0] = kasprintf(GFP_KERNEL, "ALIAS=%s", alias);
-       if (!envp[0]) {
-               kfree(alias);
-               return -ENOMEM;
-       }
-
-       disk->alias = alias;
-       printk(KERN_INFO "alias: assigned %s to %s\n", alias, disk->disk_name);
-
-       kobject_uevent_env(&dev->kobj, KOBJ_ADD, envp);
-
-       kfree(envp[0]);
-       return ret;
-}
-
 static ssize_t disk_range_show(struct device *dev,
                               struct device_attribute *attr, char *buf)
 {
@@ -1043,7 +974,6 @@ static ssize_t disk_discard_alignment_show(struct device *dev,
        return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue));
 }
 
-static DEVICE_ATTR(alias, S_IRUGO|S_IWUSR, alias_show, alias_store);
 static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
 static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
 static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
@@ -1066,7 +996,6 @@ static struct device_attribute dev_attr_fail_timeout =
 #endif
 
 static struct attribute *disk_attrs[] = {
-       &dev_attr_alias.attr,
        &dev_attr_range.attr,
        &dev_attr_ext_range.attr,
        &dev_attr_removable.attr,
index 127408069ca7fa745953fd5a8e164cd74779c680..631b9477b99c02f827103aa00a8d3a83c380d359 100644 (file)
@@ -932,7 +932,8 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
 static int erst_open_pstore(struct pstore_info *psi);
 static int erst_close_pstore(struct pstore_info *psi);
 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
-                          struct timespec *time, struct pstore_info *psi);
+                          struct timespec *time, char **buf,
+                          struct pstore_info *psi);
 static int erst_writer(enum pstore_type_id type, u64 *id, unsigned int part,
                       size_t size, struct pstore_info *psi);
 static int erst_clearer(enum pstore_type_id type, u64 id,
@@ -986,17 +987,23 @@ static int erst_close_pstore(struct pstore_info *psi)
 }
 
 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
-                          struct timespec *time, struct pstore_info *psi)
+                          struct timespec *time, char **buf,
+                          struct pstore_info *psi)
 {
        int rc;
        ssize_t len = 0;
        u64 record_id;
-       struct cper_pstore_record *rcd = (struct cper_pstore_record *)
-                                       (erst_info.buf - sizeof(*rcd));
+       struct cper_pstore_record *rcd;
+       size_t rcd_len = sizeof(*rcd) + erst_info.bufsize;
 
        if (erst_disable)
                return -ENODEV;
 
+       rcd = kmalloc(rcd_len, GFP_KERNEL);
+       if (!rcd) {
+               rc = -ENOMEM;
+               goto out;
+       }
 skip:
        rc = erst_get_record_id_next(&reader_pos, &record_id);
        if (rc)
@@ -1004,22 +1011,27 @@ skip:
 
        /* no more record */
        if (record_id == APEI_ERST_INVALID_RECORD_ID) {
-               rc = -1;
+               rc = -EINVAL;
                goto out;
        }
 
-       len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
-                       erst_info.bufsize);
+       len = erst_read(record_id, &rcd->hdr, rcd_len);
        /* The record may be cleared by others, try read next record */
        if (len == -ENOENT)
                goto skip;
-       else if (len < 0) {
-               rc = -1;
+       else if (len < sizeof(*rcd)) {
+               rc = -EIO;
                goto out;
        }
        if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
                goto skip;
 
+       *buf = kmalloc(len, GFP_KERNEL);
+       if (*buf == NULL) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       memcpy(*buf, rcd->data, len - sizeof(*rcd));
        *id = record_id;
        if (uuid_le_cmp(rcd->sec_hdr.section_type,
                        CPER_SECTION_TYPE_DMESG) == 0)
@@ -1037,6 +1049,7 @@ skip:
        time->tv_nsec = 0;
 
 out:
+       kfree(rcd);
        return (rc < 0) ? rc : (len - sizeof(*rcd));
 }
 
index ec555951176eddb717de85d010dde532151a3127..43b875810d1b7b91c98386fb6f3a5c58be79fdb9 100644 (file)
@@ -67,7 +67,7 @@ static int __init ahci_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct ahci_platform_data *pdata = dev_get_platdata(dev);
        const struct platform_device_id *id = platform_get_device_id(pdev);
-       struct ata_port_info pi = ahci_port_info[id->driver_data];
+       struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
        const struct ata_port_info *ppi[] = { &pi, NULL };
        struct ahci_host_priv *hpriv;
        struct ata_host *host;
index 63d53277d6a92f4393cd22563d75c4b9b8d32462..4cadfa28f940450ee2f5a890af44e34ad583e921 100644 (file)
@@ -2533,10 +2533,12 @@ static int ata_pci_init_one(struct pci_dev *pdev,
        if (rc)
                goto out;
 
+#ifdef CONFIG_ATA_BMDMA
        if (bmdma)
                /* prepare and activate BMDMA host */
                rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
        else
+#endif
                /* prepare and activate SFF host */
                rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
        if (rc)
@@ -2544,10 +2546,12 @@ static int ata_pci_init_one(struct pci_dev *pdev,
        host->private_data = host_priv;
        host->flags |= hflags;
 
+#ifdef CONFIG_ATA_BMDMA
        if (bmdma) {
                pci_set_master(pdev);
                rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
        } else
+#endif
                rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
 out:
        if (rc == 0)
index 82c865452c7080d180ec6a453ab1efb3e988dac3..d8b3d89db043e7e9ead44cb8b4a00946f4980fa6 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kallsyms.h>
 #include <linux/mutex.h>
 #include <linux/async.h>
+#include <linux/pm_runtime.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -1742,6 +1743,8 @@ void device_shutdown(void)
                 */
                list_del_init(&dev->kobj.entry);
                spin_unlock(&devices_kset->list_lock);
+               /* Disable all device's runtime power management */
+               pm_runtime_disable(dev);
 
                if (dev->bus && dev->bus->shutdown) {
                        dev_dbg(dev, "shutdown\n");
index 793f796c4da3e1cd20143e1266d41246f2289b73..5693ecee9a4052a339b9eca105ff3704fffe29b4 100644 (file)
@@ -127,12 +127,13 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
                       nid, K(node_page_state(nid, NR_WRITEBACK)),
                       nid, K(node_page_state(nid, NR_FILE_PAGES)),
                       nid, K(node_page_state(nid, NR_FILE_MAPPED)),
-                      nid, K(node_page_state(nid, NR_ANON_PAGES)
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+                      nid, K(node_page_state(nid, NR_ANON_PAGES)
                        + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
-                       HPAGE_PMD_NR
+                       HPAGE_PMD_NR),
+#else
+                      nid, K(node_page_state(nid, NR_ANON_PAGES)),
 #endif
-                      ),
                       nid, K(node_page_state(nid, NR_SHMEM)),
                       nid, node_page_state(nid, NR_KERNEL_STACK) *
                                THREAD_SIZE / 1024,
@@ -143,13 +144,14 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
                       nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) +
                                node_page_state(nid, NR_SLAB_UNRECLAIMABLE)),
                       nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)),
-                      nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+                      nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))
                        , nid,
                        K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
-                       HPAGE_PMD_NR)
+                       HPAGE_PMD_NR));
+#else
+                      nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)));
 #endif
-                      );
        n += hugetlb_report_node_meminfo(nid, buf + n);
        return n;
 }
index 5f0f85d5c5765558a25fa7ec165be968e5fbcabf..428e55e012dcd06f91ade3154c941aab6f1d5bb5 100644 (file)
@@ -229,7 +229,8 @@ int pm_clk_suspend(struct device *dev)
 
        list_for_each_entry_reverse(ce, &psd->clock_list, node) {
                if (ce->status < PCE_STATUS_ERROR) {
-                       clk_disable(ce->clk);
+                       if (ce->status == PCE_STATUS_ENABLED)
+                               clk_disable(ce->clk);
                        ce->status = PCE_STATUS_ACQUIRED;
                }
        }
index 7fa098464dae62921a5acf32af3537f649b604fe..c3d2dfcf438dd1735fcf401be9f8185440e9a1a9 100644 (file)
@@ -920,7 +920,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
  End:
        if (!error) {
                dev->power.is_suspended = true;
-               if (dev->power.wakeup_path && dev->parent)
+               if (dev->power.wakeup_path
+                   && dev->parent && !dev->parent->power.ignore_children)
                        dev->parent->power.wakeup_path = true;
        }
 
index 30a94eadc200c7f89f7e2448126ad93cd6a6a2f2..86de6c50fc4181f796c5d0e3d20e796380f112b0 100644 (file)
@@ -212,11 +212,9 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
        if (!dev || !req) /*guard against callers passing in null */
                return -EINVAL;
 
-       if (dev_pm_qos_request_active(req)) {
-               WARN(1, KERN_ERR "dev_pm_qos_add_request() called for already "
-                       "added request\n");
+       if (WARN(dev_pm_qos_request_active(req),
+                "%s() called for already added request\n", __func__))
                return -EINVAL;
-       }
 
        req->dev = dev;
 
@@ -271,11 +269,9 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
        if (!req) /*guard against callers passing in null */
                return -EINVAL;
 
-       if (!dev_pm_qos_request_active(req)) {
-               WARN(1, KERN_ERR "dev_pm_qos_update_request() called for "
-                       "unknown object\n");
+       if (WARN(!dev_pm_qos_request_active(req),
+                "%s() called for unknown object\n", __func__))
                return -EINVAL;
-       }
 
        mutex_lock(&dev_pm_qos_mtx);
 
@@ -312,11 +308,9 @@ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
        if (!req) /*guard against callers passing in null */
                return -EINVAL;
 
-       if (!dev_pm_qos_request_active(req)) {
-               WARN(1, KERN_ERR "dev_pm_qos_remove_request() called for "
-                       "unknown object\n");
+       if (WARN(!dev_pm_qos_request_active(req),
+                "%s() called for unknown object\n", __func__))
                return -EINVAL;
-       }
 
        mutex_lock(&dev_pm_qos_mtx);
 
index 486f94ef24d499bfe0d17eb379fe5043a94f36a5..8004ac30a7a8634bc7f963be8db2c6c1eac61ce4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -4319,6 +4320,10 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)
                dev_warn(&h->pdev->dev, "controller appears to be disabled\n");
                return -ENODEV;
        }
+
+       pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
+                               PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
+
        err = pci_enable_device(h->pdev);
        if (err) {
                dev_warn(&h->pdev->dev, "Unable to Enable PCI device\n");
@@ -5158,6 +5163,7 @@ reinit_after_soft_reset:
        h->cciss_max_sectors = 8192;
 
        rebuild_lun_table(h, 1, 0);
+       cciss_engage_scsi(h);
        h->busy_initializing = 0;
        return 1;
 
index 951a4e33b92b788b208d6320636b77422bf9474f..e820b68d2f6cd4d74382b85b5e020069294f00f3 100644 (file)
@@ -1720,5 +1720,6 @@ static int  cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
 /* If no tape support, then these become defined out of existence */
 
 #define cciss_scsi_setup(cntl_num)
+#define cciss_engage_scsi(h)
 
 #endif /* CONFIG_CISS_SCSI_TAPE */
index 3d806820280e3bc4aaa5e81d6bea411f6597e400..68b205a9338f631adbd98df74836b98aa95d27ac 100644 (file)
@@ -161,17 +161,19 @@ static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
        &xor_funcs
 };
 
-static loff_t get_loop_size(struct loop_device *lo, struct file *file)
+static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file)
 {
-       loff_t size, offset, loopsize;
+       loff_t size, loopsize;
 
        /* Compute loopsize in bytes */
        size = i_size_read(file->f_mapping->host);
-       offset = lo->lo_offset;
        loopsize = size - offset;
-       if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize)
-               loopsize = lo->lo_sizelimit;
+       /* offset is beyond i_size, wierd but possible */
+       if (loopsize < 0)
+               return 0;
 
+       if (sizelimit > 0 && sizelimit < loopsize)
+               loopsize = sizelimit;
        /*
         * Unfortunately, if we want to do I/O on the device,
         * the number of 512-byte sectors has to fit into a sector_t.
@@ -179,17 +181,25 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file)
        return loopsize >> 9;
 }
 
+static loff_t get_loop_size(struct loop_device *lo, struct file *file)
+{
+       return get_size(lo->lo_offset, lo->lo_sizelimit, file);
+}
+
 static int
-figure_loop_size(struct loop_device *lo)
+figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit)
 {
-       loff_t size = get_loop_size(lo, lo->lo_backing_file);
+       loff_t size = get_size(offset, sizelimit, lo->lo_backing_file);
        sector_t x = (sector_t)size;
 
        if (unlikely((loff_t)x != size))
                return -EFBIG;
-
+       if (lo->lo_offset != offset)
+               lo->lo_offset = offset;
+       if (lo->lo_sizelimit != sizelimit)
+               lo->lo_sizelimit = sizelimit;
        set_capacity(lo->lo_disk, x);
-       return 0;                                       
+       return 0;
 }
 
 static inline int
@@ -372,7 +382,8 @@ do_lo_receive(struct loop_device *lo,
 
        if (retval < 0)
                return retval;
-
+       if (retval != bvec->bv_len)
+               return -EIO;
        return 0;
 }
 
@@ -1058,9 +1069,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
 
        if (lo->lo_offset != info->lo_offset ||
            lo->lo_sizelimit != info->lo_sizelimit) {
-               lo->lo_offset = info->lo_offset;
-               lo->lo_sizelimit = info->lo_sizelimit;
-               if (figure_loop_size(lo))
+               if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
                        return -EFBIG;
        }
        loop_config_discard(lo);
@@ -1246,7 +1255,7 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
        err = -ENXIO;
        if (unlikely(lo->lo_state != Lo_bound))
                goto out;
-       err = figure_loop_size(lo);
+       err = figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);
        if (unlikely(err))
                goto out;
        sec = get_capacity(lo->lo_disk);
@@ -1284,13 +1293,19 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
                        goto out_unlocked;
                break;
        case LOOP_SET_STATUS:
-               err = loop_set_status_old(lo, (struct loop_info __user *) arg);
+               err = -EPERM;
+               if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+                       err = loop_set_status_old(lo,
+                                       (struct loop_info __user *)arg);
                break;
        case LOOP_GET_STATUS:
                err = loop_get_status_old(lo, (struct loop_info __user *) arg);
                break;
        case LOOP_SET_STATUS64:
-               err = loop_set_status64(lo, (struct loop_info64 __user *) arg);
+               err = -EPERM;
+               if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+                       err = loop_set_status64(lo,
+                                       (struct loop_info64 __user *) arg);
                break;
        case LOOP_GET_STATUS64:
                err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
index 6b9a2000d56affdd7788ff26581ae587f3937f96..a79fb4f7ff622632809c2b93f47df93fb7561ccb 100644 (file)
@@ -630,6 +630,7 @@ static ssize_t pg_read(struct file *filp, char __user *buf, size_t count, loff_t
                if (dev->status & 0x10)
                        return -ETIME;
 
+       memset(&hdr, 0, sizeof(hdr));
        hdr.magic = PG_MAGIC;
        hdr.dlen = dev->dlen;
        copy = 0;
index f9b726091ad0bba89464bad3a59f363318eba508..fe4ebc375b3dafd274da41c803cbb9ac37754146 100644 (file)
@@ -100,6 +100,9 @@ static struct usb_device_id btusb_table[] = {
        /* Canyon CN-BTU1 with HID interfaces */
        { USB_DEVICE(0x0c10, 0x0000) },
 
+       /* Broadcom BCM20702A0 */
+       { USB_DEVICE(0x413c, 0x8197) },
+
        { }     /* Terminating entry */
 };
 
index 63e19ba56bbea5a12ee784f023bd13a758eaf611..6035ab8d5ef7e25e6eae89fbfdc53476f248de8b 100644 (file)
@@ -941,7 +941,7 @@ void get_random_bytes(void *buf, int nbytes)
                if (!arch_get_random_long(&v))
                        break;
                
-               memcpy(buf, &v, chunk);
+               memcpy(p, &v, chunk);
                p += chunk;
                nbytes -= chunk;
        }
index 5c6f56f21443ae7e01a1b9fc90b3202674fbaa37..dcd8babae9eb36fe864bae433558e5e1b4c77d83 100644 (file)
@@ -343,11 +343,13 @@ static void mv_process_hash_current(int first_block)
                else
                        op.config |= CFG_MID_FRAG;
 
-               writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A);
-               writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B);
-               writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C);
-               writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D);
-               writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E);
+               if (first_block) {
+                       writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A);
+                       writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B);
+                       writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C);
+                       writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D);
+                       writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E);
+               }
        }
 
        memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config));
index 643b055ed3cdc619d07166e8eaa84b2f849252df..8f0491037080df38856b76ec73db77cf18d3320f 100644 (file)
@@ -1,36 +1,29 @@
-config ARCH_HAS_DEVFREQ
-       bool
-       depends on ARCH_HAS_OPP
-       help
-         Denotes that the architecture supports DEVFREQ. If the architecture
-         supports multiple OPP entries per device and the frequency of the
-         devices with OPPs may be altered dynamically, the architecture
-         supports DEVFREQ.
-
 menuconfig PM_DEVFREQ
        bool "Generic Dynamic Voltage and Frequency Scaling (DVFS) support"
-       depends on PM_OPP && ARCH_HAS_DEVFREQ
        help
-         With OPP support, a device may have a list of frequencies and
-         voltages available. DEVFREQ, a generic DVFS framework can be
-         registered for a device with OPP support in order to let the
-         governor provided to DEVFREQ choose an operating frequency
-         based on the OPP's list and the policy given with DEVFREQ.
+         A device may have a list of frequencies and voltages available.
+         devfreq, a generic DVFS framework can be registered for a device
+         in order to let the governor provided to devfreq choose an
+         operating frequency based on the device driver's policy.
 
-         Each device may have its own governor and policy. DEVFREQ can
+         Each device may have its own governor and policy. Devfreq can
          reevaluate the device state periodically and/or based on the
-         OPP list changes (each frequency/voltage pair in OPP may be
-         disabled or enabled).
+         notification to "nb", a notifier block, of devfreq.
 
-         Like some CPUs with CPUFREQ, a device may have multiple clocks.
+         Like some CPUs with CPUfreq, a device may have multiple clocks.
          However, because the clock frequencies of a single device are
-         determined by the single device's state, an instance of DEVFREQ
+         determined by the single device's state, an instance of devfreq
          is attached to a single device and returns a "representative"
-         clock frequency from the OPP of the device, which is also attached
-         to a device by 1-to-1. The device registering DEVFREQ takes the
-         responsiblity to "interpret" the frequency listed in OPP and
+         clock frequency of the device, which is also attached
+         to a device by 1-to-1. The device registering devfreq takes the
+         responsiblity to "interpret" the representative frequency and
          to set its every clock accordingly with the "target" callback
-         given to DEVFREQ.
+         given to devfreq.
+
+         When OPP is used with the devfreq device, it is recommended to
+         register devfreq's nb to the OPP's notifier head.  If OPP is
+         used with the devfreq device, you may use OPP helper
+         functions defined in devfreq.h.
 
 if PM_DEVFREQ
 
index 5d15b812377bc9ad23420e6d41bd7ea62dc62e2f..59d24e9cb8c512a949a24803c5bf11a143fc649d 100644 (file)
@@ -15,7 +15,9 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/opp.h>
 #include <linux/devfreq.h>
 #include <linux/workqueue.h>
@@ -416,10 +418,14 @@ out:
  */
 int devfreq_remove_device(struct devfreq *devfreq)
 {
+       bool central_polling;
+
        if (!devfreq)
                return -EINVAL;
 
-       if (!devfreq->governor->no_central_polling) {
+       central_polling = !devfreq->governor->no_central_polling;
+
+       if (central_polling) {
                mutex_lock(&devfreq_list_lock);
                while (wait_remove_device == devfreq) {
                        mutex_unlock(&devfreq_list_lock);
@@ -431,7 +437,7 @@ int devfreq_remove_device(struct devfreq *devfreq)
        mutex_lock(&devfreq->lock);
        _remove_devfreq(devfreq, false); /* it unlocks devfreq->lock */
 
-       if (!devfreq->governor->no_central_polling)
+       if (central_polling)
                mutex_unlock(&devfreq_list_lock);
 
        return 0;
index 8af8e864a9cffbc13c91c625a837e11bb8de24fe..73464a62adf74ae1483a16ad71847c03fc03169f 100644 (file)
@@ -1128,7 +1128,7 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = {
        { .compatible = "fsl,p1020-memory-controller", },
        { .compatible = "fsl,p1021-memory-controller", },
        { .compatible = "fsl,p2020-memory-controller", },
-       { .compatible = "fsl,p4080-memory-controller", },
+       { .compatible = "fsl,qoriq-memory-controller", },
        {},
 };
 MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match);
index bcb1126e3d00b2357a0c5748edbd8b1b470c0423..153980be4ee64462f12a97563c0143fc59b3eb82 100644 (file)
@@ -585,14 +585,12 @@ int dmi_name_in_serial(const char *str)
 }
 
 /**
- *     dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
+ *     dmi_name_in_vendors - Check if string is in the DMI system or board vendor name
  *     @str:   Case sensitive Name
  */
 int dmi_name_in_vendors(const char *str)
 {
-       static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
-                               DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
-                               DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
+       static int fields[] = { DMI_SYS_VENDOR, DMI_BOARD_VENDOR, DMI_NONE };
        int i;
        for (i = 0; fields[i] != DMI_NONE; i++) {
                int f = fields[i];
index 8370f72d87ff5ed955789973845629f406f6734e..b0a81173a268175f71606e1aad2ab6067b67f698 100644 (file)
@@ -457,7 +457,8 @@ static int efi_pstore_close(struct pstore_info *psi)
 }
 
 static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
-                              struct timespec *timespec, struct pstore_info *psi)
+                              struct timespec *timespec,
+                              char **buf, struct pstore_info *psi)
 {
        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
        struct efivars *efivars = psi->data;
@@ -478,7 +479,11 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
                                timespec->tv_nsec = 0;
                                get_var_data_locked(efivars, &efivars->walk_entry->var);
                                size = efivars->walk_entry->var.DataSize;
-                               memcpy(psi->buf, efivars->walk_entry->var.Data, size);
+                               *buf = kmalloc(size, GFP_KERNEL);
+                               if (*buf == NULL)
+                                       return -ENOMEM;
+                               memcpy(*buf, efivars->walk_entry->var.Data,
+                                      size);
                                efivars->walk_entry = list_entry(efivars->walk_entry->list.next,
                                                   struct efivar_entry, list);
                                return size;
@@ -576,7 +581,8 @@ static int efi_pstore_close(struct pstore_info *psi)
 }
 
 static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
-                              struct timespec *time, struct pstore_info *psi)
+                              struct timespec *timespec,
+                              char **buf, struct pstore_info *psi)
 {
        return -1;
 }
index 147df8ae79dbd42a3105a38dd67a067fca7d36f6..d3f3e8f5456129e7036fc3737181d37b40b8c642 100644 (file)
@@ -546,7 +546,7 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip)
  * Translate OpenFirmware node properties into platform_data
  * WARNING: This is DEPRECATED and will be removed eventually!
  */
-void
+static void
 pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
 {
        struct device_node *node;
@@ -574,7 +574,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
                *invert = *val;
 }
 #else
-void
+static void
 pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
 {
        *gpio_base = -1;
index 405c63b9d539a74826b0ecfdb6d4000f5a43b2f5..8323fc3898401ac957d9a677b947455f5a598b91 100644 (file)
@@ -1873,6 +1873,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
        }
 
        if (num_clips && clips_ptr) {
+               if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
+                       ret = -EINVAL;
+                       goto out_err1;
+               }
                clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
                if (!clips) {
                        ret = -ENOMEM;
index 68b756253f9f20f300ce548b9f98a2e3fa5748b2..44a5d0ad8b7c56e99c9ce85f2dfcf14d19e855e0 100644 (file)
@@ -110,10 +110,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
        /* Prevent vblank irq processing while disabling vblank irqs,
         * so no updates of timestamps or count can happen after we've
         * disabled. Needed to prevent races in case of delayed irq's.
-        * Disable preemption, so vblank_time_lock is held as short as
-        * possible, even under a kernel with PREEMPT_RT patches.
         */
-       preempt_disable();
        spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
 
        dev->driver->disable_vblank(dev, crtc);
@@ -164,7 +161,6 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
        clear_vblank_timestamps(dev, crtc);
 
        spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
-       preempt_enable();
 }
 
 static void vblank_disable_fn(unsigned long arg)
@@ -889,10 +885,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
        /* Going from 0->1 means we have to enable interrupts again */
        if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
-               /* Disable preemption while holding vblank_time_lock. Do
-                * it explicitely to guard against PREEMPT_RT kernel.
-                */
-               preempt_disable();
                spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);
                if (!dev->vblank_enabled[crtc]) {
                        /* Enable vblank irqs under vblank_time_lock protection.
@@ -912,7 +904,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
                        }
                }
                spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2);
-               preempt_enable();
        } else {
                if (!dev->vblank_enabled[crtc]) {
                        atomic_dec(&dev->vblank_refcount[crtc]);
index 6f8afea94fc979b74476746aca1ae32341846357..2bb07bca511a12b6949892186565cfde960db8ca 100644 (file)
 #include "drm.h"
 
 #include "exynos_drm_drv.h"
+#include "exynos_drm_gem.h"
 #include "exynos_drm_buf.h"
 
-static DEFINE_MUTEX(exynos_drm_buf_lock);
-
 static int lowlevel_buffer_allocate(struct drm_device *dev,
-               struct exynos_drm_buf_entry *entry)
+               struct exynos_drm_gem_buf *buffer)
 {
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       entry->vaddr = dma_alloc_writecombine(dev->dev, entry->size,
-                       (dma_addr_t *)&entry->paddr, GFP_KERNEL);
-       if (!entry->paddr) {
+       buffer->kvaddr = dma_alloc_writecombine(dev->dev, buffer->size,
+                       &buffer->dma_addr, GFP_KERNEL);
+       if (!buffer->kvaddr) {
                DRM_ERROR("failed to allocate buffer.\n");
                return -ENOMEM;
        }
 
-       DRM_DEBUG_KMS("allocated : vaddr(0x%x), paddr(0x%x), size(0x%x)\n",
-                       (unsigned int)entry->vaddr, entry->paddr, entry->size);
+       DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
+                       (unsigned long)buffer->kvaddr,
+                       (unsigned long)buffer->dma_addr,
+                       buffer->size);
 
        return 0;
 }
 
 static void lowlevel_buffer_deallocate(struct drm_device *dev,
-               struct exynos_drm_buf_entry *entry)
+               struct exynos_drm_gem_buf *buffer)
 {
        DRM_DEBUG_KMS("%s.\n", __FILE__);
 
-       if (entry->paddr && entry->vaddr && entry->size)
-               dma_free_writecombine(dev->dev, entry->size, entry->vaddr,
-                               entry->paddr);
+       if (buffer->dma_addr && buffer->size)
+               dma_free_writecombine(dev->dev, buffer->size, buffer->kvaddr,
+                               (dma_addr_t)buffer->dma_addr);
        else
-               DRM_DEBUG_KMS("entry data is null.\n");
+               DRM_DEBUG_KMS("buffer data are invalid.\n");
 }
 
-struct exynos_drm_buf_entry *exynos_drm_buf_create(struct drm_device *dev,
+struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev,
                unsigned int size)
 {
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
 
        DRM_DEBUG_KMS("%s.\n", __FILE__);
+       DRM_DEBUG_KMS("desired size = 0x%x\n", size);
 
-       entry = kzalloc(sizeof(*entry), GFP_KERNEL);
-       if (!entry) {
-               DRM_ERROR("failed to allocate exynos_drm_buf_entry.\n");
+       buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+       if (!buffer) {
+               DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n");
                return ERR_PTR(-ENOMEM);
        }
 
-       entry->size = size;
+       buffer->size = size;
 
        /*
         * allocate memory region with size and set the memory information
-        * to vaddr and paddr of a entry object.
+        * to vaddr and dma_addr of a buffer object.
         */
-       if (lowlevel_buffer_allocate(dev, entry) < 0) {
-               kfree(entry);
-               entry = NULL;
+       if (lowlevel_buffer_allocate(dev, buffer) < 0) {
+               kfree(buffer);
+               buffer = NULL;
                return ERR_PTR(-ENOMEM);
        }
 
-       return entry;
+       return buffer;
 }
 
 void exynos_drm_buf_destroy(struct drm_device *dev,
-               struct exynos_drm_buf_entry *entry)
+               struct exynos_drm_gem_buf *buffer)
 {
        DRM_DEBUG_KMS("%s.\n", __FILE__);
 
-       if (!entry) {
-               DRM_DEBUG_KMS("entry is null.\n");
+       if (!buffer) {
+               DRM_DEBUG_KMS("buffer is null.\n");
                return;
        }
 
-       lowlevel_buffer_deallocate(dev, entry);
+       lowlevel_buffer_deallocate(dev, buffer);
 
-       kfree(entry);
-       entry = NULL;
+       kfree(buffer);
+       buffer = NULL;
 }
 
 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
index 045d59eab01a29b5270410d661968d408dcfa663..6e91f9caa5dbdfe12aade5461c3ad253888f20bf 100644 (file)
 #ifndef _EXYNOS_DRM_BUF_H_
 #define _EXYNOS_DRM_BUF_H_
 
-/*
- * exynos drm buffer entry structure.
- *
- * @paddr: physical address of allocated memory.
- * @vaddr: kernel virtual address of allocated memory.
- * @size: size of allocated memory.
- */
-struct exynos_drm_buf_entry {
-       dma_addr_t paddr;
-       void __iomem *vaddr;
-       unsigned int size;
-};
-
 /* allocate physical memory. */
-struct exynos_drm_buf_entry *exynos_drm_buf_create(struct drm_device *dev,
+struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev,
                unsigned int size);
 
-/* get physical memory information of a drm framebuffer. */
-struct exynos_drm_buf_entry *exynos_drm_fb_get_buf(struct drm_framebuffer *fb);
+/* get memory information of a drm framebuffer. */
+struct exynos_drm_gem_buf *exynos_drm_fb_get_buf(struct drm_framebuffer *fb);
 
 /* remove allocated physical memory. */
 void exynos_drm_buf_destroy(struct drm_device *dev,
-               struct exynos_drm_buf_entry *entry);
+               struct exynos_drm_gem_buf *buffer);
 
 #endif
index 985d9e7687287d915c6a76e2b7219f9e7840e7f8..d620b0784257f05cab7c52b121a460c99f6f7daf 100644 (file)
@@ -37,6 +37,8 @@
 
 struct exynos_drm_connector {
        struct drm_connector    drm_connector;
+       uint32_t                encoder_id;
+       struct exynos_drm_manager *manager;
 };
 
 /* convert exynos_video_timings to drm_display_mode */
@@ -47,6 +49,7 @@ convert_to_display_mode(struct drm_display_mode *mode,
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
        mode->clock = timing->pixclock / 1000;
+       mode->vrefresh = timing->refresh;
 
        mode->hdisplay = timing->xres;
        mode->hsync_start = mode->hdisplay + timing->left_margin;
@@ -57,6 +60,12 @@ convert_to_display_mode(struct drm_display_mode *mode,
        mode->vsync_start = mode->vdisplay + timing->upper_margin;
        mode->vsync_end = mode->vsync_start + timing->vsync_len;
        mode->vtotal = mode->vsync_end + timing->lower_margin;
+
+       if (timing->vmode & FB_VMODE_INTERLACED)
+               mode->flags |= DRM_MODE_FLAG_INTERLACE;
+
+       if (timing->vmode & FB_VMODE_DOUBLE)
+               mode->flags |= DRM_MODE_FLAG_DBLSCAN;
 }
 
 /* convert drm_display_mode to exynos_video_timings */
@@ -69,7 +78,7 @@ convert_to_video_timing(struct fb_videomode *timing,
        memset(timing, 0, sizeof(*timing));
 
        timing->pixclock = mode->clock * 1000;
-       timing->refresh = mode->vrefresh;
+       timing->refresh = drm_mode_vrefresh(mode);
 
        timing->xres = mode->hdisplay;
        timing->left_margin = mode->hsync_start - mode->hdisplay;
@@ -92,15 +101,16 @@ convert_to_video_timing(struct fb_videomode *timing,
 
 static int exynos_drm_connector_get_modes(struct drm_connector *connector)
 {
-       struct exynos_drm_manager *manager =
-                               exynos_drm_get_manager(connector->encoder);
-       struct exynos_drm_display *display = manager->display;
+       struct exynos_drm_connector *exynos_connector =
+                                       to_exynos_connector(connector);
+       struct exynos_drm_manager *manager = exynos_connector->manager;
+       struct exynos_drm_display_ops *display_ops = manager->display_ops;
        unsigned int count;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (!display) {
-               DRM_DEBUG_KMS("display is null.\n");
+       if (!display_ops) {
+               DRM_DEBUG_KMS("display_ops is null.\n");
                return 0;
        }
 
@@ -112,7 +122,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
         * P.S. in case of lcd panel, count is always 1 if success
         * because lcd panel has only one mode.
         */
-       if (display->get_edid) {
+       if (display_ops->get_edid) {
                int ret;
                void *edid;
 
@@ -122,7 +132,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
                        return 0;
                }
 
-               ret = display->get_edid(manager->dev, connector,
+               ret = display_ops->get_edid(manager->dev, connector,
                                                edid, MAX_EDID);
                if (ret < 0) {
                        DRM_ERROR("failed to get edid data.\n");
@@ -140,8 +150,8 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
                struct drm_display_mode *mode = drm_mode_create(connector->dev);
                struct fb_videomode *timing;
 
-               if (display->get_timing)
-                       timing = display->get_timing(manager->dev);
+               if (display_ops->get_timing)
+                       timing = display_ops->get_timing(manager->dev);
                else {
                        drm_mode_destroy(connector->dev, mode);
                        return 0;
@@ -162,9 +172,10 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
 static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
                                            struct drm_display_mode *mode)
 {
-       struct exynos_drm_manager *manager =
-                               exynos_drm_get_manager(connector->encoder);
-       struct exynos_drm_display *display = manager->display;
+       struct exynos_drm_connector *exynos_connector =
+                                       to_exynos_connector(connector);
+       struct exynos_drm_manager *manager = exynos_connector->manager;
+       struct exynos_drm_display_ops *display_ops = manager->display_ops;
        struct fb_videomode timing;
        int ret = MODE_BAD;
 
@@ -172,8 +183,8 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
 
        convert_to_video_timing(&timing, mode);
 
-       if (display && display->check_timing)
-               if (!display->check_timing(manager->dev, (void *)&timing))
+       if (display_ops && display_ops->check_timing)
+               if (!display_ops->check_timing(manager->dev, (void *)&timing))
                        ret = MODE_OK;
 
        return ret;
@@ -181,9 +192,25 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
 
 struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
 {
+       struct drm_device *dev = connector->dev;
+       struct exynos_drm_connector *exynos_connector =
+                                       to_exynos_connector(connector);
+       struct drm_mode_object *obj;
+       struct drm_encoder *encoder;
+
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       return connector->encoder;
+       obj = drm_mode_object_find(dev, exynos_connector->encoder_id,
+                                  DRM_MODE_OBJECT_ENCODER);
+       if (!obj) {
+               DRM_DEBUG_KMS("Unknown ENCODER ID %d\n",
+                               exynos_connector->encoder_id);
+               return NULL;
+       }
+
+       encoder = obj_to_encoder(obj);
+
+       return encoder;
 }
 
 static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
@@ -196,15 +223,17 @@ static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
 static enum drm_connector_status
 exynos_drm_connector_detect(struct drm_connector *connector, bool force)
 {
-       struct exynos_drm_manager *manager =
-                               exynos_drm_get_manager(connector->encoder);
-       struct exynos_drm_display *display = manager->display;
+       struct exynos_drm_connector *exynos_connector =
+                                       to_exynos_connector(connector);
+       struct exynos_drm_manager *manager = exynos_connector->manager;
+       struct exynos_drm_display_ops *display_ops =
+                                       manager->display_ops;
        enum drm_connector_status status = connector_status_disconnected;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (display && display->is_connected) {
-               if (display->is_connected(manager->dev))
+       if (display_ops && display_ops->is_connected) {
+               if (display_ops->is_connected(manager->dev))
                        status = connector_status_connected;
                else
                        status = connector_status_disconnected;
@@ -251,9 +280,11 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
 
        connector = &exynos_connector->drm_connector;
 
-       switch (manager->display->type) {
+       switch (manager->display_ops->type) {
        case EXYNOS_DISPLAY_TYPE_HDMI:
                type = DRM_MODE_CONNECTOR_HDMIA;
+               connector->interlace_allowed = true;
+               connector->polled = DRM_CONNECTOR_POLL_HPD;
                break;
        default:
                type = DRM_MODE_CONNECTOR_Unknown;
@@ -267,7 +298,10 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
        if (err)
                goto err_connector;
 
+       exynos_connector->encoder_id = encoder->base.id;
+       exynos_connector->manager = manager;
        connector->encoder = encoder;
+
        err = drm_mode_connector_attach_encoder(connector, encoder);
        if (err) {
                DRM_ERROR("failed to attach a connector to a encoder\n");
index 9337e5e2dbb6204428178c8c3a962ebb3d61fab0..ee43cc22085304f7f07f267cd63a7d2be05d249a 100644 (file)
 #include "drmP.h"
 #include "drm_crtc_helper.h"
 
+#include "exynos_drm_crtc.h"
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_encoder.h"
+#include "exynos_drm_gem.h"
 #include "exynos_drm_buf.h"
 
 #define to_exynos_crtc(x)      container_of(x, struct exynos_drm_crtc,\
                                drm_crtc)
 
-/*
- * Exynos specific crtc postion structure.
- *
- * @fb_x: offset x on a framebuffer to be displyed
- *     - the unit is screen coordinates.
- * @fb_y: offset y on a framebuffer to be displayed
- *     - the unit is screen coordinates.
- * @crtc_x: offset x on hardware screen.
- * @crtc_y: offset y on hardware screen.
- * @crtc_w: width of hardware screen.
- * @crtc_h: height of hardware screen.
- */
-struct exynos_drm_crtc_pos {
-       unsigned int fb_x;
-       unsigned int fb_y;
-       unsigned int crtc_x;
-       unsigned int crtc_y;
-       unsigned int crtc_w;
-       unsigned int crtc_h;
-};
-
 /*
  * Exynos specific crtc structure.
  *
@@ -85,30 +66,31 @@ static void exynos_drm_crtc_apply(struct drm_crtc *crtc)
 
        exynos_drm_fn_encoder(crtc, overlay,
                        exynos_drm_encoder_crtc_mode_set);
-       exynos_drm_fn_encoder(crtc, NULL, exynos_drm_encoder_crtc_commit);
+       exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
+                       exynos_drm_encoder_crtc_commit);
 }
 
-static int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
-                                      struct drm_framebuffer *fb,
-                                      struct drm_display_mode *mode,
-                                      struct exynos_drm_crtc_pos *pos)
+int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
+                             struct drm_framebuffer *fb,
+                             struct drm_display_mode *mode,
+                             struct exynos_drm_crtc_pos *pos)
 {
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
        unsigned int actual_w;
        unsigned int actual_h;
 
-       entry = exynos_drm_fb_get_buf(fb);
-       if (!entry) {
-               DRM_LOG_KMS("entry is null.\n");
+       buffer = exynos_drm_fb_get_buf(fb);
+       if (!buffer) {
+               DRM_LOG_KMS("buffer is null.\n");
                return -EFAULT;
        }
 
-       overlay->paddr = entry->paddr;
-       overlay->vaddr = entry->vaddr;
+       overlay->dma_addr = buffer->dma_addr;
+       overlay->vaddr = buffer->kvaddr;
 
-       DRM_DEBUG_KMS("vaddr = 0x%lx, paddr = 0x%lx\n",
+       DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n",
                        (unsigned long)overlay->vaddr,
-                       (unsigned long)overlay->paddr);
+                       (unsigned long)overlay->dma_addr);
 
        actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w);
        actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h);
@@ -171,9 +153,26 @@ static int exynos_drm_crtc_update(struct drm_crtc *crtc)
 
 static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
-       DRM_DEBUG_KMS("%s\n", __FILE__);
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
-       /* TODO */
+       DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
+
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
+                               exynos_drm_encoder_crtc_commit);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               /* TODO */
+               exynos_drm_fn_encoder(crtc, NULL,
+                               exynos_drm_encoder_crtc_disable);
+               break;
+       default:
+               DRM_DEBUG_KMS("unspecified mode %d\n", mode);
+               break;
+       }
 }
 
 static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
@@ -185,9 +184,12 @@ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
 
 static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
 {
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       /* drm framework doesn't check NULL. */
+       exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
+                       exynos_drm_encoder_crtc_commit);
 }
 
 static bool
index c584042d6d2cb21c8282975f9edf28898b4e56e0..25f72a62cb880b757b54e0514693eedd624ce27b 100644 (file)
@@ -35,4 +35,29 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr);
 int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc);
 void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc);
 
+/*
+ * Exynos specific crtc postion structure.
+ *
+ * @fb_x: offset x on a framebuffer to be displyed
+ *     - the unit is screen coordinates.
+ * @fb_y: offset y on a framebuffer to be displayed
+ *     - the unit is screen coordinates.
+ * @crtc_x: offset x on hardware screen.
+ * @crtc_y: offset y on hardware screen.
+ * @crtc_w: width of hardware screen.
+ * @crtc_h: height of hardware screen.
+ */
+struct exynos_drm_crtc_pos {
+       unsigned int fb_x;
+       unsigned int fb_y;
+       unsigned int crtc_x;
+       unsigned int crtc_y;
+       unsigned int crtc_w;
+       unsigned int crtc_h;
+};
+
+int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
+                             struct drm_framebuffer *fb,
+                             struct drm_display_mode *mode,
+                             struct exynos_drm_crtc_pos *pos);
 #endif
index 83810cbe3c1770aeea62814dfdd98c2e1b33df2e..53e2216de61dd5c42c35eaa7f0c23ca1e991a621 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "drmP.h"
 #include "drm.h"
+#include "drm_crtc_helper.h"
 
 #include <drm/exynos_drm.h>
 
@@ -61,6 +62,9 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 
        drm_mode_config_init(dev);
 
+       /* init kms poll for handling hpd */
+       drm_kms_helper_poll_init(dev);
+
        exynos_drm_mode_config_init(dev);
 
        /*
@@ -116,6 +120,7 @@ static int exynos_drm_unload(struct drm_device *dev)
        exynos_drm_fbdev_fini(dev);
        exynos_drm_device_unregister(dev);
        drm_vblank_cleanup(dev);
+       drm_kms_helper_poll_fini(dev);
        drm_mode_config_cleanup(dev);
        kfree(dev->dev_private);
 
index c03683f2ae72dffb084aaede5dba582a68c835f9..5e02e6ecc2e026955c9bf88bd5461bf893c1dbec 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef _EXYNOS_DRM_DRV_H_
 #define _EXYNOS_DRM_DRV_H_
 
+#include <linux/module.h>
 #include "drm.h"
 
 #define MAX_CRTC       2
@@ -79,8 +80,8 @@ struct exynos_drm_overlay_ops {
  * @scan_flag: interlace or progressive way.
  *     (it could be DRM_MODE_FLAG_*)
  * @bpp: pixel size.(in bit)
- * @paddr: bus(accessed by dma) physical memory address to this overlay
- *             and this is physically continuous.
+ * @dma_addr: bus(accessed by dma) address to the memory region allocated
+ *     for a overlay.
  * @vaddr: virtual memory addresss to this overlay.
  * @default_win: a window to be enabled.
  * @color_key: color key on or off.
@@ -108,7 +109,7 @@ struct exynos_drm_overlay {
        unsigned int scan_flag;
        unsigned int bpp;
        unsigned int pitch;
-       dma_addr_t paddr;
+       dma_addr_t dma_addr;
        void __iomem *vaddr;
 
        bool default_win;
@@ -130,7 +131,7 @@ struct exynos_drm_overlay {
  * @check_timing: check if timing is valid or not.
  * @power_on: display device on or off.
  */
-struct exynos_drm_display {
+struct exynos_drm_display_ops {
        enum exynos_drm_output_type type;
        bool (*is_connected)(struct device *dev);
        int (*get_edid)(struct device *dev, struct drm_connector *connector,
@@ -146,12 +147,14 @@ struct exynos_drm_display {
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *           would be called by encoder->mode_set().
  * @commit: set current hw specific display mode to hw.
+ * @disable: disable hardware specific display mode.
  * @enable_vblank: specific driver callback for enabling vblank interrupt.
  * @disable_vblank: specific driver callback for disabling vblank interrupt.
  */
 struct exynos_drm_manager_ops {
        void (*mode_set)(struct device *subdrv_dev, void *mode);
        void (*commit)(struct device *subdrv_dev);
+       void (*disable)(struct device *subdrv_dev);
        int (*enable_vblank)(struct device *subdrv_dev);
        void (*disable_vblank)(struct device *subdrv_dev);
 };
@@ -178,7 +181,7 @@ struct exynos_drm_manager {
        int pipe;
        struct exynos_drm_manager_ops *ops;
        struct exynos_drm_overlay_ops *overlay_ops;
-       struct exynos_drm_display *display;
+       struct exynos_drm_display_ops *display_ops;
 };
 
 /*
index 7cf6fa86a67efb57e10407213639e8084d2c2138..153061415bafba2d3c83d155a7e86a4901db0b52 100644 (file)
@@ -53,15 +53,36 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct drm_connector *connector;
        struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
+       struct exynos_drm_manager_ops *manager_ops = manager->ops;
 
        DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode);
 
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               if (manager_ops && manager_ops->commit)
+                       manager_ops->commit(manager->dev);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               /* TODO */
+               if (manager_ops && manager_ops->disable)
+                       manager_ops->disable(manager->dev);
+               break;
+       default:
+               DRM_ERROR("unspecified mode %d\n", mode);
+               break;
+       }
+
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                if (connector->encoder == encoder) {
-                       struct exynos_drm_display *display = manager->display;
+                       struct exynos_drm_display_ops *display_ops =
+                                                       manager->display_ops;
 
-                       if (display && display->power_on)
-                               display->power_on(manager->dev, mode);
+                       DRM_DEBUG_KMS("connector[%d] dpms[%d]\n",
+                                       connector->base.id, mode);
+                       if (display_ops && display_ops->power_on)
+                               display_ops->power_on(manager->dev, mode);
                }
        }
 }
@@ -116,15 +137,11 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
 {
        struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
        struct exynos_drm_manager_ops *manager_ops = manager->ops;
-       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
        if (manager_ops && manager_ops->commit)
                manager_ops->commit(manager->dev);
-
-       if (overlay_ops && overlay_ops->commit)
-               overlay_ops->commit(manager->dev);
 }
 
 static struct drm_crtc *
@@ -208,10 +225,23 @@ void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data,
 {
        struct drm_device *dev = crtc->dev;
        struct drm_encoder *encoder;
+       struct exynos_drm_private *private = dev->dev_private;
+       struct exynos_drm_manager *manager;
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               if (encoder->crtc != crtc)
-                       continue;
+               /*
+                * if crtc is detached from encoder, check pipe,
+                * otherwise check crtc attached to encoder
+                */
+               if (!encoder->crtc) {
+                       manager = to_exynos_encoder(encoder)->manager;
+                       if (manager->pipe < 0 ||
+                                       private->crtc[manager->pipe] != crtc)
+                               continue;
+               } else {
+                       if (encoder->crtc != crtc)
+                               continue;
+               }
 
                fn(encoder, data);
        }
@@ -250,8 +280,18 @@ void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data)
        struct exynos_drm_manager *manager =
                to_exynos_encoder(encoder)->manager;
        struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+       int crtc = *(int *)data;
+
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       /*
+        * when crtc is detached from encoder, this pipe is used
+        * to select manager operation
+        */
+       manager->pipe = crtc;
 
-       overlay_ops->commit(manager->dev);
+       if (overlay_ops && overlay_ops->commit)
+               overlay_ops->commit(manager->dev);
 }
 
 void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data)
@@ -261,7 +301,28 @@ void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data)
        struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
        struct exynos_drm_overlay *overlay = data;
 
-       overlay_ops->mode_set(manager->dev, overlay);
+       if (overlay_ops && overlay_ops->mode_set)
+               overlay_ops->mode_set(manager->dev, overlay);
+}
+
+void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data)
+{
+       struct exynos_drm_manager *manager =
+               to_exynos_encoder(encoder)->manager;
+       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+
+       DRM_DEBUG_KMS("\n");
+
+       if (overlay_ops && overlay_ops->disable)
+               overlay_ops->disable(manager->dev);
+
+       /*
+        * crtc is already detached from encoder and last
+        * function for detaching is properly done, so
+        * clear pipe from manager to prevent repeated call
+        */
+       if (!encoder->crtc)
+               manager->pipe = -1;
 }
 
 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
index 5ecd645d06a97e1959599ecfd94d2b7ba2d50847..a22acfbf0e4ed6dc31894d03f7a5369158ded8a2 100644 (file)
@@ -41,5 +41,6 @@ void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data);
 void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data);
 void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data);
 void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data);
+void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data);
 
 #endif
index 48d29cfd5240197f645c6732a9360bb255656f97..5bf4a1ac7f828cd26509857e5ed9b024f094f831 100644 (file)
@@ -29,7 +29,9 @@
 #include "drmP.h"
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
+#include "drm_fb_helper.h"
 
+#include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_buf.h"
 #include "exynos_drm_gem.h"
  *
  * @fb: drm framebuffer obejct.
  * @exynos_gem_obj: exynos specific gem object containing a gem object.
- * @entry: pointer to exynos drm buffer entry object.
- *     - containing only the information to physically continuous memory
- *     region allocated at default framebuffer creation.
+ * @buffer: pointer to exynos_drm_gem_buffer object.
+ *     - contain the memory information to memory region allocated
+ *     at default framebuffer creation.
  */
 struct exynos_drm_fb {
        struct drm_framebuffer          fb;
        struct exynos_drm_gem_obj       *exynos_gem_obj;
-       struct exynos_drm_buf_entry     *entry;
+       struct exynos_drm_gem_buf       *buffer;
 };
 
 static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
@@ -63,8 +65,8 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
         * default framebuffer has no gem object so
         * a buffer of the default framebuffer should be released at here.
         */
-       if (!exynos_fb->exynos_gem_obj && exynos_fb->entry)
-               exynos_drm_buf_destroy(fb->dev, exynos_fb->entry);
+       if (!exynos_fb->exynos_gem_obj && exynos_fb->buffer)
+               exynos_drm_buf_destroy(fb->dev, exynos_fb->buffer);
 
        kfree(exynos_fb);
        exynos_fb = NULL;
@@ -143,29 +145,29 @@ exynos_drm_fb_init(struct drm_file *file_priv, struct drm_device *dev,
         */
        if (!mode_cmd->handle) {
                if (!file_priv) {
-                       struct exynos_drm_buf_entry *entry;
+                       struct exynos_drm_gem_buf *buffer;
 
                        /*
                         * in case that file_priv is NULL, it allocates
                         * only buffer and this buffer would be used
                         * for default framebuffer.
                         */
-                       entry = exynos_drm_buf_create(dev, size);
-                       if (IS_ERR(entry)) {
-                               ret = PTR_ERR(entry);
+                       buffer = exynos_drm_buf_create(dev, size);
+                       if (IS_ERR(buffer)) {
+                               ret = PTR_ERR(buffer);
                                goto err_buffer;
                        }
 
-                       exynos_fb->entry = entry;
+                       exynos_fb->buffer = buffer;
 
-                       DRM_LOG_KMS("default fb: paddr = 0x%lx, size = 0x%x\n",
-                                       (unsigned long)entry->paddr, size);
+                       DRM_LOG_KMS("default: dma_addr = 0x%lx, size = 0x%x\n",
+                                       (unsigned long)buffer->dma_addr, size);
 
                        goto out;
                } else {
-                       exynos_gem_obj = exynos_drm_gem_create(file_priv, dev,
-                                                       size,
-                                                       &mode_cmd->handle);
+                       exynos_gem_obj = exynos_drm_gem_create(dev, file_priv,
+                                                       &mode_cmd->handle,
+                                                       size);
                        if (IS_ERR(exynos_gem_obj)) {
                                ret = PTR_ERR(exynos_gem_obj);
                                goto err_buffer;
@@ -189,10 +191,10 @@ exynos_drm_fb_init(struct drm_file *file_priv, struct drm_device *dev,
         * so that default framebuffer has no its own gem object,
         * only its own buffer object.
         */
-       exynos_fb->entry = exynos_gem_obj->entry;
+       exynos_fb->buffer = exynos_gem_obj->buffer;
 
-       DRM_LOG_KMS("paddr = 0x%lx, size = 0x%x, gem object = 0x%x\n",
-                       (unsigned long)exynos_fb->entry->paddr, size,
+       DRM_LOG_KMS("dma_addr = 0x%lx, size = 0x%x, gem object = 0x%x\n",
+                       (unsigned long)exynos_fb->buffer->dma_addr, size,
                        (unsigned int)&exynos_gem_obj->base);
 
 out:
@@ -220,26 +222,36 @@ struct drm_framebuffer *exynos_drm_fb_create(struct drm_device *dev,
        return exynos_drm_fb_init(file_priv, dev, mode_cmd);
 }
 
-struct exynos_drm_buf_entry *exynos_drm_fb_get_buf(struct drm_framebuffer *fb)
+struct exynos_drm_gem_buf *exynos_drm_fb_get_buf(struct drm_framebuffer *fb)
 {
        struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       entry = exynos_fb->entry;
-       if (!entry)
+       buffer = exynos_fb->buffer;
+       if (!buffer)
                return NULL;
 
-       DRM_DEBUG_KMS("vaddr = 0x%lx, paddr = 0x%lx\n",
-                       (unsigned long)entry->vaddr,
-                       (unsigned long)entry->paddr);
+       DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n",
+                       (unsigned long)buffer->kvaddr,
+                       (unsigned long)buffer->dma_addr);
 
-       return entry;
+       return buffer;
+}
+
+static void exynos_drm_output_poll_changed(struct drm_device *dev)
+{
+       struct exynos_drm_private *private = dev->dev_private;
+       struct drm_fb_helper *fb_helper = private->fb_helper;
+
+       if (fb_helper)
+               drm_fb_helper_hotplug_event(fb_helper);
 }
 
 static struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
        .fb_create = exynos_drm_fb_create,
+       .output_poll_changed = exynos_drm_output_poll_changed,
 };
 
 void exynos_drm_mode_config_init(struct drm_device *dev)
index 1f4b3d1a77134d46ae193446a2720020dfd745cf..836f4100818710e830229b985591bfc85a047f03 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
+#include "exynos_drm_gem.h"
 #include "exynos_drm_buf.h"
 
 #define MAX_CONNECTOR          4
@@ -85,15 +86,13 @@ static struct fb_ops exynos_drm_fb_ops = {
 };
 
 static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
-                                    struct drm_framebuffer *fb,
-                                    unsigned int fb_width,
-                                    unsigned int fb_height)
+                                    struct drm_framebuffer *fb)
 {
        struct fb_info *fbi = helper->fbdev;
        struct drm_device *dev = helper->dev;
        struct exynos_drm_fbdev *exynos_fb = to_exynos_fbdev(helper);
-       struct exynos_drm_buf_entry *entry;
-       unsigned int size = fb_width * fb_height * (fb->bits_per_pixel >> 3);
+       struct exynos_drm_gem_buf *buffer;
+       unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
        unsigned long offset;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -101,20 +100,20 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
        exynos_fb->fb = fb;
 
        drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth);
-       drm_fb_helper_fill_var(fbi, helper, fb_width, fb_height);
+       drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
 
-       entry = exynos_drm_fb_get_buf(fb);
-       if (!entry) {
-               DRM_LOG_KMS("entry is null.\n");
+       buffer = exynos_drm_fb_get_buf(fb);
+       if (!buffer) {
+               DRM_LOG_KMS("buffer is null.\n");
                return -EFAULT;
        }
 
        offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
        offset += fbi->var.yoffset * fb->pitch;
 
-       dev->mode_config.fb_base = entry->paddr;
-       fbi->screen_base = entry->vaddr + offset;
-       fbi->fix.smem_start = entry->paddr + offset;
+       dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
+       fbi->screen_base = buffer->kvaddr + offset;
+       fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset);
        fbi->screen_size = size;
        fbi->fix.smem_len = size;
 
@@ -171,8 +170,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
                goto out;
        }
 
-       ret = exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
-                       sizes->fb_height);
+       ret = exynos_drm_fbdev_update(helper, helper->fb);
        if (ret < 0)
                fb_dealloc_cmap(&fbi->cmap);
 
@@ -235,8 +233,7 @@ static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper,
        }
 
        helper->fb = exynos_fbdev->fb;
-       return exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
-                       sizes->fb_height);
+       return exynos_drm_fbdev_update(helper, helper->fb);
 }
 
 static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
@@ -405,6 +402,18 @@ int exynos_drm_fbdev_reinit(struct drm_device *dev)
        fb_helper = private->fb_helper;
 
        if (fb_helper) {
+               struct list_head temp_list;
+
+               INIT_LIST_HEAD(&temp_list);
+
+               /*
+                * fb_helper is reintialized but kernel fb is reused
+                * so kernel_fb_list need to be backuped and restored
+                */
+               if (!list_empty(&fb_helper->kernel_fb_list))
+                       list_replace_init(&fb_helper->kernel_fb_list,
+                                       &temp_list);
+
                drm_fb_helper_fini(fb_helper);
 
                ret = drm_fb_helper_init(dev, fb_helper,
@@ -414,6 +423,9 @@ int exynos_drm_fbdev_reinit(struct drm_device *dev)
                        return ret;
                }
 
+               if (!list_empty(&temp_list))
+                       list_replace(&temp_list, &fb_helper->kernel_fb_list);
+
                ret = drm_fb_helper_single_add_all_connectors(fb_helper);
                if (ret < 0) {
                        DRM_ERROR("failed to add fb helper to connectors\n");
index 4659c88cdd9bbaec81e6d6d1d9fe1d7b03964dec..db3b3d9e731d86475d734884e2ec113a8be5f914 100644 (file)
@@ -64,7 +64,7 @@ struct fimd_win_data {
        unsigned int            fb_width;
        unsigned int            fb_height;
        unsigned int            bpp;
-       dma_addr_t              paddr;
+       dma_addr_t              dma_addr;
        void __iomem            *vaddr;
        unsigned int            buf_offsize;
        unsigned int            line_size;      /* bytes */
@@ -124,7 +124,7 @@ static int fimd_display_power_on(struct device *dev, int mode)
        return 0;
 }
 
-static struct exynos_drm_display fimd_display = {
+static struct exynos_drm_display_ops fimd_display_ops = {
        .type = EXYNOS_DISPLAY_TYPE_LCD,
        .is_connected = fimd_display_is_connected,
        .get_timing = fimd_get_timing,
@@ -177,6 +177,40 @@ static void fimd_commit(struct device *dev)
        writel(val, ctx->regs + VIDCON0);
 }
 
+static void fimd_disable(struct device *dev)
+{
+       struct fimd_context *ctx = get_fimd_context(dev);
+       struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
+       struct drm_device *drm_dev = subdrv->drm_dev;
+       struct exynos_drm_manager *manager = &subdrv->manager;
+       u32 val;
+
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       /* fimd dma off */
+       val = readl(ctx->regs + VIDCON0);
+       val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F);
+       writel(val, ctx->regs + VIDCON0);
+
+       /*
+        * if vblank is enabled status with dma off then
+        * it disables vsync interrupt.
+        */
+       if (drm_dev->vblank_enabled[manager->pipe] &&
+               atomic_read(&drm_dev->vblank_refcount[manager->pipe])) {
+               drm_vblank_put(drm_dev, manager->pipe);
+
+               /*
+                * if vblank_disable_allowed is 0 then disable
+                * vsync interrupt right now else the vsync interrupt
+                * would be disabled by drm timer once a current process
+                * gives up ownershop of vblank event.
+                */
+               if (!drm_dev->vblank_disable_allowed)
+                       drm_vblank_off(drm_dev, manager->pipe);
+       }
+}
+
 static int fimd_enable_vblank(struct device *dev)
 {
        struct fimd_context *ctx = get_fimd_context(dev);
@@ -220,6 +254,7 @@ static void fimd_disable_vblank(struct device *dev)
 
 static struct exynos_drm_manager_ops fimd_manager_ops = {
        .commit = fimd_commit,
+       .disable = fimd_disable,
        .enable_vblank = fimd_enable_vblank,
        .disable_vblank = fimd_disable_vblank,
 };
@@ -251,7 +286,7 @@ static void fimd_win_mode_set(struct device *dev,
        win_data->ovl_height = overlay->crtc_height;
        win_data->fb_width = overlay->fb_width;
        win_data->fb_height = overlay->fb_height;
-       win_data->paddr = overlay->paddr + offset;
+       win_data->dma_addr = overlay->dma_addr + offset;
        win_data->vaddr = overlay->vaddr + offset;
        win_data->bpp = overlay->bpp;
        win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
@@ -263,7 +298,7 @@ static void fimd_win_mode_set(struct device *dev,
        DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
                        win_data->ovl_width, win_data->ovl_height);
        DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n",
-                       (unsigned long)win_data->paddr,
+                       (unsigned long)win_data->dma_addr,
                        (unsigned long)win_data->vaddr);
        DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
                        overlay->fb_width, overlay->crtc_width);
@@ -376,16 +411,16 @@ static void fimd_win_commit(struct device *dev)
        writel(val, ctx->regs + SHADOWCON);
 
        /* buffer start address */
-       val = win_data->paddr;
+       val = (unsigned long)win_data->dma_addr;
        writel(val, ctx->regs + VIDWx_BUF_START(win, 0));
 
        /* buffer end address */
        size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3);
-       val = win_data->paddr + size;
+       val = (unsigned long)(win_data->dma_addr + size);
        writel(val, ctx->regs + VIDWx_BUF_END(win, 0));
 
        DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n",
-                       (unsigned long)win_data->paddr, val, size);
+                       (unsigned long)win_data->dma_addr, val, size);
        DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
                        win_data->ovl_width, win_data->ovl_height);
 
@@ -447,7 +482,6 @@ static void fimd_win_commit(struct device *dev)
 static void fimd_win_disable(struct device *dev)
 {
        struct fimd_context *ctx = get_fimd_context(dev);
-       struct fimd_win_data *win_data;
        int win = ctx->default_win;
        u32 val;
 
@@ -456,8 +490,6 @@ static void fimd_win_disable(struct device *dev)
        if (win < 0 || win > WINDOWS_NR)
                return;
 
-       win_data = &ctx->win_data[win];
-
        /* protect windows */
        val = readl(ctx->regs + SHADOWCON);
        val |= SHADOWCON_WINx_PROTECT(win);
@@ -528,6 +560,16 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
                /* VSYNC interrupt */
                writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1);
 
+       /*
+        * in case that vblank_disable_allowed is 1, it could induce
+        * the problem that manager->pipe could be -1 because with
+        * disable callback, vsync interrupt isn't disabled and at this moment,
+        * vsync interrupt could occur. the vsync interrupt would be disabled
+        * by timer handler later.
+        */
+       if (manager->pipe == -1)
+               return IRQ_HANDLED;
+
        drm_handle_vblank(drm_dev, manager->pipe);
        fimd_finish_pageflip(drm_dev, manager->pipe);
 
@@ -548,13 +590,6 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
         */
        drm_dev->irq_enabled = 1;
 
-       /*
-        * with vblank_disable_allowed = 1, vblank interrupt will be disabled
-        * by drm timer once a current process gives up ownership of
-        * vblank event.(drm_vblank_put function was called)
-        */
-       drm_dev->vblank_disable_allowed = 1;
-
        return 0;
 }
 
@@ -731,7 +766,7 @@ static int __devinit fimd_probe(struct platform_device *pdev)
        subdrv->manager.pipe = -1;
        subdrv->manager.ops = &fimd_manager_ops;
        subdrv->manager.overlay_ops = &fimd_overlay_ops;
-       subdrv->manager.display = &fimd_display;
+       subdrv->manager.display_ops = &fimd_display_ops;
        subdrv->manager.dev = dev;
 
        platform_set_drvdata(pdev, ctx);
index a8e7a88906ed22e43fb23d23a859dc825a335451..aba0fe47f7eaae47c10ac4b0839eba8c1edf7f54 100644 (file)
@@ -62,40 +62,28 @@ static unsigned int get_gem_mmap_offset(struct drm_gem_object *obj)
        return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT;
 }
 
-struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_file *file_priv,
-               struct drm_device *dev, unsigned int size,
-               unsigned int *handle)
+static struct exynos_drm_gem_obj
+               *exynos_drm_gem_init(struct drm_device *drm_dev,
+                       struct drm_file *file_priv, unsigned int *handle,
+                       unsigned int size)
 {
        struct exynos_drm_gem_obj *exynos_gem_obj;
-       struct exynos_drm_buf_entry *entry;
        struct drm_gem_object *obj;
        int ret;
 
-       DRM_DEBUG_KMS("%s\n", __FILE__);
-
-       size = roundup(size, PAGE_SIZE);
-
        exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL);
        if (!exynos_gem_obj) {
                DRM_ERROR("failed to allocate exynos gem object.\n");
                return ERR_PTR(-ENOMEM);
        }
 
-       /* allocate the new buffer object and memory region. */
-       entry = exynos_drm_buf_create(dev, size);
-       if (!entry) {
-               kfree(exynos_gem_obj);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       exynos_gem_obj->entry = entry;
-
        obj = &exynos_gem_obj->base;
 
-       ret = drm_gem_object_init(dev, obj, size);
+       ret = drm_gem_object_init(drm_dev, obj, size);
        if (ret < 0) {
-               DRM_ERROR("failed to initailize gem object.\n");
-               goto err_obj_init;
+               DRM_ERROR("failed to initialize gem object.\n");
+               ret = -EINVAL;
+               goto err_object_init;
        }
 
        DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
@@ -127,24 +115,50 @@ err_handle_create:
 err_create_mmap_offset:
        drm_gem_object_release(obj);
 
-err_obj_init:
-       exynos_drm_buf_destroy(dev, exynos_gem_obj->entry);
-
+err_object_init:
        kfree(exynos_gem_obj);
 
        return ERR_PTR(ret);
 }
 
+struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
+                               struct drm_file *file_priv,
+                               unsigned int *handle, unsigned long size)
+{
+
+       struct exynos_drm_gem_obj *exynos_gem_obj = NULL;
+       struct exynos_drm_gem_buf *buffer;
+
+       size = roundup(size, PAGE_SIZE);
+
+       DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
+
+       buffer = exynos_drm_buf_create(dev, size);
+       if (IS_ERR(buffer)) {
+               return ERR_CAST(buffer);
+       }
+
+       exynos_gem_obj = exynos_drm_gem_init(dev, file_priv, handle, size);
+       if (IS_ERR(exynos_gem_obj)) {
+               exynos_drm_buf_destroy(dev, buffer);
+               return exynos_gem_obj;
+       }
+
+       exynos_gem_obj->buffer = buffer;
+
+       return exynos_gem_obj;
+}
+
 int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
-               struct drm_file *file_priv)
+                                       struct drm_file *file_priv)
 {
        struct drm_exynos_gem_create *args = data;
-       struct exynos_drm_gem_obj *exynos_gem_obj;
+       struct exynos_drm_gem_obj *exynos_gem_obj = NULL;
 
-       DRM_DEBUG_KMS("%s : size = 0x%x\n", __FILE__, args->size);
+       DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       exynos_gem_obj = exynos_drm_gem_create(file_priv, dev, args->size,
-                       &args->handle);
+       exynos_gem_obj = exynos_drm_gem_create(dev, file_priv,
+                                               &args->handle, args->size);
        if (IS_ERR(exynos_gem_obj))
                return PTR_ERR(exynos_gem_obj);
 
@@ -175,7 +189,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
 {
        struct drm_gem_object *obj = filp->private_data;
        struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
        unsigned long pfn, vm_size;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -187,20 +201,20 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
 
        vm_size = vma->vm_end - vma->vm_start;
        /*
-        * a entry contains information to physically continuous memory
+        * a buffer contains information to physically continuous memory
         * allocated by user request or at framebuffer creation.
         */
-       entry = exynos_gem_obj->entry;
+       buffer = exynos_gem_obj->buffer;
 
        /* check if user-requested size is valid. */
-       if (vm_size > entry->size)
+       if (vm_size > buffer->size)
                return -EINVAL;
 
        /*
         * get page frame number to physical memory to be mapped
         * to user space.
         */
-       pfn = exynos_gem_obj->entry->paddr >> PAGE_SHIFT;
+       pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >> PAGE_SHIFT;
 
        DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn);
 
@@ -281,7 +295,7 @@ void exynos_drm_gem_free_object(struct drm_gem_object *gem_obj)
 
        exynos_gem_obj = to_exynos_gem_obj(gem_obj);
 
-       exynos_drm_buf_destroy(gem_obj->dev, exynos_gem_obj->entry);
+       exynos_drm_buf_destroy(gem_obj->dev, exynos_gem_obj->buffer);
 
        kfree(exynos_gem_obj);
 }
@@ -302,8 +316,8 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
        args->pitch = args->width * args->bpp >> 3;
        args->size = args->pitch * args->height;
 
-       exynos_gem_obj = exynos_drm_gem_create(file_priv, dev, args->size,
-                                                       &args->handle);
+       exynos_gem_obj = exynos_drm_gem_create(dev, file_priv, &args->handle,
+                                                       args->size);
        if (IS_ERR(exynos_gem_obj))
                return PTR_ERR(exynos_gem_obj);
 
@@ -360,7 +374,8 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 
        mutex_lock(&dev->struct_mutex);
 
-       pfn = (exynos_gem_obj->entry->paddr >> PAGE_SHIFT) + page_offset;
+       pfn = (((unsigned long)exynos_gem_obj->buffer->dma_addr) >>
+                       PAGE_SHIFT) + page_offset;
 
        ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
 
index e5fc0148277bf84b5fe8c9a31365256c940da802..ef8797334e6da746c54eed761521aacdc7afd7a8 100644 (file)
 #define to_exynos_gem_obj(x)   container_of(x,\
                        struct exynos_drm_gem_obj, base)
 
+/*
+ * exynos drm gem buffer structure.
+ *
+ * @kvaddr: kernel virtual address to allocated memory region.
+ * @dma_addr: bus address(accessed by dma) to allocated memory region.
+ *     - this address could be physical address without IOMMU and
+ *     device address with IOMMU.
+ * @size: size of allocated memory region.
+ */
+struct exynos_drm_gem_buf {
+       void __iomem            *kvaddr;
+       dma_addr_t              dma_addr;
+       unsigned long           size;
+};
+
 /*
  * exynos drm buffer structure.
  *
  * @base: a gem object.
  *     - a new handle to this gem object would be created
  *     by drm_gem_handle_create().
- * @entry: pointer to exynos drm buffer entry object.
- *     - containing the information to physically
+ * @buffer: a pointer to exynos_drm_gem_buffer object.
+ *     - contain the information to memory region allocated
+ *     by user request or at framebuffer creation.
  *     continuous memory region allocated by user request
  *     or at framebuffer creation.
  *
  */
 struct exynos_drm_gem_obj {
        struct drm_gem_object base;
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
 };
 
 /* create a new buffer and get a new gem handle. */
-struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_file *file_priv,
-               struct drm_device *dev, unsigned int size,
-               unsigned int *handle);
+struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
+               struct drm_file *file_priv,
+               unsigned int *handle, unsigned long size);
 
 /*
  * request gem object creation and buffer allocation as the size
index 4f40f1ce1d8effd5ff1c5502cfcefcaaf49af751..d09a6e02dc95374caf456923cba25efa94aafa94 100644 (file)
@@ -636,11 +636,16 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring;
+       int ret;
 
        ring = &dev_priv->ring[(uintptr_t)node->info_ent->data];
        if (ring->size == 0)
                return 0;
 
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
        seq_printf(m, "Ring %s:\n", ring->name);
        seq_printf(m, "  Head :    %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR);
        seq_printf(m, "  Tail :    %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR);
@@ -654,6 +659,8 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
        seq_printf(m, "  Control : %08x\n", I915_READ_CTL(ring));
        seq_printf(m, "  Start :   %08x\n", I915_READ_START(ring));
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
@@ -842,7 +849,16 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       u16 crstanddelay = I915_READ16(CRSTANDVID);
+       u16 crstanddelay;
+       int ret;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       crstanddelay = I915_READ16(CRSTANDVID);
+
+       mutex_unlock(&dev->struct_mutex);
 
        seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f));
 
@@ -940,7 +956,11 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 delayfreq;
-       int i;
+       int ret, i;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
 
        for (i = 0; i < 16; i++) {
                delayfreq = I915_READ(PXVFREQ_BASE + i * 4);
@@ -948,6 +968,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)
                           (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT);
        }
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
@@ -962,13 +984,19 @@ static int i915_inttoext_table(struct seq_file *m, void *unused)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 inttoext;
-       int i;
+       int ret, i;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
 
        for (i = 1; i <= 32; i++) {
                inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4);
                seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext);
        }
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
@@ -977,9 +1005,19 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       u32 rgvmodectl = I915_READ(MEMMODECTL);
-       u32 rstdbyctl = I915_READ(RSTDBYCTL);
-       u16 crstandvid = I915_READ16(CRSTANDVID);
+       u32 rgvmodectl, rstdbyctl;
+       u16 crstandvid;
+       int ret;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       rgvmodectl = I915_READ(MEMMODECTL);
+       rstdbyctl = I915_READ(RSTDBYCTL);
+       crstandvid = I915_READ16(CRSTANDVID);
+
+       mutex_unlock(&dev->struct_mutex);
 
        seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
                   "yes" : "no");
@@ -1167,9 +1205,16 @@ static int i915_gfxec(struct seq_file *m, void *unused)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       int ret;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
 
        seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4));
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
index e9c2cfe45daae06b71fcae28836d3ae6dbb0497f..15bfa9145d2b7f007b21f54ecee19b8b502648f2 100644 (file)
@@ -68,7 +68,7 @@ module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
 MODULE_PARM_DESC(i915_enable_rc6,
                "Enable power-saving render C-state 6 (default: true)");
 
-unsigned int i915_enable_fbc __read_mostly = -1;
+int i915_enable_fbc __read_mostly = -1;
 module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
 MODULE_PARM_DESC(i915_enable_fbc,
                "Enable frame buffer compression for power savings "
@@ -80,7 +80,7 @@ MODULE_PARM_DESC(lvds_downclock,
                "Use panel (LVDS/eDP) downclocking for power savings "
                "(default: false)");
 
-unsigned int i915_panel_use_ssc __read_mostly = -1;
+int i915_panel_use_ssc __read_mostly = -1;
 module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600);
 MODULE_PARM_DESC(lvds_use_ssc,
                "Use Spread Spectrum Clock with panels [LVDS/eDP] "
@@ -107,7 +107,7 @@ static struct drm_driver driver;
 extern int intel_agp_enabled;
 
 #define INTEL_VGA_DEVICE(id, info) {           \
-       .class = PCI_CLASS_DISPLAY_VGA << 8,    \
+       .class = PCI_BASE_CLASS_DISPLAY << 16,  \
        .class_mask = 0xff0000,                 \
        .vendor = 0x8086,                       \
        .device = id,                           \
index 06a37f4fd74b17ad82a0ba912da22d9df63e0dba..4a9c1b97980493b47c1f4e03a7e299f800a7f4e0 100644 (file)
@@ -126,6 +126,9 @@ struct drm_i915_master_private {
        struct _drm_i915_sarea *sarea_priv;
 };
 #define I915_FENCE_REG_NONE -1
+#define I915_MAX_NUM_FENCES 16
+/* 16 fences + sign bit for FENCE_REG_NONE */
+#define I915_MAX_NUM_FENCE_BITS 5
 
 struct drm_i915_fence_reg {
        struct list_head lru_list;
@@ -168,7 +171,7 @@ struct drm_i915_error_state {
        u32 instdone1;
        u32 seqno;
        u64 bbaddr;
-       u64 fence[16];
+       u64 fence[I915_MAX_NUM_FENCES];
        struct timeval time;
        struct drm_i915_error_object {
                int page_count;
@@ -182,7 +185,7 @@ struct drm_i915_error_state {
                u32 gtt_offset;
                u32 read_domains;
                u32 write_domain;
-               s32 fence_reg:5;
+               s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
                s32 pinned:2;
                u32 tiling:2;
                u32 dirty:1;
@@ -375,7 +378,7 @@ typedef struct drm_i915_private {
        struct notifier_block lid_notifier;
 
        int crt_ddc_pin;
-       struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
+       struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */
        int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
        int num_fence_regs; /* 8 on pre-965, 16 otherwise */
 
@@ -506,7 +509,7 @@ typedef struct drm_i915_private {
        u8 saveAR[21];
        u8 saveDACMASK;
        u8 saveCR[37];
-       uint64_t saveFENCE[16];
+       uint64_t saveFENCE[I915_MAX_NUM_FENCES];
        u32 saveCURACNTR;
        u32 saveCURAPOS;
        u32 saveCURABASE;
@@ -777,10 +780,8 @@ struct drm_i915_gem_object {
         * Fence register bits (if any) for this object.  Will be set
         * as needed when mapped into the GTT.
         * Protected by dev->struct_mutex.
-        *
-        * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)
         */
-       signed int fence_reg:5;
+       signed int fence_reg:I915_MAX_NUM_FENCE_BITS;
 
        /**
         * Advice: are the backing pages purgeable?
@@ -999,10 +1000,10 @@ extern int i915_panel_ignore_lid __read_mostly;
 extern unsigned int i915_powersave __read_mostly;
 extern unsigned int i915_semaphores __read_mostly;
 extern unsigned int i915_lvds_downclock __read_mostly;
-extern unsigned int i915_panel_use_ssc __read_mostly;
+extern int i915_panel_use_ssc __read_mostly;
 extern int i915_vbt_sdvo_panel_type __read_mostly;
 extern unsigned int i915_enable_rc6 __read_mostly;
-extern unsigned int i915_enable_fbc __read_mostly;
+extern int i915_enable_fbc __read_mostly;
 extern bool i915_enable_hangcheck __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
index d18b07adcffa3779fb8f6ba9090e5c2f9c279d66..8359dc777041be9265e53907025564196b1d0fbc 100644 (file)
@@ -1745,7 +1745,7 @@ static void i915_gem_reset_fences(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
 
-       for (i = 0; i < 16; i++) {
+       for (i = 0; i < dev_priv->num_fence_regs; i++) {
                struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
                struct drm_i915_gem_object *obj = reg->obj;
 
@@ -3512,9 +3512,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
                         * so emit a request to do so.
                         */
                        request = kzalloc(sizeof(*request), GFP_KERNEL);
-                       if (request)
+                       if (request) {
                                ret = i915_add_request(obj->ring, NULL, request);
-                       else
+                               if (ret)
+                                       kfree(request);
+                       } else
                                ret = -ENOMEM;
                }
 
@@ -3613,7 +3615,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
        obj->base.write_domain = I915_GEM_DOMAIN_CPU;
        obj->base.read_domains = I915_GEM_DOMAIN_CPU;
 
-       if (IS_GEN6(dev)) {
+       if (IS_GEN6(dev) || IS_GEN7(dev)) {
                /* On Gen6, we can have the GPU use the LLC (the CPU
                 * cache) for about a 10% performance improvement
                 * compared to uncached.  Graphics requests other than
@@ -3877,7 +3879,7 @@ i915_gem_load(struct drm_device *dev)
        INIT_LIST_HEAD(&dev_priv->mm.gtt_list);
        for (i = 0; i < I915_NUM_RINGS; i++)
                init_ring_lists(&dev_priv->ring[i]);
-       for (i = 0; i < 16; i++)
+       for (i = 0; i < I915_MAX_NUM_FENCES; i++)
                INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
        INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
                          i915_gem_retire_work_handler);
index 9ee2729fe5c65ec3690a1f9dcf403045c79a4907..b40004b559771dc0244814335d44fb1537625087 100644 (file)
@@ -824,6 +824,7 @@ static void i915_gem_record_fences(struct drm_device *dev,
 
        /* Fences */
        switch (INTEL_INFO(dev)->gen) {
+       case 7:
        case 6:
                for (i = 0; i < 16; i++)
                        error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
index 5a09416e611f566774e18ad7095d3c007ea1876b..b080cc82400153a68aed7cca1f3319de361a1f93 100644 (file)
  */
 #define   PP_READY             (1 << 30)
 #define   PP_SEQUENCE_NONE     (0 << 28)
-#define   PP_SEQUENCE_ON       (1 << 28)
-#define   PP_SEQUENCE_OFF      (2 << 28)
-#define   PP_SEQUENCE_MASK     0x30000000
+#define   PP_SEQUENCE_POWER_UP (1 << 28)
+#define   PP_SEQUENCE_POWER_DOWN (2 << 28)
+#define   PP_SEQUENCE_MASK     (3 << 28)
+#define   PP_SEQUENCE_SHIFT    28
 #define   PP_CYCLE_DELAY_ACTIVE        (1 << 27)
-#define   PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
 #define   PP_SEQUENCE_STATE_MASK 0x0000000f
+#define   PP_SEQUENCE_STATE_OFF_IDLE   (0x0 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_1   (0x1 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_2   (0x2 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_3   (0x3 << 0)
+#define   PP_SEQUENCE_STATE_ON_IDLE    (0x8 << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_0    (0x9 << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_2    (0xa << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_3    (0xb << 0)
+#define   PP_SEQUENCE_STATE_RESET      (0xf << 0)
 #define PP_CONTROL     0x61204
 #define   POWER_TARGET_ON      (1 << 0)
 #define PP_ON_DELAYS   0x61208
 #define  GT_FIFO_FREE_ENTRIES                  0x120008
 #define    GT_FIFO_NUM_RESERVED_ENTRIES                20
 
+#define GEN6_UCGCTL2                           0x9404
+# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE              (1 << 12)
+# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE               (1 << 11)
+
 #define GEN6_RPNSWREQ                          0xA008
 #define   GEN6_TURBO_DISABLE                   (1<<31)
 #define   GEN6_FREQUENCY(x)                    ((x)<<25)
index f8f602d76650177c1d7b3a11c9cac3b185fee1bf..7886e4fb60e3e23fb283461a690dbe43a928fc6e 100644 (file)
@@ -370,6 +370,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
 
        /* Fences */
        switch (INTEL_INFO(dev)->gen) {
+       case 7:
        case 6:
                for (i = 0; i < 16; i++)
                        dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
@@ -404,6 +405,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
 
        /* Fences */
        switch (INTEL_INFO(dev)->gen) {
+       case 7:
        case 6:
                for (i = 0; i < 16; i++)
                        I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]);
index 981b1f1c04d8da4459f9ae776cf0681576eb915f..e77a863a3833f63511a98991508b2f5c1a6ee0d1 100644 (file)
@@ -2933,7 +2933,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
 
        /* For PCH DP, enable TRANS_DP_CTL */
        if (HAS_PCH_CPT(dev) &&
-           intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
+           (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
+            intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
                u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5;
                reg = TRANS_DP_CTL(pipe);
                temp = I915_READ(reg);
@@ -4711,7 +4712,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                                lvds_bpc = 6;
 
                        if (lvds_bpc < display_bpc) {
-                               DRM_DEBUG_DRIVER("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
+                               DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
                                display_bpc = lvds_bpc;
                        }
                        continue;
@@ -4722,7 +4723,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                        unsigned int edp_bpc = dev_priv->edp.bpp / 3;
 
                        if (edp_bpc < display_bpc) {
-                               DRM_DEBUG_DRIVER("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
+                               DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
                                display_bpc = edp_bpc;
                        }
                        continue;
@@ -4737,7 +4738,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                        /* Don't use an invalid EDID bpc value */
                        if (connector->display_info.bpc &&
                            connector->display_info.bpc < display_bpc) {
-                               DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
+                               DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
                                display_bpc = connector->display_info.bpc;
                        }
                }
@@ -4748,10 +4749,10 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                 */
                if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
                        if (display_bpc > 8 && display_bpc < 12) {
-                               DRM_DEBUG_DRIVER("forcing bpc to 12 for HDMI\n");
+                               DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
                                display_bpc = 12;
                        } else {
-                               DRM_DEBUG_DRIVER("forcing bpc to 8 for HDMI\n");
+                               DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
                                display_bpc = 8;
                        }
                }
@@ -4789,8 +4790,8 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
 
        display_bpc = min(display_bpc, bpc);
 
-       DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n",
-                        bpc, display_bpc);
+       DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n",
+                     bpc, display_bpc);
 
        *pipe_bpp = display_bpc * 3;
 
@@ -5671,7 +5672,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
        pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;
        if ((is_lvds && dev_priv->lvds_dither) || dither) {
                pipeconf |= PIPECONF_DITHER_EN;
-               pipeconf |= PIPECONF_DITHER_TYPE_ST1;
+               pipeconf |= PIPECONF_DITHER_TYPE_SP;
        }
        if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
                intel_dp_set_m_n(crtc, mode, adjusted_mode);
@@ -8148,6 +8149,20 @@ static void gen6_init_clock_gating(struct drm_device *dev)
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
 
+       /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
+        * gating disable must be set.  Failure to set it results in
+        * flickering pixels due to Z write ordering failures after
+        * some amount of runtime in the Mesa "fire" demo, and Unigine
+        * Sanctuary and Tropics, and apparently anything else with
+        * alpha test or pixel discard.
+        *
+        * According to the spec, bit 11 (RCCUNIT) must also be set,
+        * but we didn't debug actual testcases to find it out.
+        */
+       I915_WRITE(GEN6_UCGCTL2,
+                  GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
+                  GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
+
        /*
         * According to the spec the following bits should be
         * set in order to enable memory self-refresh and fbc:
index 09b318b0227f3571402c479c06bb376c6aae7eda..4d0358fad93795c31dd9d4229daa3c7c2ecedcc5 100644 (file)
@@ -59,7 +59,6 @@ struct intel_dp {
        struct i2c_algo_dp_aux_data algo;
        bool is_pch_edp;
        uint8_t train_set[4];
-       uint8_t link_status[DP_LINK_STATUS_SIZE];
        int panel_power_up_delay;
        int panel_power_down_delay;
        int panel_power_cycle_delay;
@@ -68,7 +67,6 @@ struct intel_dp {
        struct drm_display_mode *panel_fixed_mode;  /* for eDP */
        struct delayed_work panel_vdd_work;
        bool want_panel_vdd;
-       unsigned long panel_off_jiffies;
 };
 
 /**
@@ -157,16 +155,12 @@ intel_edp_link_config(struct intel_encoder *intel_encoder,
 static int
 intel_dp_max_lane_count(struct intel_dp *intel_dp)
 {
-       int max_lane_count = 4;
-
-       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
-               max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
-               switch (max_lane_count) {
-               case 1: case 2: case 4:
-                       break;
-               default:
-                       max_lane_count = 4;
-               }
+       int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
+       switch (max_lane_count) {
+       case 1: case 2: case 4:
+               break;
+       default:
+               max_lane_count = 4;
        }
        return max_lane_count;
 }
@@ -768,12 +762,11 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                        continue;
 
                intel_dp = enc_to_intel_dp(encoder);
-               if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
+               if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
+                   intel_dp->base.type == INTEL_OUTPUT_EDP)
+               {
                        lane_count = intel_dp->lane_count;
                        break;
-               } else if (is_edp(intel_dp)) {
-                       lane_count = dev_priv->edp.lanes;
-                       break;
                }
        }
 
@@ -810,6 +803,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                  struct drm_display_mode *adjusted_mode)
 {
        struct drm_device *dev = encoder->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        struct drm_crtc *crtc = intel_dp->base.base.crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -822,18 +816,31 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                        ironlake_edp_pll_off(encoder);
        }
 
-       intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
-       intel_dp->DP |= intel_dp->color_range;
+       /*
+        * There are three kinds of DP registers:
+        *
+        *      IBX PCH
+        *      CPU
+        *      CPT PCH
+        *
+        * IBX PCH and CPU are the same for almost everything,
+        * except that the CPU DP PLL is configured in this
+        * register
+        *
+        * CPT PCH is quite different, having many bits moved
+        * to the TRANS_DP_CTL register instead. That
+        * configuration happens (oddly) in ironlake_pch_enable
+        */
 
-       if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
-               intel_dp->DP |= DP_SYNC_HS_HIGH;
-       if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
-               intel_dp->DP |= DP_SYNC_VS_HIGH;
+       /* Preserve the BIOS-computed detected bit. This is
+        * supposed to be read-only.
+        */
+       intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
+       intel_dp->DP |=  DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
 
-       if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
-               intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
-       else
-               intel_dp->DP |= DP_LINK_TRAIN_OFF;
+       /* Handle DP bits in common between all three register formats */
+
+       intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
 
        switch (intel_dp->lane_count) {
        case 1:
@@ -852,59 +859,106 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
                intel_write_eld(encoder, adjusted_mode);
        }
-
        memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
        intel_dp->link_configuration[0] = intel_dp->link_bw;
        intel_dp->link_configuration[1] = intel_dp->lane_count;
        intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B;
-
        /*
         * Check for DPCD version > 1.1 and enhanced framing support
         */
        if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
            (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
                intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
-               intel_dp->DP |= DP_ENHANCED_FRAMING;
        }
 
-       /* CPT DP's pipe select is decided in TRANS_DP_CTL */
-       if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev))
-               intel_dp->DP |= DP_PIPEB_SELECT;
+       /* Split out the IBX/CPU vs CPT settings */
 
-       if (is_cpu_edp(intel_dp)) {
-               /* don't miss out required setting for eDP */
-               intel_dp->DP |= DP_PLL_ENABLE;
-               if (adjusted_mode->clock < 200000)
-                       intel_dp->DP |= DP_PLL_FREQ_160MHZ;
-               else
-                       intel_dp->DP |= DP_PLL_FREQ_270MHZ;
+       if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
+               intel_dp->DP |= intel_dp->color_range;
+
+               if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+                       intel_dp->DP |= DP_SYNC_HS_HIGH;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+                       intel_dp->DP |= DP_SYNC_VS_HIGH;
+               intel_dp->DP |= DP_LINK_TRAIN_OFF;
+
+               if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
+                       intel_dp->DP |= DP_ENHANCED_FRAMING;
+
+               if (intel_crtc->pipe == 1)
+                       intel_dp->DP |= DP_PIPEB_SELECT;
+
+               if (is_cpu_edp(intel_dp)) {
+                       /* don't miss out required setting for eDP */
+                       intel_dp->DP |= DP_PLL_ENABLE;
+                       if (adjusted_mode->clock < 200000)
+                               intel_dp->DP |= DP_PLL_FREQ_160MHZ;
+                       else
+                               intel_dp->DP |= DP_PLL_FREQ_270MHZ;
+               }
+       } else {
+               intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
        }
 }
 
-static void ironlake_wait_panel_off(struct intel_dp *intel_dp)
+#define IDLE_ON_MASK           (PP_ON | 0        | PP_SEQUENCE_MASK | 0                     | PP_SEQUENCE_STATE_MASK)
+#define IDLE_ON_VALUE          (PP_ON | 0        | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_ON_IDLE)
+
+#define IDLE_OFF_MASK          (PP_ON | 0        | PP_SEQUENCE_MASK | 0                     | PP_SEQUENCE_STATE_MASK)
+#define IDLE_OFF_VALUE         (0     | 0        | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_OFF_IDLE)
+
+#define IDLE_CYCLE_MASK                (PP_ON | 0        | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK)
+#define IDLE_CYCLE_VALUE       (0     | 0        | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_OFF_IDLE)
+
+static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
+                                      u32 mask,
+                                      u32 value)
 {
-       unsigned long   off_time;
-       unsigned long   delay;
+       struct drm_device *dev = intel_dp->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
-       DRM_DEBUG_KMS("Wait for panel power off time\n");
+       DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
+                     mask, value,
+                     I915_READ(PCH_PP_STATUS),
+                     I915_READ(PCH_PP_CONTROL));
 
-       if (ironlake_edp_have_panel_power(intel_dp) ||
-           ironlake_edp_have_panel_vdd(intel_dp))
-       {
-               DRM_DEBUG_KMS("Panel still on, no delay needed\n");
-               return;
+       if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) {
+               DRM_ERROR("Panel status timeout: status %08x control %08x\n",
+                         I915_READ(PCH_PP_STATUS),
+                         I915_READ(PCH_PP_CONTROL));
        }
+}
 
-       off_time = intel_dp->panel_off_jiffies + msecs_to_jiffies(intel_dp->panel_power_down_delay);
-       if (time_after(jiffies, off_time)) {
-               DRM_DEBUG_KMS("Time already passed");
-               return;
-       }
-       delay = jiffies_to_msecs(off_time - jiffies);
-       if (delay > intel_dp->panel_power_down_delay)
-               delay = intel_dp->panel_power_down_delay;
-       DRM_DEBUG_KMS("Waiting an additional %ld ms\n", delay);
-       msleep(delay);
+static void ironlake_wait_panel_on(struct intel_dp *intel_dp)
+{
+       DRM_DEBUG_KMS("Wait for panel power on\n");
+       ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE);
+}
+
+static void ironlake_wait_panel_off(struct intel_dp *intel_dp)
+{
+       DRM_DEBUG_KMS("Wait for panel power off time\n");
+       ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE);
+}
+
+static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp)
+{
+       DRM_DEBUG_KMS("Wait for panel power cycle\n");
+       ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE);
+}
+
+
+/* Read the current pp_control value, unlocking the register if it
+ * is locked
+ */
+
+static  u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv)
+{
+       u32     control = I915_READ(PCH_PP_CONTROL);
+
+       control &= ~PANEL_UNLOCK_MASK;
+       control |= PANEL_UNLOCK_REGS;
+       return control;
 }
 
 static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
@@ -921,15 +975,16 @@ static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
             "eDP VDD already requested on\n");
 
        intel_dp->want_panel_vdd = true;
+
        if (ironlake_edp_have_panel_vdd(intel_dp)) {
                DRM_DEBUG_KMS("eDP VDD already on\n");
                return;
        }
 
-       ironlake_wait_panel_off(intel_dp);
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
+       if (!ironlake_edp_have_panel_power(intel_dp))
+               ironlake_wait_panel_power_cycle(intel_dp);
+
+       pp = ironlake_get_pp_control(dev_priv);
        pp |= EDP_FORCE_VDD;
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
@@ -952,9 +1007,7 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
        u32 pp;
 
        if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) {
-               pp = I915_READ(PCH_PP_CONTROL);
-               pp &= ~PANEL_UNLOCK_MASK;
-               pp |= PANEL_UNLOCK_REGS;
+               pp = ironlake_get_pp_control(dev_priv);
                pp &= ~EDP_FORCE_VDD;
                I915_WRITE(PCH_PP_CONTROL, pp);
                POSTING_READ(PCH_PP_CONTROL);
@@ -962,7 +1015,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
                /* Make sure sequencer is idle before allowing subsequent activity */
                DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
                              I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
-               intel_dp->panel_off_jiffies = jiffies;
+
+               msleep(intel_dp->panel_power_down_delay);
        }
 }
 
@@ -972,9 +1026,9 @@ static void ironlake_panel_vdd_work(struct work_struct *__work)
                                                 struct intel_dp, panel_vdd_work);
        struct drm_device *dev = intel_dp->base.base.dev;
 
-       mutex_lock(&dev->struct_mutex);
+       mutex_lock(&dev->mode_config.mutex);
        ironlake_panel_vdd_off_sync(intel_dp);
-       mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->mode_config.mutex);
 }
 
 static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
@@ -984,7 +1038,7 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
 
        DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd);
        WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on");
-       
+
        intel_dp->want_panel_vdd = false;
 
        if (sync) {
@@ -1000,23 +1054,25 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
        }
 }
 
-/* Returns true if the panel was already on when called */
 static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 {
        struct drm_device *dev = intel_dp->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE;
+       u32 pp;
 
        if (!is_edp(intel_dp))
                return;
-       if (ironlake_edp_have_panel_power(intel_dp))
+
+       DRM_DEBUG_KMS("Turn eDP power on\n");
+
+       if (ironlake_edp_have_panel_power(intel_dp)) {
+               DRM_DEBUG_KMS("eDP power already on\n");
                return;
+       }
 
-       ironlake_wait_panel_off(intel_dp);
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
+       ironlake_wait_panel_power_cycle(intel_dp);
 
+       pp = ironlake_get_pp_control(dev_priv);
        if (IS_GEN5(dev)) {
                /* ILK workaround: disable reset around power sequence */
                pp &= ~PANEL_POWER_RESET;
@@ -1025,13 +1081,13 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
        }
 
        pp |= POWER_TARGET_ON;
+       if (!IS_GEN5(dev))
+               pp |= PANEL_POWER_RESET;
+
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
 
-       if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask,
-                    5000))
-               DRM_ERROR("panel on wait timed out: 0x%08x\n",
-                         I915_READ(PCH_PP_STATUS));
+       ironlake_wait_panel_on(intel_dp);
 
        if (IS_GEN5(dev)) {
                pp |= PANEL_POWER_RESET; /* restore panel reset bit */
@@ -1040,46 +1096,25 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
        }
 }
 
-static void ironlake_edp_panel_off(struct drm_encoder *encoder)
+static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 {
-       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-       struct drm_device *dev = encoder->dev;
+       struct drm_device *dev = intel_dp->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK |
-               PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK;
+       u32 pp;
 
        if (!is_edp(intel_dp))
                return;
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
 
-       if (IS_GEN5(dev)) {
-               /* ILK workaround: disable reset around power sequence */
-               pp &= ~PANEL_POWER_RESET;
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
-       }
+       DRM_DEBUG_KMS("Turn eDP power off\n");
 
-       intel_dp->panel_off_jiffies = jiffies;
+       WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n");
 
-       if (IS_GEN5(dev)) {
-               pp &= ~POWER_TARGET_ON;
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
-               pp &= ~POWER_TARGET_ON;
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
-               msleep(intel_dp->panel_power_cycle_delay);
-
-               if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000))
-                       DRM_ERROR("panel off wait timed out: 0x%08x\n",
-                                 I915_READ(PCH_PP_STATUS));
+       pp = ironlake_get_pp_control(dev_priv);
+       pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
+       I915_WRITE(PCH_PP_CONTROL, pp);
+       POSTING_READ(PCH_PP_CONTROL);
 
-               pp |= PANEL_POWER_RESET; /* restore panel reset bit */
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
-       }
+       ironlake_wait_panel_off(intel_dp);
 }
 
 static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
@@ -1099,9 +1134,7 @@ static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
         * allowing it to appear.
         */
        msleep(intel_dp->backlight_on_delay);
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
+       pp = ironlake_get_pp_control(dev_priv);
        pp |= EDP_BLC_ENABLE;
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
@@ -1117,9 +1150,7 @@ static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
                return;
 
        DRM_DEBUG_KMS("\n");
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
+       pp = ironlake_get_pp_control(dev_priv);
        pp &= ~EDP_BLC_ENABLE;
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
@@ -1187,17 +1218,18 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
+       ironlake_edp_backlight_off(intel_dp);
+       ironlake_edp_panel_off(intel_dp);
+
        /* Wake up the sink first */
        ironlake_edp_panel_vdd_on(intel_dp);
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+       intel_dp_link_down(intel_dp);
        ironlake_edp_panel_vdd_off(intel_dp, false);
 
        /* Make sure the panel is off before trying to
         * change the mode
         */
-       ironlake_edp_backlight_off(intel_dp);
-       intel_dp_link_down(intel_dp);
-       ironlake_edp_panel_off(encoder);
 }
 
 static void intel_dp_commit(struct drm_encoder *encoder)
@@ -1211,7 +1243,6 @@ static void intel_dp_commit(struct drm_encoder *encoder)
        intel_dp_start_link_train(intel_dp);
        ironlake_edp_panel_on(intel_dp);
        ironlake_edp_panel_vdd_off(intel_dp, true);
-
        intel_dp_complete_link_train(intel_dp);
        ironlake_edp_backlight_on(intel_dp);
 
@@ -1230,16 +1261,20 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
        if (mode != DRM_MODE_DPMS_ON) {
+               ironlake_edp_backlight_off(intel_dp);
+               ironlake_edp_panel_off(intel_dp);
+
                ironlake_edp_panel_vdd_on(intel_dp);
-               if (is_edp(intel_dp))
-                       ironlake_edp_backlight_off(intel_dp);
                intel_dp_sink_dpms(intel_dp, mode);
                intel_dp_link_down(intel_dp);
-               ironlake_edp_panel_off(encoder);
-               if (is_edp(intel_dp) && !is_pch_edp(intel_dp))
-                       ironlake_edp_pll_off(encoder);
                ironlake_edp_panel_vdd_off(intel_dp, false);
+
+               if (is_cpu_edp(intel_dp))
+                       ironlake_edp_pll_off(encoder);
        } else {
+               if (is_cpu_edp(intel_dp))
+                       ironlake_edp_pll_on(encoder);
+
                ironlake_edp_panel_vdd_on(intel_dp);
                intel_dp_sink_dpms(intel_dp, mode);
                if (!(dp_reg & DP_PORT_EN)) {
@@ -1247,7 +1282,6 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
                        ironlake_edp_panel_on(intel_dp);
                        ironlake_edp_panel_vdd_off(intel_dp, true);
                        intel_dp_complete_link_train(intel_dp);
-                       ironlake_edp_backlight_on(intel_dp);
                } else
                        ironlake_edp_panel_vdd_off(intel_dp, false);
                ironlake_edp_backlight_on(intel_dp);
@@ -1285,11 +1319,11 @@ intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address,
  * link status information
  */
 static bool
-intel_dp_get_link_status(struct intel_dp *intel_dp)
+intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
        return intel_dp_aux_native_read_retry(intel_dp,
                                              DP_LANE0_1_STATUS,
-                                             intel_dp->link_status,
+                                             link_status,
                                              DP_LINK_STATUS_SIZE);
 }
 
@@ -1301,27 +1335,25 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
 }
 
 static uint8_t
-intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
+intel_get_adjust_request_voltage(uint8_t adjust_request[2],
                                 int lane)
 {
-       int         i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
        int         s = ((lane & 1) ?
                         DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
                         DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
-       uint8_t l = intel_dp_link_status(link_status, i);
+       uint8_t l = adjust_request[lane>>1];
 
        return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
 }
 
 static uint8_t
-intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
+intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2],
                                      int lane)
 {
-       int         i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
        int         s = ((lane & 1) ?
                         DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
                         DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
-       uint8_t l = intel_dp_link_status(link_status, i);
+       uint8_t l = adjust_request[lane>>1];
 
        return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
 }
@@ -1344,6 +1376,7 @@ static char       *link_train_names[] = {
  * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
  */
 #define I830_DP_VOLTAGE_MAX        DP_TRAIN_VOLTAGE_SWING_800
+#define I830_DP_VOLTAGE_MAX_CPT            DP_TRAIN_VOLTAGE_SWING_1200
 
 static uint8_t
 intel_dp_pre_emphasis_max(uint8_t voltage_swing)
@@ -1362,15 +1395,18 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
 }
 
 static void
-intel_get_adjust_train(struct intel_dp *intel_dp)
+intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
+       struct drm_device *dev = intel_dp->base.base.dev;
        uint8_t v = 0;
        uint8_t p = 0;
        int lane;
+       uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS);
+       int voltage_max;
 
        for (lane = 0; lane < intel_dp->lane_count; lane++) {
-               uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane);
-               uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane);
+               uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane);
+               uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane);
 
                if (this_v > v)
                        v = this_v;
@@ -1378,8 +1414,12 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
                        p = this_p;
        }
 
-       if (v >= I830_DP_VOLTAGE_MAX)
-               v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
+       if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+               voltage_max = I830_DP_VOLTAGE_MAX_CPT;
+       else
+               voltage_max = I830_DP_VOLTAGE_MAX;
+       if (v >= voltage_max)
+               v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
 
        if (p >= intel_dp_pre_emphasis_max(v))
                p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
@@ -1389,7 +1429,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
 }
 
 static uint32_t
-intel_dp_signal_levels(uint8_t train_set, int lane_count)
+intel_dp_signal_levels(uint8_t train_set)
 {
        uint32_t        signal_levels = 0;
 
@@ -1458,9 +1498,8 @@ static uint8_t
 intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
                      int lane)
 {
-       int i = DP_LANE0_1_STATUS + (lane >> 1);
        int s = (lane & 1) * 4;
-       uint8_t l = intel_dp_link_status(link_status, i);
+       uint8_t l = link_status[lane>>1];
 
        return (l >> s) & 0xf;
 }
@@ -1485,18 +1524,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count
                         DP_LANE_CHANNEL_EQ_DONE|\
                         DP_LANE_SYMBOL_LOCKED)
 static bool
-intel_channel_eq_ok(struct intel_dp *intel_dp)
+intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
        uint8_t lane_align;
        uint8_t lane_status;
        int lane;
 
-       lane_align = intel_dp_link_status(intel_dp->link_status,
+       lane_align = intel_dp_link_status(link_status,
                                          DP_LANE_ALIGN_STATUS_UPDATED);
        if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
                return false;
        for (lane = 0; lane < intel_dp->lane_count; lane++) {
-               lane_status = intel_get_lane_status(intel_dp->link_status, lane);
+               lane_status = intel_get_lane_status(link_status, lane);
                if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)
                        return false;
        }
@@ -1521,8 +1560,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 
        ret = intel_dp_aux_native_write(intel_dp,
                                        DP_TRAINING_LANE0_SET,
-                                       intel_dp->train_set, 4);
-       if (ret != 4)
+                                       intel_dp->train_set,
+                                       intel_dp->lane_count);
+       if (ret != intel_dp->lane_count)
                return false;
 
        return true;
@@ -1538,7 +1578,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
        int i;
        uint8_t voltage;
        bool clock_recovery = false;
-       int tries;
+       int voltage_tries, loop_tries;
        u32 reg;
        uint32_t DP = intel_dp->DP;
 
@@ -1565,16 +1605,20 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                DP &= ~DP_LINK_TRAIN_MASK;
        memset(intel_dp->train_set, 0, 4);
        voltage = 0xff;
-       tries = 0;
+       voltage_tries = 0;
+       loop_tries = 0;
        clock_recovery = false;
        for (;;) {
                /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
+               uint8_t     link_status[DP_LINK_STATUS_SIZE];
                uint32_t    signal_levels;
-               if (IS_GEN6(dev) && is_edp(intel_dp)) {
+
+               if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
-                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
+                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);
+                       DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels);
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
@@ -1590,10 +1634,13 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                /* Set training pattern 1 */
 
                udelay(100);
-               if (!intel_dp_get_link_status(intel_dp))
+               if (!intel_dp_get_link_status(intel_dp, link_status)) {
+                       DRM_ERROR("failed to get link status\n");
                        break;
+               }
 
-               if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+               if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+                       DRM_DEBUG_KMS("clock recovery OK\n");
                        clock_recovery = true;
                        break;
                }
@@ -1602,20 +1649,30 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                for (i = 0; i < intel_dp->lane_count; i++)
                        if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
                                break;
-               if (i == intel_dp->lane_count)
-                       break;
+               if (i == intel_dp->lane_count) {
+                       ++loop_tries;
+                       if (loop_tries == 5) {
+                               DRM_DEBUG_KMS("too many full retries, give up\n");
+                               break;
+                       }
+                       memset(intel_dp->train_set, 0, 4);
+                       voltage_tries = 0;
+                       continue;
+               }
 
                /* Check to see if we've tried the same voltage 5 times */
                if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
-                       ++tries;
-                       if (tries == 5)
+                       ++voltage_tries;
+                       if (voltage_tries == 5) {
+                               DRM_DEBUG_KMS("too many voltage retries, give up\n");
                                break;
+                       }
                } else
-                       tries = 0;
+                       voltage_tries = 0;
                voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
                /* Compute new intel_dp->train_set as requested by target */
-               intel_get_adjust_train(intel_dp);
+               intel_get_adjust_train(intel_dp, link_status);
        }
 
        intel_dp->DP = DP;
@@ -1638,6 +1695,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
        for (;;) {
                /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
                uint32_t    signal_levels;
+               uint8_t     link_status[DP_LINK_STATUS_SIZE];
 
                if (cr_tries > 5) {
                        DRM_ERROR("failed to train DP, aborting\n");
@@ -1645,11 +1703,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                        break;
                }
 
-               if (IS_GEN6(dev) && is_edp(intel_dp)) {
+               if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
-                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
+                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
@@ -1665,17 +1723,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                        break;
 
                udelay(400);
-               if (!intel_dp_get_link_status(intel_dp))
+               if (!intel_dp_get_link_status(intel_dp, link_status))
                        break;
 
                /* Make sure clock is still ok */
-               if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+               if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
                        intel_dp_start_link_train(intel_dp);
                        cr_tries++;
                        continue;
                }
 
-               if (intel_channel_eq_ok(intel_dp)) {
+               if (intel_channel_eq_ok(intel_dp, link_status)) {
                        channel_eq = true;
                        break;
                }
@@ -1690,7 +1748,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                }
 
                /* Compute new intel_dp->train_set as requested by target */
-               intel_get_adjust_train(intel_dp);
+               intel_get_adjust_train(intel_dp, link_status);
                ++tries;
        }
 
@@ -1735,8 +1793,12 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
        msleep(17);
 
-       if (is_edp(intel_dp))
-               DP |= DP_LINK_TRAIN_OFF;
+       if (is_edp(intel_dp)) {
+               if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+                       DP |= DP_LINK_TRAIN_OFF_CPT;
+               else
+                       DP |= DP_LINK_TRAIN_OFF;
+       }
 
        if (!HAS_PCH_CPT(dev) &&
            I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
@@ -1822,6 +1884,7 @@ static void
 intel_dp_check_link_status(struct intel_dp *intel_dp)
 {
        u8 sink_irq_vector;
+       u8 link_status[DP_LINK_STATUS_SIZE];
 
        if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON)
                return;
@@ -1830,7 +1893,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
                return;
 
        /* Try to read receiver status if the link appears to be up */
-       if (!intel_dp_get_link_status(intel_dp)) {
+       if (!intel_dp_get_link_status(intel_dp, link_status)) {
                intel_dp_link_down(intel_dp);
                return;
        }
@@ -1855,7 +1918,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
                        DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
        }
 
-       if (!intel_channel_eq_ok(intel_dp)) {
+       if (!intel_channel_eq_ok(intel_dp, link_status)) {
                DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
                              drm_get_encoder_name(&intel_dp->base.base));
                intel_dp_start_link_train(intel_dp);
@@ -2179,7 +2242,8 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)
                        continue;
 
                intel_dp = enc_to_intel_dp(encoder);
-               if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
+               if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
+                   intel_dp->base.type == INTEL_OUTPUT_EDP)
                        return intel_dp->output_reg;
        }
 
@@ -2321,7 +2385,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 
                cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>
                        PANEL_LIGHT_ON_DELAY_SHIFT;
-               
+
                cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>
                        PANEL_LIGHT_OFF_DELAY_SHIFT;
 
@@ -2354,11 +2418,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
                              intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
 
-               intel_dp->panel_off_jiffies = jiffies - intel_dp->panel_power_down_delay;
-
                ironlake_edp_panel_vdd_on(intel_dp);
                ret = intel_dp_get_dpcd(intel_dp);
                ironlake_edp_panel_vdd_off(intel_dp, false);
+
                if (ret) {
                        if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
                                dev_priv->no_aux_handshake =
index 499d4c0dbeebd93f944d338ffc29184ed5103617..21f60b7d69a30819d13f7e0fd942e3ebe4fe7bbd 100644 (file)
@@ -326,7 +326,8 @@ static int intel_panel_update_status(struct backlight_device *bd)
 static int intel_panel_get_brightness(struct backlight_device *bd)
 {
        struct drm_device *dev = bl_get_data(bd);
-       return intel_panel_get_backlight(dev);
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       return dev_priv->backlight_level;
 }
 
 static const struct backlight_ops intel_panel_bl_ops = {
index 7fdfa8ea7570654b6d3faf70e410e5ff6b9554d7..38e1bda73d33be343058b1f63f9349ca7f80e3f1 100644 (file)
@@ -480,21 +480,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                }
                break;
        case DB_Z_INFO:
-               r = evergreen_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
-                                       "0x%04X\n", reg);
-                       return -EINVAL;
-               }
                track->db_z_info = radeon_get_ib_value(p, idx);
-               ib[idx] &= ~Z_ARRAY_MODE(0xf);
-               track->db_z_info &= ~Z_ARRAY_MODE(0xf);
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                       ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-               } else {
-                       ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                       track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               if (!p->keep_tiling_flags) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                               "0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       ib[idx] &= ~Z_ARRAY_MODE(0xf);
+                       track->db_z_info &= ~Z_ARRAY_MODE(0xf);
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                               ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                               track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                       } else {
+                               ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                               track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                       }
                }
                break;
        case DB_STENCIL_INFO:
@@ -607,40 +609,44 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
        case CB_COLOR5_INFO:
        case CB_COLOR6_INFO:
        case CB_COLOR7_INFO:
-               r = evergreen_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
-                                       "0x%04X\n", reg);
-                       return -EINVAL;
-               }
                tmp = (reg - CB_COLOR0_INFO) / 0x3c;
                track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                       ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-               } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-                       ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               if (!p->keep_tiling_flags) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                               "0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                               ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                               track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                       } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+                               ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                               track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                       }
                }
                break;
        case CB_COLOR8_INFO:
        case CB_COLOR9_INFO:
        case CB_COLOR10_INFO:
        case CB_COLOR11_INFO:
-               r = evergreen_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
-                                       "0x%04X\n", reg);
-                       return -EINVAL;
-               }
                tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8;
                track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                       ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-               } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-                       ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               if (!p->keep_tiling_flags) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                               "0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                               ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                               track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                       } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+                               ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                               track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                       }
                }
                break;
        case CB_COLOR0_PITCH:
@@ -1311,10 +1317,12 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
                                        return -EINVAL;
                                }
                                ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-                               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                                       ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                                       ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                               if (!p->keep_tiling_flags) {
+                                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                                               ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
+                                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                                               ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                               }
                                texture = reloc->robj;
                                /* tex mip base */
                                r = evergreen_cs_packet_next_reloc(p, &reloc);
index 400b26df652a8305c04d58f46db998672646b150..c93bc64707e1d6e3b59a5e2a7fe632b19e6efe99 100644 (file)
@@ -701,16 +701,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        return r;
                }
 
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                       tile_flags |= R300_TXO_MACRO_TILE;
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                       tile_flags |= R300_TXO_MICRO_TILE;
-               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
-                       tile_flags |= R300_TXO_MICRO_TILE_SQUARE;
-
-               tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
-               tmp |= tile_flags;
-               ib[idx] = tmp;
+               if (p->keep_tiling_flags) {
+                       ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */
+                                 ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset);
+               } else {
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                               tile_flags |= R300_TXO_MACRO_TILE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                               tile_flags |= R300_TXO_MICRO_TILE;
+                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                               tile_flags |= R300_TXO_MICRO_TILE_SQUARE;
+
+                       tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
+                       tmp |= tile_flags;
+                       ib[idx] = tmp;
+               }
                track->textures[i].robj = reloc->robj;
                track->tex_dirty = true;
                break;
@@ -760,24 +765,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                /* RB3D_COLORPITCH1 */
                /* RB3D_COLORPITCH2 */
                /* RB3D_COLORPITCH3 */
-               r = r100_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-                                 idx, reg);
-                       r100_cs_dump_packet(p, pkt);
-                       return r;
-               }
+               if (!p->keep_tiling_flags) {
+                       r = r100_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                         idx, reg);
+                               r100_cs_dump_packet(p, pkt);
+                               return r;
+                       }
 
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                       tile_flags |= R300_COLOR_TILE_ENABLE;
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                       tile_flags |= R300_COLOR_MICROTILE_ENABLE;
-               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
-                       tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                               tile_flags |= R300_COLOR_TILE_ENABLE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                               tile_flags |= R300_COLOR_MICROTILE_ENABLE;
+                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                               tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;
 
-               tmp = idx_value & ~(0x7 << 16);
-               tmp |= tile_flags;
-               ib[idx] = tmp;
+                       tmp = idx_value & ~(0x7 << 16);
+                       tmp |= tile_flags;
+                       ib[idx] = tmp;
+               }
                i = (reg - 0x4E38) >> 2;
                track->cb[i].pitch = idx_value & 0x3FFE;
                switch (((idx_value >> 21) & 0xF)) {
@@ -843,25 +850,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                break;
        case 0x4F24:
                /* ZB_DEPTHPITCH */
-               r = r100_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-                                 idx, reg);
-                       r100_cs_dump_packet(p, pkt);
-                       return r;
-               }
-
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                       tile_flags |= R300_DEPTHMACROTILE_ENABLE;
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                       tile_flags |= R300_DEPTHMICROTILE_TILED;
-               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
-                       tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;
+               if (!p->keep_tiling_flags) {
+                       r = r100_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                         idx, reg);
+                               r100_cs_dump_packet(p, pkt);
+                               return r;
+                       }
 
-               tmp = idx_value & ~(0x7 << 16);
-               tmp |= tile_flags;
-               ib[idx] = tmp;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                               tile_flags |= R300_DEPTHMACROTILE_ENABLE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                               tile_flags |= R300_DEPTHMICROTILE_TILED;
+                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                               tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;
 
+                       tmp = idx_value & ~(0x7 << 16);
+                       tmp |= tile_flags;
+                       ib[idx] = tmp;
+               }
                track->zb.pitch = idx_value & 0x3FFC;
                track->zb_dirty = true;
                break;
index 0a2e023c15570ffdbd8c78280ac84123b6b17034..cb1acffd24303aca4c49b11e62b74719a527d51b 100644 (file)
@@ -941,7 +941,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                track->db_depth_control = radeon_get_ib_value(p, idx);
                break;
        case R_028010_DB_DEPTH_INFO:
-               if (r600_cs_packet_next_is_pkt3_nop(p)) {
+               if (!p->keep_tiling_flags &&
+                   r600_cs_packet_next_is_pkt3_nop(p)) {
                        r = r600_cs_packet_next_reloc(p, &reloc);
                        if (r) {
                                dev_warn(p->dev, "bad SET_CONTEXT_REG "
@@ -992,7 +993,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
        case R_0280B4_CB_COLOR5_INFO:
        case R_0280B8_CB_COLOR6_INFO:
        case R_0280BC_CB_COLOR7_INFO:
-               if (r600_cs_packet_next_is_pkt3_nop(p)) {
+               if (!p->keep_tiling_flags &&
+                    r600_cs_packet_next_is_pkt3_nop(p)) {
                        r = r600_cs_packet_next_reloc(p, &reloc);
                        if (r) {
                                dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
@@ -1291,10 +1293,12 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
        mip_offset <<= 8;
 
        word0 = radeon_get_ib_value(p, idx + 0);
-       if (tiling_flags & RADEON_TILING_MACRO)
-               word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
-       else if (tiling_flags & RADEON_TILING_MICRO)
-               word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+       if (!p->keep_tiling_flags) {
+               if (tiling_flags & RADEON_TILING_MACRO)
+                       word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+               else if (tiling_flags & RADEON_TILING_MICRO)
+                       word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+       }
        word1 = radeon_get_ib_value(p, idx + 1);
        w0 = G_038000_TEX_WIDTH(word0) + 1;
        h0 = G_038004_TEX_HEIGHT(word1) + 1;
@@ -1621,10 +1625,12 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                                        return -EINVAL;
                                }
                                base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-                               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                                       ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
-                               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                                       ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+                               if (!p->keep_tiling_flags) {
+                                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                                               ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+                                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                                               ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+                               }
                                texture = reloc->robj;
                                /* tex mip base */
                                r = r600_cs_packet_next_reloc(p, &reloc);
index fc5a1d642cb509236db4c57c5ac64472c83ebee4..8227e76b5c70a1d1b97bcac741f1559272a2250e 100644 (file)
@@ -611,7 +611,8 @@ struct radeon_cs_parser {
        struct radeon_ib        *ib;
        void                    *track;
        unsigned                family;
-       int parser_error;
+       int                     parser_error;
+       bool                    keep_tiling_flags;
 };
 
 extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx);
index d2d179267af3fc878d210b40563e55c0a58eeac3..d24baf30efcb8e583ab38b0540fe508369e47423 100644 (file)
@@ -62,6 +62,87 @@ union atom_supported_devices {
        struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
 };
 
+static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev,
+                                         ATOM_GPIO_I2C_ASSIGMENT *gpio,
+                                         u8 index)
+{
+       /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */
+       if ((rdev->family == CHIP_R420) ||
+           (rdev->family == CHIP_R423) ||
+           (rdev->family == CHIP_RV410)) {
+               if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) ||
+                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) ||
+                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) {
+                       gpio->ucClkMaskShift = 0x19;
+                       gpio->ucDataMaskShift = 0x18;
+               }
+       }
+
+       /* some evergreen boards have bad data for this entry */
+       if (ASIC_IS_DCE4(rdev)) {
+               if ((index == 7) &&
+                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
+                   (gpio->sucI2cId.ucAccess == 0)) {
+                       gpio->sucI2cId.ucAccess = 0x97;
+                       gpio->ucDataMaskShift = 8;
+                       gpio->ucDataEnShift = 8;
+                       gpio->ucDataY_Shift = 8;
+                       gpio->ucDataA_Shift = 8;
+               }
+       }
+
+       /* some DCE3 boards have bad data for this entry */
+       if (ASIC_IS_DCE3(rdev)) {
+               if ((index == 4) &&
+                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
+                   (gpio->sucI2cId.ucAccess == 0x94))
+                       gpio->sucI2cId.ucAccess = 0x14;
+       }
+}
+
+static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio)
+{
+       struct radeon_i2c_bus_rec i2c;
+
+       memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
+
+       i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+       i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+       i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+       i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+       i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+       i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+       i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+       i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+       i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+       i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+       i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
+       i2c.en_data_mask = (1 << gpio->ucDataEnShift);
+       i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
+       i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
+       i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
+       i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
+
+       if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+               i2c.hw_capable = true;
+       else
+               i2c.hw_capable = false;
+
+       if (gpio->sucI2cId.ucAccess == 0xa0)
+               i2c.mm_i2c = true;
+       else
+               i2c.mm_i2c = false;
+
+       i2c.i2c_id = gpio->sucI2cId.ucAccess;
+
+       if (i2c.mask_clk_reg)
+               i2c.valid = true;
+       else
+               i2c.valid = false;
+
+       return i2c;
+}
+
 static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,
                                                               uint8_t id)
 {
@@ -85,59 +166,10 @@ static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rd
                for (i = 0; i < num_indices; i++) {
                        gpio = &i2c_info->asGPIO_Info[i];
 
-                       /* some evergreen boards have bad data for this entry */
-                       if (ASIC_IS_DCE4(rdev)) {
-                               if ((i == 7) &&
-                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
-                                   (gpio->sucI2cId.ucAccess == 0)) {
-                                       gpio->sucI2cId.ucAccess = 0x97;
-                                       gpio->ucDataMaskShift = 8;
-                                       gpio->ucDataEnShift = 8;
-                                       gpio->ucDataY_Shift = 8;
-                                       gpio->ucDataA_Shift = 8;
-                               }
-                       }
-
-                       /* some DCE3 boards have bad data for this entry */
-                       if (ASIC_IS_DCE3(rdev)) {
-                               if ((i == 4) &&
-                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
-                                   (gpio->sucI2cId.ucAccess == 0x94))
-                                       gpio->sucI2cId.ucAccess = 0x14;
-                       }
+                       radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);
 
                        if (gpio->sucI2cId.ucAccess == id) {
-                               i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
-                               i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
-                               i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
-                               i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
-                               i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
-                               i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
-                               i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
-                               i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
-                               i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
-                               i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
-                               i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
-                               i2c.en_data_mask = (1 << gpio->ucDataEnShift);
-                               i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
-                               i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
-                               i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
-                               i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
-
-                               if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
-                                       i2c.hw_capable = true;
-                               else
-                                       i2c.hw_capable = false;
-
-                               if (gpio->sucI2cId.ucAccess == 0xa0)
-                                       i2c.mm_i2c = true;
-                               else
-                                       i2c.mm_i2c = false;
-
-                               i2c.i2c_id = gpio->sucI2cId.ucAccess;
-
-                               if (i2c.mask_clk_reg)
-                                       i2c.valid = true;
+                               i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);
                                break;
                        }
                }
@@ -157,8 +189,6 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
        int i, num_indices;
        char stmp[32];
 
-       memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
-
        if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
                i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
 
@@ -167,60 +197,12 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
 
                for (i = 0; i < num_indices; i++) {
                        gpio = &i2c_info->asGPIO_Info[i];
-                       i2c.valid = false;
-
-                       /* some evergreen boards have bad data for this entry */
-                       if (ASIC_IS_DCE4(rdev)) {
-                               if ((i == 7) &&
-                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
-                                   (gpio->sucI2cId.ucAccess == 0)) {
-                                       gpio->sucI2cId.ucAccess = 0x97;
-                                       gpio->ucDataMaskShift = 8;
-                                       gpio->ucDataEnShift = 8;
-                                       gpio->ucDataY_Shift = 8;
-                                       gpio->ucDataA_Shift = 8;
-                               }
-                       }
-
-                       /* some DCE3 boards have bad data for this entry */
-                       if (ASIC_IS_DCE3(rdev)) {
-                               if ((i == 4) &&
-                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
-                                   (gpio->sucI2cId.ucAccess == 0x94))
-                                       gpio->sucI2cId.ucAccess = 0x14;
-                       }
 
-                       i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
-                       i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
-                       i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
-                       i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
-                       i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
-                       i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
-                       i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
-                       i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
-                       i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
-                       i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
-                       i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
-                       i2c.en_data_mask = (1 << gpio->ucDataEnShift);
-                       i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
-                       i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
-                       i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
-                       i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
-
-                       if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
-                               i2c.hw_capable = true;
-                       else
-                               i2c.hw_capable = false;
+                       radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);
 
-                       if (gpio->sucI2cId.ucAccess == 0xa0)
-                               i2c.mm_i2c = true;
-                       else
-                               i2c.mm_i2c = false;
+                       i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);
 
-                       i2c.i2c_id = gpio->sucI2cId.ucAccess;
-
-                       if (i2c.mask_clk_reg) {
-                               i2c.valid = true;
+                       if (i2c.valid) {
                                sprintf(stmp, "0x%x", i2c.i2c_id);
                                rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp);
                        }
@@ -1996,14 +1978,14 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
                return state_index;
        /* last mode is usually default, array is low to high */
        for (i = 0; i < num_modes; i++) {
+               rdev->pm.power_state[state_index].clock_info =
+                       kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+               if (!rdev->pm.power_state[state_index].clock_info)
+                       return state_index;
+               rdev->pm.power_state[state_index].num_clock_modes = 1;
                rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
                switch (frev) {
                case 1:
-                       rdev->pm.power_state[state_index].clock_info =
-                               kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
-                       if (!rdev->pm.power_state[state_index].clock_info)
-                               return state_index;
-                       rdev->pm.power_state[state_index].num_clock_modes = 1;
                        rdev->pm.power_state[state_index].clock_info[0].mclk =
                                le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
                        rdev->pm.power_state[state_index].clock_info[0].sclk =
@@ -2039,11 +2021,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
                        state_index++;
                        break;
                case 2:
-                       rdev->pm.power_state[state_index].clock_info =
-                               kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
-                       if (!rdev->pm.power_state[state_index].clock_info)
-                               return state_index;
-                       rdev->pm.power_state[state_index].num_clock_modes = 1;
                        rdev->pm.power_state[state_index].clock_info[0].mclk =
                                le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
                        rdev->pm.power_state[state_index].clock_info[0].sclk =
@@ -2080,11 +2057,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
                        state_index++;
                        break;
                case 3:
-                       rdev->pm.power_state[state_index].clock_info =
-                               kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
-                       if (!rdev->pm.power_state[state_index].clock_info)
-                               return state_index;
-                       rdev->pm.power_state[state_index].num_clock_modes = 1;
                        rdev->pm.power_state[state_index].clock_info[0].mclk =
                                le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
                        rdev->pm.power_state[state_index].clock_info[0].sclk =
index ccaa243c1442f8fe045df65af570e059baf11fb0..29afd71e0840a0b9995b5e30027577adeec45b92 100644 (file)
@@ -93,7 +93,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
 {
        struct drm_radeon_cs *cs = data;
        uint64_t *chunk_array_ptr;
-       unsigned size, i;
+       unsigned size, i, flags = 0;
 
        if (!cs->num_chunks) {
                return 0;
@@ -140,6 +140,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
                        if (p->chunks[i].length_dw == 0)
                                return -EINVAL;
                }
+               if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS &&
+                   !p->chunks[i].length_dw) {
+                       return -EINVAL;
+               }
 
                p->chunks[i].length_dw = user_chunk.length_dw;
                p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data;
@@ -155,6 +159,9 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
                                               p->chunks[i].user_ptr, size)) {
                                return -EFAULT;
                        }
+                       if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) {
+                               flags = p->chunks[i].kdata[0];
+                       }
                } else {
                        p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL);
                        p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL);
@@ -174,6 +181,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
                          p->chunks[p->chunk_ib_idx].length_dw);
                return -EINVAL;
        }
+
+       p->keep_tiling_flags = (flags & RADEON_CS_KEEP_TILING_FLAGS) != 0;
        return 0;
 }
 
index a0b35e9094896cf90202d8f54effd942b0398054..71499fc3daf524f8b719692e9ff7aacb6219b2e9 100644 (file)
  *   2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query
  *   2.10.0 - fusion 2D tiling
  *   2.11.0 - backend map, initial compute support for the CS checker
+ *   2.12.0 - RADEON_CS_KEEP_TILING_FLAGS
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       11
+#define KMS_DRIVER_MINOR       12
 #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 617b64678fc62f24c70df6ae3fd7ba3bc7d6c9bf..0bb0f5f713e6cf9166a1b91eb19ab81b85206716 100644 (file)
@@ -574,10 +574,16 @@ retry:
                return ret;
 
        spin_lock(&glob->lru_lock);
+
+       if (unlikely(list_empty(&bo->ddestroy))) {
+               spin_unlock(&glob->lru_lock);
+               return 0;
+       }
+
        ret = ttm_bo_reserve_locked(bo, interruptible,
                                    no_wait_reserve, false, 0);
 
-       if (unlikely(ret != 0) || list_empty(&bo->ddestroy)) {
+       if (unlikely(ret != 0)) {
                spin_unlock(&glob->lru_lock);
                return ret;
        }
index c72f1c0b5e637951a450b21378f2edfeb8e92725..111d956d8e7d0d919d088405ddeaf3b341c87092 100644 (file)
@@ -465,31 +465,29 @@ static void vga_arbiter_check_bridge_sharing(struct vga_device *vgadev)
        while (new_bus) {
                new_bridge = new_bus->self;
 
-               if (new_bridge) {
-                       /* go through list of devices already registered */
-                       list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
-                               bus = same_bridge_vgadev->pdev->bus;
-                               bridge = bus->self;
-
-                               /* see if the share a bridge with this device */
-                               if (new_bridge == bridge) {
-                                       /* if their direct parent bridge is the same
-                                          as any bridge of this device then it can't be used
-                                          for that device */
-                                       same_bridge_vgadev->bridge_has_one_vga = false;
-                               }
+               /* go through list of devices already registered */
+               list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
+                       bus = same_bridge_vgadev->pdev->bus;
+                       bridge = bus->self;
+
+                       /* see if the share a bridge with this device */
+                       if (new_bridge == bridge) {
+                               /* if their direct parent bridge is the same
+                                  as any bridge of this device then it can't be used
+                                  for that device */
+                               same_bridge_vgadev->bridge_has_one_vga = false;
+                       }
 
-                               /* now iterate the previous devices bridge hierarchy */
-                               /* if the new devices parent bridge is in the other devices
-                                  hierarchy then we can't use it to control this device */
-                               while (bus) {
-                                       bridge = bus->self;
-                                       if (bridge) {
-                                               if (bridge == vgadev->pdev->bus->self)
-                                                       vgadev->bridge_has_one_vga = false;
-                                       }
-                                       bus = bus->parent;
+                       /* now iterate the previous devices bridge hierarchy */
+                       /* if the new devices parent bridge is in the other devices
+                          hierarchy then we can't use it to control this device */
+                       while (bus) {
+                               bridge = bus->self;
+                               if (bridge) {
+                                       if (bridge == vgadev->pdev->bus->self)
+                                               vgadev->bridge_has_one_vga = false;
                                }
+                               bus = bus->parent;
                        }
                }
                new_bus = new_bus->parent;
@@ -993,14 +991,20 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
                                uc = &priv->cards[i];
                }
 
-               if (!uc)
-                       return -EINVAL;
+               if (!uc) {
+                       ret_val = -EINVAL;
+                       goto done;
+               }
 
-               if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0)
-                       return -EINVAL;
+               if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) {
+                       ret_val = -EINVAL;
+                       goto done;
+               }
 
-               if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0)
-                       return -EINVAL;
+               if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) {
+                       ret_val = -EINVAL;
+                       goto done;
+               }
 
                vga_put(pdev, io_state);
 
index 9ec854ae118b91c5fea647d61bab7f29117a10a5..91be41f6080947936bdd355f25500397ecfd1dfe 100644 (file)
@@ -315,7 +315,7 @@ config SENSORS_DS1621
 
 config SENSORS_EXYNOS4_TMU
        tristate "Temperature sensor on Samsung EXYNOS4"
-       depends on EXYNOS4_DEV_TMU
+       depends on ARCH_EXYNOS4
        help
          If you say yes here you get support for TMU (Thermal Managment
          Unit) on SAMSUNG EXYNOS4 series of SoC.
index 318e38e853764eeeea220bfb519079cf20f687bc..5d760f3d21c2d61ee85227ab7107bf4c38e011f9 100644 (file)
@@ -160,7 +160,6 @@ MODULE_DEVICE_TABLE(spi, ad7314_id);
 static struct spi_driver ad7314_driver = {
        .driver = {
                .name = "ad7314",
-               .bus = &spi_bus_type,
                .owner = THIS_MODULE,
        },
        .probe = ad7314_probe,
index 52319340e182da8f189eae518d80bd3674d26425..04450f8bf5da28e4dff56e70ab86e294920c2cf2 100644 (file)
@@ -227,7 +227,6 @@ static int __devexit ads7871_remove(struct spi_device *spi)
 static struct spi_driver ads7871_driver = {
        .driver = {
                .name = DEVICE_NAME,
-               .bus = &spi_bus_type,
                .owner = THIS_MODULE,
        },
 
index faa0884f61f67bc49e72e93c075160d46078cba4..f2359a0093bd65e52c6985e6a06eef3a0cec8d37 100644 (file)
@@ -506,17 +506,7 @@ static struct platform_driver exynos4_tmu_driver = {
        .resume = exynos4_tmu_resume,
 };
 
-static int __init exynos4_tmu_driver_init(void)
-{
-       return platform_driver_register(&exynos4_tmu_driver);
-}
-module_init(exynos4_tmu_driver_init);
-
-static void __exit exynos4_tmu_driver_exit(void)
-{
-       platform_driver_unregister(&exynos4_tmu_driver);
-}
-module_exit(exynos4_tmu_driver_exit);
+module_platform_driver(exynos4_tmu_driver);
 
 MODULE_DESCRIPTION("EXYNOS4 TMU Driver");
 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
index 89aa9fb743af07260c8deadbc8956eb4c1ada2de..9ba38f318ffb458247dd66b58b77c3c03e203727 100644 (file)
@@ -539,18 +539,7 @@ static struct platform_driver gpio_fan_driver = {
        },
 };
 
-static int __init gpio_fan_init(void)
-{
-       return platform_driver_register(&gpio_fan_driver);
-}
-
-static void __exit gpio_fan_exit(void)
-{
-       platform_driver_unregister(&gpio_fan_driver);
-}
-
-module_init(gpio_fan_init);
-module_exit(gpio_fan_exit);
+module_platform_driver(gpio_fan_driver);
 
 MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
 MODULE_DESCRIPTION("GPIO FAN driver");
index fea292d43407cecba6e75b70021617f871d6b1b8..7a48b1eb423334780116f1cb6e16edcec8f19a49 100644 (file)
@@ -212,17 +212,7 @@ struct platform_driver jz4740_hwmon_driver = {
        },
 };
 
-static int __init jz4740_hwmon_init(void)
-{
-       return platform_driver_register(&jz4740_hwmon_driver);
-}
-module_init(jz4740_hwmon_init);
-
-static void __exit jz4740_hwmon_exit(void)
-{
-       platform_driver_unregister(&jz4740_hwmon_driver);
-}
-module_exit(jz4740_hwmon_exit);
+module_platform_driver(jz4740_hwmon_driver);
 
 MODULE_DESCRIPTION("JZ4740 SoC HWMON driver");
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
index eab11615dced6b54e71996bfd4df60c159bbe570..9b382ec2c3bd4de978d98a6d9f24f797684fe534 100644 (file)
@@ -432,19 +432,7 @@ static struct platform_driver ntc_thermistor_driver = {
        .id_table = ntc_thermistor_id,
 };
 
-static int __init ntc_thermistor_init(void)
-{
-       return platform_driver_register(&ntc_thermistor_driver);
-}
-
-module_init(ntc_thermistor_init);
-
-static void __exit ntc_thermistor_cleanup(void)
-{
-       platform_driver_unregister(&ntc_thermistor_driver);
-}
-
-module_exit(ntc_thermistor_cleanup);
+module_platform_driver(ntc_thermistor_driver);
 
 MODULE_DESCRIPTION("NTC Thermistor Driver");
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
index b39f52e2752a7bca54a1bb25c7083382b01aa52e..f6c26d19f521aaa98dd2b0596d67ab27028b8d15 100644 (file)
@@ -393,18 +393,7 @@ static struct platform_driver s3c_hwmon_driver = {
        .remove         = __devexit_p(s3c_hwmon_remove),
 };
 
-static int __init s3c_hwmon_init(void)
-{
-       return platform_driver_register(&s3c_hwmon_driver);
-}
-
-static void __exit s3c_hwmon_exit(void)
-{
-       platform_driver_unregister(&s3c_hwmon_driver);
-}
-
-module_init(s3c_hwmon_init);
-module_exit(s3c_hwmon_exit);
+module_platform_driver(s3c_hwmon_driver);
 
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("S3C ADC HWMon driver");
index e3b5c6039c2541e67e63066e4311f2dc6c1021b6..79b6dabe3161461a3f1ccdf277588860f7863df9 100644 (file)
@@ -590,19 +590,8 @@ static struct platform_driver sch5627_driver = {
        .remove         = sch5627_remove,
 };
 
-static int __init sch5627_init(void)
-{
-       return platform_driver_register(&sch5627_driver);
-}
-
-static void __exit sch5627_exit(void)
-{
-       platform_driver_unregister(&sch5627_driver);
-}
+module_platform_driver(sch5627_driver);
 
 MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_LICENSE("GPL");
-
-module_init(sch5627_init);
-module_exit(sch5627_exit);
index 244407aa79fcbe05dc05b10ae7d88c0327db6d29..9d5236fb09b421e6a1e78cd5b190eaa9d19f6a2d 100644 (file)
@@ -521,19 +521,8 @@ static struct platform_driver sch5636_driver = {
        .remove         = sch5636_remove,
 };
 
-static int __init sch5636_init(void)
-{
-       return platform_driver_register(&sch5636_driver);
-}
-
-static void __exit sch5636_exit(void)
-{
-       platform_driver_unregister(&sch5636_driver);
-}
+module_platform_driver(sch5636_driver);
 
 MODULE_DESCRIPTION("SMSC SCH5636 Hardware Monitoring Driver");
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_LICENSE("GPL");
-
-module_init(sch5636_init);
-module_exit(sch5636_exit);
index 57240740b161d190329b5ca3b7dfaf0d049ef02e..0018c7dd0097de5045f646d98e715713ea7edba4 100644 (file)
@@ -136,19 +136,7 @@ static struct platform_driver twl4030_madc_hwmon_driver = {
                   },
 };
 
-static int __init twl4030_madc_hwmon_init(void)
-{
-       return platform_driver_register(&twl4030_madc_hwmon_driver);
-}
-
-module_init(twl4030_madc_hwmon_init);
-
-static void __exit twl4030_madc_hwmon_exit(void)
-{
-       platform_driver_unregister(&twl4030_madc_hwmon_driver);
-}
-
-module_exit(twl4030_madc_hwmon_exit);
+module_platform_driver(twl4030_madc_hwmon_driver);
 
 MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver");
 MODULE_LICENSE("GPL");
index 3cd07bf42dca4203c93712823fdf3dd2fb3335fa..b9a87e89bab4471ce29aba1509f14bd908603b3e 100644 (file)
@@ -309,15 +309,4 @@ static struct platform_driver env_driver = {
        .remove         = __devexit_p(env_remove),
 };
 
-static int __init env_init(void)
-{
-       return platform_driver_register(&env_driver);
-}
-
-static void __exit env_exit(void)
-{
-       platform_driver_unregister(&env_driver);
-}
-
-module_init(env_init);
-module_exit(env_exit);
+module_platform_driver(env_driver);
index 97b1f834a4714b540fd95352271bb253ef130c9c..9b598ed26020563978f1142840c4b6a5f0ecad77 100644 (file)
@@ -209,17 +209,7 @@ static struct platform_driver wm831x_hwmon_driver = {
        },
 };
 
-static int __init wm831x_hwmon_init(void)
-{
-       return platform_driver_register(&wm831x_hwmon_driver);
-}
-module_init(wm831x_hwmon_init);
-
-static void __exit wm831x_hwmon_exit(void)
-{
-       platform_driver_unregister(&wm831x_hwmon_driver);
-}
-module_exit(wm831x_hwmon_exit);
+module_platform_driver(wm831x_hwmon_driver);
 
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("WM831x Hardware Monitoring");
index 13290595ca8660f25ebbd0e0c350795dc3d6ccc8..3ff67edbdc44af02a7d0553dd2d74530cc00ca6f 100644 (file)
@@ -133,17 +133,7 @@ static struct platform_driver wm8350_hwmon_driver = {
        },
 };
 
-static int __init wm8350_hwmon_init(void)
-{
-       return platform_driver_register(&wm8350_hwmon_driver);
-}
-module_init(wm8350_hwmon_init);
-
-static void __exit wm8350_hwmon_exit(void)
-{
-       platform_driver_unregister(&wm8350_hwmon_driver);
-}
-module_exit(wm8350_hwmon_exit);
+module_platform_driver(wm8350_hwmon_driver);
 
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("WM8350 Hardware Monitoring");
index 85584a547c25201a1375bf92b074af571d37be0e..525c7345fa0b904242a0ef10a5d9502ab5e4baf1 100644 (file)
@@ -488,7 +488,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
 
        if (flags & I2C_M_TEN) {
                /* a ten bit address */
-               addr = 0xf0 | ((msg->addr >> 7) & 0x03);
+               addr = 0xf0 | ((msg->addr >> 7) & 0x06);
                bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
                /* try extended address code...*/
                ret = try_address(i2c_adap, addr, retries);
@@ -498,7 +498,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
                        return -ENXIO;
                }
                /* the remaining 8 bit address */
-               ret = i2c_outb(i2c_adap, msg->addr & 0x7f);
+               ret = i2c_outb(i2c_adap, msg->addr & 0xff);
                if ((ret != 1) && !nak_ok) {
                        /* the chip did not ack / xmission error occurred */
                        dev_err(&i2c_adap->dev, "died at 2nd address code\n");
index 835e47b39bc264535c567669d12a81784a8c90c7..03b61577888748a4d9a61cfe46b413eaaa219737 100644 (file)
@@ -593,7 +593,7 @@ static int __devinit nuc900_i2c_probe(struct platform_device *pdev)
        i2c->adap.algo_data = i2c;
        i2c->adap.dev.parent = &pdev->dev;
 
-       mfp_set_groupg(&pdev->dev);
+       mfp_set_groupg(&pdev->dev, NULL);
 
        clk_get_rate(i2c->clk);
 
index 131079a3e2923a1feaa05248a236d8ee27890c4a..1e5606185b4f581939d6da4334b36747e90c35ba 100644 (file)
@@ -539,8 +539,10 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
        client->dev.type = &i2c_client_type;
        client->dev.of_node = info->of_node;
 
+       /* For 10-bit clients, add an arbitrary offset to avoid collisions */
        dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
-                    client->addr);
+                    client->addr | ((client->flags & I2C_CLIENT_TEN)
+                                    ? 0xa000 : 0));
        status = device_register(&client->dev);
        if (status)
                goto out_err;
index c90ce50b619f7b483b85483a24457a8cab73f3c2..57a45ce84b2d42f893cf45fb6e876bc1904bcfde 100644 (file)
@@ -579,7 +579,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy)
        return 0;
 }
 
-int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
+static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
                         void *data)
 {
        struct device *dev = data;
index 67cbcfa351225b4f7c60dce041562a411d76430e..847553fd8b963beca810aadb548d2f4f96db666e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
  *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
- *  Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
+ *  Copyright (C) 2007-2011 Bartlomiej Zolnierkiewicz
  *
  * CYPRESS CY82C693 chipset IDE controller
  *
@@ -90,7 +90,7 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
        u8 time_16, time_8;
 
        /* select primary or secondary channel */
-       if (hwif->index > 0) {  /* drive is on the secondary channel */
+       if (drive->dn > 1) {  /* drive is on the secondary channel */
                dev = pci_get_slot(dev->bus, dev->devfn+1);
                if (!dev) {
                        printk(KERN_ERR "%s: tune_drive: "
@@ -141,7 +141,7 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
                pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16);
                pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8);
        }
-       if (hwif->index > 0)
+       if (drive->dn > 1)
                pci_dev_put(dev);
 }
 
index 4a697a238e280e2ce14c627d0d1f4bf053b86b45..8716066a2f2b79c1ddeb1236a9b2091d7bd62f63 100644 (file)
@@ -521,8 +521,8 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
        if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
                d.init_dma = icside_dma_init;
                d.port_ops = &icside_v6_port_ops;
+       } else
                d.dma_ops = NULL;
-       }
 
        ret = ide_host_register(host, &d, hws);
        if (ret)
index b59d04c720517d722633f9feef63a42505f86625..1892e81fb00f615b80c3dfaa8f10a643037a5eb6 100644 (file)
@@ -331,7 +331,7 @@ static const struct ide_port_ops ich_port_ops = {
                .udma_mask      = udma,                 \
        }
 
-#define DECLARE_ICH_DEV(udma) \
+#define DECLARE_ICH_DEV(mwdma, udma) \
        { \
                .name           = DRV_NAME, \
                .init_chipset   = init_chipset_ich, \
@@ -340,7 +340,7 @@ static const struct ide_port_ops ich_port_ops = {
                .port_ops       = &ich_port_ops, \
                .pio_mask       = ATA_PIO4, \
                .swdma_mask     = ATA_SWDMA2_ONLY, \
-               .mwdma_mask     = ATA_MWDMA12_ONLY, \
+               .mwdma_mask     = mwdma, \
                .udma_mask      = udma, \
        }
 
@@ -362,13 +362,15 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = {
        /* 2: PIIX4 */
        DECLARE_PIIX_DEV(ATA_UDMA2),
        /* 3: ICH0 */
-       DECLARE_ICH_DEV(ATA_UDMA2),
+       DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA2),
        /* 4: ICH */
-       DECLARE_ICH_DEV(ATA_UDMA4),
+       DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA4),
        /* 5: PIIX4 */
        DECLARE_PIIX_DEV(ATA_UDMA4),
-       /* 6: ICH[2-7]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */
-       DECLARE_ICH_DEV(ATA_UDMA5),
+       /* 6: ICH[2-6]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */
+       DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA5),
+       /* 7: ICH7/7-R, no MWDMA1 */
+       DECLARE_ICH_DEV(ATA_MWDMA2_ONLY, ATA_UDMA5),
 };
 
 /**
@@ -438,9 +440,9 @@ static const struct pci_device_id piix_pci_tbl[] = {
 #endif
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB_2),      6 },
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH6_19),    6 },
-       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21),    6 },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21),    7 },
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_1),  6 },
-       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18),    6 },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18),    7 },
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH8_6),     6 },
        { 0, },
 };
index e53a1b78378b02c414c0c292c954974c763d880d..281c91426345946279412880bc804d01d287ec4c 100644 (file)
@@ -113,12 +113,26 @@ static const struct pci_device_id triflex_pci_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, triflex_pci_tbl);
 
+#ifdef CONFIG_PM
+static int triflex_ide_pci_suspend(struct pci_dev *dev, pm_message_t state)
+{
+       /*
+        * We must not disable or powerdown the device.
+        * APM bios refuses to suspend if IDE is not accessible.
+        */
+       pci_save_state(dev);
+       return 0;
+}
+#else
+#define triflex_ide_pci_suspend NULL
+#endif
+
 static struct pci_driver triflex_pci_driver = {
        .name           = "TRIFLEX_IDE",
        .id_table       = triflex_pci_tbl,
        .probe          = triflex_init_one,
        .remove         = ide_pci_remove,
-       .suspend        = ide_pci_suspend,
+       .suspend        = triflex_ide_pci_suspend,
        .resume         = ide_pci_resume,
 };
 
index 691276bafd7812c168c4dadbe1aa315bf43bad80..e9cf51b1343ba520d8928367a1eca80f9f531657 100644 (file)
@@ -216,7 +216,9 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 
        neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
        if (!neigh || !(neigh->nud_state & NUD_VALID)) {
+               rcu_read_lock();
                neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
+               rcu_read_unlock();
                ret = -ENODATA;
                if (neigh)
                        goto release;
@@ -274,15 +276,16 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                goto put;
        }
 
+       rcu_read_lock();
        neigh = dst_get_neighbour(dst);
        if (!neigh || !(neigh->nud_state & NUD_VALID)) {
                if (neigh)
                        neigh_event_send(neigh, NULL);
                ret = -ENODATA;
-               goto put;
+       } else {
+               ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
        }
-
-       ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
+       rcu_read_unlock();
 put:
        dst_release(dst);
        return ret;
index de6d0774e60990f644e39ca815159f68b5a065d1..c88b12beef25be72383f3423894121882d76d009 100644 (file)
@@ -1375,8 +1375,10 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
                goto reject;
        }
        dst = &rt->dst;
+       rcu_read_lock();
        neigh = dst_get_neighbour(dst);
        l2t = t3_l2t_get(tdev, neigh, neigh->dev);
+       rcu_read_unlock();
        if (!l2t) {
                printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
                       __func__);
@@ -1946,10 +1948,12 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        }
        ep->dst = &rt->dst;
 
+       rcu_read_lock();
        neigh = dst_get_neighbour(ep->dst);
 
        /* get a l2t entry */
        ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev);
+       rcu_read_unlock();
        if (!ep->l2t) {
                printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
                err = -ENOMEM;
index b36cdac9c558a35aa78f2061e9f7435dc1504754..0747004313ad5cabdc34a6e206b0fb5d49e25a32 100644 (file)
@@ -542,8 +542,10 @@ static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb,
                     (mpa_rev_to_use == 2 ? MPA_ENHANCED_RDMA_CONN : 0);
        mpa->private_data_size = htons(ep->plen);
        mpa->revision = mpa_rev_to_use;
-       if (mpa_rev_to_use == 1)
+       if (mpa_rev_to_use == 1) {
                ep->tried_with_mpa_v1 = 1;
+               ep->retry_with_mpa_v1 = 0;
+       }
 
        if (mpa_rev_to_use == 2) {
                mpa->private_data_size +=
@@ -1594,6 +1596,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
                goto reject;
        }
        dst = &rt->dst;
+       rcu_read_lock();
        neigh = dst_get_neighbour(dst);
        if (neigh->dev->flags & IFF_LOOPBACK) {
                pdev = ip_dev_find(&init_net, peer_ip);
@@ -1620,6 +1623,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
                rss_qid = dev->rdev.lldi.rxq_ids[
                          cxgb4_port_idx(neigh->dev) * step];
        }
+       rcu_read_unlock();
        if (!l2t) {
                printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
                       __func__);
@@ -1820,6 +1824,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
        }
        ep->dst = &rt->dst;
 
+       rcu_read_lock();
        neigh = dst_get_neighbour(ep->dst);
 
        /* get a l2t entry */
@@ -1856,6 +1861,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
                ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[
                        cxgb4_port_idx(neigh->dev) * step];
        }
+       rcu_read_unlock();
        if (!ep->l2t) {
                printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
                err = -ENOMEM;
@@ -2301,6 +2307,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        }
        ep->dst = &rt->dst;
 
+       rcu_read_lock();
        neigh = dst_get_neighbour(ep->dst);
 
        /* get a l2t entry */
@@ -2339,6 +2346,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
                ep->retry_with_mpa_v1 = 0;
                ep->tried_with_mpa_v1 = 0;
        }
+       rcu_read_unlock();
        if (!ep->l2t) {
                printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
                err = -ENOMEM;
index f35a935267e77e7a58c3be85437cbcb1a1f35cb7..0f1607c8325a5bc8a03e3a5d5471d39ed5741e8b 100644 (file)
@@ -311,7 +311,7 @@ void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count)
        while (ptr != cq->sw_pidx) {
                cqe = &cq->sw_queue[ptr];
                if (RQ_TYPE(cqe) && (CQE_OPCODE(cqe) != FW_RI_READ_RESP) &&
-                   (CQE_QPID(cqe) == wq->rq.qid) && cqe_completes_wr(cqe, wq))
+                   (CQE_QPID(cqe) == wq->sq.qid) && cqe_completes_wr(cqe, wq))
                        (*count)++;
                if (++ptr == cq->size)
                        ptr = 0;
index dfce9ea98a39b3f0f68e6d152d438554ebe8ee84..0a52d72371ee5f6cf2f938ba81fa0c887fd00070 100644 (file)
@@ -1377,9 +1377,11 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
                neigh_release(neigh);
        }
 
-       if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
+       if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) {
+               rcu_read_lock();
                neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
-
+               rcu_read_unlock();
+       }
        ip_rt_put(rt);
        return rc;
 }
index 5bd2162b95dcb8c93051ce7e496b628222764184..1d5895941e193e35e5ff88804fb00a9c29c8a5fa 100644 (file)
@@ -2307,19 +2307,11 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd)
                SYM_LSB(IBCCtrlA_0, MaxPktLen);
        ppd->cpspec->ibcctrl_a = ibc; /* without linkcmd or linkinitcmd! */
 
-       /* initially come up waiting for TS1, without sending anything. */
-       val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE <<
-               QLOGIC_IB_IBCC_LINKINITCMD_SHIFT);
-
-       ppd->cpspec->ibcctrl_a = val;
        /*
         * Reset the PCS interface to the serdes (and also ibc, which is still
         * in reset from above).  Writes new value of ibcctrl_a as last step.
         */
        qib_7322_mini_pcs_reset(ppd);
-       qib_write_kreg(dd, kr_scratch, 0ULL);
-       /* clear the linkinit cmds */
-       ppd->cpspec->ibcctrl_a &= ~SYM_MASK(IBCCtrlA_0, LinkInitCmd);
 
        if (!ppd->cpspec->ibcctrl_b) {
                unsigned lse = ppd->link_speed_enabled;
@@ -2385,6 +2377,14 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd)
        ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn);
        set_vls(ppd);
 
+       /* initially come up DISABLED, without sending anything. */
+       val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE <<
+                                       QLOGIC_IB_IBCC_LINKINITCMD_SHIFT);
+       qib_write_kreg_port(ppd, krp_ibcctrl_a, val);
+       qib_write_kreg(dd, kr_scratch, 0ULL);
+       /* clear the linkinit cmds */
+       ppd->cpspec->ibcctrl_a = val & ~SYM_MASK(IBCCtrlA_0, LinkInitCmd);
+
        /* be paranoid against later code motion, etc. */
        spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags);
        ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable);
@@ -5241,7 +5241,7 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs)
                           off */
                        if (ppd->dd->flags & QIB_HAS_QSFP) {
                                qd->t_insert = get_jiffies_64();
-                               schedule_work(&qd->work);
+                               queue_work(ib_wq, &qd->work);
                        }
                        spin_lock_irqsave(&ppd->sdma_lock, flags);
                        if (__qib_sdma_running(ppd))
index e06c4ed383f14598674ce8a0847c9780a6231c46..fa71b1e666c5414fbba2357fe531e75cabc7986c 100644 (file)
@@ -480,18 +480,6 @@ void qib_qsfp_init(struct qib_qsfp_data *qd,
        udelay(20); /* Generous RST dwell */
 
        dd->f_gpio_mod(dd, mask, mask, mask);
-       /* Spec says module can take up to two seconds! */
-       mask = QSFP_GPIO_MOD_PRS_N;
-       if (qd->ppd->hw_pidx)
-               mask <<= QSFP_GPIO_PORT2_SHIFT;
-
-       /* Do not try to wait here. Better to let event handle it */
-       if (!qib_qsfp_mod_present(qd->ppd))
-               goto bail;
-       /* We see a module, but it may be unwise to look yet. Just schedule */
-       qd->t_insert = get_jiffies_64();
-       queue_work(ib_wq, &qd->work);
-bail:
        return;
 }
 
index 0ef9af94997dcd5737922aa37a1483491b0c63f1..4115be54ba3b32626dc75c4529a3aa186b6f02c1 100644 (file)
@@ -57,21 +57,24 @@ struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
                                 struct ib_pd *pd, struct ib_ah_attr *attr)
 {
        struct ipoib_ah *ah;
+       struct ib_ah *vah;
 
        ah = kmalloc(sizeof *ah, GFP_KERNEL);
        if (!ah)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        ah->dev       = dev;
        ah->last_send = 0;
        kref_init(&ah->ref);
 
-       ah->ah = ib_create_ah(pd, attr);
-       if (IS_ERR(ah->ah)) {
+       vah = ib_create_ah(pd, attr);
+       if (IS_ERR(vah)) {
                kfree(ah);
-               ah = NULL;
-       } else
+               ah = (struct ipoib_ah *)vah;
+       } else {
+               ah->ah = vah;
                ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah);
+       }
 
        return ah;
 }
index 7567b60002309a19a2d0a4cc13da855a46042be4..83695b48b010a643a9b16d9240fa9a8538fa5d06 100644 (file)
@@ -432,7 +432,7 @@ static void path_rec_completion(int status,
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       if (ah) {
+       if (!IS_ERR_OR_NULL(ah)) {
                path->pathrec = *pathrec;
 
                old_ah   = path->ah;
@@ -555,6 +555,7 @@ static int path_rec_start(struct net_device *dev,
        return 0;
 }
 
+/* called with rcu_read_lock */
 static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -636,6 +637,7 @@ err_drop:
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+/* called with rcu_read_lock */
 static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
@@ -720,13 +722,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct neighbour *n = NULL;
        unsigned long flags;
 
+       rcu_read_lock();
        if (likely(skb_dst(skb)))
                n = dst_get_neighbour(skb_dst(skb));
 
        if (likely(n)) {
                if (unlikely(!*to_ipoib_neigh(n))) {
                        ipoib_path_lookup(skb, dev);
-                       return NETDEV_TX_OK;
+                       goto unlock;
                }
 
                neigh = *to_ipoib_neigh(n);
@@ -749,17 +752,17 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        ipoib_neigh_free(dev, neigh);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        ipoib_path_lookup(skb, dev);
-                       return NETDEV_TX_OK;
+                       goto unlock;
                }
 
                if (ipoib_cm_get(neigh)) {
                        if (ipoib_cm_up(neigh)) {
                                ipoib_cm_send(dev, skb, ipoib_cm_get(neigh));
-                               return NETDEV_TX_OK;
+                               goto unlock;
                        }
                } else if (neigh->ah) {
                        ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha));
-                       return NETDEV_TX_OK;
+                       goto unlock;
                }
 
                if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
@@ -793,13 +796,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                           phdr->hwaddr + 4);
                                dev_kfree_skb_any(skb);
                                ++dev->stats.tx_dropped;
-                               return NETDEV_TX_OK;
+                               goto unlock;
                        }
 
                        unicast_arp_send(skb, dev, phdr);
                }
        }
-
+unlock:
+       rcu_read_unlock();
        return NETDEV_TX_OK;
 }
 
@@ -837,7 +841,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
        dst = skb_dst(skb);
        n = NULL;
        if (dst)
-               n = dst_get_neighbour(dst);
+               n = dst_get_neighbour_raw(dst);
        if ((!dst || !n) && daddr) {
                struct ipoib_pseudoheader *phdr =
                        (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
index 1b7a9768635673f1a78f74e54e9e33fd37a80eb7..873bff97e69e266f6c39624f5fe3319eb76f7aae 100644 (file)
@@ -240,8 +240,11 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
                av.grh.dgid = mcast->mcmember.mgid;
 
                ah = ipoib_create_ah(dev, priv->pd, &av);
-               if (!ah) {
-                       ipoib_warn(priv, "ib_address_create failed\n");
+               if (IS_ERR(ah)) {
+                       ipoib_warn(priv, "ib_address_create failed %ld\n",
+                               -PTR_ERR(ah));
+                       /* use original error */
+                       return PTR_ERR(ah);
                } else {
                        spin_lock_irq(&priv->lock);
                        mcast->ah = ah;
@@ -266,7 +269,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
 
                skb->dev = dev;
                if (dst)
-                       n = dst_get_neighbour(dst);
+                       n = dst_get_neighbour_raw(dst);
                if (!dst || !n) {
                        /* put pseudoheader back on for next time */
                        skb_push(skb, sizeof (struct ipoib_pseudoheader));
@@ -722,6 +725,8 @@ out:
        if (mcast && mcast->ah) {
                struct dst_entry *dst = skb_dst(skb);
                struct neighbour *n = NULL;
+
+               rcu_read_lock();
                if (dst)
                        n = dst_get_neighbour(dst);
                if (n && !*to_ipoib_neigh(n)) {
@@ -734,7 +739,7 @@ out:
                                list_add_tail(&neigh->list, &mcast->neigh_list);
                        }
                }
-
+               rcu_read_unlock();
                spin_unlock_irqrestore(&priv->lock, flags);
                ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
                return;
index 09b93b11a274278b399e0adbfb1dc8e6917e35e9..e2a9867c19d52fce53cac578bdaf265d3211bba1 100644 (file)
@@ -1210,18 +1210,28 @@ static int elantech_reconnect(struct psmouse *psmouse)
  */
 static int elantech_set_properties(struct elantech_data *etd)
 {
+       /* This represents the version of IC body. */
        int ver = (etd->fw_version & 0x0f0000) >> 16;
 
+       /* Early version of Elan touchpads doesn't obey the rule. */
        if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600)
                etd->hw_version = 1;
-       else if (etd->fw_version < 0x150600)
-               etd->hw_version = 2;
-       else if (ver == 5)
-               etd->hw_version = 3;
-       else if (ver == 6)
-               etd->hw_version = 4;
-       else
-               return -1;
+       else {
+               switch (ver) {
+               case 2:
+               case 4:
+                       etd->hw_version = 2;
+                       break;
+               case 5:
+                       etd->hw_version = 3;
+                       break;
+               case 6:
+                       etd->hw_version = 4;
+                       break;
+               default:
+                       return -1;
+               }
+       }
 
        /*
         * Turn on packet checking by default.
index 4b2a42f9f0bb471748ee3d6676da48255fd73231..d4d08bd9205b87b7ddc617c55fee84ec6259a2b8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/irq.h>
 #include <linux/serio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/mach-types.h>
 #include <plat/board-ams-delta.h>
index bb9f5d31f0d0616463609f4b20c940ee0ec2d451..b4cfc6c8be89db327134dd7dd722dfa2623d472a 100644 (file)
@@ -431,6 +431,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
                },
        },
+       {
+               /* Newer HP Pavilion dv4 models */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
+               },
+       },
        { }
 };
 
@@ -560,6 +567,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
                },
        },
+       {
+               /* Newer HP Pavilion dv4 models */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
+               },
+       },
        { }
 };
 
index 661b692573e7790e7d75a4b815cd7741dfe47c74..6d5628bb060115d6e3f032210f9bc862a0ef397b 100644 (file)
@@ -270,11 +270,8 @@ void led_blink_set(struct led_classdev *led_cdev,
        del_timer_sync(&led_cdev->blink_timer);
 
        if (led_cdev->blink_set &&
-           !led_cdev->blink_set(led_cdev, delay_on, delay_off)) {
-               led_cdev->blink_delay_on = *delay_on;
-               led_cdev->blink_delay_off = *delay_off;
+           !led_cdev->blink_set(led_cdev, delay_on, delay_off))
                return;
-       }
 
        /* blink with 1 Hz as default if nothing specified */
        if (!*delay_on && !*delay_off)
index d593878d66d054e76f75860aec7176b9c012a5cf..5664696f2d3a8512c6ef96aca461dde22e5d486f 100644 (file)
@@ -472,7 +472,7 @@ config BMP085
          module will be called bmp085.
 
 config PCH_PHUB
-       tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"
+       tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
        depends on PCI
        help
          This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
@@ -480,12 +480,13 @@ config PCH_PHUB
          processor. The Topcliff has MAC address and Option ROM data in SROM.
          This driver can access MAC address and Option ROM data in SROM.
 
-         This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
-         Output Hub), ML7213 and ML7223.
-         ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
-         for MP(Media Phone) use.
-         ML7213/ML7223 is companion chip for Intel Atom E6xx series.
-         ML7213/ML7223 is completely compatible for Intel EG20T PCH.
+         This driver also can be used for LAPIS Semiconductor's IOH,
+         ML7213/ML7223/ML7831.
+         ML7213 which is for IVI(In-Vehicle Infotainment) use.
+         ML7223 IOH is for MP(Media Phone) use.
+         ML7831 IOH is for general purpose use.
+         ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
+         ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
 
          To compile this driver as a module, choose M here: the module will
          be called pch_phub.
index a662f5987b6892591008291e3b5b05506918ed9e..82b2cb77ae197b2124ede9131dc4cbe0902ce0e8 100644 (file)
@@ -100,7 +100,7 @@ enum dpot_devid {
        AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27),
        AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
                        BRDAC0, 7, 28),
-       AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
+       AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
                        BRDAC0, 8, 29),
        AD8402_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
                        BRDAC0 | BRDAC1, 8, 30),
index 7ce6065dc20e806a06845f08bcec084adbb4418d..eb5cd28bc6d8d7a1917f7f15d82b267b692315f8 100644 (file)
@@ -945,8 +945,7 @@ static int fpga_of_remove(struct platform_device *op)
 /* CTL-CPLD Version Register */
 #define CTL_CPLD_VERSION       0x2000
 
-static int fpga_of_probe(struct platform_device *op,
-                        const struct of_device_id *match)
+static int fpga_of_probe(struct platform_device *op)
 {
        struct device_node *of_node = op->dev.of_node;
        struct device *this_device;
@@ -1107,7 +1106,7 @@ static struct of_device_id fpga_of_match[] = {
        {},
 };
 
-static struct of_platform_driver fpga_of_driver = {
+static struct platform_driver fpga_of_driver = {
        .probe          = fpga_of_probe,
        .remove         = fpga_of_remove,
        .driver         = {
@@ -1124,12 +1123,12 @@ static struct of_platform_driver fpga_of_driver = {
 static int __init fpga_init(void)
 {
        led_trigger_register_simple("fpga", &ledtrig_fpga);
-       return of_register_platform_driver(&fpga_of_driver);
+       return platform_driver_register(&fpga_of_driver);
 }
 
 static void __exit fpga_exit(void)
 {
-       of_unregister_platform_driver(&fpga_of_driver);
+       platform_driver_unregister(&fpga_of_driver);
        led_trigger_unregister_simple(ledtrig_fpga);
 }
 
index 3965821fef174c308ac73e37072d552287985d91..14e974b2a7812452d14ad2d92979e8d84483da7e 100644 (file)
@@ -1249,8 +1249,7 @@ static bool dma_filter(struct dma_chan *chan, void *data)
        return true;
 }
 
-static int data_of_probe(struct platform_device *op,
-                        const struct of_device_id *match)
+static int data_of_probe(struct platform_device *op)
 {
        struct device_node *of_node = op->dev.of_node;
        struct device *this_device;
@@ -1401,7 +1400,7 @@ static struct of_device_id data_of_match[] = {
        {},
 };
 
-static struct of_platform_driver data_of_driver = {
+static struct platform_driver data_of_driver = {
        .probe          = data_of_probe,
        .remove         = data_of_remove,
        .driver         = {
@@ -1417,12 +1416,12 @@ static struct of_platform_driver data_of_driver = {
 
 static int __init data_init(void)
 {
-       return of_register_platform_driver(&data_of_driver);
+       return platform_driver_register(&data_of_driver);
 }
 
 static void __exit data_exit(void)
 {
-       of_unregister_platform_driver(&data_of_driver);
+       platform_driver_unregister(&data_of_driver);
 }
 
 MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
index 26cf12ca7f503e5d2babb111ab6eaf132cf5c5a2..701edf6589705cb42f290a04c233239f7248760a 100644 (file)
@@ -85,7 +85,7 @@ config EEPROM_93XX46
 
 config EEPROM_DIGSY_MTC_CFG
        bool "DigsyMTC display configuration EEPROMs device"
-       depends on PPC_MPC5200_GPIO && GPIOLIB && SPI_GPIO
+       depends on GPIO_MPC5200 && SPI_GPIO
        help
          This option enables access to display configuration EEPROMs
          on digsy_mtc board. You have to additionally select Microwire
index dee33addcaebf82c2652e089830fff7d442a8ed2..10fc4785dba7dd65330a7008db87a4423a0bedd5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ * Copyright (C) 2011 LAPIS Semiconductor 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
 #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
                                              (Intel EG20T PCH)*/
 #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
-                                               offset(OKI SEMICONDUCTOR ML7213)
+                                               offset(LAPIS Semicon ML7213)
                                              */
 #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
-                                               offset(OKI SEMICONDUCTOR ML7223)
+                                               offset(LAPIS Semicon ML7223)
                                              */
 
 /* MAX number of INT_REDUCE_CONTROL registers */
@@ -73,6 +73,9 @@
 #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB        0x8012 /* for Bus-m */
 #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB        0x8002 /* for Bus-n */
 
+/* Macros for ML7831 */
+#define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801
+
 /* SROM ACCESS Macro */
 #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
 
  * @pch_mac_start_address:             MAC address area start address
  * @pch_opt_rom_start_address:         Option ROM start address
  * @ioh_type:                          Save IOH type
+ * @pdev:                              pointer to pci device struct
  */
 struct pch_phub_reg {
        u32 phub_id_reg;
@@ -136,6 +140,7 @@ struct pch_phub_reg {
        u32 pch_mac_start_address;
        u32 pch_opt_rom_start_address;
        int ioh_type;
+       struct pci_dev *pdev;
 };
 
 /* SROM SPEC for MAC address assignment offset */
@@ -471,7 +476,7 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
        int retval;
        int i;
 
-       if (chip->ioh_type == 1) /* EG20T */
+       if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/
                retval = pch_phub_gbe_serial_rom_conf(chip);
        else    /* ML7223 */
                retval = pch_phub_gbe_serial_rom_conf_mp(chip);
@@ -498,6 +503,7 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
        unsigned int orom_size;
        int ret;
        int err;
+       ssize_t rom_size;
 
        struct pch_phub_reg *chip =
                dev_get_drvdata(container_of(kobj, struct device, kobj));
@@ -509,6 +515,10 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
        }
 
        /* Get Rom signature */
+       chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
+       if (!chip->pch_phub_extrom_base_address)
+               goto exrom_map_err;
+
        pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
                                (unsigned char *)&rom_signature);
        rom_signature &= 0xff;
@@ -539,10 +549,13 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
                goto return_err;
        }
 return_ok:
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
        mutex_unlock(&pch_phub_mutex);
        return addr_offset;
 
 return_err:
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
+exrom_map_err:
        mutex_unlock(&pch_phub_mutex);
 return_err_nomutex:
        return err;
@@ -555,6 +568,7 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
        int err;
        unsigned int addr_offset;
        int ret;
+       ssize_t rom_size;
        struct pch_phub_reg *chip =
                dev_get_drvdata(container_of(kobj, struct device, kobj));
 
@@ -571,6 +585,12 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
                goto return_ok;
        }
 
+       chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
+       if (!chip->pch_phub_extrom_base_address) {
+               err = -ENOMEM;
+               goto exrom_map_err;
+       }
+
        for (addr_offset = 0; addr_offset < count; addr_offset++) {
                if (PCH_PHUB_OROM_SIZE < off + addr_offset)
                        goto return_ok;
@@ -585,10 +605,14 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
        }
 
 return_ok:
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
        mutex_unlock(&pch_phub_mutex);
        return addr_offset;
 
 return_err:
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
+
+exrom_map_err:
        mutex_unlock(&pch_phub_mutex);
        return err;
 }
@@ -598,8 +622,14 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
 {
        u8 mac[8];
        struct pch_phub_reg *chip = dev_get_drvdata(dev);
+       ssize_t rom_size;
+
+       chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
+       if (!chip->pch_phub_extrom_base_address)
+               return -ENOMEM;
 
        pch_phub_read_gbe_mac_addr(chip, mac);
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
 
        return sprintf(buf, "%pM\n", mac);
 }
@@ -608,6 +638,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
                             const char *buf, size_t count)
 {
        u8 mac[6];
+       ssize_t rom_size;
        struct pch_phub_reg *chip = dev_get_drvdata(dev);
 
        if (count != 18)
@@ -617,7 +648,12 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
                (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
                (u32 *)&mac[4], (u32 *)&mac[5]);
 
+       chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
+       if (!chip->pch_phub_extrom_base_address)
+               return -ENOMEM;
+
        pch_phub_write_gbe_mac_addr(chip, mac);
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
 
        return count;
 }
@@ -640,7 +676,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
        int retval;
 
        int ret;
-       ssize_t rom_size;
        struct pch_phub_reg *chip;
 
        chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
@@ -677,19 +712,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
                "in pch_phub_base_address variable is %p\n", __func__,
                chip->pch_phub_base_address);
 
-       if (id->driver_data != 3) {
-               chip->pch_phub_extrom_base_address =\
-                                                  pci_map_rom(pdev, &rom_size);
-               if (chip->pch_phub_extrom_base_address == 0) {
-                       dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
-                       ret = -ENOMEM;
-                       goto err_pci_map;
-               }
-               dev_dbg(&pdev->dev, "%s : "
-                       "pci_map_rom SUCCESS and value in "
-                       "pch_phub_extrom_base_address variable is %p\n",
-                       __func__, chip->pch_phub_extrom_base_address);
-       }
+       chip->pdev = pdev; /* Save pci device struct */
 
        if (id->driver_data == 1) { /* EG20T PCH */
                const char *board_name;
@@ -763,6 +786,22 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
                chip->pch_opt_rom_start_address =\
                                                 PCH_PHUB_ROM_START_ADDR_ML7223;
                chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
+       } else if (id->driver_data == 5) { /* ML7831 */
+               retval = sysfs_create_file(&pdev->dev.kobj,
+                                          &dev_attr_pch_mac.attr);
+               if (retval)
+                       goto err_sysfs_create;
+
+               retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+               if (retval)
+                       goto exit_bin_attr;
+
+               /* set the prefech value */
+               iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
+               /* set the interrupt delay value */
+               iowrite32(0x25, chip->pch_phub_base_address + 0x44);
+               chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
+               chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
        }
 
        chip->ioh_type = id->driver_data;
@@ -773,8 +812,6 @@ exit_bin_attr:
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
 
 err_sysfs_create:
-       pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
-err_pci_map:
        pci_iounmap(pdev, chip->pch_phub_base_address);
 err_pci_iomap:
        pci_release_regions(pdev);
@@ -792,7 +829,6 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev)
 
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
        sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
-       pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
        pci_iounmap(pdev, chip->pch_phub_base_address);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@ -847,6 +883,7 @@ static struct pci_device_id pch_phub_pcidev_id[] = {
        { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2,  },
        { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3,  },
        { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4,  },
+       { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5,  },
        { }
 };
 MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
@@ -873,5 +910,5 @@ static void __exit pch_phub_pci_exit(void)
 module_init(pch_phub_pci_init);
 module_exit(pch_phub_pci_exit);
 
-MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB");
+MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB");
 MODULE_LICENSE("GPL");
index cfbddbef11de3b67c54be85797dd124843ca8596..43d073bc1d9c5fef61a1cb3a1e741a6cd6b6e0f9 100644 (file)
@@ -903,6 +903,6 @@ static void __exit spear_pcie_gadget_exit(void)
 }
 module_exit(spear_pcie_gadget_exit);
 
-MODULE_ALIAS("pcie-gadget-spear");
+MODULE_ALIAS("platform:pcie-gadget-spear");
 MODULE_AUTHOR("Pratyush Anand");
 MODULE_LICENSE("GPL");
index 583f66cd5bbd63dc199468b87b96baf32582bcb1..654a5e94e0e7c4f227c93b75a7791c406c586d38 100644 (file)
@@ -245,6 +245,8 @@ source "drivers/net/ethernet/Kconfig"
 
 source "drivers/net/fddi/Kconfig"
 
+source "drivers/net/hippi/Kconfig"
+
 config NET_SB1000
        tristate "General Instruments Surfboard 1000"
        depends on PNP
index 5a20804fdece8d1c281e310e49509973185a33ed..4ef7e2fd9fe6f5b577c13fc56a5b2ae45a54a0bd 100644 (file)
@@ -319,6 +319,13 @@ static ssize_t bonding_store_mode(struct device *d,
                goto out;
        }
 
+       if (bond->slave_cnt > 0) {
+               pr_err("unable to update mode of %s because it has slaves.\n",
+                       bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
        new_value = bond_parse_parm(buf, bond_mode_tbl);
        if (new_value < 0)  {
                pr_err("%s: Ignoring invalid mode value %.*s.\n",
index 6486ab8c8fc87d803a6e5a3d507d50796704db08..2f6361e949f0c836562ff896928cb6709abf883a 100644 (file)
@@ -10548,33 +10548,38 @@ do {                                                                  \
 
 int bnx2x_init_firmware(struct bnx2x *bp)
 {
-       const char *fw_file_name;
        struct bnx2x_fw_file_hdr *fw_hdr;
        int rc;
 
-       if (CHIP_IS_E1(bp))
-               fw_file_name = FW_FILE_NAME_E1;
-       else if (CHIP_IS_E1H(bp))
-               fw_file_name = FW_FILE_NAME_E1H;
-       else if (!CHIP_IS_E1x(bp))
-               fw_file_name = FW_FILE_NAME_E2;
-       else {
-               BNX2X_ERR("Unsupported chip revision\n");
-               return -EINVAL;
-       }
 
-       BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
+       if (!bp->firmware) {
+               const char *fw_file_name;
 
-       rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev);
-       if (rc) {
-               BNX2X_ERR("Can't load firmware file %s\n", fw_file_name);
-               goto request_firmware_exit;
-       }
+               if (CHIP_IS_E1(bp))
+                       fw_file_name = FW_FILE_NAME_E1;
+               else if (CHIP_IS_E1H(bp))
+                       fw_file_name = FW_FILE_NAME_E1H;
+               else if (!CHIP_IS_E1x(bp))
+                       fw_file_name = FW_FILE_NAME_E2;
+               else {
+                       BNX2X_ERR("Unsupported chip revision\n");
+                       return -EINVAL;
+               }
+               BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
 
-       rc = bnx2x_check_firmware(bp);
-       if (rc) {
-               BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
-               goto request_firmware_exit;
+               rc = request_firmware(&bp->firmware, fw_file_name,
+                                     &bp->pdev->dev);
+               if (rc) {
+                       BNX2X_ERR("Can't load firmware file %s\n",
+                                 fw_file_name);
+                       goto request_firmware_exit;
+               }
+
+               rc = bnx2x_check_firmware(bp);
+               if (rc) {
+                       BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
+                       goto request_firmware_exit;
+               }
        }
 
        fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
@@ -10630,6 +10635,7 @@ static void bnx2x_release_firmware(struct bnx2x *bp)
        kfree(bp->init_ops);
        kfree(bp->init_data);
        release_firmware(bp->firmware);
+       bp->firmware = NULL;
 }
 
 
@@ -10925,6 +10931,8 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
        if (bp->doorbells)
                iounmap(bp->doorbells);
 
+       bnx2x_release_firmware(bp);
+
        bnx2x_free_mem_bp(bp);
 
        free_netdev(dev);
index 0440425c83d6820e3ba2ad12ec57430ec9896492..14517691f8dbe9a759abe26a7e5f5debd2515eb4 100644 (file)
@@ -5380,7 +5380,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
        rc = drv->init_fw(bp);
        if (rc) {
                BNX2X_ERR("Error loading firmware\n");
-               goto fw_init_err;
+               goto init_err;
        }
 
        /* Handle the beginning of COMMON_XXX pases separatelly... */
@@ -5388,25 +5388,25 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
        case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:
                rc = bnx2x_func_init_cmn_chip(bp, drv);
                if (rc)
-                       goto init_hw_err;
+                       goto init_err;
 
                break;
        case FW_MSG_CODE_DRV_LOAD_COMMON:
                rc = bnx2x_func_init_cmn(bp, drv);
                if (rc)
-                       goto init_hw_err;
+                       goto init_err;
 
                break;
        case FW_MSG_CODE_DRV_LOAD_PORT:
                rc = bnx2x_func_init_port(bp, drv);
                if (rc)
-                       goto init_hw_err;
+                       goto init_err;
 
                break;
        case FW_MSG_CODE_DRV_LOAD_FUNCTION:
                rc = bnx2x_func_init_func(bp, drv);
                if (rc)
-                       goto init_hw_err;
+                       goto init_err;
 
                break;
        default:
@@ -5414,10 +5414,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
                rc = -EINVAL;
        }
 
-init_hw_err:
-       drv->release_fw(bp);
-
-fw_init_err:
+init_err:
        drv->gunzip_end(bp);
 
        /* In case of success, complete the comand immediatelly: no ramrods
index 98849a1fc749995070dadd607175f55ef89d2fa0..b48378a41e492ce3df245214235c25b901a436c1 100644 (file)
@@ -7,6 +7,7 @@ config HAVE_NET_MACB
 
 config NET_ATMEL
        bool "Atmel devices"
+       default y
        depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y.
index 6bb2b9506cadfde73ddef809bc0fcf78dd202b0a..0b3567ab812151f00210544cc805815b0953a90d 100644 (file)
@@ -34,6 +34,8 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
 
 #include <asm/checksum.h>
 
index fdc6c394c683ed64e9ecd456427e742d0f101bcd..7803efa46eb26b4b9fb5465ea1cb1df15d26d8ed 100644 (file)
@@ -50,7 +50,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.29"
+#define DRV_VERSION            "1.30"
 
 /*
  * The Yukon II chipset takes 64 bit command blocks (called list elements)
@@ -68,7 +68,7 @@
 #define MAX_SKB_TX_LE  (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
 #define TX_MIN_PENDING         (MAX_SKB_TX_LE+1)
 #define TX_MAX_PENDING         1024
-#define TX_DEF_PENDING         127
+#define TX_DEF_PENDING         63
 
 #define TX_WATCHDOG            (5 * HZ)
 #define NAPI_WEIGHT            64
@@ -869,6 +869,7 @@ static void sky2_wol_init(struct sky2_port *sky2)
 
        /* block receiver */
        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+       sky2_read32(hw, B0_CTST);
 }
 
 static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
@@ -1274,6 +1275,14 @@ static void rx_set_checksum(struct sky2_port *sky2)
                     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
 }
 
+/*
+ * Fixed initial key as seed to RSS.
+ */
+static const uint32_t rss_init_key[10] = {
+       0x7c3351da, 0x51c5cf4e, 0x44adbdd1, 0xe8d38d18, 0x48897c43,
+       0xb1d60e7e, 0x6a3dd760, 0x01a2e453, 0x16f46f13, 0x1a0e7b30
+};
+
 /* Enable/disable receive hash calculation (RSS) */
 static void rx_set_rss(struct net_device *dev, u32 features)
 {
@@ -1289,12 +1298,9 @@ static void rx_set_rss(struct net_device *dev, u32 features)
 
        /* Program RSS initial values */
        if (features & NETIF_F_RXHASH) {
-               u32 key[nkeys];
-
-               get_random_bytes(key, nkeys * sizeof(u32));
                for (i = 0; i < nkeys; i++)
                        sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
-                                    key[i]);
+                                    rss_init_key[i]);
 
                /* Need to turn on (undocumented) flag to make hashing work  */
                sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
@@ -1717,6 +1723,8 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
        if (err)
                dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
        else {
+               hw->flags |= SKY2_HW_IRQ_SETUP;
+
                napi_enable(&hw->napi);
                sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
                sky2_read32(hw, B0_IMSK);
@@ -1727,7 +1735,7 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
 
 
 /* Bring up network interface. */
-static int sky2_up(struct net_device *dev)
+static int sky2_open(struct net_device *dev)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
@@ -1747,6 +1755,11 @@ static int sky2_up(struct net_device *dev)
 
        sky2_hw_up(sky2);
 
+       if (hw->chip_id == CHIP_ID_YUKON_OPT ||
+           hw->chip_id == CHIP_ID_YUKON_PRM ||
+           hw->chip_id == CHIP_ID_YUKON_OP_2)
+               imask |= Y2_IS_PHY_QLNK;        /* enable PHY Quick Link */
+
        /* Enable interrupts from phy/mac for port */
        imask = sky2_read32(hw, B0_IMSK);
        imask |= portirq_msk[port];
@@ -2040,6 +2053,8 @@ static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
 
        sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
        sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+
+       sky2_read32(hw, B0_CTST);
 }
 
 static void sky2_hw_down(struct sky2_port *sky2)
@@ -2090,7 +2105,7 @@ static void sky2_hw_down(struct sky2_port *sky2)
 }
 
 /* Network shutdown */
-static int sky2_down(struct net_device *dev)
+static int sky2_close(struct net_device *dev)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
@@ -2101,15 +2116,22 @@ static int sky2_down(struct net_device *dev)
 
        netif_info(sky2, ifdown, dev, "disabling interface\n");
 
-       /* Disable port IRQ */
-       sky2_write32(hw, B0_IMSK,
-                    sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]);
-       sky2_read32(hw, B0_IMSK);
-
        if (hw->ports == 1) {
+               sky2_write32(hw, B0_IMSK, 0);
+               sky2_read32(hw, B0_IMSK);
+
                napi_disable(&hw->napi);
                free_irq(hw->pdev->irq, hw);
+               hw->flags &= ~SKY2_HW_IRQ_SETUP;
        } else {
+               u32 imask;
+
+               /* Disable port IRQ */
+               imask  = sky2_read32(hw, B0_IMSK);
+               imask &= ~portirq_msk[sky2->port];
+               sky2_write32(hw, B0_IMSK, imask);
+               sky2_read32(hw, B0_IMSK);
+
                synchronize_irq(hw->pdev->irq);
                napi_synchronize(&hw->napi);
        }
@@ -2587,7 +2609,7 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
        if (netif_running(dev)) {
                sky2_tx_complete(sky2, last);
 
-               /* Wake unless it's detached, and called e.g. from sky2_down() */
+               /* Wake unless it's detached, and called e.g. from sky2_close() */
                if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
                        netif_wake_queue(dev);
        }
@@ -3258,7 +3280,6 @@ static void sky2_reset(struct sky2_hw *hw)
            hw->chip_id == CHIP_ID_YUKON_PRM ||
            hw->chip_id == CHIP_ID_YUKON_OP_2) {
                u16 reg;
-               u32 msk;
 
                if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
                        /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
@@ -3281,11 +3302,6 @@ static void sky2_reset(struct sky2_hw *hw)
                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
                sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
 
-               /* enable PHY Quick Link */
-               msk = sky2_read32(hw, B0_IMSK);
-               msk |= Y2_IS_PHY_QLNK;
-               sky2_write32(hw, B0_IMSK, msk);
-
                /* check if PSMv2 was running before */
                reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
                if (reg & PCI_EXP_LNKCTL_ASPMC)
@@ -3383,7 +3399,7 @@ static void sky2_detach(struct net_device *dev)
                netif_tx_lock(dev);
                netif_device_detach(dev);       /* stop txq */
                netif_tx_unlock(dev);
-               sky2_down(dev);
+               sky2_close(dev);
        }
 }
 
@@ -3393,7 +3409,7 @@ static int sky2_reattach(struct net_device *dev)
        int err = 0;
 
        if (netif_running(dev)) {
-               err = sky2_up(dev);
+               err = sky2_open(dev);
                if (err) {
                        netdev_info(dev, "could not restart %d\n", err);
                        dev_close(dev);
@@ -3410,10 +3426,13 @@ static void sky2_all_down(struct sky2_hw *hw)
 {
        int i;
 
-       sky2_read32(hw, B0_IMSK);
-       sky2_write32(hw, B0_IMSK, 0);
-       synchronize_irq(hw->pdev->irq);
-       napi_disable(&hw->napi);
+       if (hw->flags & SKY2_HW_IRQ_SETUP) {
+               sky2_read32(hw, B0_IMSK);
+               sky2_write32(hw, B0_IMSK, 0);
+
+               synchronize_irq(hw->pdev->irq);
+               napi_disable(&hw->napi);
+       }
 
        for (i = 0; i < hw->ports; i++) {
                struct net_device *dev = hw->dev[i];
@@ -3446,11 +3465,12 @@ static void sky2_all_up(struct sky2_hw *hw)
                netif_wake_queue(dev);
        }
 
-       sky2_write32(hw, B0_IMSK, imask);
-       sky2_read32(hw, B0_IMSK);
-
-       sky2_read32(hw, B0_Y2_SP_LISR);
-       napi_enable(&hw->napi);
+       if (hw->flags & SKY2_HW_IRQ_SETUP) {
+               sky2_write32(hw, B0_IMSK, imask);
+               sky2_read32(hw, B0_IMSK);
+               sky2_read32(hw, B0_Y2_SP_LISR);
+               napi_enable(&hw->napi);
+       }
 }
 
 static void sky2_restart(struct work_struct *work)
@@ -4071,6 +4091,16 @@ static int sky2_set_coalesce(struct net_device *dev,
        return 0;
 }
 
+/*
+ * Hardware is limited to min of 128 and max of 2048 for ring size
+ * and  rounded up to next power of two
+ * to avoid division in modulus calclation
+ */
+static unsigned long roundup_ring_size(unsigned long pending)
+{
+       return max(128ul, roundup_pow_of_two(pending+1));
+}
+
 static void sky2_get_ringparam(struct net_device *dev,
                               struct ethtool_ringparam *ering)
 {
@@ -4098,7 +4128,7 @@ static int sky2_set_ringparam(struct net_device *dev,
 
        sky2->rx_pending = ering->rx_pending;
        sky2->tx_pending = ering->tx_pending;
-       sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1);
+       sky2->tx_ring_size = roundup_ring_size(sky2->tx_pending);
 
        return sky2_reattach(dev);
 }
@@ -4556,7 +4586,7 @@ static int sky2_device_event(struct notifier_block *unused,
        struct net_device *dev = ptr;
        struct sky2_port *sky2 = netdev_priv(dev);
 
-       if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug)
+       if (dev->netdev_ops->ndo_open != sky2_open || !sky2_debug)
                return NOTIFY_DONE;
 
        switch (event) {
@@ -4621,8 +4651,8 @@ static __exit void sky2_debug_cleanup(void)
    not allowing netpoll on second port */
 static const struct net_device_ops sky2_netdev_ops[2] = {
   {
-       .ndo_open               = sky2_up,
-       .ndo_stop               = sky2_down,
+       .ndo_open               = sky2_open,
+       .ndo_stop               = sky2_close,
        .ndo_start_xmit         = sky2_xmit_frame,
        .ndo_do_ioctl           = sky2_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
@@ -4638,8 +4668,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
 #endif
   },
   {
-       .ndo_open               = sky2_up,
-       .ndo_stop               = sky2_down,
+       .ndo_open               = sky2_open,
+       .ndo_stop               = sky2_close,
        .ndo_start_xmit         = sky2_xmit_frame,
        .ndo_do_ioctl           = sky2_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
@@ -4692,7 +4722,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        spin_lock_init(&sky2->phy_lock);
 
        sky2->tx_pending = TX_DEF_PENDING;
-       sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1);
+       sky2->tx_ring_size = roundup_ring_size(TX_DEF_PENDING);
        sky2->rx_pending = RX_DEF_PENDING;
 
        hw->dev[port] = dev;
index 0af31b8b5f106174b74c99cd124c758d95c71672..ff6f58bf822aa378ffa0975140733fa40bf41f5d 100644 (file)
@@ -2287,6 +2287,7 @@ struct sky2_hw {
 #define SKY2_HW_RSS_BROKEN     0x00000100
 #define SKY2_HW_VLAN_BROKEN     0x00000200
 #define SKY2_HW_RSS_CHKSUM     0x00000400      /* RSS requires chksum */
+#define SKY2_HW_IRQ_SETUP      0x00000800
 
        u8                   chip_id;
        u8                   chip_rev;
index b89c36dbf5b3ea7927fb46252819210bdd55ec26..c2df6c35860317e63a1473e2b69636bedaadc777 100644 (file)
@@ -581,6 +581,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
                 * Packet is OK - process it.
                 */
                length = be32_to_cpu(cqe->byte_cnt);
+               length -= ring->fcs_del;
                ring->bytes += length;
                ring->packets++;
 
@@ -813,8 +814,11 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
        context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
 
        /* Cancel FCS removal if FW allows */
-       if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP)
+       if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) {
                context->param3 |= cpu_to_be32(1 << 29);
+               ring->fcs_del = ETH_FCS_LEN;
+       } else
+               ring->fcs_del = 0;
 
        err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, context, qp, state);
        if (err) {
index 8fda331c65dfddd19a69da927444ec41be546da4..207b5add3ca848134ea44bf3fadd918ef2912c3f 100644 (file)
@@ -272,6 +272,7 @@ struct mlx4_en_rx_ring {
        u32 prod;
        u32 cons;
        u32 buf_size;
+       u8  fcs_del;
        void *buf;
        void *rx_info;
        unsigned long bytes;
index 1dca57013cb2d868f3881a528a3dccc27e7605a9..1c61d36e657070d16ecf921992e59a883bf574c3 100644 (file)
@@ -609,7 +609,7 @@ struct nv_ethtool_str {
 };
 
 static const struct nv_ethtool_str nv_estats_str[] = {
-       { "tx_bytes" },
+       { "tx_bytes" }, /* includes Ethernet FCS CRC */
        { "tx_zero_rexmt" },
        { "tx_one_rexmt" },
        { "tx_many_rexmt" },
@@ -637,7 +637,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {
        /* version 2 stats */
        { "tx_deferral" },
        { "tx_packets" },
-       { "rx_bytes" },
+       { "rx_bytes" }, /* includes Ethernet FCS CRC */
        { "tx_pause" },
        { "rx_pause" },
        { "rx_drop_frame" },
@@ -649,7 +649,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {
 };
 
 struct nv_ethtool_stats {
-       u64 tx_bytes;
+       u64 tx_bytes; /* should be ifconfig->tx_bytes + 4*tx_packets */
        u64 tx_zero_rexmt;
        u64 tx_one_rexmt;
        u64 tx_many_rexmt;
@@ -670,14 +670,14 @@ struct nv_ethtool_stats {
        u64 rx_unicast;
        u64 rx_multicast;
        u64 rx_broadcast;
-       u64 rx_packets;
+       u64 rx_packets; /* should be ifconfig->rx_packets */
        u64 rx_errors_total;
        u64 tx_errors_total;
 
        /* version 2 stats */
        u64 tx_deferral;
-       u64 tx_packets;
-       u64 rx_bytes;
+       u64 tx_packets; /* should be ifconfig->tx_packets */
+       u64 rx_bytes;   /* should be ifconfig->rx_bytes + 4*rx_packets */
        u64 tx_pause;
        u64 rx_pause;
        u64 rx_drop_frame;
@@ -1706,10 +1706,17 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
        if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {
                nv_get_hw_stats(dev);
 
+               /*
+                * Note: because HW stats are not always available and
+                * for consistency reasons, the following ifconfig
+                * stats are managed by software: rx_bytes, tx_bytes,
+                * rx_packets and tx_packets. The related hardware
+                * stats reported by ethtool should be equivalent to
+                * these ifconfig stats, with 4 additional bytes per
+                * packet (Ethernet FCS CRC).
+                */
+
                /* copy to net_device stats */
-               dev->stats.tx_packets = np->estats.tx_packets;
-               dev->stats.rx_bytes = np->estats.rx_bytes;
-               dev->stats.tx_bytes = np->estats.tx_bytes;
                dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
                dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
                dev->stats.rx_crc_errors = np->estats.rx_crc_errors;
@@ -2380,6 +2387,9 @@ static int nv_tx_done(struct net_device *dev, int limit)
                                if (flags & NV_TX_ERROR) {
                                        if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK))
                                                nv_legacybackoff_reseed(dev);
+                               } else {
+                                       dev->stats.tx_packets++;
+                                       dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
                                }
                                dev_kfree_skb_any(np->get_tx_ctx->skb);
                                np->get_tx_ctx->skb = NULL;
@@ -2390,6 +2400,9 @@ static int nv_tx_done(struct net_device *dev, int limit)
                                if (flags & NV_TX2_ERROR) {
                                        if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK))
                                                nv_legacybackoff_reseed(dev);
+                               } else {
+                                       dev->stats.tx_packets++;
+                                       dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
                                }
                                dev_kfree_skb_any(np->get_tx_ctx->skb);
                                np->get_tx_ctx->skb = NULL;
@@ -2429,6 +2442,9 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
                                        else
                                                nv_legacybackoff_reseed(dev);
                                }
+                       } else {
+                               dev->stats.tx_packets++;
+                               dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
                        }
 
                        dev_kfree_skb_any(np->get_tx_ctx->skb);
@@ -2678,6 +2694,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
                skb->protocol = eth_type_trans(skb, dev);
                napi_gro_receive(&np->napi, skb);
                dev->stats.rx_packets++;
+               dev->stats.rx_bytes += len;
 next_pkt:
                if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
                        np->get_rx.orig = np->first_rx.orig;
@@ -2761,6 +2778,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
                        }
                        napi_gro_receive(&np->napi, skb);
                        dev->stats.rx_packets++;
+                       dev->stats.rx_bytes += len;
                } else {
                        dev_kfree_skb(skb);
                }
index 9c075ea2682e2025043d1099ad3d2c70c20b00bf..9cb5f912e4891f5b832bb941bce6916c5248bdb6 100644 (file)
@@ -18,8 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
  */
 
-#include <linux/module.h>      /* for __MODULE_STRING */
 #include "pch_gbe.h"
+#include <linux/module.h>      /* for __MODULE_STRING */
 
 #define OPTION_UNSET   -1
 #define OPTION_DISABLED 0
index 1fc01ca72b466095b682f209b266f7209f8d3ec1..4bf68cfef39072d607420c476160944888d5fa47 100644 (file)
@@ -940,7 +940,7 @@ static void r6040_multicast_list(struct net_device *dev)
        iowrite16(lp->mcr0, ioaddr + MCR0);
 
        /* Fill the MAC hash tables with their values */
-       if (lp->mcr0 && MCR0_HASH_EN) {
+       if (lp->mcr0 & MCR0_HASH_EN) {
                iowrite16(hash_table[0], ioaddr + MAR0);
                iowrite16(hash_table[1], ioaddr + MAR1);
                iowrite16(hash_table[2], ioaddr + MAR2);
index 92b45f08858fab787a7ac3de3297f9b8c318ea67..6f06aa10f0d729a040a6e34a244d57338ba3025f 100644 (file)
@@ -1292,7 +1292,7 @@ static void __rtl8169_check_link_status(struct net_device *dev,
                netif_carrier_off(dev);
                netif_info(tp, ifdown, dev, "link down\n");
                if (pm)
-                       pm_schedule_suspend(&tp->pci_dev->dev, 100);
+                       pm_schedule_suspend(&tp->pci_dev->dev, 5000);
        }
        spin_unlock_irqrestore(&tp->lock, flags);
 }
index d2be42aafbef201e48ea5d1fb177564aaeaacf31..8843071fe987bd1543b91387f6da9c3c9a8d0800 100644 (file)
@@ -1937,6 +1937,7 @@ static int __devinit smsc911x_init(struct net_device *dev)
 {
        struct smsc911x_data *pdata = netdev_priv(dev);
        unsigned int byte_test;
+       unsigned int to = 100;
 
        SMSC_TRACE(pdata, probe, "Driver Parameters:");
        SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX",
@@ -1952,6 +1953,17 @@ static int __devinit smsc911x_init(struct net_device *dev)
                return -ENODEV;
        }
 
+       /*
+        * poll the READY bit in PMT_CTRL. Any other access to the device is
+        * forbidden while this bit isn't set. Try for 100ms
+        */
+       while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
+               udelay(1000);
+       if (to == 0) {
+               pr_err("Device not READY in 100ms aborting\n");
+               return -ENODEV;
+       }
+
        /* Check byte ordering */
        byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
        SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test);
index da66ac511c4c60df8dabe849cd02ba9ae2d76dad..4d5402a1d262976bdede2fed63875000d81e17fb 100644 (file)
@@ -39,10 +39,11 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
        /* DMA SW reset */
        value |= DMA_BUS_MODE_SFT_RESET;
        writel(value, ioaddr + DMA_BUS_MODE);
-       limit = 15000;
+       limit = 10;
        while (limit--) {
                if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
                        break;
+               mdelay(10);
        }
        if (limit < 0)
                return -EBUSY;
index 627f656b0f3c581bbb20a45084b7c1fd87a22194..bc17fd08b55dc9085a9ea66cefe1f388fd3ce985 100644 (file)
@@ -41,10 +41,11 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
        /* DMA SW reset */
        value |= DMA_BUS_MODE_SFT_RESET;
        writel(value, ioaddr + DMA_BUS_MODE);
-       limit = 15000;
+       limit = 10;
        while (limit--) {
                if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
                        break;
+               mdelay(10);
        }
        if (limit < 0)
                return -EBUSY;
index 9bafa6cf9e8b5af13b262e1efc28809ff9a9c910..a140a8fbf0515c70e2471639907239f34b55f036 100644 (file)
@@ -72,7 +72,6 @@ struct stmmac_priv {
        spinlock_t lock;
        spinlock_t tx_lock;
        int wolopts;
-       int wolenabled;
        int wol_irq;
 #ifdef CONFIG_STMMAC_TIMER
        struct stmmac_timer *tm;
@@ -80,6 +79,7 @@ struct stmmac_priv {
        struct plat_stmmacenet_data *plat;
        struct stmmac_counters mmc;
        struct dma_features dma_cap;
+       int hw_cap_support;
 };
 
 extern int stmmac_mdio_unregister(struct net_device *ndev);
index e8eff09bbbd73c7b036f5cd9520d030c949fddc1..0395f9eba801e9281f6af9a9fca8dc12057b55e4 100644 (file)
@@ -430,6 +430,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        struct stmmac_priv *priv = netdev_priv(dev);
        u32 support = WAKE_MAGIC | WAKE_UCAST;
 
+       /* By default almost all GMAC devices support the WoL via
+        * magic frame but we can disable it if the HW capability
+        * register shows no support for pmt_magic_frame. */
+       if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))
+               wol->wolopts &= ~WAKE_MAGIC;
+
        if (!device_can_wakeup(priv->device))
                return -EINVAL;
 
index 20546bbbb8db04744d39b2e4a4e5710f04fa6538..8ea770a89f2556b8c762f2af345e5044d45ff9ba 100644 (file)
@@ -321,12 +321,10 @@ static int stmmac_init_phy(struct net_device *dev)
        }
 
        /* Stop Advertising 1000BASE Capability if interface is not GMII */
-       if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) ||
-           (interface == PHY_INTERFACE_MODE_RMII))) {
-               phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
-                                     SUPPORTED_Asym_Pause);
-               phydev->advertising = phydev->supported;
-       }
+       if ((interface == PHY_INTERFACE_MODE_MII) ||
+           (interface == PHY_INTERFACE_MODE_RMII))
+               phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
+                                        SUPPORTED_1000baseT_Full);
 
        /*
         * Broken HW is sometimes missing the pull-up resistor on the
@@ -807,8 +805,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
        return 0;
 }
 
-/* New GMAC chips support a new register to indicate the
- * presence of the optional feature/functions.
+/**
+ * stmmac_selec_desc_mode
+ * @dev : device pointer
+ * Description: select the Enhanced/Alternate or Normal descriptors */
+static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
+{
+       if (priv->plat->enh_desc) {
+               pr_info(" Enhanced/Alternate descriptors\n");
+               priv->hw->desc = &enh_desc_ops;
+       } else {
+               pr_info(" Normal descriptors\n");
+               priv->hw->desc = &ndesc_ops;
+       }
+}
+
+/**
+ * stmmac_get_hw_features
+ * @priv : private device pointer
+ * Description:
+ *  new GMAC chip generations have a new register to indicate the
+ *  presence of the optional feature/functions.
+ *  This can be also used to override the value passed through the
+ *  platform and necessary for old MAC10/100 and GMAC chips.
  */
 static int stmmac_get_hw_features(struct stmmac_priv *priv)
 {
@@ -829,7 +848,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
                        (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
                priv->dma_cap.pmt_magic_frame =
                        (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
-               /*MMC*/
+               /* MMC */
                priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
                /* IEEE 1588-2002*/
                priv->dma_cap.time_stamp =
@@ -857,8 +876,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
                priv->dma_cap.enh_desc =
                        (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
 
-       } else
-               pr_debug("\tNo HW DMA feature register supported");
+       }
 
        return hw_cap;
 }
@@ -913,6 +931,44 @@ static int stmmac_open(struct net_device *dev)
                goto open_error;
        }
 
+       stmmac_get_synopsys_id(priv);
+
+       priv->hw_cap_support = stmmac_get_hw_features(priv);
+
+       if (priv->hw_cap_support) {
+               pr_info(" Support DMA HW capability register");
+
+               /* We can override some gmac/dma configuration fields: e.g.
+                * enh_desc, tx_coe (e.g. that are passed through the
+                * platform) with the values from the HW capability
+                * register (if supported).
+                */
+               priv->plat->enh_desc = priv->dma_cap.enh_desc;
+               priv->plat->tx_coe = priv->dma_cap.tx_coe;
+               priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
+
+               /* By default disable wol on magic frame if not supported */
+               if (!priv->dma_cap.pmt_magic_frame)
+                       priv->wolopts &= ~WAKE_MAGIC;
+
+       } else
+               pr_info(" No HW DMA feature register supported");
+
+       /* Select the enhnaced/normal descriptor structures */
+       stmmac_selec_desc_mode(priv);
+
+       /* PMT module is not integrated in all the MAC devices. */
+       if (priv->plat->pmt) {
+               pr_info(" Remote wake-up capable\n");
+               device_set_wakeup_capable(priv->device, 1);
+       }
+
+       priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
+       if (priv->rx_coe)
+               pr_info(" Checksum Offload Engine supported\n");
+       if (priv->plat->tx_coe)
+               pr_info(" Checksum insertion supported\n");
+
        /* Create and initialize the TX/RX descriptors chains. */
        priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
        priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
@@ -935,15 +991,6 @@ static int stmmac_open(struct net_device *dev)
        /* Initialize the MAC Core */
        priv->hw->mac->core_init(priv->ioaddr);
 
-       stmmac_get_synopsys_id(priv);
-
-       stmmac_get_hw_features(priv);
-
-       priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
-       if (priv->rx_coe)
-               pr_info("stmmac: Rx Checksum Offload Engine supported\n");
-       if (priv->plat->tx_coe)
-               pr_info("\tTX Checksum insertion supported\n");
        netdev_update_features(dev);
 
        /* Request the IRQ lines */
@@ -1489,9 +1536,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        if (!priv->phydev)
                return -EINVAL;
 
-       spin_lock(&priv->lock);
        ret = phy_mii_ioctl(priv->phydev, rq, cmd);
-       spin_unlock(&priv->lock);
 
        return ret;
 }
@@ -1558,7 +1603,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
        struct net_device *dev = seq->private;
        struct stmmac_priv *priv = netdev_priv(dev);
 
-       if (!stmmac_get_hw_features(priv)) {
+       if (!priv->hw_cap_support) {
                seq_printf(seq, "DMA HW features not supported\n");
                return 0;
        }
@@ -1766,12 +1811,6 @@ static int stmmac_mac_device_setup(struct net_device *dev)
        if (!device)
                return -ENOMEM;
 
-       if (priv->plat->enh_desc) {
-               device->desc = &enh_desc_ops;
-               pr_info("\tEnhanced descriptor structure\n");
-       } else
-               device->desc = &ndesc_ops;
-
        priv->hw = device;
        priv->hw->ring = &ring_mode_ops;
 
@@ -1845,11 +1884,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
 
        priv->ioaddr = addr;
 
-       /* PMT module is not integrated in all the MAC devices. */
-       if (plat_dat->pmt) {
-               pr_info("\tPMT module supported\n");
-               device_set_wakeup_capable(&pdev->dev, 1);
-       }
        /*
         * On some platforms e.g. SPEAr the wake up irq differs from the mac irq
         * The external wake up irq can be passed through the platform code
@@ -1862,7 +1896,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
        if (priv->wol_irq == -ENXIO)
                priv->wol_irq = ndev->irq;
 
-
        platform_set_drvdata(pdev, ndev);
 
        /* Set the I/O base addr */
@@ -1875,7 +1908,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
                        goto out_free_ndev;
        }
 
-       /* MAC HW revice detection */
+       /* MAC HW device detection */
        ret = stmmac_mac_device_setup(ndev);
        if (ret < 0)
                goto out_plat_exit;
@@ -1978,12 +2011,13 @@ static int stmmac_suspend(struct device *dev)
        if (!ndev || !netif_running(ndev))
                return 0;
 
+       if (priv->phydev)
+               phy_stop(priv->phydev);
+
        spin_lock(&priv->lock);
 
        netif_device_detach(ndev);
        netif_stop_queue(ndev);
-       if (priv->phydev)
-               phy_stop(priv->phydev);
 
 #ifdef CONFIG_STMMAC_TIMER
        priv->tm->timer_stop();
@@ -2041,12 +2075,13 @@ static int stmmac_resume(struct device *dev)
 #endif
        napi_enable(&priv->napi);
 
-       if (priv->phydev)
-               phy_start(priv->phydev);
-
        netif_start_queue(ndev);
 
        spin_unlock(&priv->lock);
+
+       if (priv->phydev)
+               phy_start(priv->phydev);
+
        return 0;
 }
 
index c517dac02ae1837343ff48465274f7b3e54caae3..cf14ab9db5768f7781f7b9983120c01644fad0aa 100644 (file)
@@ -2637,7 +2637,7 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i
        sbus_dp = op->dev.parent->of_node;
 
        /* We can match PCI devices too, do not accept those here. */
-       if (strcmp(sbus_dp->name, "sbus"))
+       if (strcmp(sbus_dp->name, "sbus") && strcmp(sbus_dp->name, "sbi"))
                return err;
 
        if (is_qfe) {
index caf3659e173cda3a04735cb1ecad7cfd94de27c7..2681b53820eefaf3edaa8e6e336b9b6de12d8bf0 100644 (file)
@@ -114,6 +114,7 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
                return;
        temac_iow(lp, XTE_LSW0_OFFSET, value);
        temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
+       temac_indirect_busywait(lp);
 }
 
 /**
@@ -203,6 +204,9 @@ static void temac_dma_bd_release(struct net_device *ndev)
        struct temac_local *lp = netdev_priv(ndev);
        int i;
 
+       /* Reset Local Link (DMA) */
+       lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
+
        for (i = 0; i < RX_BD_NUM; i++) {
                if (!lp->rx_skb[i])
                        break;
@@ -860,6 +864,8 @@ static int temac_open(struct net_device *ndev)
                phy_start(lp->phy_dev);
        }
 
+       temac_device_reset(ndev);
+
        rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
        if (rc)
                goto err_tx_irq;
@@ -867,7 +873,6 @@ static int temac_open(struct net_device *ndev)
        if (rc)
                goto err_rx_irq;
 
-       temac_device_reset(ndev);
        return 0;
 
  err_rx_irq:
index 7393eb732ee6737b31fa28c70f5baf1c4e1f3499..95eb34fdbba7b2ac1996303675bc9b0b262cbadf 100644 (file)
@@ -36,4 +36,4 @@ config ROADRUNNER_LARGE_RINGS
          kernel code or by user space programs. Say Y here only if you have
          the memory.
 
-endif /* HIPPI */
+endif # HIPPI
index e81e22e3d1d2fcf84be504403002b52d492a01d8..e6fed4d4cb77f70c8c6d62af16d53a57ed31c99c 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/usb/usbnet.h>
 #include <linux/slab.h>
 
-#define DRIVER_VERSION "26-Sep-2011"
+#define DRIVER_VERSION "08-Nov-2011"
 #define DRIVER_NAME "asix"
 
 /* ASIX AX8817X based USB 2.0 Ethernet Devices */
 #define MARVELL_CTRL_TXDELAY   0x0002
 #define MARVELL_CTRL_RXDELAY   0x0080
 
-#define        PHY_MODE_RTL8211CL      0x0004
+#define        PHY_MODE_RTL8211CL      0x000C
 
 /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
 struct asix_data {
@@ -652,9 +652,17 @@ static u32 asix_get_phyid(struct usbnet *dev)
 {
        int phy_reg;
        u32 phy_id;
+       int i;
 
-       phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
-       if (phy_reg < 0)
+       /* Poll for the rare case the FW or phy isn't ready yet.  */
+       for (i = 0; i < 100; i++) {
+               phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
+               if (phy_reg != 0 && phy_reg != 0xFFFF)
+                       break;
+               mdelay(1);
+       }
+
+       if (phy_reg <= 0 || phy_reg == 0xFFFF)
                return 0;
 
        phy_id = (phy_reg & 0xffff) << 16;
@@ -1075,7 +1083,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
 
 static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
 {
-       int ret;
+       int ret, embd_phy;
        struct asix_data *data = (struct asix_data *)&dev->data;
        u8 buf[ETH_ALEN];
        u32 phyid;
@@ -1100,16 +1108,36 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->mii.reg_num_mask = 0x1f;
        dev->mii.phy_id = asix_get_phy_addr(dev);
 
-       phyid = asix_get_phyid(dev);
-       dbg("PHYID=0x%08x", phyid);
-
        dev->net->netdev_ops = &ax88772_netdev_ops;
        dev->net->ethtool_ops = &ax88772_ethtool_ops;
 
-       ret = ax88772_reset(dev);
+       embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);
+
+       /* Reset the PHY to normal operation mode */
+       ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL);
+       if (ret < 0) {
+               dbg("Select PHY #1 failed: %d", ret);
+               return ret;
+       }
+
+       ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL);
+       if (ret < 0)
+               return ret;
+
+       msleep(150);
+
+       ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);
        if (ret < 0)
                return ret;
 
+       msleep(150);
+
+       ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE);
+
+       /* Read PHYID register *AFTER* the PHY was reset properly */
+       phyid = asix_get_phyid(dev);
+       dbg("PHYID=0x%08x", phyid);
+
        /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
        if (dev->driver_info->flags & FLAG_FRAMING_AX) {
                /* hard_mtu  is still the default - the device does not support
@@ -1220,6 +1248,7 @@ static int ax88178_reset(struct usbnet *dev)
        __le16 eeprom;
        u8 status;
        int gpio0 = 0;
+       u32 phyid;
 
        asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
        dbg("GPIO Status: 0x%04x", status);
@@ -1235,12 +1264,13 @@ static int ax88178_reset(struct usbnet *dev)
                data->ledmode = 0;
                gpio0 = 1;
        } else {
-               data->phymode = le16_to_cpu(eeprom) & 7;
+               data->phymode = le16_to_cpu(eeprom) & 0x7F;
                data->ledmode = le16_to_cpu(eeprom) >> 8;
                gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
        }
        dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
 
+       /* Power up external GigaPHY through AX88178 GPIO pin */
        asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
        if ((le16_to_cpu(eeprom) >> 8) != 1) {
                asix_write_gpio(dev, 0x003c, 30);
@@ -1252,6 +1282,13 @@ static int ax88178_reset(struct usbnet *dev)
                asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
        }
 
+       /* Read PHYID register *AFTER* powering up PHY */
+       phyid = asix_get_phyid(dev);
+       dbg("PHYID=0x%08x", phyid);
+
+       /* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */
+       asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL);
+
        asix_sw_reset(dev, 0);
        msleep(150);
 
@@ -1396,7 +1433,6 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
 {
        int ret;
        u8 buf[ETH_ALEN];
-       u32 phyid;
        struct asix_data *data = (struct asix_data *)&dev->data;
 
        data->eeprom_len = AX88772_EEPROM_LEN;
@@ -1423,12 +1459,12 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->netdev_ops = &ax88178_netdev_ops;
        dev->net->ethtool_ops = &ax88178_ethtool_ops;
 
-       phyid = asix_get_phyid(dev);
-       dbg("PHYID=0x%08x", phyid);
+       /* Blink LEDS so users know driver saw dongle */
+       asix_sw_reset(dev, 0);
+       msleep(150);
 
-       ret = ax88178_reset(dev);
-       if (ret < 0)
-               return ret;
+       asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
+       msleep(150);
 
        /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
        if (dev->driver_info->flags & FLAG_FRAMING_AX) {
index c924ea2bce07a4c06aa8d6ab5d9c23620b446915..99ed6eb4dfaf6b8b1153dbe9bfcb4e5917500986 100644 (file)
@@ -567,7 +567,7 @@ static const struct usb_device_id   products [] = {
 {
        USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
                        USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-       .driver_info = (unsigned long)&wwan_info,
+       .driver_info = 0,
 },
 
 /*
index d43db32f94781f64e57fc4285c7c398e9287e885..9c26c6390d69a72abffbf47dc91d9aea96ec1ba0 100644 (file)
@@ -144,10 +144,11 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
        }
 
        frame = (struct vl600_frame_hdr *) buf->data;
-       /* NOTE: Should check that frame->magic == 0x53544448?
-        * Otherwise if we receive garbage at the beginning of the frame
-        * we may end up allocating a huge buffer and saving all the
-        * future incoming data into it.  */
+       /* Yes, check that frame->magic == 0x53544448 (or 0x44544d48),
+        * otherwise we may run out of memory w/a bad packet */
+       if (ntohl(frame->magic) != 0x53544448 &&
+                       ntohl(frame->magic) != 0x44544d48)
+               goto error;
 
        if (buf->len < sizeof(*frame) ||
                        buf->len != le32_to_cpup(&frame->len)) {
@@ -296,6 +297,11 @@ encapsulate:
         * overwrite the remaining fields.
         */
        packet = (struct vl600_pkt_hdr *) skb->data;
+       /* The VL600 wants IPv6 packets to have an IPv4 ethertype
+        * Since this modem only supports IPv4 and IPv6, just set all
+        * frames to 0x0800 (ETH_P_IP)
+        */
+       packet->h_proto = htons(ETH_P_IP);
        memset(&packet->dummy, 0, sizeof(packet->dummy));
        packet->len = cpu_to_le32(orig_len);
 
@@ -308,21 +314,12 @@ encapsulate:
        if (skb->len < full_len) /* Pad */
                skb_put(skb, full_len - skb->len);
 
-       /* The VL600 wants IPv6 packets to have an IPv4 ethertype
-        * Check if this is an IPv6 packet, and set the ethertype
-        * to 0x800
-        */
-       if ((skb->data[sizeof(struct vl600_pkt_hdr *) + 0x22] & 0xf0) == 0x60) {
-               skb->data[sizeof(struct vl600_pkt_hdr *) + 0x20] = 0x08;
-               skb->data[sizeof(struct vl600_pkt_hdr *) + 0x21] = 0;
-       }
-
        return skb;
 }
 
 static const struct driver_info        vl600_info = {
        .description    = "LG VL600 modem",
-       .flags          = FLAG_ETHER | FLAG_RX_ASSEMBLE,
+       .flags          = FLAG_RX_ASSEMBLE | FLAG_WWAN,
        .bind           = vl600_bind,
        .unbind         = vl600_unbind,
        .status         = usbnet_cdc_status,
index 22a7cf951e728132b6f55d0d99584fc50e374eaa..a5b9b12ef268134fef1e978d8e19ce5468c16135 100644 (file)
@@ -51,6 +51,7 @@
 #define USB_VENDOR_ID_SMSC             (0x0424)
 #define USB_PRODUCT_ID_LAN7500         (0x7500)
 #define USB_PRODUCT_ID_LAN7505         (0x7505)
+#define RXW_PADDING                    2
 
 #define check_warn(ret, fmt, args...) \
        ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
@@ -1088,13 +1089,13 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 
                memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
                le32_to_cpus(&rx_cmd_b);
-               skb_pull(skb, 4 + NET_IP_ALIGN);
+               skb_pull(skb, 4 + RXW_PADDING);
 
                packet = skb->data;
 
                /* get the packet length */
-               size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN;
-               align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
+               size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING;
+               align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
 
                if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
                        netif_dbg(dev, rx_err, dev->net,
index 2f91acccb7dbc80499e7988b74ac62521bd06799..8873c6e6fb9627c02c41d4b1d36ffb340da3eacf 100644 (file)
@@ -1827,7 +1827,8 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
        }
 
        /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
-       REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
 }
 
 /*
index 85fa9cc73502c8f30b70a8d15da73dd28071fdcf..65ecb5bab25a2a0a0c1e64d5122397238ab1e0ca 100644 (file)
@@ -254,6 +254,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
        int r;
 
        sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+       if (!sband)
+               return;
 
        /*
         * If no country IE has been received always enable active scan
index 58ea0e5fabfd495b7c1ffaa6d56ee84d84bd0d17..5f77cbe0b6aaeb5d6e121ad5e37b70a3b8596d62 100644 (file)
@@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
        }
 }
 
+/* TODO: verify if needed for SSLPN or LCN  */
 static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
 {
        const struct b43_phy *phy = &dev->phy;
@@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
        unsigned int plcp_fragment_len;
        u32 mac_ctl = 0;
        u16 phy_ctl = 0;
+       bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP ||
+                             phy->type == B43_PHYTYPE_N ||
+                             phy->type == B43_PHYTYPE_HT);
        u8 extra_ft = 0;
        struct ieee80211_rate *txrate;
        struct ieee80211_tx_rate *rates;
@@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                        extra_ft |= B43_TXH_EFT_RTSFB_CCK;
 
                if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
-                   phy->type == B43_PHYTYPE_N) {
+                   fill_phy_ctl1) {
                        txhdr->phy_ctl1_rts = cpu_to_le16(
                                b43_generate_tx_phy_ctl1(dev, rts_rate));
                        txhdr->phy_ctl1_rts_fb = cpu_to_le16(
@@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                break;
        }
 
-       if (phy->type == B43_PHYTYPE_N) {
+       if (fill_phy_ctl1) {
                txhdr->phy_ctl1 =
                        cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
                txhdr->phy_ctl1_fb =
@@ -736,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
 
        /* Link quality statistics */
        switch (chanstat & B43_RX_CHAN_PHYTYPE) {
+       case B43_PHYTYPE_HT:
+               /* TODO: is max the right choice? */
+               status.signal = max_t(__s8,
+                       max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1),
+                       rxhdr->phy_ht_power2);
+               break;
        case B43_PHYTYPE_N:
+               /* Broadcom has code for min and avg, but always uses max */
                if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
                        status.signal = max(rxhdr->power1, rxhdr->power2);
                else
index 16c514d54afabb6be6f57c078e631e5a7d4c8647..98d90747836a482fa836f6e30c8fc173e1c935e5 100644 (file)
@@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 {
                } __packed;
        } __packed;
        union {
+               /* HT-PHY */
+               struct {
+                       PAD_BYTES(1);
+                       __s8 phy_ht_power0;
+               } __packed;
+
                /* RSSI for N-PHYs */
                struct {
                        __s8 power2;
@@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 {
 
                __le16 phy_status2;     /* PHY RX Status 2 */
        } __packed;
-       __le16 phy_status3;     /* PHY RX Status 3 */
+       union {
+               /* HT-PHY */
+               struct {
+                       __s8 phy_ht_power1;
+                       __s8 phy_ht_power2;
+               } __packed;
+
+               __le16 phy_status3;     /* PHY RX Status 3 */
+       } __packed;
        union {
                /* Tested with 598.314, 644.1001 and 666.2 */
                struct {
index b56a30297c269712840a8696f77d1d84daab358a..6ebec8f42846977439c07844cba9a6f7e429801c 100644 (file)
@@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t)
 
 static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
 {
-       uint dmactrlflags = di->dma.dmactrlflags;
+       uint dmactrlflags;
 
        if (di == NULL) {
-               DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+               DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
                return 0;
        }
 
+       dmactrlflags = di->dma.dmactrlflags;
        dmactrlflags &= ~mask;
        dmactrlflags |= flags;
 
index da3411057afca2d9debd63bbe1f2523c650f337d..ce918980e97799a51fc3b0b9a732d28fe706c84a 100644 (file)
@@ -990,29 +990,16 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
        return 0;
 }
 
-static void iwl_trans_pcie_disable_sync_irq(struct iwl_trans *trans)
+static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
 {
        unsigned long flags;
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
+       /* tell the device to stop sending interrupts */
        spin_lock_irqsave(&trans->shrd->lock, flags);
        iwl_disable_interrupts(trans);
        spin_unlock_irqrestore(&trans->shrd->lock, flags);
 
-       /* wait to make sure we flush pending tasklet*/
-       synchronize_irq(bus(trans)->irq);
-       tasklet_kill(&trans_pcie->irq_tasklet);
-}
-
-static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
-{
-       /* stop and reset the on-board processor */
-       iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
-
-       /* tell the device to stop sending interrupts */
-       iwl_trans_pcie_disable_sync_irq(trans);
-
        /* device going down, Stop using ICT table */
        iwl_disable_ict(trans);
 
@@ -1039,6 +1026,20 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
 
        /* Stop the device, and put it in low power state */
        iwl_apm_stop(priv(trans));
+
+       /* Upon stop, the APM issues an interrupt if HW RF kill is set.
+        * Clean again the interrupt here
+        */
+       spin_lock_irqsave(&trans->shrd->lock, flags);
+       iwl_disable_interrupts(trans);
+       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+
+       /* wait to make sure we flush pending tasklet*/
+       synchronize_irq(bus(trans)->irq);
+       tasklet_kill(&trans_pcie->irq_tasklet);
+
+       /* stop and reset the on-board processor */
+       iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 }
 
 static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
index 4fcd653bddc4a6fafee3da28188d76fe3c279173..a7f1ab28940d3ae6ad8e4fbda26b18087b4c21b4 100644 (file)
@@ -634,7 +634,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
                        if (channel &&
                            !(channel->flags & IEEE80211_CHAN_DISABLED))
                                cfg80211_inform_bss(wiphy, channel,
-                                       bssid, le64_to_cpu(*(__le64 *)tsfdesc),
+                                       bssid, get_unaligned_le64(tsfdesc),
                                        capa, intvl, ie, ielen,
                                        LBS_SCAN_RSSI_TO_MBM(rssi),
                                        GFP_KERNEL);
index 11b69b300dc0821e52980fef3d248a50377f026a..728baa445259c5ead043fa2540017c6d9ee19135 100644 (file)
@@ -995,6 +995,7 @@ static int if_spi_host_to_card(struct lbs_private *priv,
                spin_unlock_irqrestore(&card->buffer_lock, flags);
                break;
        default:
+               kfree(packet);
                netdev_err(priv->dev, "can't transfer buffer of type %d\n",
                           type);
                err = -EINVAL;
index dae8dbb24a03e83352742b20c3320c9819019889..8d3ab378662b77ac4c55c40bceba1b8a53715552 100644 (file)
@@ -819,8 +819,10 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                        wildcard_ssid_tlv->header.len = cpu_to_le16(
                                (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
                                                         max_ssid_length)));
-                       wildcard_ssid_tlv->max_ssid_length =
-                               user_scan_in->ssid_list[ssid_idx].max_len;
+
+                       /* max_ssid_length = 0 tells firmware to perform
+                          specific scan for the SSID filled */
+                       wildcard_ssid_tlv->max_ssid_length = 0;
 
                        memcpy(wildcard_ssid_tlv->ssid,
                               user_scan_in->ssid_list[ssid_idx].ssid,
@@ -1469,7 +1471,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
                               s32 rssi, const u8 *ie_buf, size_t ie_len,
                               u16 beacon_period, u16 cap_info_bitmap, u8 band)
 {
-       struct mwifiex_bssdescriptor *bss_desc = NULL;
+       struct mwifiex_bssdescriptor *bss_desc;
        int ret;
        unsigned long flags;
        u8 *beacon_ie;
@@ -1484,6 +1486,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
 
        beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);
        if (!beacon_ie) {
+               kfree(bss_desc);
                dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
                return -ENOMEM;
        }
index f1565792f2701c6285b202456c831341f6f5e181..377876315b8d4a9bcdcc91b228b14bed45bef943 100644 (file)
@@ -919,6 +919,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x050d, 0x935b) },
        /* Buffalo */
        { USB_DEVICE(0x0411, 0x00e8) },
+       { USB_DEVICE(0x0411, 0x0158) },
        { USB_DEVICE(0x0411, 0x016f) },
        { USB_DEVICE(0x0411, 0x01a2) },
        /* Corega */
index 2ec5c00235e612941fca457a20a9f16b1b8718b9..99ff12d0c29dfce934719f304cd66511fc30d514 100644 (file)
@@ -943,6 +943,7 @@ struct rt2x00_dev {
         * Powersaving work
         */
        struct delayed_work autowakeup_work;
+       struct work_struct sleep_work;
 
        /*
         * Data queue arrays for RX, TX, Beacon and ATIM.
index e1fb2a8569be292d0f26f5347b0bfa828737bd39..edd317fa7c0aafb06658d06616cc74a5e73c0bd0 100644 (file)
@@ -465,6 +465,23 @@ static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie)
        return NULL;
 }
 
+static void rt2x00lib_sleep(struct work_struct *work)
+{
+       struct rt2x00_dev *rt2x00dev =
+           container_of(work, struct rt2x00_dev, sleep_work);
+
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return;
+
+       /*
+        * Check again is powersaving is enabled, to prevent races from delayed
+        * work execution.
+        */
+       if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
+               rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
+                                IEEE80211_CONF_CHANGE_PS);
+}
+
 static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
                                      struct sk_buff *skb,
                                      struct rxdone_entry_desc *rxdesc)
@@ -512,8 +529,7 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
        cam |= (tim_ie->bitmap_ctrl & 0x01);
 
        if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
-               rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
-                                IEEE80211_CONF_CHANGE_PS);
+               queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work);
 }
 
 static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
@@ -1141,6 +1157,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 
        INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
        INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
+       INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
 
        /*
         * Let the driver probe the device to detect the capabilities.
@@ -1197,6 +1214,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
         */
        cancel_work_sync(&rt2x00dev->intf_work);
        cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
+       cancel_work_sync(&rt2x00dev->sleep_work);
        if (rt2x00_is_usb(rt2x00dev)) {
                del_timer_sync(&rt2x00dev->txstatus_timer);
                cancel_work_sync(&rt2x00dev->rxdone_work);
index 128ccb79318c86c7e0a8bc4a65c61389b58e959f..fc29c671cf3b34db3fc695fbd70209720a3c52e8 100644 (file)
@@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
                                                break;
                                        }
                                /* Fail if SSID isn't present in the filters */
-                               if (j == req->n_ssids) {
+                               if (j == cmd->n_ssids) {
                                        ret = -EINVAL;
                                        goto out_free;
                                }
index 6d3dd3988d0f2891e65514a2bac68b184409ac1d..19c0115092dd7a692c0d035063a3e83c111618a2 100644 (file)
@@ -60,27 +60,27 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
  */
 struct device_node *of_irq_find_parent(struct device_node *child)
 {
-       struct device_node *p, *c = child;
+       struct device_node *p;
        const __be32 *parp;
 
-       if (!of_node_get(c))
+       if (!of_node_get(child))
                return NULL;
 
        do {
-               parp = of_get_property(c, "interrupt-parent", NULL);
+               parp = of_get_property(child, "interrupt-parent", NULL);
                if (parp == NULL)
-                       p = of_get_parent(c);
+                       p = of_get_parent(child);
                else {
                        if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
                                p = of_node_get(of_irq_dflt_pic);
                        else
                                p = of_find_node_by_phandle(be32_to_cpup(parp));
                }
-               of_node_put(c);
-               c = p;
+               of_node_put(child);
+               child = p;
        } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
 
-       return (p == child) ? NULL : p;
+       return p;
 }
 
 /**
@@ -424,6 +424,8 @@ void __init of_irq_init(const struct of_device_id *matches)
 
                desc->dev = np;
                desc->interrupt_parent = of_irq_find_parent(np);
+               if (desc->interrupt_parent == np)
+                       desc->interrupt_parent = NULL;
                list_add_tail(&desc->list, &intc_desc_list);
        }
 
index b6f9749b4fa769638392610221b0751fba73eabb..f02b5235056d938ac2713c4534ff0bd3d89d7c8f 100644 (file)
@@ -76,6 +76,7 @@ config PCI_IOV
 
 config PCI_PRI
        bool "PCI PRI support"
+       depends on PCI
        select PCI_ATS
        help
          PRI is the PCI Page Request Interface. It allows PCI devices that are
index 596172b4ae955802a5778dd0c375b870b9a11909..fce1c54a0c8d8acf480c4b208ced89fb060ac95a 100644 (file)
@@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle)
 {
        acpi_status status;
        unsigned long long tmp;
+       struct acpi_pci_root *root;
        acpi_handle dummy_handle;
 
+       /*
+        * We shouldn't use this bridge if PCIe native hotplug control has been
+        * granted by the BIOS for it.
+        */
+       root = acpi_pci_find_root(handle);
+       if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
+               return -ENODEV;
+
        /* if the bridge doesn't have _STA, we assume it is always there */
        status = acpi_get_handle(handle, "_STA", &dummy_handle);
        if (ACPI_SUCCESS(status)) {
@@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
 static acpi_status
 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
+       struct acpi_pci_root *root;
        int *count = (int *)context;
 
-       if (acpi_is_root_bridge(handle)) {
-               acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-                               handle_hotplug_event_bridge, NULL);
-                       (*count)++;
-       }
+       if (!acpi_is_root_bridge(handle))
+               return AE_OK;
+
+       root = acpi_pci_find_root(handle);
+       if (!root)
+               return AE_OK;
+
+       if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
+               return AE_OK;
+
+       (*count)++;
+       acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+                                   handle_hotplug_event_bridge, NULL);
+
        return AE_OK ;
 }
 
index 1e9c9aacc3a6c82363b39602c5f6bab1b4bbd30d..085dbb5fc168be33de77d0ced5c411c807ffc2ef 100644 (file)
@@ -213,9 +213,6 @@ static int board_added(struct slot *p_slot)
                goto err_exit;
        }
 
-       /* Wait for 1 second after checking link training status */
-       msleep(1000);
-
        /* Check for a power fault */
        if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
                ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
index 96dc4734e4affcc6c7f763a9853342678df8a7c6..7b1414810ae3e0e0a5ccbcd9bec0f21051cf95db 100644 (file)
@@ -280,6 +280,14 @@ int pciehp_check_link_status(struct controller *ctrl)
         else
                 msleep(1000);
 
+       /*
+        * Need to wait for 1000 ms after Data Link Layer Link Active
+        * (DLLLA) bit reads 1b before sending configuration request.
+        * We need it before checking Link Training (LT) bit becuase
+        * LT is still set even after DLLLA bit is set on some platform.
+        */
+       msleep(1000);
+
        retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
        if (retval) {
                ctrl_err(ctrl, "Cannot read LNKSTATUS register\n");
@@ -294,6 +302,16 @@ int pciehp_check_link_status(struct controller *ctrl)
                return retval;
        }
 
+       /*
+        * If the port supports Link speeds greater than 5.0 GT/s, we
+        * must wait for 100 ms after Link training completes before
+        * sending configuration request.
+        */
+       if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT)
+               msleep(100);
+
+       pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
+
        return retval;
 }
 
@@ -484,7 +502,6 @@ int pciehp_power_on_slot(struct slot * slot)
        u16 slot_cmd;
        u16 cmd_mask;
        u16 slot_status;
-       u16 lnk_status;
        int retval = 0;
 
        /* Clear sticky power-fault bit from previous power failures */
@@ -516,14 +533,6 @@ int pciehp_power_on_slot(struct slot * slot)
        ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
                 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 
-       retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
-       if (retval) {
-               ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n",
-                               __func__);
-               return retval;
-       }
-       pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
-
        return retval;
 }
 
index aca972bbfb4c8ba04e7fc74efd74636ebe49ea65..dd7e0c51a33e5e5f79eb9f11b444fe4667d2ba2d 100644 (file)
@@ -278,8 +278,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int is_shpc_capable(struct pci_dev *dev)
 {
-       if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device ==
-                                               PCI_DEVICE_ID_AMD_GOLAM_7450))
+       if (dev->vendor == PCI_VENDOR_ID_AMD &&
+           dev->device == PCI_DEVICE_ID_AMD_GOLAM_7450)
                return 1;
        if (!pci_find_capability(dev, PCI_CAP_ID_SHPC))
                return 0;
index 36547f0ce305e987c7a414a47d6a4e5806b239cb..75ba2311b54f3f37b62176a37e032c480be9f3f1 100644 (file)
@@ -944,8 +944,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
        ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
        ctrl_dbg(ctrl, "Hotplug Controller:\n");
 
-       if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
-                               PCI_DEVICE_ID_AMD_GOLAM_7450)) {
+       if (pdev->vendor == PCI_VENDOR_ID_AMD &&
+           pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) {
                /* amd shpc driver doesn't use Base Offset; assume 0 */
                ctrl->mmio_base = pci_resource_start(pdev, 0);
                ctrl->mmio_size = pci_resource_len(pdev, 0);
index a43cfd906c6d678759d241a3fae9363889e1c15d..d93e962f26100c7e0498f80f7dac437c6f0e87f5 100644 (file)
@@ -589,14 +589,14 @@ static const struct backlight_ops dell_ops = {
        .update_status  = dell_send_intensity,
 };
 
-static void touchpad_led_on()
+static void touchpad_led_on(void)
 {
        int command = 0x97;
        char data = 1;
        i8042_command(&data, command | 1 << 12);
 }
 
-static void touchpad_led_off()
+static void touchpad_led_off(void)
 {
        int command = 0x97;
        char data = 2;
index 5abeb3ac3e8da43df3d58bf677c3ac0e3d17116e..298c6c6a279574561eb24f329b115fe134d274a1 100644 (file)
@@ -160,7 +160,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id)
                        break;
        }
 
-       if (!ri)
+       if (i == ARRAY_SIZE(aat2870_regulators))
                return NULL;
 
        ri->enable_addr = AAT2870_LDO_EN;
index 669d0216022195e36bcb8f59b25cf14de1dff6c9..938398f3e869c57814fc130b9133ac435118214e 100644 (file)
@@ -2799,8 +2799,8 @@ void regulator_unregister(struct regulator_dev *rdev)
        list_del(&rdev->list);
        if (rdev->supply)
                regulator_put(rdev->supply);
-       device_unregister(&rdev->dev);
        kfree(rdev->constraints);
+       device_unregister(&rdev->dev);
        mutex_unlock(&regulator_list_mutex);
 }
 EXPORT_SYMBOL_GPL(regulator_unregister);
index 66d2d60b436a3e7a28092d64a499fd203db764a5..b552aae55b417c7cd9aa97fba33bd61ad0b7e787 100644 (file)
@@ -664,10 +664,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
 
        switch (id) {
        case TPS65910_REG_VDD1:
-               dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+               dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
                if (dcdc_mult == 1)
                        dcdc_mult--;
-               vsel = (selector % VDD1_2_NUM_VOLTS) + 3;
+               vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
 
                tps65910_modify_bits(pmic, TPS65910_VDD1,
                                (dcdc_mult << VDD1_VGAIN_SEL_SHIFT),
@@ -675,10 +675,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
                tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel);
                break;
        case TPS65910_REG_VDD2:
-               dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+               dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
                if (dcdc_mult == 1)
                        dcdc_mult--;
-               vsel = (selector % VDD1_2_NUM_VOLTS) + 3;
+               vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
 
                tps65910_modify_bits(pmic, TPS65910_VDD2,
                                (dcdc_mult << VDD2_VGAIN_SEL_SHIFT),
@@ -756,9 +756,9 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
        switch (id) {
        case TPS65910_REG_VDD1:
        case TPS65910_REG_VDD2:
-               mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+               mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
                volt = VDD1_2_MIN_VOLT +
-                               (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET;
+                               (selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
                break;
        case TPS65911_REG_VDDCTRL:
                volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
@@ -947,6 +947,8 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
 
                if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
                        pmic->desc[i].ops = &tps65910_ops_dcdc;
+                       pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE *
+                                                       VDD1_2_NUM_VOLT_COARSE;
                } else if (i == TPS65910_REG_VDD3) {
                        if (tps65910_chip_id(tps65910) == TPS65910)
                                pmic->desc[i].ops = &tps65910_ops_vdd3;
index ee8747f4fa08b187ef2f79dbb51e3f69a770bc21..11cc308d66e925db83fa8c50697e734608aac1b8 100644 (file)
@@ -71,6 +71,7 @@ struct twlreg_info {
 #define VREG_TYPE              1
 #define VREG_REMAP             2
 #define VREG_DEDICATED         3       /* LDO control */
+#define VREG_VOLTAGE_SMPS_4030 9
 /* TWL6030 register offsets */
 #define VREG_TRANS             1
 #define VREG_STATE             2
@@ -514,6 +515,32 @@ static struct regulator_ops twl4030ldo_ops = {
        .get_status     = twl4030reg_get_status,
 };
 
+static int
+twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
+                       unsigned *selector)
+{
+       struct twlreg_info *info = rdev_get_drvdata(rdev);
+       int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
+
+       twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030,
+               vsel);
+       return 0;
+}
+
+static int twl4030smps_get_voltage(struct regulator_dev *rdev)
+{
+       struct twlreg_info *info = rdev_get_drvdata(rdev);
+       int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
+               VREG_VOLTAGE_SMPS_4030);
+
+       return vsel * 12500 + 600000;
+}
+
+static struct regulator_ops twl4030smps_ops = {
+       .set_voltage    = twl4030smps_set_voltage,
+       .get_voltage    = twl4030smps_get_voltage,
+};
+
 static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
@@ -856,6 +883,21 @@ static struct regulator_ops twlsmps_ops = {
                }, \
        }
 
+#define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \
+       { \
+       .base = offset, \
+       .id = num, \
+       .delay = turnon_delay, \
+       .remap = remap_conf, \
+       .desc = { \
+               .name = #label, \
+               .id = TWL4030_REG_##label, \
+               .ops = &twl4030smps_ops, \
+               .type = REGULATOR_VOLTAGE, \
+               .owner = THIS_MODULE, \
+               }, \
+       }
+
 #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
        .base = offset, \
        .min_mV = min_mVolts, \
@@ -947,8 +989,8 @@ static struct twlreg_info twl_regs[] = {
        TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08),
        TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08),
        TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08),
-       TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08),
-       TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08),
+       TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08),
+       TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08),
        TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08),
        TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08),
        TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08),
index b3eba3cddd42658f76cb7ec84a3c13187993d1b4..e4b6880aabd05492b2a08c0511f400340b9fc0fa 100644 (file)
@@ -220,7 +220,7 @@ static void puv3_rtc_enable(struct platform_device *pdev, int en)
        }
 }
 
-static int puv3_rtc_remove(struct platform_device *dev)
+static int __devexit puv3_rtc_remove(struct platform_device *dev)
 {
        struct rtc_device *rtc = platform_get_drvdata(dev);
 
@@ -236,7 +236,7 @@ static int puv3_rtc_remove(struct platform_device *dev)
        return 0;
 }
 
-static int puv3_rtc_probe(struct platform_device *pdev)
+static int __devinit puv3_rtc_probe(struct platform_device *pdev)
 {
        struct rtc_device *rtc;
        struct resource *res;
index 43068fbd0baacfe8beb7d353cda35a8c06c371e2..1b6d9247fdc78a4237d5e7048347a0a66875d140 100644 (file)
@@ -641,6 +641,8 @@ static int __init zcore_init(void)
 
        if (ipl_info.type != IPL_TYPE_FCP_DUMP)
                return -ENODATA;
+       if (OLDMEM_BASE)
+               return -ENODATA;
 
        zcore_dbf = debug_register("zcore", 4, 1, 4 * sizeof(long));
        debug_register_view(zcore_dbf, &debug_sprintf_view);
index b77ae519d79c4eea8c6d87a1e08609dc70ae0276..ec94f049e99543849ed56c90c665102c40c5b87e 100644 (file)
@@ -1271,18 +1271,16 @@ ap_config_timeout(unsigned long ptr)
 }
 
 /**
- * ap_schedule_poll_timer(): Schedule poll timer.
+ * __ap_schedule_poll_timer(): Schedule poll timer.
  *
  * Set up the timer to run the poll tasklet
  */
-static inline void ap_schedule_poll_timer(void)
+static inline void __ap_schedule_poll_timer(void)
 {
        ktime_t hr_time;
 
        spin_lock_bh(&ap_poll_timer_lock);
-       if (ap_using_interrupts() || ap_suspend_flag)
-               goto out;
-       if (hrtimer_is_queued(&ap_poll_timer))
+       if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag)
                goto out;
        if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
                hr_time = ktime_set(0, poll_timeout);
@@ -1293,6 +1291,18 @@ out:
        spin_unlock_bh(&ap_poll_timer_lock);
 }
 
+/**
+ * ap_schedule_poll_timer(): Schedule poll timer.
+ *
+ * Set up the timer to run the poll tasklet
+ */
+static inline void ap_schedule_poll_timer(void)
+{
+       if (ap_using_interrupts())
+               return;
+       __ap_schedule_poll_timer();
+}
+
 /**
  * ap_poll_read(): Receive pending reply messages from an AP device.
  * @ap_dev: pointer to the AP device
@@ -1374,8 +1384,9 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
                        *flags |= 1;
                *flags |= 2;
                break;
-       case AP_RESPONSE_Q_FULL:
        case AP_RESPONSE_RESET_IN_PROGRESS:
+               __ap_schedule_poll_timer();
+       case AP_RESPONSE_Q_FULL:
                *flags |= 2;
                break;
        case AP_RESPONSE_MESSAGE_TOO_BIG:
index fa80ba1f0344318a30697cf09af4a44cb135f857..9b66d2d1809b30647c2db82c88ba62306f2061b3 100644 (file)
@@ -4,7 +4,7 @@ menu "S/390 network device drivers"
 config LCS
        def_tristate m
        prompt "Lan Channel Station Interface"
-       depends on CCW && NETDEVICES && (NET_ETHERNET || TR || FDDI)
+       depends on CCW && NETDEVICES && (ETHERNET || TR || FDDI)
        help
           Select this option if you want to use LCS networking on IBM System z.
           This device driver supports Token Ring (IEEE 802.5),
index c28713da1ec5d380f9e904bab6f2946016cb76ec..863fc2197155c36c0f956cd9d3bb7781d8b46778 100644 (file)
@@ -50,7 +50,7 @@
 #include "lcs.h"
 
 
-#if !defined(CONFIG_NET_ETHERNET) && \
+#if !defined(CONFIG_ETHERNET) && \
     !defined(CONFIG_TR) && !defined(CONFIG_FDDI)
 #error Cannot compile lcs.c without some net devices switched on.
 #endif
@@ -1634,7 +1634,7 @@ lcs_startlan_auto(struct lcs_card *card)
        int rc;
 
        LCS_DBF_TEXT(2, trace, "strtauto");
-#ifdef CONFIG_NET_ETHERNET
+#ifdef CONFIG_ETHERNET
        card->lan_type = LCS_FRAME_TYPE_ENET;
        rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
        if (rc == 0)
@@ -2166,7 +2166,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
                goto netdev_out;
        }
        switch (card->lan_type) {
-#ifdef CONFIG_NET_ETHERNET
+#ifdef CONFIG_ETHERNET
        case LCS_FRAME_TYPE_ENET:
                card->lan_type_trans = eth_type_trans;
                dev = alloc_etherdev(0);
index 3251333a23df18b6e8f378f0f681ac818145f0e1..b6a6356d09b3a52857a1f47f14d1a2241b04e142 100644 (file)
@@ -1994,6 +1994,8 @@ static struct net_device *netiucv_init_netdevice(char *username)
                           netiucv_setup_netdevice);
        if (!dev)
                return NULL;
+       if (dev_alloc_name(dev, dev->name) < 0)
+               goto out_netdev;
 
        privptr = netdev_priv(dev);
        privptr->fsm = init_fsm("netiucvdev", dev_state_names,
index b77c65ed13812f9d7e5462c0bcb5bcb9c1fa33f1..4abc79d3963f86ee2dc7dfd14c1fb240bf2eb540 100644 (file)
@@ -236,8 +236,7 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
 #define QETH_IN_BUF_COUNT_MAX 128
 #define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)
 #define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \
-               ((card)->ssqd.qdioac1 & AC1_SIGA_INPUT_NEEDED ? 1 : \
-                ((card)->qdio.in_buf_pool.buf_count / 2))
+                ((card)->qdio.in_buf_pool.buf_count / 2)
 
 /* buffers we have to be behind before we get a PCI */
 #define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1)
index 81534437373a3c1209c914db4fb2a32d45860e44..fff57de78943c6d55cda3ece38a22f69bcda76b1 100644 (file)
@@ -881,7 +881,6 @@ EXPORT_SYMBOL_GPL(qeth_do_run_thread);
 void qeth_schedule_recovery(struct qeth_card *card)
 {
        QETH_CARD_TEXT(card, 2, "startrec");
-       WARN_ON(1);
        if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
                schedule_work(&card->kernel_thread_starter);
 }
index e4c1176ee25b2fd9942cfad447826611bbc7037f..4d5307ddbe55b03ce78b89e423369927c171c2c1 100644 (file)
@@ -2756,11 +2756,13 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
        struct neighbour *n = NULL;
        struct dst_entry *dst;
 
+       rcu_read_lock();
        dst = skb_dst(skb);
        if (dst)
                n = dst_get_neighbour(dst);
        if (n) {
                cast_type = n->type;
+               rcu_read_unlock();
                if ((cast_type == RTN_BROADCAST) ||
                    (cast_type == RTN_MULTICAST) ||
                    (cast_type == RTN_ANYCAST))
@@ -2768,6 +2770,8 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
                else
                        return RTN_UNSPEC;
        }
+       rcu_read_unlock();
+
        /* try something else */
        if (skb->protocol == ETH_P_IPV6)
                return (skb_network_header(skb)[24] == 0xff) ?
@@ -2847,6 +2851,8 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
        }
 
        hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr);
+
+       rcu_read_lock();
        dst = skb_dst(skb);
        if (dst)
                n = dst_get_neighbour(dst);
@@ -2893,6 +2899,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
                                QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;
                }
        }
+       rcu_read_unlock();
 }
 
 static inline void qeth_l3_hdr_csum(struct qeth_card *card,
index 0ea2fbfe0e993a42932221d52f0040aaf52b96db..d979bb26522ff8348df72caa8d2c5871deb7f5b4 100644 (file)
@@ -335,10 +335,10 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
                                        QETH_IN_BUF_COUNT_MAX)
                                qeth_realloc_buffer_pool(card,
                                        QETH_IN_BUF_COUNT_MAX);
-                       break;
                } else
                        rc = -EPERM;
-       default:   /* fall through */
+               break;
+       default:
                rc = -EINVAL;
        }
 out:
index 4aa76d6f11dfed870db05bb098f13cf4aa3d361a..705e13e470af18850ae4375533ae4f85495b592c 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
@@ -1109,6 +1110,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
                unique_id++;
        }
 
+       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+                              PCIE_LINK_STATE_CLKPM);
+
        error = pci_enable_device(pdev);
        if (error)
                goto out;
index e76107b2ade3a2b7a2666daab0c7a0b683e53d74..865d452542be923ef7c02bc0f4eea816dfc898b3 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -3922,6 +3923,10 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h)
                dev_warn(&h->pdev->dev, "controller appears to be disabled\n");
                return -ENODEV;
        }
+
+       pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
+                              PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
+
        err = pci_enable_device(h->pdev);
        if (err) {
                dev_warn(&h->pdev->dev, "unable to enable PCI device\n");
index 8889b1babcacaebdc97d8333d5bdaebf2dd93b88..4e041f6d808cd6e49666b35c8d8aec0f1b0a76c5 100644 (file)
@@ -2802,6 +2802,11 @@ _scsih_error_recovery_delete_devices(struct MPT2SAS_ADAPTER *ioc)
 
        if (ioc->is_driver_loading)
                return;
+
+       fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+       if (!fw_event)
+               return;
+
        fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES;
        fw_event->ioc = ioc;
        _scsih_fw_event_add(ioc, fw_event);
index 06bc26554a67359a8656ef976b6d483e71bfd0fb..f85cfa6c47b5212982bcbfcd9065936c27360f3d 100644 (file)
@@ -1409,6 +1409,8 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
 
        blk_start_request(req);
 
+       scmd_printk(KERN_INFO, cmd, "killing request\n");
+
        sdev = cmd->device;
        starget = scsi_target(sdev);
        shost = sdev->host;
@@ -1490,7 +1492,6 @@ static void scsi_request_fn(struct request_queue *q)
        struct request *req;
 
        if (!sdev) {
-               printk("scsi: killing requests for dead queue\n");
                while ((req = blk_peek_request(q)) != NULL)
                        scsi_kill_request(req, q);
                return;
index 72273a0e56662569931f812b6f628a3e3a4748c8..b3c6d957fbd8aa587dcd039547eaa82bd67b6476 100644 (file)
@@ -319,11 +319,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
        return sdev;
 
 out_device_destroy:
-       scsi_device_set_state(sdev, SDEV_DEL);
-       transport_destroy_device(&sdev->sdev_gendev);
-       put_device(&sdev->sdev_dev);
-       scsi_free_queue(sdev->request_queue);
-       put_device(&sdev->sdev_gendev);
+       __scsi_remove_device(sdev);
 out:
        if (display_failure_msg)
                printk(ALLOC_FAILURE_MSG, __func__);
index e763254741c296169b6d662d5f398c1a90170cc2..21c70b2b83119e333ebe4c5b5e18ab70f2ce6a0a 100644 (file)
@@ -426,7 +426,7 @@ static int __devinit nuc900_spi_probe(struct platform_device *pdev)
                goto err_clk;
        }
 
-       mfp_set_groupg(&pdev->dev);
+       mfp_set_groupg(&pdev->dev, NULL);
        nuc900_init_spi(hw);
 
        err = spi_bitbang_start(&hw->bitbang);
index f103e470cb6362e248a264576e457e03f0ab5409..5559b229919870fad59680b722e1390585ba61ca 100644 (file)
@@ -2184,6 +2184,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
                goto  err_clk_prep;
        }
 
+       status = clk_enable(pl022->clk);
+       if (status) {
+               dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
+               goto err_no_clk_en;
+       }
+
        /* Disable SSP */
        writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
               SSP_CR1(pl022->virtbase));
@@ -2237,6 +2243,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
 
        free_irq(adev->irq[0], pl022);
  err_no_irq:
+       clk_disable(pl022->clk);
+ err_no_clk_en:
        clk_unprepare(pl022->clk);
  err_clk_prep:
        clk_put(pl022->clk);
index 9e1864c6dfd08caf355f1e0c3aa347d6b0386beb..8190f2aaf53bb88aaea8df5c025d6f83c2ee68d1 100644 (file)
@@ -1,6 +1,7 @@
 config ET131X
        tristate "Agere ET-1310 Gigabit Ethernet support"
-       depends on PCI
+       depends on PCI && NET && NETDEVICES
+       select PHYLIB
        default n
        ---help---
          This driver supports Agere ET-1310 ethernet adapters.
index f5f44a02456fd5aa20ae06b9b524dee1b1c01757..0c1c6ca8c3794de60d440f3dc33bb60f8ebb2e83 100644 (file)
@@ -4469,6 +4469,12 @@ static int et131x_resume(struct device *dev)
        return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume);
+#define ET131X_PM_OPS (&et131x_pm_ops)
+#else
+#define ET131X_PM_OPS NULL
+#endif
+
 /* ISR functions */
 
 /**
@@ -5470,12 +5476,6 @@ err_out:
        return result;
 }
 
-static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume);
-#define ET131X_PM_OPS (&et131x_pm_ops)
-#else
-#define ET131X_PM_OPS NULL
-#endif
-
 static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = {
        { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL},
        { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL},
index 326e967d54ef035258e7d4c325c4d6c26d731edc..aec9311b108c7c73b2b599c42976cbe99e1ca8b2 100644 (file)
@@ -242,19 +242,26 @@ static const struct file_operations iio_event_chrdev_fileops = {
 
 static int iio_event_getfd(struct iio_dev *indio_dev)
 {
-       if (indio_dev->event_interface == NULL)
+       struct iio_event_interface *ev_int = indio_dev->event_interface;
+       int fd;
+
+       if (ev_int == NULL)
                return -ENODEV;
 
-       mutex_lock(&indio_dev->event_interface->event_list_lock);
-       if (test_and_set_bit(IIO_BUSY_BIT_POS,
-                            &indio_dev->event_interface->flags)) {
-               mutex_unlock(&indio_dev->event_interface->event_list_lock);
+       mutex_lock(&ev_int->event_list_lock);
+       if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
+               mutex_unlock(&ev_int->event_list_lock);
                return -EBUSY;
        }
-       mutex_unlock(&indio_dev->event_interface->event_list_lock);
-       return anon_inode_getfd("iio:event",
-                               &iio_event_chrdev_fileops,
-                               indio_dev->event_interface, O_RDONLY);
+       mutex_unlock(&ev_int->event_list_lock);
+       fd = anon_inode_getfd("iio:event",
+                               &iio_event_chrdev_fileops, ev_int, O_RDONLY);
+       if (fd < 0) {
+               mutex_lock(&ev_int->event_list_lock);
+               clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
+               mutex_unlock(&ev_int->event_list_lock);
+       }
+       return fd;
 }
 
 static int __init iio_init(void)
index d335c7d6fa0f849ac22dbdbe526948dafb5e872b..828526d4c28985221e6b6ebba019053e1a137d21 100644 (file)
@@ -32,8 +32,8 @@
 #include "as102_fw.h"
 #include "dvbdev.h"
 
-int debug;
-module_param_named(debug, debug, int, 0644);
+int as102_debug;
+module_param_named(debug, as102_debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)");
 
 int dual_tuner;
index bcda635b5a9967454f95c843ccf4ae4c42a22d15..fd33f5a12dcc2167cf9dada508b13521f7159b8f 100644 (file)
@@ -37,7 +37,8 @@ extern struct spi_driver as102_spi_driver;
 #define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"
 #define DRIVER_NAME "as10x_usb"
 
-extern int debug;
+extern int as102_debug;
+#define debug  as102_debug
 
 #define dprintk(debug, args...) \
        do { if (debug) {       \
index b445cd63f901dc4299d55eef54c6675151d8387a..2542c37439049e8e878f29600b8d08c7f6635cd3 100644 (file)
@@ -275,7 +275,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
                CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i;
-                       hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page) + fs->page_offset));
+                       hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page.p) + fs->page_offset));
                        hw_buffer.s.size = fs->size;
                        CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;
                }
index 5cde96b2e6e17d10c71f03a1e8e13fcb78179e6a..5c2a15b42dfede39997352cc7289871bd4dfd161 100644 (file)
@@ -1,6 +1,6 @@
 config SLICOSS
        tristate "Alacritech Gigabit IS-NIC support"
-       depends on PCI && X86
+       depends on PCI && X86 && NET
        default n
        help
          This driver supports Alacritech's IS-NIC gigabit ethernet cards.
index 435f6facbc238606feeea4ce26b508ed34ddb6af..44fbebab5075f98f337d880288993b01ad9e7271 100644 (file)
@@ -46,6 +46,7 @@ static inline char __dcc_getchar(void)
 
        asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg"
                : "=r" (__c));
+       isb();
 
        return __c;
 }
@@ -55,6 +56,7 @@ static inline void __dcc_putchar(char c)
        asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char"
                : /* no output register */
                : "r" (c));
+       isb();
 }
 
 static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
index 5f479dada6f2b25a309b48c50d5b2dee0a35777d..925a1e547a834f10942ab878357a0568254b6ae8 100644 (file)
@@ -1560,7 +1560,7 @@ config SERIAL_IFX6X60
          Support for the IFX6x60 modem devices on Intel MID platforms.
 
 config SERIAL_PCH_UART
-       tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART"
+       tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) UART"
        depends on PCI
        select SERIAL_CORE
        help
@@ -1568,12 +1568,12 @@ config SERIAL_PCH_UART
          which is an IOH(Input/Output Hub) for x86 embedded processor.
          Enabling PCH_DMA, this PCH UART works as DMA mode.
 
-         This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
-         Output Hub), ML7213 and ML7223.
-         ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
-         for MP(Media Phone) use.
-         ML7213/ML7223 is companion chip for Intel Atom E6xx series.
-         ML7213/ML7223 is completely compatible for Intel EG20T PCH.
+         This driver also can be used for LAPIS Semiconductor IOH(Input/
+         Output Hub), ML7213, ML7223 and ML7831.
+         ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is
+         for MP(Media Phone) use and ML7831 IOH is for general purpose use.
+         ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
+         ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
 
 config SERIAL_MSM_SMD
        bool "Enable tty device interface for some SMD ports"
index 4a0f86fa1e90566c03c693c413a581a80e40e7b6..4c823f341d9895cd88a5f0d710f56449714fef86 100644 (file)
@@ -228,7 +228,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
        if (rs485conf->flags & SER_RS485_ENABLED) {
                dev_dbg(port->dev, "Setting UART to RS485\n");
                atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
-               if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
+               if ((rs485conf->delay_rts_after_send) > 0)
                        UART_PUT_TTGR(port, rs485conf->delay_rts_after_send);
                mode |= ATMEL_US_USMODE_RS485;
        } else {
@@ -304,7 +304,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
 
        if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
                dev_dbg(port->dev, "Setting UART to RS485\n");
-               if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+               if ((atmel_port->rs485.delay_rts_after_send) > 0)
                        UART_PUT_TTGR(port,
                                        atmel_port->rs485.delay_rts_after_send);
                mode |= ATMEL_US_USMODE_RS485;
@@ -1228,7 +1228,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
 
        if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
                dev_dbg(port->dev, "Setting UART to RS485\n");
-               if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+               if ((atmel_port->rs485.delay_rts_after_send) > 0)
                        UART_PUT_TTGR(port,
                                        atmel_port->rs485.delay_rts_after_send);
                mode |= ATMEL_US_USMODE_RS485;
@@ -1447,16 +1447,6 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
                rs485conf->delay_rts_after_send = rs485_delay[1];
                rs485conf->flags = 0;
 
-               if (rs485conf->delay_rts_before_send == 0 &&
-                   rs485conf->delay_rts_after_send == 0) {
-                       rs485conf->flags |= SER_RS485_RTS_ON_SEND;
-               } else {
-                       if (rs485conf->delay_rts_before_send)
-                               rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND;
-                       if (rs485conf->delay_rts_after_send)
-                               rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
-               }
-
                if (of_get_property(np, "rs485-rx-during-tx", NULL))
                        rs485conf->flags |= SER_RS485_RX_DURING_TX;
 
index b7435043f2fe90d87d646141060318851ad12a86..1dfba7b779c84ed1f151b490295b0a99751b7b72 100644 (file)
@@ -3234,9 +3234,8 @@ rs_write(struct tty_struct *tty,
                e100_disable_rx(info);
                e100_enable_rx_irq(info);
 #endif
-               if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) &&
-                       (info->rs485.delay_rts_before_send > 0))
-                               msleep(info->rs485.delay_rts_before_send);
+               if (info->rs485.delay_rts_before_send > 0)
+                       msleep(info->rs485.delay_rts_before_send);
        }
 #endif /* CONFIG_ETRAX_RS485 */
 
@@ -3693,10 +3692,6 @@ rs_ioctl(struct tty_struct *tty,
 
                rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send;
                rs485data.flags = 0;
-               if (rs485data.delay_rts_before_send != 0)
-                       rs485data.flags |= SER_RS485_RTS_BEFORE_SEND;
-               else
-                       rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND);
 
                if (rs485ctrl.enabled)
                        rs485data.flags |= SER_RS485_ENABLED;
@@ -4531,7 +4526,6 @@ static int __init rs_init(void)
                /* Set sane defaults */
                info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND);
                info->rs485.flags |= SER_RS485_RTS_AFTER_SEND;
-               info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND);
                info->rs485.delay_rts_before_send = 0;
                info->rs485.flags &= ~(SER_RS485_ENABLED);
 #endif
index 286c386d9c4677d16cf0effcf9769f34c9249e52..e272d3919c67fdb6b465902fe7a5cb17978cc3a5 100644 (file)
@@ -884,7 +884,6 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
 {
        struct uart_hsu_port *up =
                        container_of(port, struct uart_hsu_port, port);
-       struct tty_struct *tty = port->state->port.tty;
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
@@ -907,8 +906,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
        }
 
        /* CMSPAR isn't supported by this driver */
-       if (tty)
-               tty->termios->c_cflag &= ~CMSPAR;
+       termios->c_cflag &= ~CMSPAR;
 
        if (termios->c_cflag & CSTOPB)
                cval |= UART_LCR_STOP;
index 21febef926aa7c31f09ef26dbbbfa34d78f76df1..d6aba8c087e4784370648976c0d018a569c374f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ *Copyright (C) 2011 LAPIS Semiconductor 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
@@ -46,8 +46,8 @@ enum {
 
 /* Set the max number of UART port
  * Intel EG20T PCH: 4 port
- * OKI SEMICONDUCTOR ML7213 IOH: 3 port
- * OKI SEMICONDUCTOR ML7223 IOH: 2 port
+ * LAPIS Semiconductor ML7213 IOH: 3 port
+ * LAPIS Semiconductor ML7223 IOH: 2 port
 */
 #define PCH_UART_NR    4
 
@@ -258,6 +258,8 @@ enum pch_uart_num_t {
        pch_ml7213_uart2,
        pch_ml7223_uart0,
        pch_ml7223_uart1,
+       pch_ml7831_uart0,
+       pch_ml7831_uart1,
 };
 
 static struct pch_uart_driver_data drv_dat[] = {
@@ -270,6 +272,8 @@ static struct pch_uart_driver_data drv_dat[] = {
        [pch_ml7213_uart2] = {PCH_UART_2LINE, 2},
        [pch_ml7223_uart0] = {PCH_UART_8LINE, 0},
        [pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
+       [pch_ml7831_uart0] = {PCH_UART_8LINE, 0},
+       [pch_ml7831_uart1] = {PCH_UART_2LINE, 1},
 };
 
 static unsigned int default_baud = 9600;
@@ -628,6 +632,7 @@ static void pch_request_dma(struct uart_port *port)
                dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n",
                        __func__);
                dma_release_channel(priv->chan_tx);
+               priv->chan_tx = NULL;
                return;
        }
 
@@ -1215,8 +1220,7 @@ static void pch_uart_shutdown(struct uart_port *port)
                dev_err(priv->port.dev,
                        "pch_uart_hal_set_fifo Failed(ret=%d)\n", ret);
 
-       if (priv->use_dma_flag)
-               pch_free_dma(port);
+       pch_free_dma(port);
 
        free_irq(priv->port.irq, priv);
 }
@@ -1280,6 +1284,7 @@ static void pch_uart_set_termios(struct uart_port *port,
        if (rtn)
                goto out;
 
+       pch_uart_set_mctrl(&priv->port, priv->port.mctrl);
        /* Don't rewrite B0 */
        if (tty_termios_baud_rate(termios))
                tty_termios_encode_baud_rate(termios, baud, baud);
@@ -1552,6 +1557,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = {
         .driver_data = pch_ml7223_uart0},
        {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),
         .driver_data = pch_ml7223_uart1},
+       {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811),
+        .driver_data = pch_ml7831_uart0},
+       {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812),
+        .driver_data = pch_ml7831_uart1},
        {0,},
 };
 
index 512c49f98e85a2c59e70b2c454877589756376a2..8e0924f55446f963b8b9d79a0d66347d30c982bc 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <linux/kmod.h>
 #include <linux/nsproxy.h>
+#include <linux/ratelimit.h>
 
 /*
  *     This guards the refcounted line discipline lists. The lock
@@ -547,15 +548,16 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
 /**
  *     tty_ldisc_wait_idle     -       wait for the ldisc to become idle
  *     @tty: tty to wait for
+ *     @timeout: for how long to wait at most
  *
  *     Wait for the line discipline to become idle. The discipline must
  *     have been halted for this to guarantee it remains idle.
  */
-static int tty_ldisc_wait_idle(struct tty_struct *tty)
+static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
 {
-       int ret;
+       long ret;
        ret = wait_event_timeout(tty_ldisc_idle,
-                       atomic_read(&tty->ldisc->users) == 1, 5 * HZ);
+                       atomic_read(&tty->ldisc->users) == 1, timeout);
        if (ret < 0)
                return ret;
        return ret > 0 ? 0 : -EBUSY;
@@ -665,7 +667,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 
        tty_ldisc_flush_works(tty);
 
-       retval = tty_ldisc_wait_idle(tty);
+       retval = tty_ldisc_wait_idle(tty, 5 * HZ);
 
        tty_lock();
        mutex_lock(&tty->ldisc_mutex);
@@ -762,8 +764,6 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
        if (IS_ERR(ld))
                return -1;
 
-       WARN_ON_ONCE(tty_ldisc_wait_idle(tty));
-
        tty_ldisc_close(tty, tty->ldisc);
        tty_ldisc_put(tty->ldisc);
        tty->ldisc = NULL;
@@ -838,7 +838,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
        tty_unlock();
        cancel_work_sync(&tty->buf.work);
        mutex_unlock(&tty->ldisc_mutex);
-
+retry:
        tty_lock();
        mutex_lock(&tty->ldisc_mutex);
 
@@ -847,6 +847,22 @@ void tty_ldisc_hangup(struct tty_struct *tty)
           it means auditing a lot of other paths so this is
           a FIXME */
        if (tty->ldisc) {       /* Not yet closed */
+               if (atomic_read(&tty->ldisc->users) != 1) {
+                       char cur_n[TASK_COMM_LEN], tty_n[64];
+                       long timeout = 3 * HZ;
+                       tty_unlock();
+
+                       while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
+                               timeout = MAX_SCHEDULE_TIMEOUT;
+                               printk_ratelimited(KERN_WARNING
+                                       "%s: waiting (%s) for %s took too long, but we keep waiting...\n",
+                                       __func__, get_task_comm(cur_n, current),
+                                       tty_name(tty, tty_n));
+                       }
+                       mutex_unlock(&tty->ldisc_mutex);
+                       goto retry;
+               }
+
                if (reset == 0) {
 
                        if (!tty_ldisc_reinit(tty, tty->termios->c_line))
index 6960715c5063ce15d18ad1437af834bdb6be1c20..e8c564a533469f00f7e40435933ae496187aa20a 100644 (file)
@@ -539,7 +539,6 @@ static void acm_port_down(struct acm *acm)
 {
        int i;
 
-       mutex_lock(&open_mutex);
        if (acm->dev) {
                usb_autopm_get_interface(acm->control);
                acm_set_control(acm, acm->ctrlout = 0);
@@ -551,14 +550,15 @@ static void acm_port_down(struct acm *acm)
                acm->control->needs_remote_wakeup = 0;
                usb_autopm_put_interface(acm->control);
        }
-       mutex_unlock(&open_mutex);
 }
 
 static void acm_tty_hangup(struct tty_struct *tty)
 {
        struct acm *acm = tty->driver_data;
        tty_port_hangup(&acm->port);
+       mutex_lock(&open_mutex);
        acm_port_down(acm);
+       mutex_unlock(&open_mutex);
 }
 
 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
@@ -569,8 +569,9 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
           shutdown */
        if (!acm)
                return;
+
+       mutex_lock(&open_mutex);
        if (tty_port_close_start(&acm->port, tty, filp) == 0) {
-               mutex_lock(&open_mutex);
                if (!acm->dev) {
                        tty_port_tty_set(&acm->port, NULL);
                        acm_tty_unregister(acm);
@@ -582,6 +583,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
        acm_port_down(acm);
        tty_port_close_end(&acm->port, tty);
        tty_port_tty_set(&acm->port, NULL);
+       mutex_unlock(&open_mutex);
 }
 
 static int acm_tty_write(struct tty_struct *tty,
index 96f05b29c9ad23ba6c0874a29dc2066c16806476..79781461eec97ad27c4986178266a63034f4693f 100644 (file)
@@ -813,6 +813,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                                        USB_PORT_FEAT_C_PORT_LINK_STATE);
                }
 
+               if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
+                               hub_is_superspeed(hub->hdev)) {
+                       need_debounce_delay = true;
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_BH_PORT_RESET);
+               }
                /* We can forget about a "removed" device when there's a
                 * physical disconnect or the connect status changes.
                 */
index d6a8d8269bfbe6b68648d52068d846208aa9dd05..ecf12e15a7ef48a201c192dbc056b108c2416340 100644 (file)
@@ -50,15 +50,42 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Logitech Webcam B/C500 */
        { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Logitech Webcam C600 */
+       { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Logitech Webcam Pro 9000 */
        { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Logitech Webcam C905 */
+       { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Webcam C210 */
+       { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Webcam C260 */
+       { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Logitech Webcam C310 */
        { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Logitech Webcam C910 */
+       { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Webcam C160 */
+       { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Logitech Webcam C270 */
        { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Logitech Quickcam Pro 9000 */
+       { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Quickcam E3500 */
+       { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Quickcam Vision Pro */
+       { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Logitech Harmony 700-series */
        { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
 
index fa824cfdd2eb42bf0869257303835a4305a16690..25dbd8614e7226ccf915bfa30817226a10272f3c 100644 (file)
@@ -1284,6 +1284,7 @@ static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)
                        int             ret;
 
                        dep->endpoint.maxpacket = 1024;
+                       dep->endpoint.max_streams = 15;
                        dep->endpoint.ops = &dwc3_gadget_ep_ops;
                        list_add_tail(&dep->endpoint.ep_list,
                                        &dwc->gadget.ep_list);
index b21cd376c11af5978095c97f49bdee67aa1ec6d0..23a447373c51f0c7d3f9a08cadad7a90f217c24a 100644 (file)
@@ -469,7 +469,7 @@ config USB_LANGWELL
           gadget drivers to also be dynamically linked.
 
 config USB_EG20T
-       tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC"
+       tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC"
        depends on PCI
        select USB_GADGET_DUALSPEED
        help
@@ -485,10 +485,11 @@ config USB_EG20T
          This driver dose not support interrupt transfer or isochronous
          transfer modes.
 
-         This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is
+         This driver also can be used for LAPIS Semiconductor's ML7213 which is
          for IVI(In-Vehicle Infotainment) use.
-         ML7213 is companion chip for Intel Atom E6xx series.
-         ML7213 is completely compatible for Intel EG20T PCH.
+         ML7831 is for general purpose use.
+         ML7213/ML7831 is companion chip for Intel Atom E6xx series.
+         ML7213/ML7831 is completely compatible for Intel EG20T PCH.
 
 config USB_CI13XXX_MSM
        tristate "MIPS USB CI13xxx for MSM"
index 4eedfe557154c285b9625d2117523ea3feef78ea..1fc612914c52e464ec89a82ec9e39048068c0b27 100644 (file)
@@ -122,3 +122,5 @@ static int __init ci13xxx_msm_init(void)
        return platform_driver_register(&ci13xxx_msm_driver);
 }
 module_init(ci13xxx_msm_init);
+
+MODULE_LICENSE("GPL v2");
index 83428f56253bd5283a8962448fa8cd7b899aee96..9a0c3979ff43faa2c54f05efa5fe8c76d8f23dff 100644 (file)
@@ -71,6 +71,9 @@
 /******************************************************************************
  * DEFINE
  *****************************************************************************/
+
+#define DMA_ADDR_INVALID       (~(dma_addr_t)0)
+
 /* ctrl register bank access */
 static DEFINE_SPINLOCK(udc_lock);
 
@@ -1434,7 +1437,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
                return -EALREADY;
 
        mReq->req.status = -EALREADY;
-       if (length && !mReq->req.dma) {
+       if (length && mReq->req.dma == DMA_ADDR_INVALID) {
                mReq->req.dma = \
                        dma_map_single(mEp->device, mReq->req.buf,
                                       length, mEp->dir ? DMA_TO_DEVICE :
@@ -1453,7 +1456,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
                                dma_unmap_single(mEp->device, mReq->req.dma,
                                        length, mEp->dir ? DMA_TO_DEVICE :
                                        DMA_FROM_DEVICE);
-                               mReq->req.dma = 0;
+                               mReq->req.dma = DMA_ADDR_INVALID;
                                mReq->map     = 0;
                        }
                        return -ENOMEM;
@@ -1549,7 +1552,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
        if (mReq->map) {
                dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
                                 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-               mReq->req.dma = 0;
+               mReq->req.dma = DMA_ADDR_INVALID;
                mReq->map     = 0;
        }
 
@@ -1610,7 +1613,6 @@ __acquires(mEp->lock)
  * @gadget: gadget
  *
  * This function returns an error code
- * Caller must hold lock
  */
 static int _gadget_stop_activity(struct usb_gadget *gadget)
 {
@@ -2189,6 +2191,7 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
        mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
        if (mReq != NULL) {
                INIT_LIST_HEAD(&mReq->queue);
+               mReq->req.dma = DMA_ADDR_INVALID;
 
                mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
                                           &mReq->dma);
@@ -2328,7 +2331,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
        if (mReq->map) {
                dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
                                 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-               mReq->req.dma = 0;
+               mReq->req.dma = DMA_ADDR_INVALID;
                mReq->map     = 0;
        }
        req->status = -ECONNRESET;
@@ -2500,12 +2503,12 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget)
        spin_lock_irqsave(udc->lock, flags);
        if (!udc->remote_wakeup) {
                ret = -EOPNOTSUPP;
-               dbg_trace("remote wakeup feature is not enabled\n");
+               trace("remote wakeup feature is not enabled\n");
                goto out;
        }
        if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
                ret = -EINVAL;
-               dbg_trace("port is not suspended\n");
+               trace("port is not suspended\n");
                goto out;
        }
        hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR);
@@ -2703,7 +2706,9 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver)
                if (udc->udc_driver->notify_event)
                        udc->udc_driver->notify_event(udc,
                        CI13XXX_CONTROLLER_STOPPED_EVENT);
+               spin_unlock_irqrestore(udc->lock, flags);
                _gadget_stop_activity(&udc->gadget);
+               spin_lock_irqsave(udc->lock, flags);
                pm_runtime_put(&udc->gadget.dev);
        }
 
@@ -2850,7 +2855,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
        struct ci13xxx *udc;
        int retval = 0;
 
-       trace("%p, %p, %p", dev, regs, name);
+       trace("%p, %p, %p", dev, regs, driver->name);
 
        if (dev == NULL || regs == NULL || driver == NULL ||
                        driver->name == NULL)
index 52583a2353304acb25119365a5432c916e0aeb73..c39d58860fa0414a2c862941dbc4382ddb2e1b0f 100644 (file)
@@ -624,7 +624,8 @@ static int fsg_setup(struct usb_function *f,
                if (ctrl->bRequestType !=
                    (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                        break;
-               if (w_index != fsg->interface_number || w_value != 0)
+               if (w_index != fsg->interface_number || w_value != 0 ||
+                               w_length != 0)
                        return -EDOM;
 
                /*
@@ -639,7 +640,8 @@ static int fsg_setup(struct usb_function *f,
                if (ctrl->bRequestType !=
                    (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                        break;
-               if (w_index != fsg->interface_number || w_value != 0)
+               if (w_index != fsg->interface_number || w_value != 0 ||
+                               w_length != 1)
                        return -EDOM;
                VDBG(fsg, "get max LUN\n");
                *(u8 *)req->buf = fsg->common->nluns - 1;
index 67b222908cf9fe264a3213b945f0beae5fa83569..3797b3d6c622bd49ff709b33303a86e323294c44 100644 (file)
@@ -95,7 +95,6 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req);
 
 DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
 DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
-DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(16);
 DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);
 
 /* B.3.1  Standard AC Interface Descriptor */
@@ -140,26 +139,6 @@ static struct usb_ms_header_descriptor ms_header_desc __initdata = {
        /* .wTotalLength =      DYNAMIC */
 };
 
-/* B.4.3  Embedded MIDI IN Jack Descriptor */
-static struct usb_midi_in_jack_descriptor jack_in_emb_desc = {
-       .bLength =            USB_DT_MIDI_IN_SIZE,
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubtype =   USB_MS_MIDI_IN_JACK,
-       .bJackType =        USB_MS_EMBEDDED,
-       /* .bJackID =           DYNAMIC */
-};
-
-/* B.4.4  Embedded MIDI OUT Jack Descriptor */
-static struct usb_midi_out_jack_descriptor_16 jack_out_emb_desc = {
-       /* .bLength =           DYNAMIC */
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubtype =   USB_MS_MIDI_OUT_JACK,
-       .bJackType =            USB_MS_EMBEDDED,
-       /* .bJackID =           DYNAMIC */
-       /* .bNrInputPins =      DYNAMIC */
-       /* .pins =              DYNAMIC */
-};
-
 /* B.5.1  Standard Bulk OUT Endpoint Descriptor */
 static struct usb_endpoint_descriptor bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_AUDIO_SIZE,
@@ -758,9 +737,11 @@ fail:
 static int __init
 f_midi_bind(struct usb_configuration *c, struct usb_function *f)
 {
-       struct usb_descriptor_header *midi_function[(MAX_PORTS * 2) + 12];
+       struct usb_descriptor_header **midi_function;
        struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS];
+       struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS];
        struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS];
+       struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc[MAX_PORTS];
        struct usb_composite_dev *cdev = c->cdev;
        struct f_midi *midi = func_to_midi(f);
        int status, n, jack = 1, i = 0;
@@ -798,6 +779,14 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
                goto fail;
        midi->out_ep->driver_data = cdev;       /* claim */
 
+       /* allocate temporary function list */
+       midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(midi_function),
+                               GFP_KERNEL);
+       if (!midi_function) {
+               status = -ENOMEM;
+               goto fail;
+       }
+
        /*
         * construct the function's descriptor set. As the number of
         * input and output MIDI ports is configurable, we have to do
@@ -811,73 +800,74 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
 
        /* calculate the header's wTotalLength */
        n = USB_DT_MS_HEADER_SIZE
-               + (1 + midi->in_ports) * USB_DT_MIDI_IN_SIZE
-               + (1 + midi->out_ports) * USB_DT_MIDI_OUT_SIZE(1);
+               + (midi->in_ports + midi->out_ports) *
+                       (USB_DT_MIDI_IN_SIZE + USB_DT_MIDI_OUT_SIZE(1));
        ms_header_desc.wTotalLength = cpu_to_le16(n);
 
        midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc;
 
-       /* we have one embedded IN jack */
-       jack_in_emb_desc.bJackID = jack++;
-       midi_function[i++] = (struct usb_descriptor_header *) &jack_in_emb_desc;
-
-       /* and a dynamic amount of external IN jacks */
-       for (n = 0; n < midi->in_ports; n++) {
-               struct usb_midi_in_jack_descriptor *ext = &jack_in_ext_desc[n];
-
-               ext->bLength =                  USB_DT_MIDI_IN_SIZE;
-               ext->bDescriptorType =          USB_DT_CS_INTERFACE;
-               ext->bDescriptorSubtype =       USB_MS_MIDI_IN_JACK;
-               ext->bJackType =                USB_MS_EXTERNAL;
-               ext->bJackID =                  jack++;
-               ext->iJack =                    0;
-
-               midi_function[i++] = (struct usb_descriptor_header *) ext;
-       }
-
-       /* one embedded OUT jack ... */
-       jack_out_emb_desc.bLength = USB_DT_MIDI_OUT_SIZE(midi->in_ports);
-       jack_out_emb_desc.bJackID = jack++;
-       jack_out_emb_desc.bNrInputPins = midi->in_ports;
-       /* ... which referencess all external IN jacks */
+       /* configure the external IN jacks, each linked to an embedded OUT jack */
        for (n = 0; n < midi->in_ports; n++) {
-               jack_out_emb_desc.pins[n].baSourceID = jack_in_ext_desc[n].bJackID;
-               jack_out_emb_desc.pins[n].baSourcePin = 1;
+               struct usb_midi_in_jack_descriptor *in_ext = &jack_in_ext_desc[n];
+               struct usb_midi_out_jack_descriptor_1 *out_emb = &jack_out_emb_desc[n];
+
+               in_ext->bLength                 = USB_DT_MIDI_IN_SIZE;
+               in_ext->bDescriptorType         = USB_DT_CS_INTERFACE;
+               in_ext->bDescriptorSubtype      = USB_MS_MIDI_IN_JACK;
+               in_ext->bJackType               = USB_MS_EXTERNAL;
+               in_ext->bJackID                 = jack++;
+               in_ext->iJack                   = 0;
+               midi_function[i++] = (struct usb_descriptor_header *) in_ext;
+
+               out_emb->bLength                = USB_DT_MIDI_OUT_SIZE(1);
+               out_emb->bDescriptorType        = USB_DT_CS_INTERFACE;
+               out_emb->bDescriptorSubtype     = USB_MS_MIDI_OUT_JACK;
+               out_emb->bJackType              = USB_MS_EMBEDDED;
+               out_emb->bJackID                = jack++;
+               out_emb->bNrInputPins           = 1;
+               out_emb->pins[0].baSourcePin    = 1;
+               out_emb->pins[0].baSourceID     = in_ext->bJackID;
+               out_emb->iJack                  = 0;
+               midi_function[i++] = (struct usb_descriptor_header *) out_emb;
+
+               /* link it to the endpoint */
+               ms_in_desc.baAssocJackID[n] = out_emb->bJackID;
        }
 
-       midi_function[i++] = (struct usb_descriptor_header *) &jack_out_emb_desc;
-
-       /* and multiple external OUT jacks ... */
+       /* configure the external OUT jacks, each linked to an embedded IN jack */
        for (n = 0; n < midi->out_ports; n++) {
-               struct usb_midi_out_jack_descriptor_1 *ext = &jack_out_ext_desc[n];
-               int m;
-
-               ext->bLength =                  USB_DT_MIDI_OUT_SIZE(1);
-               ext->bDescriptorType =          USB_DT_CS_INTERFACE;
-               ext->bDescriptorSubtype =       USB_MS_MIDI_OUT_JACK;
-               ext->bJackType =                USB_MS_EXTERNAL;
-               ext->bJackID =                  jack++;
-               ext->bNrInputPins =             1;
-               ext->iJack =                    0;
-               /* ... which all reference the same embedded IN jack */
-               for (m = 0; m < midi->out_ports; m++) {
-                       ext->pins[m].baSourceID =       jack_in_emb_desc.bJackID;
-                       ext->pins[m].baSourcePin =      1;
-               }
-
-               midi_function[i++] = (struct usb_descriptor_header *) ext;
+               struct usb_midi_in_jack_descriptor *in_emb = &jack_in_emb_desc[n];
+               struct usb_midi_out_jack_descriptor_1 *out_ext = &jack_out_ext_desc[n];
+
+               in_emb->bLength                 = USB_DT_MIDI_IN_SIZE;
+               in_emb->bDescriptorType         = USB_DT_CS_INTERFACE;
+               in_emb->bDescriptorSubtype      = USB_MS_MIDI_IN_JACK;
+               in_emb->bJackType               = USB_MS_EMBEDDED;
+               in_emb->bJackID                 = jack++;
+               in_emb->iJack                   = 0;
+               midi_function[i++] = (struct usb_descriptor_header *) in_emb;
+
+               out_ext->bLength =              USB_DT_MIDI_OUT_SIZE(1);
+               out_ext->bDescriptorType =      USB_DT_CS_INTERFACE;
+               out_ext->bDescriptorSubtype =   USB_MS_MIDI_OUT_JACK;
+               out_ext->bJackType =            USB_MS_EXTERNAL;
+               out_ext->bJackID =              jack++;
+               out_ext->bNrInputPins =         1;
+               out_ext->iJack =                0;
+               out_ext->pins[0].baSourceID =   in_emb->bJackID;
+               out_ext->pins[0].baSourcePin =  1;
+               midi_function[i++] = (struct usb_descriptor_header *) out_ext;
+
+               /* link it to the endpoint */
+               ms_out_desc.baAssocJackID[n] = in_emb->bJackID;
        }
 
        /* configure the endpoint descriptors ... */
        ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
        ms_out_desc.bNumEmbMIDIJack = midi->in_ports;
-       for (n = 0; n < midi->in_ports; n++)
-               ms_out_desc.baAssocJackID[n] = jack_in_emb_desc.bJackID;
 
        ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
        ms_in_desc.bNumEmbMIDIJack = midi->out_ports;
-       for (n = 0; n < midi->out_ports; n++)
-               ms_in_desc.baAssocJackID[n] = jack_out_emb_desc.bJackID;
 
        /* ... and add them to the list */
        midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc;
@@ -901,6 +891,8 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
                f->descriptors = usb_copy_descriptors(midi_function);
        }
 
+       kfree(midi_function);
+
        return 0;
 
 fail:
index 3490770333383d3d63c08977901b9311ff7cef15..16a509ae517b6b5a317422aa2553ce1316da46c5 100644 (file)
@@ -346,7 +346,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
                }
 
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
-                               skb->len == 0, req->actual);
+                               skb->len <= 1, req->actual);
                page = NULL;
 
                if (req->actual < req->length) { /* Last fragment */
index f7e39b0365cee5de76bc66d1942eeb2e322d6123..11b5196284aed6253180b699094cd7b6dbc762ea 100644 (file)
@@ -859,7 +859,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_OUT |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0 || w_value != 0) {
+                       if (w_index != 0 || w_value != 0 || w_length != 0) {
                                value = -EDOM;
                                break;
                        }
@@ -875,7 +875,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_IN |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0 || w_value != 0) {
+                       if (w_index != 0 || w_value != 0 || w_length != 1) {
                                value = -EDOM;
                                break;
                        }
index b2c44e1d58134c185966e672508ec0a9f8d24d84..b3b3d83b7c3354744ec1fc4d4dc2765f19293a7c 100644 (file)
@@ -1717,7 +1717,7 @@ static void dtd_complete_irq(struct fsl_udc *udc)
 
 static inline enum usb_device_speed portscx_device_speed(u32 reg)
 {
-       switch (speed & PORTSCX_PORT_SPEED_MASK) {
+       switch (reg & PORTSCX_PORT_SPEED_MASK) {
        case PORTSCX_PORT_SPEED_HIGH:
                return USB_SPEED_HIGH;
        case PORTSCX_PORT_SPEED_FULL:
@@ -2480,8 +2480,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 
 #ifndef CONFIG_ARCH_MXC
        if (pdata->have_sysif_regs)
-               usb_sys_regs = (struct usb_sys_interface *)
-                               ((u32)dr_regs + USB_DR_SYS_OFFSET);
+               usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET;
 #endif
 
        /* Initialize USB clocks */
index a392ec0d2d5179beebf3923dc6b275001b4961c5..6ccae2707e596c3f24d5705495264f0dcfa4f31b 100644 (file)
@@ -1730,8 +1730,9 @@ static void
 gadgetfs_disconnect (struct usb_gadget *gadget)
 {
        struct dev_data         *dev = get_gadget_data (gadget);
+       unsigned long           flags;
 
-       spin_lock (&dev->lock);
+       spin_lock_irqsave (&dev->lock, flags);
        if (dev->state == STATE_DEV_UNCONNECTED)
                goto exit;
        dev->state = STATE_DEV_UNCONNECTED;
@@ -1740,7 +1741,7 @@ gadgetfs_disconnect (struct usb_gadget *gadget)
        next_event (dev, GADGETFS_DISCONNECT);
        ep0_readable (dev);
 exit:
-       spin_unlock (&dev->lock);
+       spin_unlock_irqrestore (&dev->lock, flags);
 }
 
 static void
index 550d6dcdf10454253cdb3d93f6a7d86219ce4a50..5048a0c07640a4ed649c848a43ae4b83c5298be4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ * Copyright (C) 2011 LAPIS Semiconductor 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
@@ -354,6 +354,7 @@ struct pch_udc_dev {
 #define PCI_DEVICE_ID_INTEL_EG20T_UDC  0x8808
 #define PCI_VENDOR_ID_ROHM             0x10DB
 #define PCI_DEVICE_ID_ML7213_IOH_UDC   0x801D
+#define PCI_DEVICE_ID_ML7831_IOH_UDC   0x8808
 
 static const char      ep0_string[] = "ep0in";
 static DEFINE_SPINLOCK(udc_stall_spinlock);    /* stall spin lock */
@@ -2970,6 +2971,11 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = {
                .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,
                .class_mask = 0xffffffff,
        },
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7831_IOH_UDC),
+               .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,
+               .class_mask = 0xffffffff,
+       },
        { 0 },
 };
 
@@ -2999,5 +3005,5 @@ static void __exit pch_udc_pci_exit(void)
 module_exit(pch_udc_pci_exit);
 
 MODULE_DESCRIPTION("Intel EG20T USB Device Controller");
-MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>");
+MODULE_AUTHOR("LAPIS Semiconductor, <tomoya-linux@dsn.lapis-semi.com>");
 MODULE_LICENSE("GPL");
index 68a826a1b866e8a9191711da9c5e0da40eaf2e22..24f84b210ce116cfd78e5bae3a1bee383d198ca0 100644 (file)
@@ -1718,6 +1718,8 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep)
        if (list_empty(&ep->queue) && !ep->busy) {
                pipe_stop(ep->r8a66597, ep->pipenum);
                r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr);
+               r8a66597_write(ep->r8a66597, ACLRM, ep->pipectr);
+               r8a66597_write(ep->r8a66597, 0, ep->pipectr);
        }
        spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
 }
@@ -1742,7 +1744,6 @@ static int r8a66597_start(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
-       int retval;
 
        if (!driver
                        || driver->speed != USB_SPEED_HIGH
@@ -1752,16 +1753,7 @@ static int r8a66597_start(struct usb_gadget *gadget,
                return -ENODEV;
 
        /* hook up the driver */
-       driver->driver.bus = NULL;
        r8a66597->driver = driver;
-       r8a66597->gadget.dev.driver = &driver->driver;
-
-       retval = device_add(&r8a66597->gadget.dev);
-       if (retval) {
-               dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n",
-                       retval);
-               goto error;
-       }
 
        init_controller(r8a66597);
        r8a66597_bset(r8a66597, VBSE, INTENB0);
@@ -1775,12 +1767,6 @@ static int r8a66597_start(struct usb_gadget *gadget,
        }
 
        return 0;
-
-error:
-       r8a66597->driver = NULL;
-       r8a66597->gadget.dev.driver = NULL;
-
-       return retval;
 }
 
 static int r8a66597_stop(struct usb_gadget *gadget,
@@ -1794,7 +1780,6 @@ static int r8a66597_stop(struct usb_gadget *gadget,
        disable_controller(r8a66597);
        spin_unlock_irqrestore(&r8a66597->lock, flags);
 
-       device_del(&r8a66597->gadget.dev);
        r8a66597->driver = NULL;
        return 0;
 }
@@ -1845,6 +1830,7 @@ static int __exit r8a66597_remove(struct platform_device *pdev)
                clk_put(r8a66597->clk);
        }
 #endif
+       device_unregister(&r8a66597->gadget.dev);
        kfree(r8a66597);
        return 0;
 }
@@ -1924,13 +1910,17 @@ static int __init r8a66597_probe(struct platform_device *pdev)
        r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
 
        r8a66597->gadget.ops = &r8a66597_gadget_ops;
-       device_initialize(&r8a66597->gadget.dev);
        dev_set_name(&r8a66597->gadget.dev, "gadget");
        r8a66597->gadget.is_dualspeed = 1;
        r8a66597->gadget.dev.parent = &pdev->dev;
        r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask;
        r8a66597->gadget.dev.release = pdev->dev.release;
        r8a66597->gadget.name = udc_name;
+       ret = device_register(&r8a66597->gadget.dev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "device_register failed\n");
+               goto clean_up;
+       }
 
        init_timer(&r8a66597->timer);
        r8a66597->timer.function = r8a66597_timer;
@@ -1945,7 +1935,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
                                clk_name);
                        ret = PTR_ERR(r8a66597->clk);
-                       goto clean_up;
+                       goto clean_up_dev;
                }
                clk_enable(r8a66597->clk);
        }
@@ -2014,7 +2004,9 @@ clean_up2:
                clk_disable(r8a66597->clk);
                clk_put(r8a66597->clk);
        }
+clean_up_dev:
 #endif
+       device_unregister(&r8a66597->gadget.dev);
 clean_up:
        if (r8a66597) {
                if (r8a66597->sudmac_reg)
index 022baeca7c94f4f55819d6cf2be5550752e3318a..6939e17f4580099af82d236c413547fe3660a18d 100644 (file)
@@ -210,10 +210,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
        kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 
        if (udc_is_newstyle(udc)) {
-               usb_gadget_disconnect(udc->gadget);
+               udc->driver->disconnect(udc->gadget);
                udc->driver->unbind(udc->gadget);
                usb_gadget_udc_stop(udc->gadget, udc->driver);
-
+               usb_gadget_disconnect(udc->gadget);
        } else {
                usb_gadget_stop(udc->gadget, udc->driver);
        }
@@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver);
 static ssize_t usb_udc_srp_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t n)
 {
-       struct usb_udc          *udc = dev_get_drvdata(dev);
+       struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
 
        if (sysfs_streq(buf, "1"))
                usb_gadget_wakeup(udc->gadget);
@@ -378,7 +378,7 @@ static ssize_t usb_udc_speed_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%s\n",
                        usb_speed_string(udc->gadget->speed));
 }
-static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL);
+static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL);
 
 #define USB_UDC_ATTR(name)                                     \
 ssize_t usb_udc_##name##_show(struct device *dev,              \
@@ -389,7 +389,7 @@ ssize_t usb_udc_##name##_show(struct device *dev,           \
                                                                \
        return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name);  \
 }                                                              \
-static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL)
+static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL)
 
 static USB_UDC_ATTR(is_dualspeed);
 static USB_UDC_ATTR(is_otg);
index 2e829fae648291d1fc885653e274b7e891d4e09e..56a32033adb3485db49484d23619d1f2dcf68071 100644 (file)
@@ -1479,10 +1479,15 @@ iso_stream_schedule (
 
                /* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
 
-               /* find a uframe slot with enough bandwidth */
-               next = start + period;
-               for (; start < next; start++) {
-
+               /* find a uframe slot with enough bandwidth.
+                * Early uframes are more precious because full-speed
+                * iso IN transfers can't use late uframes,
+                * and therefore they should be allocated last.
+                */
+               next = start;
+               start += period;
+               do {
+                       start--;
                        /* check schedule: enough space? */
                        if (stream->highspeed) {
                                if (itd_slot_ok(ehci, mod, start,
@@ -1495,7 +1500,7 @@ iso_stream_schedule (
                                                start, sched, period))
                                        break;
                        }
-               }
+               } while (start > next);
 
                /* no room in the schedule */
                if (start == next) {
index fe74bd6760187c221e79dae448005c07a25863be..b4fb511d24bcda76a4101aa605e01384c5962d21 100644 (file)
@@ -19,7 +19,7 @@ static int ehci_xls_setup(struct usb_hcd *hcd)
 
        ehci->caps = hcd->regs;
        ehci->regs = hcd->regs +
-               HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+               HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
        dbg_hcs_params(ehci, "reset");
        dbg_hcc_params(ehci, "reset");
 
index ba3a46b78b75a7bd16e54e7e9d3690dd5f9df4ef..95a9fec38e89b4e8a6daff8a3c0c75fd73315d4c 100644 (file)
@@ -223,6 +223,9 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int
        if (port < 0 || port >= 2)
                return;
 
+       if (pdata->vbus_pin[port] <= 0)
+               return;
+
        gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable);
 }
 
@@ -231,6 +234,9 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
        if (port < 0 || port >= 2)
                return -EINVAL;
 
+       if (pdata->vbus_pin[port] <= 0)
+               return -EINVAL;
+
        return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted;
 }
 
index 34efd479e068cbd8133fbd98f8c2a2cd47efa862..b2639191549e88172e803281a6c53300bd103b67 100644 (file)
@@ -389,17 +389,14 @@ ohci_shutdown (struct usb_hcd *hcd)
        struct ohci_hcd *ohci;
 
        ohci = hcd_to_ohci (hcd);
-       ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
-       ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+       ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable);
 
-       /* If the SHUTDOWN quirk is set, don't put the controller in RESET */
-       ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ?
-                       OHCI_CTRL_RWC | OHCI_CTRL_HCFS :
-                       OHCI_CTRL_RWC);
-       ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+       /* Software reset, after which the controller goes into SUSPEND */
+       ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus);
+       ohci_readl(ohci, &ohci->regs->cmdstatus);       /* flush the writes */
+       udelay(10);
 
-       /* flush the writes */
-       (void) ohci_readl (ohci, &ohci->regs->control);
+       ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);
 }
 
 static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
index ad8166c681e2894424b81850aa3a366108d8d11c..bc01b064585ac9da1d232106586d71937b78db66 100644 (file)
@@ -175,28 +175,6 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
        return 0;
 }
 
-/* nVidia controllers continue to drive Reset signalling on the bus
- * even after system shutdown, wasting power.  This flag tells the
- * shutdown routine to leave the controller OPERATIONAL instead of RESET.
- */
-static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd)
-{
-       struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
-       /* Evidently nVidia fixed their later hardware; this is a guess at
-        * the changeover point.
-        */
-#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB          0x026d
-
-       if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) {
-               ohci->flags |= OHCI_QUIRK_SHUTDOWN;
-               ohci_dbg(ohci, "enabled nVidia shutdown quirk\n");
-       }
-
-       return 0;
-}
-
 static void sb800_prefetch(struct ohci_hcd *ohci, int on)
 {
        struct pci_dev *pdev;
@@ -260,10 +238,6 @@ static const struct pci_device_id ohci_pci_quirks[] = {
                PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
                .driver_data = (unsigned long)ohci_quirk_amd700,
        },
-       {
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
-               .driver_data = (unsigned long) ohci_quirk_nvidia_shutdown,
-       },
 
        /* FIXME for some of the early AMD 760 southbridges, OHCI
         * won't work at all.  blacklist them.
index 35e5fd640ce75388c7f373544c62e965f34c0111..0795b934d00c9709800948c137a1aa84fd96e47d 100644 (file)
@@ -403,7 +403,6 @@ struct ohci_hcd {
 #define        OHCI_QUIRK_HUB_POWER    0x100                   /* distrust firmware power/oc setup */
 #define        OHCI_QUIRK_AMD_PLL      0x200                   /* AMD PLL quirk*/
 #define        OHCI_QUIRK_AMD_PREFETCH 0x400                   /* pre-fetch for ISO transfer */
-#define        OHCI_QUIRK_SHUTDOWN     0x800                   /* nVidia power bug */
        // there are also chip quirks/bugs in init logic
 
        struct work_struct      nec_work;       /* Worker for NEC quirk */
index 27a3dec32fa2f78895175f32a89f5e8f0270f7cc..caf87428ca43c3f38985d9469b566645ea3d3bf9 100644 (file)
@@ -37,6 +37,7 @@
 #define OHCI_INTRENABLE                0x10
 #define OHCI_INTRDISABLE       0x14
 #define OHCI_FMINTERVAL                0x34
+#define OHCI_HCFS              (3 << 6)        /* hc functional state */
 #define OHCI_HCR               (1 << 0)        /* host controller reset */
 #define OHCI_OCR               (1 << 3)        /* ownership change request */
 #define OHCI_CTRL_RWC          (1 << 9)        /* remote wakeup connected */
@@ -466,6 +467,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
 {
        void __iomem *base;
        u32 control;
+       u32 fminterval;
+       int cnt;
 
        if (!mmio_resource_enabled(pdev, 0))
                return;
@@ -498,41 +501,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
        }
 #endif
 
-       /* reset controller, preserving RWC (and possibly IR) */
-       writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
-       readl(base + OHCI_CONTROL);
+       /* disable interrupts */
+       writel((u32) ~0, base + OHCI_INTRDISABLE);
 
-       /* Some NVIDIA controllers stop working if kept in RESET for too long */
-       if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
-               u32 fminterval;
-               int cnt;
+       /* Reset the USB bus, if the controller isn't already in RESET */
+       if (control & OHCI_HCFS) {
+               /* Go into RESET, preserving RWC (and possibly IR) */
+               writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
+               readl(base + OHCI_CONTROL);
 
-               /* drive reset for at least 50 ms (7.1.7.5) */
+               /* drive bus reset for at least 50 ms (7.1.7.5) */
                msleep(50);
+       }
 
-               /* software reset of the controller, preserving HcFmInterval */
-               fminterval = readl(base + OHCI_FMINTERVAL);
-               writel(OHCI_HCR, base + OHCI_CMDSTATUS);
+       /* software reset of the controller, preserving HcFmInterval */
+       fminterval = readl(base + OHCI_FMINTERVAL);
+       writel(OHCI_HCR, base + OHCI_CMDSTATUS);
 
-               /* reset requires max 10 us delay */
-               for (cnt = 30; cnt > 0; --cnt) {        /* ... allow extra time */
-                       if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
-                               break;
-                       udelay(1);
-               }
-               writel(fminterval, base + OHCI_FMINTERVAL);
-
-               /* Now we're in the SUSPEND state with all devices reset
-                * and wakeups and interrupts disabled
-                */
+       /* reset requires max 10 us delay */
+       for (cnt = 30; cnt > 0; --cnt) {        /* ... allow extra time */
+               if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
+                       break;
+               udelay(1);
        }
+       writel(fminterval, base + OHCI_FMINTERVAL);
 
-       /*
-        * disable interrupts
-        */
-       writel(~(u32)0, base + OHCI_INTRDISABLE);
-       writel(~(u32)0, base + OHCI_INTRSTATUS);
-
+       /* Now the controller is safely in SUSPEND and nothing can wake it up */
        iounmap(base);
 }
 
@@ -627,7 +621,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
        void __iomem *base, *op_reg_base;
        u32     hcc_params, cap, val;
        u8      offset, cap_length;
-       int     wait_time, delta, count = 256/4;
+       int     wait_time, count = 256/4;
 
        if (!mmio_resource_enabled(pdev, 0))
                return;
@@ -673,11 +667,10 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
                writel(val, op_reg_base + EHCI_USBCMD);
 
                wait_time = 2000;
-               delta = 100;
                do {
                        writel(0x3f, op_reg_base + EHCI_USBSTS);
-                       udelay(delta);
-                       wait_time -= delta;
+                       udelay(100);
+                       wait_time -= 100;
                        val = readl(op_reg_base + EHCI_USBSTS);
                        if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
                                break;
index 42a22b8e692262fde4eab6b2133fc6cf485555a7..0e4b25fa3bcd262a898d6337aeeb9b6cec7b5600 100644 (file)
@@ -982,7 +982,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
        struct xhci_virt_device *dev;
        struct xhci_ep_ctx      *ep0_ctx;
        struct xhci_slot_ctx    *slot_ctx;
-       struct xhci_input_control_ctx *ctrl_ctx;
        u32                     port_num;
        struct usb_device *top_dev;
 
@@ -994,12 +993,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
                return -EINVAL;
        }
        ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0);
-       ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx);
        slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx);
 
-       /* 2) New slot context and endpoint 0 context are valid*/
-       ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
-
        /* 3) Only the control endpoint is valid - one endpoint context */
        slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route);
        switch (udev->speed) {
index 940321b3ec68b477549a38d4016ee047fb7a72a7..9f1d4b15d818553fc488c8651a14d0e4b3301f66 100644 (file)
@@ -816,23 +816,24 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
        struct xhci_ring *ring;
        struct xhci_td *cur_td;
        int ret, i, j;
+       unsigned long flags;
 
        ep = (struct xhci_virt_ep *) arg;
        xhci = ep->xhci;
 
-       spin_lock(&xhci->lock);
+       spin_lock_irqsave(&xhci->lock, flags);
 
        ep->stop_cmds_pending--;
        if (xhci->xhc_state & XHCI_STATE_DYING) {
                xhci_dbg(xhci, "Stop EP timer ran, but another timer marked "
                                "xHCI as DYING, exiting.\n");
-               spin_unlock(&xhci->lock);
+               spin_unlock_irqrestore(&xhci->lock, flags);
                return;
        }
        if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
                xhci_dbg(xhci, "Stop EP timer ran, but no command pending, "
                                "exiting.\n");
-               spin_unlock(&xhci->lock);
+               spin_unlock_irqrestore(&xhci->lock, flags);
                return;
        }
 
@@ -844,11 +845,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
        xhci->xhc_state |= XHCI_STATE_DYING;
        /* Disable interrupts from the host controller and start halting it */
        xhci_quiesce(xhci);
-       spin_unlock(&xhci->lock);
+       spin_unlock_irqrestore(&xhci->lock, flags);
 
        ret = xhci_halt(xhci);
 
-       spin_lock(&xhci->lock);
+       spin_lock_irqsave(&xhci->lock, flags);
        if (ret < 0) {
                /* This is bad; the host is not responding to commands and it's
                 * not allowing itself to be halted.  At least interrupts are
@@ -896,7 +897,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
                        }
                }
        }
-       spin_unlock(&xhci->lock);
+       spin_unlock_irqrestore(&xhci->lock, flags);
        xhci_dbg(xhci, "Calling usb_hc_died()\n");
        usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
        xhci_dbg(xhci, "xHCI host controller is dead.\n");
index 1ff95a0df576762000796440a9b82aae53832718..aa94c01957919001e6a5804c7bc0434b923f20bc 100644 (file)
@@ -799,7 +799,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        u32                     command, temp = 0;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        struct usb_hcd          *secondary_hcd;
-       int                     retval;
+       int                     retval = 0;
 
        /* Wait a bit if either of the roothubs need to settle from the
         * transition into bus suspend.
@@ -809,6 +809,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                                xhci->bus_state[1].next_statechange))
                msleep(100);
 
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
+
        spin_lock_irq(&xhci->lock);
        if (xhci->quirks & XHCI_RESET_ON_RESUME)
                hibernated = true;
@@ -878,20 +881,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                        return retval;
                xhci_dbg(xhci, "Start the primary HCD\n");
                retval = xhci_run(hcd->primary_hcd);
-               if (retval)
-                       goto failed_restart;
-
-               xhci_dbg(xhci, "Start the secondary HCD\n");
-               retval = xhci_run(secondary_hcd);
                if (!retval) {
-                       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-                       set_bit(HCD_FLAG_HW_ACCESSIBLE,
-                                       &xhci->shared_hcd->flags);
+                       xhci_dbg(xhci, "Start the secondary HCD\n");
+                       retval = xhci_run(secondary_hcd);
                }
-failed_restart:
                hcd->state = HC_STATE_SUSPENDED;
                xhci->shared_hcd->state = HC_STATE_SUSPENDED;
-               return retval;
+               goto done;
        }
 
        /* step 4: set Run/Stop bit */
@@ -910,11 +906,14 @@ failed_restart:
         * Running endpoints by ringing their doorbells
         */
 
-       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-       set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
-
        spin_unlock_irq(&xhci->lock);
-       return 0;
+
+ done:
+       if (retval == 0) {
+               usb_hcd_resume_root_hub(hcd);
+               usb_hcd_resume_root_hub(xhci->shared_hcd);
+       }
+       return retval;
 }
 #endif /* CONFIG_PM */
 
@@ -3504,6 +3503,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
        /* Otherwise, update the control endpoint ring enqueue pointer. */
        else
                xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev);
+       ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+       ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
+       ctrl_ctx->drop_flags = 0;
+
        xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
        xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
 
@@ -3585,7 +3588,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
        virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK)
                + 1;
        /* Zero the input context control for later use */
-       ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
        ctrl_ctx->add_flags = 0;
        ctrl_ctx->drop_flags = 0;
 
index fc34b8b1191055bcb568a171a518d389b4266f25..07a03460a598c3bcea675494a2a9009312b5d57b 100644 (file)
@@ -11,6 +11,7 @@ config USB_MUSB_HDRC
        select TWL4030_USB if MACH_OMAP_3430SDP
        select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
        select USB_OTG_UTILS
+       select USB_GADGET_DUALSPEED
        tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
        help
          Say Y here if your system has a dual role high speed USB
@@ -60,7 +61,7 @@ config USB_MUSB_BLACKFIN
 
 config USB_MUSB_UX500
        tristate "U8500 and U5500"
-       depends on (ARCH_U8500 && AB8500_USB) || (ARCH_U5500)
+       depends on (ARCH_U8500 && AB8500_USB)
 
 endchoice
 
index 08f1d0b662a37b64558e70777bf13f609da1bb47..e233d2b7d335713a3af128258f8634014aa3c5fe 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
index 4da7492ddbdba25768f4acbce91c1802195f48da..2613bfdb09b65da2ecb274edbf160b237bfde066 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
index 20a28731c338e8aa9dbf2bac295ce8ddda426e3a..c1fa12ec7a9ad456a23c761f5c328a721182a070 100644 (file)
@@ -1477,8 +1477,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \
-       defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \
-       defined(CONFIG_ARCH_U5500)
+       defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500)
 
 static irqreturn_t generic_interrupt(int irq, void *__hci)
 {
index ae4a20acef6c6e1265f2666d00c09cdee4d19032..d51043acfe1abc5013217e70b4854e153f8bdf96 100644 (file)
@@ -1999,10 +1999,6 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
                                        nuke(&hw_ep->ep_out, -ESHUTDOWN);
                        }
                }
-
-               spin_unlock(&musb->lock);
-               driver->disconnect(&musb->g);
-               spin_lock(&musb->lock);
        }
 }
 
index d2e2efaba658c6c20c485e2de2d839b8a926d005..08c679c0dde5ae110a56ec70af33819fdd20cfeb 100644 (file)
@@ -405,7 +405,7 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
 /*
  *             platform functions
  */
-static int __devinit usbhs_probe(struct platform_device *pdev)
+static int usbhs_probe(struct platform_device *pdev)
 {
        struct renesas_usbhs_platform_info *info = pdev->dev.platform_data;
        struct renesas_usbhs_driver_callback *dfunc;
index 8da685e796d1484cadbb3bcda67a5ee26ac64c44..ffdf5d15085ebbe845dbd54474c8a0e5b9464061 100644 (file)
@@ -820,7 +820,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
        if (len % 4) /* 32bit alignment */
                goto usbhsf_pio_prepare_push;
 
-       if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
+       if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
                goto usbhsf_pio_prepare_push;
 
        /* get enable DMA fifo */
@@ -897,7 +897,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done)
        if (!fifo)
                goto usbhsf_pio_prepare_pop;
 
-       if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
+       if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
                goto usbhsf_pio_prepare_pop;
 
        ret = usbhsf_fifo_select(pipe, fifo, 0);
index 8ae3733031cdb8fa17ec146d31e5d42e9eea120a..6c6875533f019096af0518e6c92d9f430c4edc49 100644 (file)
@@ -143,8 +143,8 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod);
  */
 #if    defined(CONFIG_USB_RENESAS_USBHS_HCD) || \
        defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE)
-extern int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv);
-extern int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv);
+extern int usbhs_mod_host_probe(struct usbhs_priv *priv);
+extern int usbhs_mod_host_remove(struct usbhs_priv *priv);
 #else
 static inline int usbhs_mod_host_probe(struct usbhs_priv *priv)
 {
@@ -157,8 +157,8 @@ static inline void usbhs_mod_host_remove(struct usbhs_priv *priv)
 
 #if    defined(CONFIG_USB_RENESAS_USBHS_UDC) || \
        defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE)
-extern int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv);
-extern void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv);
+extern int usbhs_mod_gadget_probe(struct usbhs_priv *priv);
+extern void usbhs_mod_gadget_remove(struct usbhs_priv *priv);
 #else
 static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 {
index 4cc7ee0babc60441914ac69ca20a2fe1d857c5e6..d9717e0bc1ff65c6d23cae4bf0693c434d8873fe 100644 (file)
@@ -830,7 +830,7 @@ static int usbhsg_stop(struct usbhs_priv *priv)
        return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED);
 }
 
-int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv)
+int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 {
        struct usbhsg_gpriv *gpriv;
        struct usbhsg_uep *uep;
@@ -927,7 +927,7 @@ usbhs_mod_gadget_probe_err_gpriv:
        return ret;
 }
 
-void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv)
+void usbhs_mod_gadget_remove(struct usbhs_priv *priv)
 {
        struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
 
index 1a7208a50afc15dc42de21b7bcbf6184ac204ff3..bade761a1e52b783a63dfb462f8b11ef4c111999 100644 (file)
@@ -103,7 +103,7 @@ struct usbhsh_hpriv {
 
        u32     port_stat;      /* USB_PORT_STAT_xxx */
 
-       struct completion       *done;
+       struct completion       setup_ack_done;
 
        /* see usbhsh_req_alloc/free */
        struct list_head        ureq_link_active;
@@ -355,6 +355,7 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv,
 struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
                                        struct usbhsh_device *udev,
                                        struct usb_host_endpoint *ep,
+                                       int dir_in_req,
                                        gfp_t mem_flags)
 {
        struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
@@ -364,27 +365,38 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
        struct usbhs_pipe *pipe, *best_pipe;
        struct device *dev = usbhsh_hcd_to_dev(hcd);
        struct usb_endpoint_descriptor *desc = &ep->desc;
-       int type, i;
+       int type, i, dir_in;
        unsigned int min_usr;
 
+       dir_in_req = !!dir_in_req;
+
        uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);
        if (!uep) {
                dev_err(dev, "usbhsh_ep alloc fail\n");
                return NULL;
        }
-       type = usb_endpoint_type(desc);
+
+       if (usb_endpoint_xfer_control(desc)) {
+               best_pipe = usbhsh_hpriv_to_dcp(hpriv);
+               goto usbhsh_endpoint_alloc_find_pipe;
+       }
 
        /*
         * find best pipe for endpoint
         * see
         *      HARDWARE LIMITATION
         */
+       type = usb_endpoint_type(desc);
        min_usr = ~0;
        best_pipe = NULL;
-       usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
+       usbhs_for_each_pipe(pipe, priv, i) {
                if (!usbhs_pipe_type_is(pipe, type))
                        continue;
 
+               dir_in = !!usbhs_pipe_is_dir_in(pipe);
+               if (0 != (dir_in - dir_in_req))
+                       continue;
+
                info = usbhsh_pipe_info(pipe);
 
                if (min_usr > info->usr_cnt) {
@@ -398,7 +410,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
                kfree(uep);
                return NULL;
        }
-
+usbhsh_endpoint_alloc_find_pipe:
        /*
         * init uep
         */
@@ -423,6 +435,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
         * see
         *  DCPMAXP/PIPEMAXP
         */
+       usbhs_pipe_sequence_data0(uep->pipe);
        usbhs_pipe_config_update(uep->pipe,
                                 usbhsh_device_number(hpriv, udev),
                                 usb_endpoint_num(desc),
@@ -430,7 +443,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
 
        dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
                usbhsh_device_number(hpriv, udev),
-               usbhs_pipe_name(pipe), uep);
+               usbhs_pipe_name(uep->pipe), uep);
 
        return uep;
 }
@@ -549,8 +562,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,
         *      usbhsh_irq_setup_ack()
         *      usbhsh_irq_setup_err()
         */
-       DECLARE_COMPLETION(done);
-       hpriv->done = &done;
+       init_completion(&hpriv->setup_ack_done);
 
        /* copy original request */
        memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest));
@@ -572,8 +584,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,
        /*
         * wait setup packet ACK
         */
-       wait_for_completion(&done);
-       hpriv->done = NULL;
+       wait_for_completion(&hpriv->setup_ack_done);
 
        dev_dbg(dev, "%s done\n", __func__);
 }
@@ -724,11 +735,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
        struct usbhsh_device *udev, *new_udev = NULL;
        struct usbhs_pipe *pipe;
        struct usbhsh_ep *uep;
+       int is_dir_in = usb_pipein(urb->pipe);
 
        int ret;
 
-       dev_dbg(dev, "%s (%s)\n",
-               __func__, usb_pipein(urb->pipe) ? "in" : "out");
+       dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
 
        ret = usb_hcd_link_urb_to_ep(hcd, urb);
        if (ret)
@@ -751,7 +762,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
         */
        uep = usbhsh_ep_to_uep(ep);
        if (!uep) {
-               uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags);
+               uep = usbhsh_endpoint_alloc(hpriv, udev, ep,
+                                           is_dir_in, mem_flags);
                if (!uep)
                        goto usbhsh_urb_enqueue_error_free_device;
        }
@@ -1095,10 +1107,7 @@ static int usbhsh_irq_setup_ack(struct usbhs_priv *priv,
 
        dev_dbg(dev, "setup packet OK\n");
 
-       if (unlikely(!hpriv->done))
-               dev_err(dev, "setup ack happen without necessary data\n");
-       else
-               complete(hpriv->done); /* see usbhsh_urb_enqueue() */
+       complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */
 
        return 0;
 }
@@ -1111,10 +1120,7 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv,
 
        dev_dbg(dev, "setup packet Err\n");
 
-       if (unlikely(!hpriv->done))
-               dev_err(dev, "setup err happen without necessary data\n");
-       else
-               complete(hpriv->done); /* see usbhsh_urb_enqueue() */
+       complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */
 
        return 0;
 }
@@ -1221,8 +1227,18 @@ static int usbhsh_stop(struct usbhs_priv *priv)
 {
        struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);
        struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
+       struct usbhs_mod *mod = usbhs_mod_get_current(priv);
        struct device *dev = usbhs_priv_to_dev(priv);
 
+       /*
+        * disable irq callback
+        */
+       mod->irq_attch  = NULL;
+       mod->irq_dtch   = NULL;
+       mod->irq_sack   = NULL;
+       mod->irq_sign   = NULL;
+       usbhs_irq_callback_update(priv, mod);
+
        usb_remove_hcd(hcd);
 
        /* disable sys */
@@ -1235,7 +1251,7 @@ static int usbhsh_stop(struct usbhs_priv *priv)
        return 0;
 }
 
-int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv)
+int usbhs_mod_host_probe(struct usbhs_priv *priv)
 {
        struct usbhsh_hpriv *hpriv;
        struct usb_hcd *hcd;
@@ -1279,7 +1295,6 @@ int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv)
        hpriv->mod.stop         = usbhsh_stop;
        hpriv->pipe_info        = pipe_info;
        hpriv->pipe_size        = pipe_size;
-       hpriv->done             = NULL;
        usbhsh_req_list_init(hpriv);
        usbhsh_port_stat_init(hpriv);
 
@@ -1299,7 +1314,7 @@ usbhs_mod_host_probe_err:
        return -ENOMEM;
 }
 
-int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv)
+int usbhs_mod_host_remove(struct usbhs_priv *priv)
 {
        struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);
        struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
index 5cdb9d912275193bd7f5a8929742c4199a45c5c4..18e875b92e001d1c290f2b95e498eea77c6b72cb 100644 (file)
@@ -42,7 +42,7 @@ static int debug;
  * Version information
  */
 
-#define DRIVER_VERSION "v0.6"
+#define DRIVER_VERSION "v0.7"
 #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>"
 #define DRIVER_DESC "USB ARK3116 serial/IrDA driver"
 #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA"
@@ -380,10 +380,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
                goto err_out;
        }
 
-       /* setup termios */
-       if (tty)
-               ark3116_set_termios(tty, port, NULL);
-
        /* remove any data still left: also clears error state */
        ark3116_read_reg(serial, UART_RX, buf);
 
@@ -406,6 +402,10 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
        /* enable DMA */
        ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT);
 
+       /* setup termios */
+       if (tty)
+               ark3116_set_termios(tty, port, NULL);
+
 err_out:
        kfree(buf);
        return result;
index 8fe034d2d3e7b1bf1c4b0471a1bfaff96ab218a7..bd4298bb6750d347f825c47026b8de0acb7096a1 100644 (file)
@@ -2104,13 +2104,19 @@ static void ftdi_set_termios(struct tty_struct *tty,
 
        cflag = termios->c_cflag;
 
-       /* FIXME -For this cut I don't care if the line is really changing or
-          not  - so just do the change regardless  - should be able to
-          compare old_termios and tty->termios */
+       if (old_termios->c_cflag == termios->c_cflag
+           && old_termios->c_ispeed == termios->c_ispeed
+           && old_termios->c_ospeed == termios->c_ospeed)
+               goto no_c_cflag_changes;
+
        /* NOTE These routines can get interrupted by
           ftdi_sio_read_bulk_callback  - need to examine what this means -
           don't see any problems yet */
 
+       if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) ==
+           (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))
+               goto no_data_parity_stop_changes;
+
        /* Set number of data bits, parity, stop bits */
 
        urb_value = 0;
@@ -2151,6 +2157,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
        }
 
        /* Now do the baudrate */
+no_data_parity_stop_changes:
        if ((cflag & CBAUD) == B0) {
                /* Disable flow control */
                if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -2178,6 +2185,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
 
        /* Set flow control */
        /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
+no_c_cflag_changes:
        if (cflag & CRTSCTS) {
                dbg("%s Setting to CRTSCTS flow control", __func__);
                if (usb_control_msg(dev,
index 89ae1f65e1b18bc46d8b8ccc0004cd94edb4ee40..d865878c9f97449a6168fd69198af63f647ac497 100644 (file)
@@ -156,6 +156,7 @@ static void option_instat_callback(struct urb *urb);
 #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
@@ -316,6 +317,9 @@ static void option_instat_callback(struct urb *urb);
 #define ZTE_PRODUCT_AC8710                     0xfff1
 #define ZTE_PRODUCT_AC2726                     0xfff5
 #define ZTE_PRODUCT_AC8710T                    0xffff
+#define ZTE_PRODUCT_MC2718                     0xffe8
+#define ZTE_PRODUCT_AD3812                     0xffeb
+#define ZTE_PRODUCT_MC2716                     0xffed
 
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
@@ -468,6 +472,10 @@ static void option_instat_callback(struct urb *urb);
 #define YUGA_PRODUCT_CLU528                    0x260D
 #define YUGA_PRODUCT_CLU526                    0x260F
 
+/* Viettel products */
+#define VIETTEL_VENDOR_ID                      0x2262
+#define VIETTEL_PRODUCT_VT1000                 0x0002
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
                OPTION_BLACKLIST_NONE = 0,
@@ -500,6 +508,18 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {
        .reserved = BIT(4),
 };
 
+static const struct option_blacklist_info zte_ad3812_z_blacklist = {
+       .sendsetup = BIT(0) | BIT(1) | BIT(2),
+};
+
+static const struct option_blacklist_info zte_mc2718_z_blacklist = {
+       .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
+};
+
+static const struct option_blacklist_info zte_mc2716_z_blacklist = {
+       .sendsetup = BIT(1) | BIT(2) | BIT(3),
+};
+
 static const struct option_blacklist_info huawei_cdc12_blacklist = {
        .reserved = BIT(1) | BIT(2),
 };
@@ -622,6 +642,7 @@ static const struct usb_device_id option_ids[] = {
        { 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),
@@ -1043,6 +1064,12 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
+        .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
+        .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
+        .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
        { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
@@ -1141,6 +1168,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
+       { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 9083d1e616b4b48c30661ecd4261dfff3c127c14..fc2d66f7f4eb0ce3410a066e3877155651398eff 100644 (file)
@@ -91,7 +91,6 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
        { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
        { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
-       { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },
        { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
index 3d10d7f02072d10250f80802b7130fb941fb6793..c38b8c00c06fddd4c71f3508df13f592d2b4480b 100644 (file)
 #define ADLINK_VENDOR_ID               0x0b63
 #define ADLINK_ND6530_PRODUCT_ID       0x6530
 
-/* WinChipHead USB->RS 232 adapter */
-#define WINCHIPHEAD_VENDOR_ID          0x4348
-#define WINCHIPHEAD_USBSER_PRODUCT_ID  0x5523
-
 /* SMART USB Serial Adapter */
 #define SMART_VENDOR_ID        0x0b8c
 #define SMART_PRODUCT_ID       0x2303
index 4dca3ef0668c9963448289c3ab1160633865a6b9..9fbe742343c6cb6d023706bd7d5bd8170191d49e 100644 (file)
@@ -1762,10 +1762,9 @@ static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb)
                result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
        } else {
                void *buf;
-               int offset;
+               int offset = 0;
                u16 PhyBlockAddr;
                u8 PageNum;
-               u32 result;
                u16 len, oldphy, newphy;
 
                buf = kmalloc(blenByte, GFP_KERNEL);
index 93c1a4d86f51785983c5bac899d272808d390aff..82dd834709c78f7627b82a53d5e268fb006744a2 100644 (file)
@@ -59,7 +59,9 @@
 
 void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
 {
-       /* Pad the SCSI command with zeros out to 12 bytes
+       /*
+        * Pad the SCSI command with zeros out to 12 bytes.  If the
+        * command already is 12 bytes or longer, leave it alone.
         *
         * NOTE: This only works because a scsi_cmnd struct field contains
         * a unsigned char cmnd[16], so we know we have storage available
@@ -67,9 +69,6 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
        for (; srb->cmd_len<12; srb->cmd_len++)
                srb->cmnd[srb->cmd_len] = 0;
 
-       /* set command length to 12 bytes */
-       srb->cmd_len = 12;
-
        /* send the command to the transport layer */
        usb_stor_invoke_transport(srb, us);
 }
index 55f91d9ab00bd18bd01df877eab846a310595956..29577bf1f559070044ee2c9f50d300d86745f78e 100644 (file)
 /* Clock registers available only on Version 2 */
 #define  LCD_CLK_ENABLE_REG                    0x6c
 #define  LCD_CLK_RESET_REG                     0x70
+#define  LCD_CLK_MAIN_RESET                    BIT(3)
 
 #define LCD_NUM_BUFFERS        2
 
@@ -244,6 +245,10 @@ static inline void lcd_enable_raster(void)
 {
        u32 reg;
 
+       /* Bring LCDC out of reset */
+       if (lcd_revision == LCD_VERSION_2)
+               lcdc_write(0, LCD_CLK_RESET_REG);
+
        reg = lcdc_read(LCD_RASTER_CTRL_REG);
        if (!(reg & LCD_RASTER_ENABLE))
                lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
@@ -257,6 +262,10 @@ static inline void lcd_disable_raster(void)
        reg = lcdc_read(LCD_RASTER_CTRL_REG);
        if (reg & LCD_RASTER_ENABLE)
                lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
+
+       if (lcd_revision == LCD_VERSION_2)
+               /* Write 1 to reset LCDC */
+               lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
 }
 
 static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
@@ -584,8 +593,12 @@ static void lcd_reset(struct da8xx_fb_par *par)
        lcdc_write(0, LCD_DMA_CTRL_REG);
        lcdc_write(0, LCD_RASTER_CTRL_REG);
 
-       if (lcd_revision == LCD_VERSION_2)
+       if (lcd_revision == LCD_VERSION_2) {
                lcdc_write(0, LCD_INT_ENABLE_SET_REG);
+               /* Write 1 to reset */
+               lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
+               lcdc_write(0, LCD_CLK_RESET_REG);
+       }
 }
 
 static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
index 0ccd7adf47bb2db54312287fb5191ac8ed4b2b94..6f61e781f15afa94ae4ebbca32b57407b648a47a 100644 (file)
@@ -19,6 +19,7 @@
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
index 3532782551cb80dfa6ee1254be24d669c2fb28ef..5c81533eacaa6224c3aed27d0c1e72a60616c3d7 100644 (file)
@@ -1720,12 +1720,11 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
        const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
        unsigned long fclk = 0;
 
-       if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
-               if (width != out_width || height != out_height)
-                       return -EINVAL;
-               else
-                       return 0;
-       }
+       if (width == out_width && height == out_height)
+               return 0;
+
+       if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
+               return -EINVAL;
 
        if (out_width < width / maxdownscale ||
                        out_width > width * 8)
index 3262f0f1fa35f395aec7637dc4e61f4fdf5766b1..c56378c555b0907255048e32384c1b5b191bc14f 100644 (file)
@@ -269,7 +269,7 @@ static void update_hdmi_timings(struct hdmi_config *cfg,
 unsigned long hdmi_get_pixel_clock(void)
 {
        /* HDMI Pixel Clock in Mhz */
-       return hdmi.ip_data.cfg.timings.timings.pixel_clock * 10000;
+       return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000;
 }
 
 static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
index 69d882cbe7095f0acde27c9e61e12ea3236948d8..c01c1c162726137e19197c112313aa7458a91e0b 100644 (file)
 #define M1200X720_R60_VSP       POSITIVE
 
 /* 1200x900@60 Sync Polarity (DCON) */
-#define M1200X900_R60_HSP       NEGATIVE
-#define M1200X900_R60_VSP       NEGATIVE
+#define M1200X900_R60_HSP       POSITIVE
+#define M1200X900_R60_VSP       POSITIVE
 
 /* 1280x600@60 Sync Polarity (GTF Mode) */
 #define M1280x600_R60_HSP       NEGATIVE
index 816ed08e7cf3c504f4ce5377b327964a30daa8e9..1a61939b85fce4f3a1269b7915b1e9c3760efe26 100644 (file)
@@ -37,7 +37,7 @@ config VIRTIO_BALLOON
 
  config VIRTIO_MMIO
        tristate "Platform bus driver for memory mapped virtio devices (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on HAS_IOMEM && EXPERIMENTAL
        select VIRTIO
        select VIRTIO_RING
        ---help---
index acc5e43c373eb25c3d24410a70a39392caf551f4..7317dc2ec426e495d54b27a46839e15b429400f2 100644 (file)
@@ -118,7 +118,7 @@ static void vm_finalize_features(struct virtio_device *vdev)
        vring_transport_features(vdev);
 
        for (i = 0; i < ARRAY_SIZE(vdev->features); i++) {
-               writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SET);
+               writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SEL);
                writel(vdev->features[i],
                                vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES);
        }
index 3d1bf41e8892b8e2150a51403726ebb52ea9d56c..03d1984bd3635042b6bbe19f9966dfe89068e1ff 100644 (file)
@@ -169,11 +169,29 @@ static void vp_set_status(struct virtio_device *vdev, u8 status)
        iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
 }
 
+/* wait for pending irq handlers */
+static void vp_synchronize_vectors(struct virtio_device *vdev)
+{
+       struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+       int i;
+
+       if (vp_dev->intx_enabled)
+               synchronize_irq(vp_dev->pci_dev->irq);
+
+       for (i = 0; i < vp_dev->msix_vectors; ++i)
+               synchronize_irq(vp_dev->msix_entries[i].vector);
+}
+
 static void vp_reset(struct virtio_device *vdev)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        /* 0 status means a reset. */
        iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
+       /* Flush out the status write, and flush in device writes,
+        * including MSi-X interrupts, if any. */
+       ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS);
+       /* Flush pending VQ/configuration callbacks. */
+       vp_synchronize_vectors(vdev);
 }
 
 /* the notify function used when creating a virt queue */
index 6285867a93568c5dd03576d5e5adf1779d7c21d1..79fd606b7cd5cad60f487120db2e3ebf408ddedb 100644 (file)
@@ -314,13 +314,6 @@ config NUC900_WATCHDOG
          To compile this driver as a module, choose M here: the
          module will be called nuc900_wdt.
 
-config ADX_WATCHDOG
-       tristate "Avionic Design Xanthos watchdog"
-       depends on ARCH_PXA_ADX
-       help
-         Say Y here if you want support for the watchdog timer on Avionic
-         Design Xanthos boards.
-
 config TS72XX_WATCHDOG
        tristate "TS-72XX SBC Watchdog"
        depends on MACH_TS72XX
index 55bd5740e91000f1616da7ad0a4adf5eb4c33ac7..fe893e91935b6652e680b3b722ab3bb7b71bf3b3 100644 (file)
@@ -51,7 +51,6 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o
 obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
 obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
 obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
-obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o
 obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
 obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
 
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c
deleted file mode 100644 (file)
index af6e6b1..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Avionic Design GmbH
- *
- * 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/fs.h>
-#include <linux/gfp.h>
-#include <linux/io.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-#include <linux/watchdog.h>
-
-#define WATCHDOG_NAME "adx-wdt"
-
-/* register offsets */
-#define        ADX_WDT_CONTROL         0x00
-#define        ADX_WDT_CONTROL_ENABLE  (1 << 0)
-#define        ADX_WDT_CONTROL_nRESET  (1 << 1)
-#define        ADX_WDT_TIMEOUT         0x08
-
-static struct platform_device *adx_wdt_dev;
-static unsigned long driver_open;
-
-#define        WDT_STATE_STOP  0
-#define        WDT_STATE_START 1
-
-struct adx_wdt {
-       void __iomem *base;
-       unsigned long timeout;
-       unsigned int state;
-       unsigned int wake;
-       spinlock_t lock;
-};
-
-static const struct watchdog_info adx_wdt_info = {
-       .identity = "Avionic Design Xanthos Watchdog",
-       .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
-};
-
-static void adx_wdt_start_locked(struct adx_wdt *wdt)
-{
-       u32 ctrl;
-
-       ctrl = readl(wdt->base + ADX_WDT_CONTROL);
-       ctrl |= ADX_WDT_CONTROL_ENABLE;
-       writel(ctrl, wdt->base + ADX_WDT_CONTROL);
-       wdt->state = WDT_STATE_START;
-}
-
-static void adx_wdt_start(struct adx_wdt *wdt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&wdt->lock, flags);
-       adx_wdt_start_locked(wdt);
-       spin_unlock_irqrestore(&wdt->lock, flags);
-}
-
-static void adx_wdt_stop_locked(struct adx_wdt *wdt)
-{
-       u32 ctrl;
-
-       ctrl = readl(wdt->base + ADX_WDT_CONTROL);
-       ctrl &= ~ADX_WDT_CONTROL_ENABLE;
-       writel(ctrl, wdt->base + ADX_WDT_CONTROL);
-       wdt->state = WDT_STATE_STOP;
-}
-
-static void adx_wdt_stop(struct adx_wdt *wdt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&wdt->lock, flags);
-       adx_wdt_stop_locked(wdt);
-       spin_unlock_irqrestore(&wdt->lock, flags);
-}
-
-static void adx_wdt_set_timeout(struct adx_wdt *wdt, unsigned long seconds)
-{
-       unsigned long timeout = seconds * 1000;
-       unsigned long flags;
-       unsigned int state;
-
-       spin_lock_irqsave(&wdt->lock, flags);
-       state = wdt->state;
-       adx_wdt_stop_locked(wdt);
-       writel(timeout, wdt->base + ADX_WDT_TIMEOUT);
-
-       if (state == WDT_STATE_START)
-               adx_wdt_start_locked(wdt);
-
-       wdt->timeout = timeout;
-       spin_unlock_irqrestore(&wdt->lock, flags);
-}
-
-static void adx_wdt_get_timeout(struct adx_wdt *wdt, unsigned long *seconds)
-{
-       *seconds = wdt->timeout / 1000;
-}
-
-static void adx_wdt_keepalive(struct adx_wdt *wdt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&wdt->lock, flags);
-       writel(wdt->timeout, wdt->base + ADX_WDT_TIMEOUT);
-       spin_unlock_irqrestore(&wdt->lock, flags);
-}
-
-static int adx_wdt_open(struct inode *inode, struct file *file)
-{
-       struct adx_wdt *wdt = platform_get_drvdata(adx_wdt_dev);
-
-       if (test_and_set_bit(0, &driver_open))
-               return -EBUSY;
-
-       file->private_data = wdt;
-       adx_wdt_set_timeout(wdt, 30);
-       adx_wdt_start(wdt);
-
-       return nonseekable_open(inode, file);
-}
-
-static int adx_wdt_release(struct inode *inode, struct file *file)
-{
-       struct adx_wdt *wdt = file->private_data;
-
-       adx_wdt_stop(wdt);
-       clear_bit(0, &driver_open);
-
-       return 0;
-}
-
-static long adx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct adx_wdt *wdt = file->private_data;
-       void __user *argp = (void __user *)arg;
-       unsigned long __user *p = argp;
-       unsigned long seconds = 0;
-       unsigned int options;
-       long ret = -EINVAL;
-
-       switch (cmd) {
-       case WDIOC_GETSUPPORT:
-               if (copy_to_user(argp, &adx_wdt_info, sizeof(adx_wdt_info)))
-                       return -EFAULT;
-               else
-                       return 0;
-
-       case WDIOC_GETSTATUS:
-       case WDIOC_GETBOOTSTATUS:
-               return put_user(0, p);
-
-       case WDIOC_KEEPALIVE:
-               adx_wdt_keepalive(wdt);
-               return 0;
-
-       case WDIOC_SETTIMEOUT:
-               if (get_user(seconds, p))
-                       return -EFAULT;
-
-               adx_wdt_set_timeout(wdt, seconds);
-
-               /* fallthrough */
-       case WDIOC_GETTIMEOUT:
-               adx_wdt_get_timeout(wdt, &seconds);
-               return put_user(seconds, p);
-
-       case WDIOC_SETOPTIONS:
-               if (copy_from_user(&options, argp, sizeof(options)))
-                       return -EFAULT;
-
-               if (options & WDIOS_DISABLECARD) {
-                       adx_wdt_stop(wdt);
-                       ret = 0;
-               }
-
-               if (options & WDIOS_ENABLECARD) {
-                       adx_wdt_start(wdt);
-                       ret = 0;
-               }
-
-               return ret;
-
-       default:
-               break;
-       }
-
-       return -ENOTTY;
-}
-
-static ssize_t adx_wdt_write(struct file *file, const char __user *data,
-               size_t len, loff_t *ppos)
-{
-       struct adx_wdt *wdt = file->private_data;
-
-       if (len)
-               adx_wdt_keepalive(wdt);
-
-       return len;
-}
-
-static const struct file_operations adx_wdt_fops = {
-       .owner = THIS_MODULE,
-       .llseek = no_llseek,
-       .open = adx_wdt_open,
-       .release = adx_wdt_release,
-       .unlocked_ioctl = adx_wdt_ioctl,
-       .write = adx_wdt_write,
-};
-
-static struct miscdevice adx_wdt_miscdev = {
-       .minor = WATCHDOG_MINOR,
-       .name = "watchdog",
-       .fops = &adx_wdt_fops,
-};
-
-static int __devinit adx_wdt_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       struct adx_wdt *wdt;
-       int ret = 0;
-       u32 ctrl;
-
-       wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
-       if (!wdt) {
-               dev_err(&pdev->dev, "cannot allocate WDT structure\n");
-               return -ENOMEM;
-       }
-
-       spin_lock_init(&wdt->lock);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "cannot obtain I/O memory region\n");
-               return -ENXIO;
-       }
-
-       res = devm_request_mem_region(&pdev->dev, res->start,
-                       resource_size(res), res->name);
-       if (!res) {
-               dev_err(&pdev->dev, "cannot request I/O memory region\n");
-               return -ENXIO;
-       }
-
-       wdt->base = devm_ioremap_nocache(&pdev->dev, res->start,
-                       resource_size(res));
-       if (!wdt->base) {
-               dev_err(&pdev->dev, "cannot remap I/O memory region\n");
-               return -ENXIO;
-       }
-
-       /* disable watchdog and reboot on timeout */
-       ctrl = readl(wdt->base + ADX_WDT_CONTROL);
-       ctrl &= ~ADX_WDT_CONTROL_ENABLE;
-       ctrl &= ~ADX_WDT_CONTROL_nRESET;
-       writel(ctrl, wdt->base + ADX_WDT_CONTROL);
-
-       platform_set_drvdata(pdev, wdt);
-       adx_wdt_dev = pdev;
-
-       ret = misc_register(&adx_wdt_miscdev);
-       if (ret) {
-               dev_err(&pdev->dev, "cannot register miscdev on minor %d "
-                               "(err=%d)\n", WATCHDOG_MINOR, ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int __devexit adx_wdt_remove(struct platform_device *pdev)
-{
-       struct adx_wdt *wdt = platform_get_drvdata(pdev);
-
-       misc_deregister(&adx_wdt_miscdev);
-       adx_wdt_stop(wdt);
-       platform_set_drvdata(pdev, NULL);
-
-       return 0;
-}
-
-static void adx_wdt_shutdown(struct platform_device *pdev)
-{
-       struct adx_wdt *wdt = platform_get_drvdata(pdev);
-       adx_wdt_stop(wdt);
-}
-
-#ifdef CONFIG_PM
-static int adx_wdt_suspend(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct adx_wdt *wdt = platform_get_drvdata(pdev);
-
-       wdt->wake = (wdt->state == WDT_STATE_START) ? 1 : 0;
-       adx_wdt_stop(wdt);
-
-       return 0;
-}
-
-static int adx_wdt_resume(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct adx_wdt *wdt = platform_get_drvdata(pdev);
-
-       if (wdt->wake)
-               adx_wdt_start(wdt);
-
-       return 0;
-}
-
-static const struct dev_pm_ops adx_wdt_pm_ops = {
-       .suspend = adx_wdt_suspend,
-       .resume = adx_wdt_resume,
-};
-
-#  define ADX_WDT_PM_OPS       (&adx_wdt_pm_ops)
-#else
-#  define ADX_WDT_PM_OPS       NULL
-#endif
-
-static struct platform_driver adx_wdt_driver = {
-       .probe = adx_wdt_probe,
-       .remove = __devexit_p(adx_wdt_remove),
-       .shutdown = adx_wdt_shutdown,
-       .driver = {
-               .name = WATCHDOG_NAME,
-               .owner = THIS_MODULE,
-               .pm = ADX_WDT_PM_OPS,
-       },
-};
-
-static int __init adx_wdt_init(void)
-{
-       return platform_driver_register(&adx_wdt_driver);
-}
-
-static void __exit adx_wdt_exit(void)
-{
-       platform_driver_unregister(&adx_wdt_driver);
-}
-
-module_init(adx_wdt_init);
-module_exit(adx_wdt_exit);
-
-MODULE_DESCRIPTION("Avionic Design Xanthos Watchdog Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
index 5de7e4fa5b8a62fcc3f366f760a4f2b7e985cfff..a79e3840782ad3f286f0971b4a3cd7f6d5a1ff0b 100644 (file)
@@ -401,8 +401,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 
        dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n",
                 (wtcon & S3C2410_WTCON_ENABLE) ?  "" : "in",
-                (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis",
-                (wtcon & S3C2410_WTCON_INTEN) ? "" : "en");
+                (wtcon & S3C2410_WTCON_RSTEN) ? "en" : "dis",
+                (wtcon & S3C2410_WTCON_INTEN) ? "en" : "dis");
 
        return 0;
 
index 7be38556aed0c5b0854a89704875218f15437b02..e789a47db41f4dc1c618efaba3c8e189851c42bb 100644 (file)
@@ -150,7 +150,7 @@ static int wm831x_wdt_set_timeout(struct watchdog_device *wdt_dev,
                if (wm831x_wdt_cfgs[i].time == timeout)
                        break;
        if (i == ARRAY_SIZE(wm831x_wdt_cfgs))
-               ret = -EINVAL;
+               return -EINVAL;
 
        ret = wm831x_reg_unlock(wm831x);
        if (ret == 0) {
index a767884a6c7a10cfb526aff86de7b0ca1848eb9f..31ab82fda38a264cd045c4b52c117eb375f8e80e 100644 (file)
@@ -501,7 +501,7 @@ EXPORT_SYMBOL_GPL(balloon_set_new_target);
  * alloc_xenballooned_pages - get pages that have been ballooned out
  * @nr_pages: Number of pages to get
  * @pages: pages returned
- * @highmem: highmem or lowmem pages
+ * @highmem: allow highmem pages
  * @return 0 on success, error otherwise
  */
 int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
@@ -511,7 +511,7 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
        mutex_lock(&balloon_mutex);
        while (pgno < nr_pages) {
                page = balloon_retrieve(highmem);
-               if (page && PageHighMem(page) == highmem) {
+               if (page && (highmem || !PageHighMem(page))) {
                        pages[pgno++] = page;
                } else {
                        enum bp_state st;
index f6832f46aea4a4861368465321cc8423f997cdfc..e1c4c6e5b469c44449f68e9e841d264eb08dbc48 100644 (file)
@@ -135,7 +135,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,
                /* Grant foreign access to the page. */
                gref->gref_id = gnttab_grant_foreign_access(op->domid,
                        pfn_to_mfn(page_to_pfn(gref->page)), readonly);
-               if (gref->gref_id < 0) {
+               if ((int)gref->gref_id < 0) {
                        rc = gref->gref_id;
                        goto undo;
                }
@@ -280,7 +280,7 @@ static long gntalloc_ioctl_alloc(struct gntalloc_file_private_data *priv,
                goto out;
        }
 
-       gref_ids = kzalloc(sizeof(gref_ids[0]) * op.count, GFP_TEMPORARY);
+       gref_ids = kcalloc(op.count, sizeof(gref_ids[0]), GFP_TEMPORARY);
        if (!gref_ids) {
                rc = -ENOMEM;
                goto out;
index 39871326afa2ebb5905d2f6afbc922bb08826d0a..afca14d9042e6cd2ae03f238143ac8188aaf35fb 100644 (file)
@@ -114,11 +114,11 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
        if (NULL == add)
                return NULL;
 
-       add->grants    = kzalloc(sizeof(add->grants[0])    * count, GFP_KERNEL);
-       add->map_ops   = kzalloc(sizeof(add->map_ops[0])   * count, GFP_KERNEL);
-       add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL);
-       add->kmap_ops  = kzalloc(sizeof(add->kmap_ops[0])  * count, GFP_KERNEL);
-       add->pages     = kzalloc(sizeof(add->pages[0])     * count, GFP_KERNEL);
+       add->grants    = kcalloc(count, sizeof(add->grants[0]), GFP_KERNEL);
+       add->map_ops   = kcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL);
+       add->unmap_ops = kcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL);
+       add->kmap_ops  = kcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL);
+       add->pages     = kcalloc(count, sizeof(add->pages[0]), GFP_KERNEL);
        if (NULL == add->grants    ||
            NULL == add->map_ops   ||
            NULL == add->unmap_ops ||
index 81c3ce6b8bbeed198a77f22e21f2031131a82f42..1906125eab491bb384293c4424c27b8f0477e6f0 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/vmalloc.h>
 #include <linux/export.h>
 #include <asm/xen/hypervisor.h>
+#include <asm/xen/page.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/event_channel.h>
 #include <xen/events.h>
@@ -436,19 +437,20 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
 int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
 {
        struct gnttab_map_grant_ref op = {
-               .flags = GNTMAP_host_map,
+               .flags = GNTMAP_host_map | GNTMAP_contains_pte,
                .ref   = gnt_ref,
                .dom   = dev->otherend_id,
        };
        struct vm_struct *area;
+       pte_t *pte;
 
        *vaddr = NULL;
 
-       area = alloc_vm_area(PAGE_SIZE);
+       area = alloc_vm_area(PAGE_SIZE, &pte);
        if (!area)
                return -ENOMEM;
 
-       op.host_addr = (unsigned long)area->addr;
+       op.host_addr = arbitrary_virt_to_machine(pte).maddr;
 
        if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
                BUG();
@@ -527,6 +529,7 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
        struct gnttab_unmap_grant_ref op = {
                .host_addr = (unsigned long)vaddr,
        };
+       unsigned int level;
 
        /* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
         * method so that we don't have to muck with vmalloc internals here.
@@ -548,6 +551,8 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
        }
 
        op.handle = (grant_handle_t)area->phys_addr;
+       op.host_addr = arbitrary_virt_to_machine(
+               lookup_address((unsigned long)vaddr, &level)).maddr;
 
        if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
                BUG();
index 41c93c72224457179bda4ca18798b6f2add617c9..b1fe82cf88cfe0864a2d9603b713f8caacecde4e 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -337,7 +337,7 @@ static void bio_fs_destructor(struct bio *bio)
  *     RETURNS:
  *     Pointer to new bio on success, NULL on failure.
  */
-struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
+struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
 {
        struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
 
@@ -365,7 +365,7 @@ static void bio_kmalloc_destructor(struct bio *bio)
  *   %__GFP_WAIT, the allocation is guaranteed to succeed.
  *
  **/
-struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
+struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
 {
        struct bio *bio;
 
@@ -696,7 +696,8 @@ static void bio_free_map_data(struct bio_map_data *bmd)
        kfree(bmd);
 }
 
-static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count,
+static struct bio_map_data *bio_alloc_map_data(int nr_segs,
+                                              unsigned int iov_count,
                                               gfp_t gfp_mask)
 {
        struct bio_map_data *bmd;
index 8855aad3929c337cb1891cd63c702ff1b69e9322..22c64fff1bd524b213ce8b13a233f861680d8424 100644 (file)
@@ -683,7 +683,7 @@ static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref,
                return PTR_ERR(fspath);
 
        if (fspath > fspath_min) {
-               ipath->fspath->val[i] = (u64)fspath;
+               ipath->fspath->val[i] = (u64)(unsigned long)fspath;
                ++ipath->fspath->elem_cnt;
                ipath->fspath->bytes_left = fspath - fspath_min;
        } else {
index 0fe615e4ea387582acc06f60cac81366f23fe069..dede441bdeee2678225187bece170710abe1a9b4 100644 (file)
@@ -514,10 +514,25 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root,
                                   struct extent_buffer *buf)
 {
+       /* ensure we can see the force_cow */
+       smp_rmb();
+
+       /*
+        * We do not need to cow a block if
+        * 1) this block is not created or changed in this transaction;
+        * 2) this block does not belong to TREE_RELOC tree;
+        * 3) the root is not forced COW.
+        *
+        * What is forced COW:
+        *    when we create snapshot during commiting the transaction,
+        *    after we've finished coping src root, we must COW the shared
+        *    block to ensure the metadata consistency.
+        */
        if (btrfs_header_generation(buf) == trans->transid &&
            !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) &&
            !(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
-             btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)))
+             btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) &&
+           !root->force_cow)
                return 0;
        return 1;
 }
index b9ba59ff9292559330745b8afb41eefacfbf1615..50634abef9b4a51336e95b8bc2aafb4edb7844a0 100644 (file)
@@ -848,7 +848,8 @@ struct btrfs_free_cluster {
 enum btrfs_caching_type {
        BTRFS_CACHE_NO          = 0,
        BTRFS_CACHE_STARTED     = 1,
-       BTRFS_CACHE_FINISHED    = 2,
+       BTRFS_CACHE_FAST        = 2,
+       BTRFS_CACHE_FINISHED    = 3,
 };
 
 enum btrfs_disk_cache_state {
@@ -1271,6 +1272,8 @@ struct btrfs_root {
         * for stat.  It may be used for more later
         */
        dev_t anon_dev;
+
+       int force_cow;
 };
 
 struct btrfs_ioctl_defrag_range_args {
@@ -2366,6 +2369,9 @@ int btrfs_block_rsv_check(struct btrfs_root *root,
 int btrfs_block_rsv_refill(struct btrfs_root *root,
                          struct btrfs_block_rsv *block_rsv,
                          u64 min_reserved);
+int btrfs_block_rsv_refill_noflush(struct btrfs_root *root,
+                                  struct btrfs_block_rsv *block_rsv,
+                                  u64 min_reserved);
 int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
                            struct btrfs_block_rsv *dst_rsv,
                            u64 num_bytes);
index 62afe5c5694e9f4681931daee508334835bad243..632f8f3cc9db67f4173ca591b1b66d9ed898627f 100644 (file)
@@ -620,7 +620,7 @@ out:
 
 static int btree_io_failed_hook(struct bio *failed_bio,
                         struct page *page, u64 start, u64 end,
-                        u64 mirror_num, struct extent_state *state)
+                        int mirror_num, struct extent_state *state)
 {
        struct extent_io_tree *tree;
        unsigned long len;
@@ -2573,22 +2573,10 @@ static int write_dev_supers(struct btrfs_device *device,
        int errors = 0;
        u32 crc;
        u64 bytenr;
-       int last_barrier = 0;
 
        if (max_mirrors == 0)
                max_mirrors = BTRFS_SUPER_MIRROR_MAX;
 
-       /* make sure only the last submit_bh does a barrier */
-       if (do_barriers) {
-               for (i = 0; i < max_mirrors; i++) {
-                       bytenr = btrfs_sb_offset(i);
-                       if (bytenr + BTRFS_SUPER_INFO_SIZE >=
-                           device->total_bytes)
-                               break;
-                       last_barrier = i;
-               }
-       }
-
        for (i = 0; i < max_mirrors; i++) {
                bytenr = btrfs_sb_offset(i);
                if (bytenr + BTRFS_SUPER_INFO_SIZE >= device->total_bytes)
@@ -2634,17 +2622,136 @@ static int write_dev_supers(struct btrfs_device *device,
                        bh->b_end_io = btrfs_end_buffer_write_sync;
                }
 
-               if (i == last_barrier && do_barriers)
-                       ret = submit_bh(WRITE_FLUSH_FUA, bh);
-               else
-                       ret = submit_bh(WRITE_SYNC, bh);
-
+               /*
+                * we fua the first super.  The others we allow
+                * to go down lazy.
+                */
+               ret = submit_bh(WRITE_FUA, bh);
                if (ret)
                        errors++;
        }
        return errors < i ? 0 : -1;
 }
 
+/*
+ * endio for the write_dev_flush, this will wake anyone waiting
+ * for the barrier when it is done
+ */
+static void btrfs_end_empty_barrier(struct bio *bio, int err)
+{
+       if (err) {
+               if (err == -EOPNOTSUPP)
+                       set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
+               clear_bit(BIO_UPTODATE, &bio->bi_flags);
+       }
+       if (bio->bi_private)
+               complete(bio->bi_private);
+       bio_put(bio);
+}
+
+/*
+ * trigger flushes for one the devices.  If you pass wait == 0, the flushes are
+ * sent down.  With wait == 1, it waits for the previous flush.
+ *
+ * any device where the flush fails with eopnotsupp are flagged as not-barrier
+ * capable
+ */
+static int write_dev_flush(struct btrfs_device *device, int wait)
+{
+       struct bio *bio;
+       int ret = 0;
+
+       if (device->nobarriers)
+               return 0;
+
+       if (wait) {
+               bio = device->flush_bio;
+               if (!bio)
+                       return 0;
+
+               wait_for_completion(&device->flush_wait);
+
+               if (bio_flagged(bio, BIO_EOPNOTSUPP)) {
+                       printk("btrfs: disabling barriers on dev %s\n",
+                              device->name);
+                       device->nobarriers = 1;
+               }
+               if (!bio_flagged(bio, BIO_UPTODATE)) {
+                       ret = -EIO;
+               }
+
+               /* drop the reference from the wait == 0 run */
+               bio_put(bio);
+               device->flush_bio = NULL;
+
+               return ret;
+       }
+
+       /*
+        * one reference for us, and we leave it for the
+        * caller
+        */
+       device->flush_bio = NULL;;
+       bio = bio_alloc(GFP_NOFS, 0);
+       if (!bio)
+               return -ENOMEM;
+
+       bio->bi_end_io = btrfs_end_empty_barrier;
+       bio->bi_bdev = device->bdev;
+       init_completion(&device->flush_wait);
+       bio->bi_private = &device->flush_wait;
+       device->flush_bio = bio;
+
+       bio_get(bio);
+       submit_bio(WRITE_FLUSH, bio);
+
+       return 0;
+}
+
+/*
+ * send an empty flush down to each device in parallel,
+ * then wait for them
+ */
+static int barrier_all_devices(struct btrfs_fs_info *info)
+{
+       struct list_head *head;
+       struct btrfs_device *dev;
+       int errors = 0;
+       int ret;
+
+       /* send down all the barriers */
+       head = &info->fs_devices->devices;
+       list_for_each_entry_rcu(dev, head, dev_list) {
+               if (!dev->bdev) {
+                       errors++;
+                       continue;
+               }
+               if (!dev->in_fs_metadata || !dev->writeable)
+                       continue;
+
+               ret = write_dev_flush(dev, 0);
+               if (ret)
+                       errors++;
+       }
+
+       /* wait for all the barriers */
+       list_for_each_entry_rcu(dev, head, dev_list) {
+               if (!dev->bdev) {
+                       errors++;
+                       continue;
+               }
+               if (!dev->in_fs_metadata || !dev->writeable)
+                       continue;
+
+               ret = write_dev_flush(dev, 1);
+               if (ret)
+                       errors++;
+       }
+       if (errors)
+               return -EIO;
+       return 0;
+}
+
 int write_all_supers(struct btrfs_root *root, int max_mirrors)
 {
        struct list_head *head;
@@ -2666,6 +2773,10 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors)
 
        mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
        head = &root->fs_info->fs_devices->devices;
+
+       if (do_barriers)
+               barrier_all_devices(root->fs_info);
+
        list_for_each_entry_rcu(dev, head, dev_list) {
                if (!dev->bdev) {
                        total_errors++;
index b232150b5b6b7500b337337ad07bd03e66f3e407..f0d5718d2587a43c96101c3408a0749fc4abefa0 100644 (file)
@@ -467,13 +467,59 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
                             struct btrfs_root *root,
                             int load_cache_only)
 {
+       DEFINE_WAIT(wait);
        struct btrfs_fs_info *fs_info = cache->fs_info;
        struct btrfs_caching_control *caching_ctl;
        int ret = 0;
 
-       smp_mb();
-       if (cache->cached != BTRFS_CACHE_NO)
+       caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS);
+       BUG_ON(!caching_ctl);
+
+       INIT_LIST_HEAD(&caching_ctl->list);
+       mutex_init(&caching_ctl->mutex);
+       init_waitqueue_head(&caching_ctl->wait);
+       caching_ctl->block_group = cache;
+       caching_ctl->progress = cache->key.objectid;
+       atomic_set(&caching_ctl->count, 1);
+       caching_ctl->work.func = caching_thread;
+
+       spin_lock(&cache->lock);
+       /*
+        * This should be a rare occasion, but this could happen I think in the
+        * case where one thread starts to load the space cache info, and then
+        * some other thread starts a transaction commit which tries to do an
+        * allocation while the other thread is still loading the space cache
+        * info.  The previous loop should have kept us from choosing this block
+        * group, but if we've moved to the state where we will wait on caching
+        * block groups we need to first check if we're doing a fast load here,
+        * so we can wait for it to finish, otherwise we could end up allocating
+        * from a block group who's cache gets evicted for one reason or
+        * another.
+        */
+       while (cache->cached == BTRFS_CACHE_FAST) {
+               struct btrfs_caching_control *ctl;
+
+               ctl = cache->caching_ctl;
+               atomic_inc(&ctl->count);
+               prepare_to_wait(&ctl->wait, &wait, TASK_UNINTERRUPTIBLE);
+               spin_unlock(&cache->lock);
+
+               schedule();
+
+               finish_wait(&ctl->wait, &wait);
+               put_caching_control(ctl);
+               spin_lock(&cache->lock);
+       }
+
+       if (cache->cached != BTRFS_CACHE_NO) {
+               spin_unlock(&cache->lock);
+               kfree(caching_ctl);
                return 0;
+       }
+       WARN_ON(cache->caching_ctl);
+       cache->caching_ctl = caching_ctl;
+       cache->cached = BTRFS_CACHE_FAST;
+       spin_unlock(&cache->lock);
 
        /*
         * We can't do the read from on-disk cache during a commit since we need
@@ -484,56 +530,51 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
        if (trans && (!trans->transaction->in_commit) &&
            (root && root != root->fs_info->tree_root) &&
            btrfs_test_opt(root, SPACE_CACHE)) {
-               spin_lock(&cache->lock);
-               if (cache->cached != BTRFS_CACHE_NO) {
-                       spin_unlock(&cache->lock);
-                       return 0;
-               }
-               cache->cached = BTRFS_CACHE_STARTED;
-               spin_unlock(&cache->lock);
-
                ret = load_free_space_cache(fs_info, cache);
 
                spin_lock(&cache->lock);
                if (ret == 1) {
+                       cache->caching_ctl = NULL;
                        cache->cached = BTRFS_CACHE_FINISHED;
                        cache->last_byte_to_unpin = (u64)-1;
                } else {
-                       cache->cached = BTRFS_CACHE_NO;
+                       if (load_cache_only) {
+                               cache->caching_ctl = NULL;
+                               cache->cached = BTRFS_CACHE_NO;
+                       } else {
+                               cache->cached = BTRFS_CACHE_STARTED;
+                       }
                }
                spin_unlock(&cache->lock);
+               wake_up(&caching_ctl->wait);
                if (ret == 1) {
+                       put_caching_control(caching_ctl);
                        free_excluded_extents(fs_info->extent_root, cache);
                        return 0;
                }
+       } else {
+               /*
+                * We are not going to do the fast caching, set cached to the
+                * appropriate value and wakeup any waiters.
+                */
+               spin_lock(&cache->lock);
+               if (load_cache_only) {
+                       cache->caching_ctl = NULL;
+                       cache->cached = BTRFS_CACHE_NO;
+               } else {
+                       cache->cached = BTRFS_CACHE_STARTED;
+               }
+               spin_unlock(&cache->lock);
+               wake_up(&caching_ctl->wait);
        }
 
-       if (load_cache_only)
-               return 0;
-
-       caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS);
-       BUG_ON(!caching_ctl);
-
-       INIT_LIST_HEAD(&caching_ctl->list);
-       mutex_init(&caching_ctl->mutex);
-       init_waitqueue_head(&caching_ctl->wait);
-       caching_ctl->block_group = cache;
-       caching_ctl->progress = cache->key.objectid;
-       /* one for caching kthread, one for caching block group list */
-       atomic_set(&caching_ctl->count, 2);
-       caching_ctl->work.func = caching_thread;
-
-       spin_lock(&cache->lock);
-       if (cache->cached != BTRFS_CACHE_NO) {
-               spin_unlock(&cache->lock);
-               kfree(caching_ctl);
+       if (load_cache_only) {
+               put_caching_control(caching_ctl);
                return 0;
        }
-       cache->caching_ctl = caching_ctl;
-       cache->cached = BTRFS_CACHE_STARTED;
-       spin_unlock(&cache->lock);
 
        down_write(&fs_info->extent_commit_sem);
+       atomic_inc(&caching_ctl->count);
        list_add_tail(&caching_ctl->list, &fs_info->caching_block_groups);
        up_write(&fs_info->extent_commit_sem);
 
@@ -3847,9 +3888,9 @@ int btrfs_block_rsv_check(struct btrfs_root *root,
        return ret;
 }
 
-int btrfs_block_rsv_refill(struct btrfs_root *root,
-                         struct btrfs_block_rsv *block_rsv,
-                         u64 min_reserved)
+static inline int __btrfs_block_rsv_refill(struct btrfs_root *root,
+                                          struct btrfs_block_rsv *block_rsv,
+                                          u64 min_reserved, int flush)
 {
        u64 num_bytes = 0;
        int ret = -ENOSPC;
@@ -3868,7 +3909,7 @@ int btrfs_block_rsv_refill(struct btrfs_root *root,
        if (!ret)
                return 0;
 
-       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1);
+       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
        if (!ret) {
                block_rsv_add_bytes(block_rsv, num_bytes, 0);
                return 0;
@@ -3877,6 +3918,20 @@ int btrfs_block_rsv_refill(struct btrfs_root *root,
        return ret;
 }
 
+int btrfs_block_rsv_refill(struct btrfs_root *root,
+                          struct btrfs_block_rsv *block_rsv,
+                          u64 min_reserved)
+{
+       return __btrfs_block_rsv_refill(root, block_rsv, min_reserved, 1);
+}
+
+int btrfs_block_rsv_refill_noflush(struct btrfs_root *root,
+                                  struct btrfs_block_rsv *block_rsv,
+                                  u64 min_reserved)
+{
+       return __btrfs_block_rsv_refill(root, block_rsv, min_reserved, 0);
+}
+
 int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
                            struct btrfs_block_rsv *dst_rsv,
                            u64 num_bytes)
@@ -5178,13 +5233,15 @@ search:
                }
 
 have_block_group:
-               if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
+               cached = block_group_cache_done(block_group);
+               if (unlikely(!cached)) {
                        u64 free_percent;
 
+                       found_uncached_bg = true;
                        ret = cache_block_group(block_group, trans,
                                                orig_root, 1);
                        if (block_group->cached == BTRFS_CACHE_FINISHED)
-                               goto have_block_group;
+                               goto alloc;
 
                        free_percent = btrfs_block_group_used(&block_group->item);
                        free_percent *= 100;
@@ -5206,7 +5263,6 @@ have_block_group:
                                                        orig_root, 0);
                                BUG_ON(ret);
                        }
-                       found_uncached_bg = true;
 
                        /*
                         * If loop is set for cached only, try the next block
@@ -5216,17 +5272,14 @@ have_block_group:
                                goto loop;
                }
 
-               cached = block_group_cache_done(block_group);
-               if (unlikely(!cached))
-                       found_uncached_bg = true;
-
+alloc:
                if (unlikely(block_group->ro))
                        goto loop;
 
                spin_lock(&block_group->free_space_ctl->tree_lock);
                if (cached &&
                    block_group->free_space_ctl->free_space <
-                   num_bytes + empty_size) {
+                   num_bytes + empty_cluster + empty_size) {
                        spin_unlock(&block_group->free_space_ctl->tree_lock);
                        goto loop;
                }
@@ -5247,12 +5300,10 @@ have_block_group:
                         * people trying to start a new cluster
                         */
                        spin_lock(&last_ptr->refill_lock);
-                       if (last_ptr->block_group &&
-                           (last_ptr->block_group->ro ||
-                           !block_group_bits(last_ptr->block_group, data))) {
-                               offset = 0;
+                       if (!last_ptr->block_group ||
+                           last_ptr->block_group->ro ||
+                           !block_group_bits(last_ptr->block_group, data))
                                goto refill_cluster;
-                       }
 
                        offset = btrfs_alloc_from_cluster(block_group, last_ptr,
                                                 num_bytes, search_start);
@@ -5303,7 +5354,7 @@ refill_cluster:
                        /* allocate a cluster in this block group */
                        ret = btrfs_find_space_cluster(trans, root,
                                               block_group, last_ptr,
-                                              offset, num_bytes,
+                                              search_start, num_bytes,
                                               empty_cluster + empty_size);
                        if (ret == 0) {
                                /*
index 1f87c4d0e7a072c6361fb218b32f024b111bb0a8..be1bf627a14b292655ad10a4478c015d2bff9a44 100644 (file)
@@ -2285,16 +2285,22 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                                clean_io_failure(start, page);
                }
                if (!uptodate) {
-                       u64 failed_mirror;
-                       failed_mirror = (u64)bio->bi_bdev;
-                       if (tree->ops && tree->ops->readpage_io_failed_hook)
-                               ret = tree->ops->readpage_io_failed_hook(
-                                               bio, page, start, end,
-                                               failed_mirror, state);
-                       else
-                               ret = bio_readpage_error(bio, page, start, end,
-                                                        failed_mirror, NULL);
+                       int failed_mirror;
+                       failed_mirror = (int)(unsigned long)bio->bi_bdev;
+                       /*
+                        * The generic bio_readpage_error handles errors the
+                        * following way: If possible, new read requests are
+                        * created and submitted and will end up in
+                        * end_bio_extent_readpage as well (if we're lucky, not
+                        * in the !uptodate case). In that case it returns 0 and
+                        * we just go on with the next page in our bio. If it
+                        * can't handle the error it will return -EIO and we
+                        * remain responsible for that page.
+                        */
+                       ret = bio_readpage_error(bio, page, start, end,
+                                                       failed_mirror, NULL);
                        if (ret == 0) {
+error_handled:
                                uptodate =
                                        test_bit(BIO_UPTODATE, &bio->bi_flags);
                                if (err)
@@ -2302,6 +2308,13 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                                uncache_state(&cached);
                                continue;
                        }
+                       if (tree->ops && tree->ops->readpage_io_failed_hook) {
+                               ret = tree->ops->readpage_io_failed_hook(
+                                                       bio, page, start, end,
+                                                       failed_mirror, state);
+                               if (ret == 0)
+                                       goto error_handled;
+                       }
                }
 
                if (uptodate) {
@@ -3366,6 +3379,9 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                return -ENOMEM;
        path->leave_spinning = 1;
 
+       start = ALIGN(start, BTRFS_I(inode)->root->sectorsize);
+       len = ALIGN(len, BTRFS_I(inode)->root->sectorsize);
+
        /*
         * lookup the last file extent.  We're not using i_size here
         * because there might be preallocation past i_size
@@ -3413,7 +3429,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0,
                         &cached_state, GFP_NOFS);
 
-       em = get_extent_skip_holes(inode, off, last_for_get_extent,
+       em = get_extent_skip_holes(inode, start, last_for_get_extent,
                                   get_extent);
        if (!em)
                goto out;
index feb9be0e23bcca09a77497d08c74a3c8864d2a8c..7604c30013227fd823b1523503f8faaeccf283c4 100644 (file)
@@ -70,7 +70,7 @@ struct extent_io_ops {
                              unsigned long bio_flags);
        int (*readpage_io_hook)(struct page *page, u64 start, u64 end);
        int (*readpage_io_failed_hook)(struct bio *bio, struct page *page,
-                                      u64 start, u64 end, u64 failed_mirror,
+                                      u64 start, u64 end, int failed_mirror,
                                       struct extent_state *state);
        int (*writepage_io_failed_hook)(struct bio *bio, struct page *page,
                                        u64 start, u64 end,
index 181760f9d2abb7aa0902a65cc93effb3f3d1b41d..ec23d43d0c357870a14bf6e79a0ce5baeb93a43d 100644 (file)
@@ -351,6 +351,11 @@ static int io_ctl_prepare_pages(struct io_ctl *io_ctl, struct inode *inode,
                }
        }
 
+       for (i = 0; i < io_ctl->num_pages; i++) {
+               clear_page_dirty_for_io(io_ctl->pages[i]);
+               set_page_extent_mapped(io_ctl->pages[i]);
+       }
+
        return 0;
 }
 
@@ -1465,6 +1470,7 @@ static void add_new_bitmap(struct btrfs_free_space_ctl *ctl,
 {
        info->offset = offset_to_bitmap(ctl, offset);
        info->bytes = 0;
+       INIT_LIST_HEAD(&info->list);
        link_free_space(ctl, info);
        ctl->total_bitmaps++;
 
@@ -1844,7 +1850,13 @@ again:
                info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset),
                                          1, 0);
                if (!info) {
-                       WARN_ON(1);
+                       /* the tree logging code might be calling us before we
+                        * have fully loaded the free space rbtree for this
+                        * block group.  So it is possible the entry won't
+                        * be in the rbtree yet at all.  The caching code
+                        * will make sure not to put it in the rbtree if
+                        * the logging code has pinned it.
+                        */
                        goto out_lock;
                }
        }
@@ -2308,6 +2320,7 @@ again:
 
        if (!found) {
                start = i;
+               cluster->max_size = 0;
                found = true;
        }
 
@@ -2451,16 +2464,23 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
 {
        struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
        struct btrfs_free_space *entry;
-       struct rb_node *node;
        int ret = -ENOSPC;
+       u64 bitmap_offset = offset_to_bitmap(ctl, offset);
 
        if (ctl->total_bitmaps == 0)
                return -ENOSPC;
 
        /*
-        * First check our cached list of bitmaps and see if there is an entry
-        * here that will work.
+        * The bitmap that covers offset won't be in the list unless offset
+        * is just its start offset.
         */
+       entry = list_first_entry(bitmaps, struct btrfs_free_space, list);
+       if (entry->offset != bitmap_offset) {
+               entry = tree_search_offset(ctl, bitmap_offset, 1, 0);
+               if (entry && list_empty(&entry->list))
+                       list_add(&entry->list, bitmaps);
+       }
+
        list_for_each_entry(entry, bitmaps, list) {
                if (entry->bytes < min_bytes)
                        continue;
@@ -2471,38 +2491,10 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
        }
 
        /*
-        * If we do have entries on our list and we are here then we didn't find
-        * anything, so go ahead and get the next entry after the last entry in
-        * this list and start the search from there.
+        * The bitmaps list has all the bitmaps that record free space
+        * starting after offset, so no more search is required.
         */
-       if (!list_empty(bitmaps)) {
-               entry = list_entry(bitmaps->prev, struct btrfs_free_space,
-                                  list);
-               node = rb_next(&entry->offset_index);
-               if (!node)
-                       return -ENOSPC;
-               entry = rb_entry(node, struct btrfs_free_space, offset_index);
-               goto search;
-       }
-
-       entry = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 0, 1);
-       if (!entry)
-               return -ENOSPC;
-
-search:
-       node = &entry->offset_index;
-       do {
-               entry = rb_entry(node, struct btrfs_free_space, offset_index);
-               node = rb_next(&entry->offset_index);
-               if (!entry->bitmap)
-                       continue;
-               if (entry->bytes < min_bytes)
-                       continue;
-               ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset,
-                                          bytes, min_bytes);
-       } while (ret && node);
-
-       return ret;
+       return -ENOSPC;
 }
 
 /*
@@ -2520,8 +2512,8 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
                             u64 offset, u64 bytes, u64 empty_size)
 {
        struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
-       struct list_head bitmaps;
        struct btrfs_free_space *entry, *tmp;
+       LIST_HEAD(bitmaps);
        u64 min_bytes;
        int ret;
 
@@ -2560,7 +2552,6 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       INIT_LIST_HEAD(&bitmaps);
        ret = setup_cluster_no_bitmap(block_group, cluster, &bitmaps, offset,
                                      bytes, min_bytes);
        if (ret)
index 116ab67a06dfcae9929669392f7267ed925c806b..2c984f7d4c2ac581787ecb6a11962d3e6fd1df75 100644 (file)
@@ -3490,7 +3490,7 @@ void btrfs_evict_inode(struct inode *inode)
         * doing the truncate.
         */
        while (1) {
-               ret = btrfs_block_rsv_refill(root, rsv, min_size);
+               ret = btrfs_block_rsv_refill_noflush(root, rsv, min_size);
 
                /*
                 * Try and steal from the global reserve since we will
@@ -6794,11 +6794,13 @@ static int btrfs_getattr(struct vfsmount *mnt,
                         struct dentry *dentry, struct kstat *stat)
 {
        struct inode *inode = dentry->d_inode;
+       u32 blocksize = inode->i_sb->s_blocksize;
+
        generic_fillattr(inode, stat);
        stat->dev = BTRFS_I(inode)->root->anon_dev;
        stat->blksize = PAGE_CACHE_SIZE;
-       stat->blocks = (inode_get_bytes(inode) +
-                       BTRFS_I(inode)->delalloc_bytes) >> 9;
+       stat->blocks = (ALIGN(inode_get_bytes(inode), blocksize) +
+               ALIGN(BTRFS_I(inode)->delalloc_bytes, blocksize)) >> 9;
        return 0;
 }
 
index 4a34c472f1261bea0c3c228e9800d04a26a6d714..72d461656f606647292657f2367ee438a50d2a40 100644 (file)
@@ -1216,12 +1216,12 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
                *devstr = '\0';
                devstr = vol_args->name;
                devid = simple_strtoull(devstr, &end, 10);
-               printk(KERN_INFO "resizing devid %llu\n",
+               printk(KERN_INFO "btrfs: resizing devid %llu\n",
                       (unsigned long long)devid);
        }
        device = btrfs_find_device(root, devid, NULL, NULL);
        if (!device) {
-               printk(KERN_INFO "resizer unable to find device %llu\n",
+               printk(KERN_INFO "btrfs: resizer unable to find device %llu\n",
                       (unsigned long long)devid);
                ret = -EINVAL;
                goto out_unlock;
@@ -1267,7 +1267,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
        do_div(new_size, root->sectorsize);
        new_size *= root->sectorsize;
 
-       printk(KERN_INFO "new size for %s is %llu\n",
+       printk(KERN_INFO "btrfs: new size for %s is %llu\n",
                device->name, (unsigned long long)new_size);
 
        if (new_size > old_size) {
@@ -1278,7 +1278,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
                }
                ret = btrfs_grow_device(trans, device, new_size);
                btrfs_commit_transaction(trans, root);
-       } else {
+       } else if (new_size < old_size) {
                ret = btrfs_shrink_device(device, new_size);
        }
 
@@ -2930,11 +2930,13 @@ static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg)
                goto out;
 
        for (i = 0; i < ipath->fspath->elem_cnt; ++i) {
-               rel_ptr = ipath->fspath->val[i] - (u64)ipath->fspath->val;
+               rel_ptr = ipath->fspath->val[i] -
+                         (u64)(unsigned long)ipath->fspath->val;
                ipath->fspath->val[i] = rel_ptr;
        }
 
-       ret = copy_to_user((void *)ipa->fspath, (void *)ipath->fspath, size);
+       ret = copy_to_user((void *)(unsigned long)ipa->fspath,
+                          (void *)(unsigned long)ipath->fspath, size);
        if (ret) {
                ret = -EFAULT;
                goto out;
@@ -3017,7 +3019,8 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
        if (ret < 0)
                goto out;
 
-       ret = copy_to_user((void *)loi->inodes, (void *)inodes, size);
+       ret = copy_to_user((void *)(unsigned long)loi->inodes,
+                          (void *)(unsigned long)inodes, size);
        if (ret)
                ret = -EFAULT;
 
index f4190f22edfb2663d345d9189ee2c618804f885b..c27bcb67f3304d806ab7e90cef8c3bcdef78b19c 100644 (file)
@@ -256,6 +256,11 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, void *ctx)
        btrfs_release_path(swarn->path);
 
        ipath = init_ipath(4096, local_root, swarn->path);
+       if (IS_ERR(ipath)) {
+               ret = PTR_ERR(ipath);
+               ipath = NULL;
+               goto err;
+       }
        ret = paths_from_inode(inum, ipath);
 
        if (ret < 0)
@@ -272,7 +277,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, void *ctx)
                        swarn->logical, swarn->dev->name,
                        (unsigned long long)swarn->sector, root, inum, offset,
                        min(isize - offset, (u64)PAGE_SIZE), nlink,
-                       (char *)ipath->fspath->val[i]);
+                       (char *)(unsigned long)ipath->fspath->val[i]);
 
        free_ipath(ipath);
        return 0;
index 8bd9d6d0e07ae97cc2060cb0695468635b422a7e..e28ad4baf483af6b4c7e5d8450dc4a73909d0247 100644 (file)
@@ -825,13 +825,9 @@ static char *setup_root_args(char *args)
 static struct dentry *mount_subvol(const char *subvol_name, int flags,
                                   const char *device_name, char *data)
 {
-       struct super_block *s;
        struct dentry *root;
        struct vfsmount *mnt;
-       struct mnt_namespace *ns_private;
        char *newargs;
-       struct path path;
-       int error;
 
        newargs = setup_root_args(data);
        if (!newargs)
@@ -842,39 +838,17 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags,
        if (IS_ERR(mnt))
                return ERR_CAST(mnt);
 
-       ns_private = create_mnt_ns(mnt);
-       if (IS_ERR(ns_private)) {
-               mntput(mnt);
-               return ERR_CAST(ns_private);
-       }
+       root = mount_subtree(mnt, subvol_name);
 
-       /*
-        * This will trigger the automount of the subvol so we can just
-        * drop the mnt we have here and return the dentry that we
-        * found.
-        */
-       error = vfs_path_lookup(mnt->mnt_root, mnt, subvol_name,
-                               LOOKUP_FOLLOW, &path);
-       put_mnt_ns(ns_private);
-       if (error)
-               return ERR_PTR(error);
-
-       if (!is_subvolume_inode(path.dentry->d_inode)) {
-               path_put(&path);
-               mntput(mnt);
-               error = -EINVAL;
+       if (!IS_ERR(root) && !is_subvolume_inode(root->d_inode)) {
+               struct super_block *s = root->d_sb;
+               dput(root);
+               root = ERR_PTR(-EINVAL);
+               deactivate_locked_super(s);
                printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n",
                                subvol_name);
-               return ERR_PTR(-EINVAL);
        }
 
-       /* Get a ref to the sb and the dentry we found and return it */
-       s = path.mnt->mnt_sb;
-       atomic_inc(&s->s_active);
-       root = dget(path.dentry);
-       path_put(&path);
-       down_write(&s->s_umount);
-
        return root;
 }
 
@@ -1083,7 +1057,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
        int i = 0, nr_devices;
        int ret;
 
-       nr_devices = fs_info->fs_devices->rw_devices;
+       nr_devices = fs_info->fs_devices->open_devices;
        BUG_ON(!nr_devices);
 
        devices_info = kmalloc(sizeof(*devices_info) * nr_devices,
@@ -1105,8 +1079,8 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
        else
                min_stripe_size = BTRFS_STRIPE_LEN;
 
-       list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
-               if (!device->in_fs_metadata)
+       list_for_each_entry(device, &fs_devices->devices, dev_list) {
+               if (!device->in_fs_metadata || !device->bdev)
                        continue;
 
                avail_space = device->total_bytes - device->bytes_used;
index 6a0574e923bc6a33b4965976328222dcf0a61cb0..81376d94cd3c6a4639ebef35df501dbefbfb2435 100644 (file)
@@ -785,6 +785,10 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
 
                        btrfs_save_ino_cache(root, trans);
 
+                       /* see comments in should_cow_block() */
+                       root->force_cow = 0;
+                       smp_wmb();
+
                        if (root->commit_root != root->node) {
                                mutex_lock(&root->fs_commit_mutex);
                                switch_commit_root(root);
@@ -947,6 +951,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        btrfs_tree_unlock(old);
        free_extent_buffer(old);
 
+       /* see comments in should_cow_block() */
+       root->force_cow = 1;
+       smp_wmb();
+
        btrfs_set_root_node(new_root_item, tmp);
        /* record when the snapshot was created in key.offset */
        key.offset = trans->transid;
index ab5b1c49f3529e9e7e112649b98f22d0a923fb35..78f2d4d4f37fe81317395688a8b090b71e53a612 100644 (file)
@@ -100,6 +100,12 @@ struct btrfs_device {
        struct reada_zone *reada_curr_zone;
        struct radix_tree_root reada_zones;
        struct radix_tree_root reada_extents;
+
+       /* for sending down flush barriers */
+       struct bio *flush_bio;
+       struct completion flush_wait;
+       int nobarriers;
+
 };
 
 struct btrfs_fs_devices {
index 2abd0dfad7f8093c252e572d90fdd42991b410be..bca3948e9dbf6758746c896359471f4730407e24 100644 (file)
@@ -1143,7 +1143,7 @@ static void ceph_d_prune(struct dentry *dentry)
 {
        struct ceph_dentry_info *di;
 
-       dout("d_release %p\n", dentry);
+       dout("ceph_d_prune %p\n", dentry);
 
        /* do we have a valid parent? */
        if (!dentry->d_parent || IS_ROOT(dentry))
index e392bfce84a3cc6873f1439ba8dd5f28fd0cd935..116f36502f178f5ce0475bdfdd77073e9452e614 100644 (file)
@@ -1328,12 +1328,13 @@ int ceph_inode_set_size(struct inode *inode, loff_t size)
  */
 void ceph_queue_writeback(struct inode *inode)
 {
+       ihold(inode);
        if (queue_work(ceph_inode_to_client(inode)->wb_wq,
                       &ceph_inode(inode)->i_wb_work)) {
                dout("ceph_queue_writeback %p\n", inode);
-               ihold(inode);
        } else {
                dout("ceph_queue_writeback %p failed\n", inode);
+               iput(inode);
        }
 }
 
@@ -1353,12 +1354,13 @@ static void ceph_writeback_work(struct work_struct *work)
  */
 void ceph_queue_invalidate(struct inode *inode)
 {
+       ihold(inode);
        if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
                       &ceph_inode(inode)->i_pg_inv_work)) {
                dout("ceph_queue_invalidate %p\n", inode);
-               ihold(inode);
        } else {
                dout("ceph_queue_invalidate %p failed\n", inode);
+               iput(inode);
        }
 }
 
@@ -1434,13 +1436,14 @@ void ceph_queue_vmtruncate(struct inode *inode)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
 
+       ihold(inode);
        if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq,
                       &ci->i_vmtruncate_work)) {
                dout("ceph_queue_vmtruncate %p\n", inode);
-               ihold(inode);
        } else {
                dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
                     inode, ci->i_truncate_pending);
+               iput(inode);
        }
 }
 
index a90846fac759bd744620a8d87789e9a56db02c48..8dc73a594a90c11e31f20ef925104ea10e5b0b15 100644 (file)
@@ -638,10 +638,12 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
        if (err == 0) {
                dout("open_root_inode success\n");
                if (ceph_ino(req->r_target_inode) == CEPH_INO_ROOT &&
-                   fsc->sb->s_root == NULL)
+                   fsc->sb->s_root == NULL) {
                        root = d_alloc_root(req->r_target_inode);
-               else
+                       ceph_init_dentry(root);
+               } else {
                        root = d_obtain_alias(req->r_target_inode);
+               }
                req->r_target_inode = NULL;
                dout("open_root_inode success, root dentry is %p\n", root);
        } else {
index a901c6901bce1cf0a8b1823e8c87d83424594474..10ba92def3f675985871f0fc72e9c6d7126357a3 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/bit_spinlock.h>
 #include <linux/rculist_bl.h>
 #include <linux/prefetch.h>
+#include <linux/ratelimit.h>
 #include "internal.h"
 
 /*
@@ -2383,8 +2384,16 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
                                actual = __d_unalias(inode, dentry, alias);
                        }
                        write_sequnlock(&rename_lock);
-                       if (IS_ERR(actual))
+                       if (IS_ERR(actual)) {
+                               if (PTR_ERR(actual) == -ELOOP)
+                                       pr_warn_ratelimited(
+                                               "VFS: Lookup of '%s' in %s %s"
+                                               " would have caused loop\n",
+                                               dentry->d_name.name,
+                                               inode->i_sb->s_type->name,
+                                               inode->i_sb->s_id);
                                dput(alias);
+                       }
                        goto out_nolock;
                }
        }
index 58609bde3b9fc076187afa3317582788f2f6bc7f..2a834255c75de911b7e1f8eb10026972913e14b4 100644 (file)
@@ -967,7 +967,7 @@ static void ecryptfs_set_default_crypt_stat_vals(
 
 /**
  * ecryptfs_new_file_context
- * @ecryptfs_dentry: The eCryptfs dentry
+ * @ecryptfs_inode: The eCryptfs inode
  *
  * If the crypto context for the file has not yet been established,
  * this is where we do that.  Establishing a new crypto context
@@ -984,13 +984,13 @@ static void ecryptfs_set_default_crypt_stat_vals(
  *
  * Returns zero on success; non-zero otherwise
  */
-int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
+int ecryptfs_new_file_context(struct inode *ecryptfs_inode)
 {
        struct ecryptfs_crypt_stat *crypt_stat =
-           &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+           &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
            &ecryptfs_superblock_to_private(
-                   ecryptfs_dentry->d_sb)->mount_crypt_stat;
+                   ecryptfs_inode->i_sb)->mount_crypt_stat;
        int cipher_name_len;
        int rc = 0;
 
@@ -1299,12 +1299,12 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
 }
 
 static int
-ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry,
+ecryptfs_write_metadata_to_contents(struct inode *ecryptfs_inode,
                                    char *virt, size_t virt_len)
 {
        int rc;
 
-       rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt,
+       rc = ecryptfs_write_lower(ecryptfs_inode, virt,
                                  0, virt_len);
        if (rc < 0)
                printk(KERN_ERR "%s: Error attempting to write header "
@@ -1338,7 +1338,8 @@ static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask,
 
 /**
  * ecryptfs_write_metadata
- * @ecryptfs_dentry: The eCryptfs dentry
+ * @ecryptfs_dentry: The eCryptfs dentry, which should be negative
+ * @ecryptfs_inode: The newly created eCryptfs inode
  *
  * Write the file headers out.  This will likely involve a userspace
  * callout, in which the session key is encrypted with one or more
@@ -1348,10 +1349,11 @@ static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask,
  *
  * Returns zero on success; non-zero on error
  */
-int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
+int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
+                           struct inode *ecryptfs_inode)
 {
        struct ecryptfs_crypt_stat *crypt_stat =
-               &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+               &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
        unsigned int order;
        char *virt;
        size_t virt_len;
@@ -1391,7 +1393,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt,
                                                      size);
        else
-               rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt,
+               rc = ecryptfs_write_metadata_to_contents(ecryptfs_inode, virt,
                                                         virt_len);
        if (rc) {
                printk(KERN_ERR "%s: Error writing metadata out to lower file; "
@@ -1943,7 +1945,7 @@ static unsigned char *portable_filename_chars = ("-.0123456789ABCD"
 
 /* We could either offset on every reverse map or just pad some 0x00's
  * at the front here */
-static const unsigned char filename_rev_map[] = {
+static const unsigned char filename_rev_map[256] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 15 */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 23 */
@@ -1959,7 +1961,7 @@ static const unsigned char filename_rev_map[] = {
        0x00, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, /* 103 */
        0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, /* 111 */
        0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, /* 119 */
-       0x3D, 0x3E, 0x3F
+       0x3D, 0x3E, 0x3F /* 123 - 255 initialized to 0x00 */
 };
 
 /**
index 54481a3b2c7960e6ba205696c9d69ec44b331194..a9f29b12fbf290ba4987f778e582357d38ae1258 100644 (file)
@@ -584,9 +584,10 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
 int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode);
 int ecryptfs_encrypt_page(struct page *page);
 int ecryptfs_decrypt_page(struct page *page);
-int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
+int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
+                           struct inode *ecryptfs_inode);
 int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
-int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+int ecryptfs_new_file_context(struct inode *ecryptfs_inode);
 void ecryptfs_write_crypt_stat_flags(char *page_virt,
                                     struct ecryptfs_crypt_stat *crypt_stat,
                                     size_t *written);
index c6ac98cf9baaeca5d898cce216aa0dc08df2716c..d3f95f941c47e68a1d0a2cbe60371f148d64e124 100644 (file)
@@ -139,6 +139,27 @@ out:
        return rc;
 }
 
+static void ecryptfs_vma_close(struct vm_area_struct *vma)
+{
+       filemap_write_and_wait(vma->vm_file->f_mapping);
+}
+
+static const struct vm_operations_struct ecryptfs_file_vm_ops = {
+       .close          = ecryptfs_vma_close,
+       .fault          = filemap_fault,
+};
+
+static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       int rc;
+
+       rc = generic_file_mmap(file, vma);
+       if (!rc)
+               vma->vm_ops = &ecryptfs_file_vm_ops;
+
+       return rc;
+}
+
 struct kmem_cache *ecryptfs_file_info_cache;
 
 /**
@@ -349,7 +370,7 @@ const struct file_operations ecryptfs_main_fops = {
 #ifdef CONFIG_COMPAT
        .compat_ioctl = ecryptfs_compat_ioctl,
 #endif
-       .mmap = generic_file_mmap,
+       .mmap = ecryptfs_file_mmap,
        .open = ecryptfs_open,
        .flush = ecryptfs_flush,
        .release = ecryptfs_release,
index a36d327f15215e471628e2fda253e84ccd6100e9..32f90a3ae63eb85bc6d162aa16f28d48b3cdac7f 100644 (file)
@@ -172,22 +172,23 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
  * it. It will also update the eCryptfs directory inode to mimic the
  * stat of the lower directory inode.
  *
- * Returns zero on success; non-zero on error condition
+ * Returns the new eCryptfs inode on success; an ERR_PTR on error condition
  */
-static int
+static struct inode *
 ecryptfs_do_create(struct inode *directory_inode,
                   struct dentry *ecryptfs_dentry, int mode)
 {
        int rc;
        struct dentry *lower_dentry;
        struct dentry *lower_dir_dentry;
+       struct inode *inode;
 
        lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
        lower_dir_dentry = lock_parent(lower_dentry);
        if (IS_ERR(lower_dir_dentry)) {
                ecryptfs_printk(KERN_ERR, "Error locking directory of "
                                "dentry\n");
-               rc = PTR_ERR(lower_dir_dentry);
+               inode = ERR_CAST(lower_dir_dentry);
                goto out;
        }
        rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
@@ -195,20 +196,19 @@ ecryptfs_do_create(struct inode *directory_inode,
        if (rc) {
                printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
                       "rc = [%d]\n", __func__, rc);
+               inode = ERR_PTR(rc);
                goto out_lock;
        }
-       rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
-                               directory_inode->i_sb);
-       if (rc) {
-               ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n");
+       inode = __ecryptfs_get_inode(lower_dentry->d_inode,
+                                    directory_inode->i_sb);
+       if (IS_ERR(inode))
                goto out_lock;
-       }
        fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode);
        fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode);
 out_lock:
        unlock_dir(lower_dir_dentry);
 out:
-       return rc;
+       return inode;
 }
 
 /**
@@ -219,26 +219,26 @@ out:
  *
  * Returns zero on success
  */
-static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
+static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
+                                   struct inode *ecryptfs_inode)
 {
        struct ecryptfs_crypt_stat *crypt_stat =
-               &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+               &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
        int rc = 0;
 
-       if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
+       if (S_ISDIR(ecryptfs_inode->i_mode)) {
                ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
                crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
                goto out;
        }
        ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
-       rc = ecryptfs_new_file_context(ecryptfs_dentry);
+       rc = ecryptfs_new_file_context(ecryptfs_inode);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error creating new file "
                                "context; rc = [%d]\n", rc);
                goto out;
        }
-       rc = ecryptfs_get_lower_file(ecryptfs_dentry,
-                                    ecryptfs_dentry->d_inode);
+       rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode);
        if (rc) {
                printk(KERN_ERR "%s: Error attempting to initialize "
                        "the lower file for the dentry with name "
@@ -246,10 +246,10 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
                        ecryptfs_dentry->d_name.name, rc);
                goto out;
        }
-       rc = ecryptfs_write_metadata(ecryptfs_dentry);
+       rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode);
        if (rc)
                printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
-       ecryptfs_put_lower_file(ecryptfs_dentry->d_inode);
+       ecryptfs_put_lower_file(ecryptfs_inode);
 out:
        return rc;
 }
@@ -269,18 +269,28 @@ static int
 ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
                int mode, struct nameidata *nd)
 {
+       struct inode *ecryptfs_inode;
        int rc;
 
-       /* ecryptfs_do_create() calls ecryptfs_interpose() */
-       rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode);
-       if (unlikely(rc)) {
+       ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry,
+                                           mode);
+       if (unlikely(IS_ERR(ecryptfs_inode))) {
                ecryptfs_printk(KERN_WARNING, "Failed to create file in"
                                "lower filesystem\n");
+               rc = PTR_ERR(ecryptfs_inode);
                goto out;
        }
        /* At this point, a file exists on "disk"; we need to make sure
         * that this on disk file is prepared to be an ecryptfs file */
-       rc = ecryptfs_initialize_file(ecryptfs_dentry);
+       rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode);
+       if (rc) {
+               drop_nlink(ecryptfs_inode);
+               unlock_new_inode(ecryptfs_inode);
+               iput(ecryptfs_inode);
+               goto out;
+       }
+       d_instantiate(ecryptfs_dentry, ecryptfs_inode);
+       unlock_new_inode(ecryptfs_inode);
 out:
        return rc;
 }
index f6dba4505f1cc7e4f251f28a18bbeea5b3dcb2a7..12ccacda44e0288e13247e3e79ebd414287eb548 100644 (file)
@@ -565,7 +565,7 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
        brelse(bitmap_bh);
        printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu"
               ", computed = %llu, %llu\n",
-              EXT4_B2C(sbi, ext4_free_blocks_count(es)),
+              EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)),
               desc_count, bitmap_count);
        return bitmap_count;
 #else
index 240f6e2dc7eeb593e4143e05fc15e4565db155b1..848f436df29f6ffec6e8487549764d98c63d5b6b 100644 (file)
@@ -2270,6 +2270,7 @@ retry:
                        ext4_msg(inode->i_sb, KERN_CRIT, "%s: jbd2_start: "
                               "%ld pages, ino %lu; err %d", __func__,
                                wbc->nr_to_write, inode->i_ino, ret);
+                       blk_finish_plug(&plug);
                        goto out_writepages;
                }
 
@@ -2806,8 +2807,8 @@ out:
        spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
 
        /* queue the work to convert unwritten extents to written */
-       queue_work(wq, &io_end->work);
        iocb->private = NULL;
+       queue_work(wq, &io_end->work);
 
        /* XXX: probably should move into the real I/O completion handler */
        inode_dio_done(inode);
index 9953d80145ad0f6331086053a7d80301c418f3a7..3858767ec672ef214ad5f288f30932ee0b5d933a 100644 (file)
@@ -1683,7 +1683,9 @@ static int parse_options(char *options, struct super_block *sb,
                        data_opt = EXT4_MOUNT_WRITEBACK_DATA;
                datacheck:
                        if (is_remount) {
-                               if (test_opt(sb, DATA_FLAGS) != data_opt) {
+                               if (!sbi->s_journal)
+                                       ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option");
+                               else if (test_opt(sb, DATA_FLAGS) != data_opt) {
                                        ext4_msg(sb, KERN_ERR,
                                                "Cannot change data mode on remount");
                                        return 0;
@@ -3099,8 +3101,6 @@ static void ext4_destroy_lazyinit_thread(void)
 }
 
 static int ext4_fill_super(struct super_block *sb, void *data, int silent)
-                               __releases(kernel_lock)
-                               __acquires(kernel_lock)
 {
        char *orig_data = kstrdup(data, GFP_KERNEL);
        struct buffer_head *bh;
index 3f32bcb0d9bd5beb882b67480ff3593d202f5837..ef175cb8cfd8e20be4be8496660521a371297a50 100644 (file)
 #include <linux/bitops.h>
 #include <linux/sched.h>
 
-static const int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 };
-
 static DEFINE_SPINLOCK(bitmap_lock);
 
-static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, __u32 numbits)
+/*
+ * bitmap consists of blocks filled with 16bit words
+ * bit set == busy, bit clear == free
+ * endianness is a mess, but for counting zero bits it really doesn't matter...
+ */
+static __u32 count_free(struct buffer_head *map[], unsigned blocksize, __u32 numbits)
 {
-       unsigned i, j, sum = 0;
-       struct buffer_head *bh;
-  
-       for (i=0; i<numblocks-1; i++) {
-               if (!(bh=map[i])) 
-                       return(0);
-               for (j=0; j<bh->b_size; j++)
-                       sum += nibblemap[bh->b_data[j] & 0xf]
-                               + nibblemap[(bh->b_data[j]>>4) & 0xf];
-       }
+       __u32 sum = 0;
+       unsigned blocks = DIV_ROUND_UP(numbits, blocksize * 8);
 
-       if (numblocks==0 || !(bh=map[numblocks-1]))
-               return(0);
-       i = ((numbits - (numblocks-1) * bh->b_size * 8) / 16) * 2;
-       for (j=0; j<i; j++) {
-               sum += nibblemap[bh->b_data[j] & 0xf]
-                       + nibblemap[(bh->b_data[j]>>4) & 0xf];
+       while (blocks--) {
+               unsigned words = blocksize / 2;
+               __u16 *p = (__u16 *)(*map++)->b_data;
+               while (words--)
+                       sum += 16 - hweight16(*p++);
        }
 
-       i = numbits%16;
-       if (i!=0) {
-               i = *(__u16 *)(&bh->b_data[j]) | ~((1<<i) - 1);
-               sum += nibblemap[i & 0xf] + nibblemap[(i>>4) & 0xf];
-               sum += nibblemap[(i>>8) & 0xf] + nibblemap[(i>>12) & 0xf];
-       }
-       return(sum);
+       return sum;
 }
 
 void minix_free_block(struct inode *inode, unsigned long block)
@@ -105,10 +93,12 @@ int minix_new_block(struct inode * inode)
        return 0;
 }
 
-unsigned long minix_count_free_blocks(struct minix_sb_info *sbi)
+unsigned long minix_count_free_blocks(struct super_block *sb)
 {
-       return (count_free(sbi->s_zmap, sbi->s_zmap_blocks,
-               sbi->s_nzones - sbi->s_firstdatazone + 1)
+       struct minix_sb_info *sbi = minix_sb(sb);
+       u32 bits = sbi->s_nzones - (sbi->s_firstdatazone + 1);
+
+       return (count_free(sbi->s_zmap, sb->s_blocksize, bits)
                << sbi->s_log_zone_size);
 }
 
@@ -273,7 +263,10 @@ struct inode *minix_new_inode(const struct inode *dir, int mode, int *error)
        return inode;
 }
 
-unsigned long minix_count_free_inodes(struct minix_sb_info *sbi)
+unsigned long minix_count_free_inodes(struct super_block *sb)
 {
-       return count_free(sbi->s_imap, sbi->s_imap_blocks, sbi->s_ninodes + 1);
+       struct minix_sb_info *sbi = minix_sb(sb);
+       u32 bits = sbi->s_ninodes + 1;
+
+       return count_free(sbi->s_imap, sb->s_blocksize, bits);
 }
index 64cdcd662ffccca98fecad85103f10a2348a76bc..1d9e33966db089eb2ba5ed3f7aab9967bd2c0b4e 100644 (file)
@@ -279,6 +279,27 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
        else if (sbi->s_mount_state & MINIX_ERROR_FS)
                printk("MINIX-fs: mounting file system with errors, "
                        "running fsck is recommended\n");
+
+       /* Apparently minix can create filesystems that allocate more blocks for
+        * the bitmaps than needed.  We simply ignore that, but verify it didn't
+        * create one with not enough blocks and bail out if so.
+        */
+       block = minix_blocks_needed(sbi->s_ninodes, s->s_blocksize);
+       if (sbi->s_imap_blocks < block) {
+               printk("MINIX-fs: file system does not have enough "
+                               "imap blocks allocated.  Refusing to mount\n");
+               goto out_iput;
+       }
+
+       block = minix_blocks_needed(
+                       (sbi->s_nzones - (sbi->s_firstdatazone + 1)),
+                       s->s_blocksize);
+       if (sbi->s_zmap_blocks < block) {
+               printk("MINIX-fs: file system does not have enough "
+                               "zmap blocks allocated.  Refusing to mount.\n");
+               goto out_iput;
+       }
+
        return 0;
 
 out_iput:
@@ -339,10 +360,10 @@ static int minix_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_type = sb->s_magic;
        buf->f_bsize = sb->s_blocksize;
        buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size;
-       buf->f_bfree = minix_count_free_blocks(sbi);
+       buf->f_bfree = minix_count_free_blocks(sb);
        buf->f_bavail = buf->f_bfree;
        buf->f_files = sbi->s_ninodes;
-       buf->f_ffree = minix_count_free_inodes(sbi);
+       buf->f_ffree = minix_count_free_inodes(sb);
        buf->f_namelen = sbi->s_namelen;
        buf->f_fsid.val[0] = (u32)id;
        buf->f_fsid.val[1] = (u32)(id >> 32);
index 341e2122879a7604611426d4f702f211ee3ed59a..26bbd55e82ea2ab42f61fa2898fd45fee17f7074 100644 (file)
@@ -48,10 +48,10 @@ extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, stru
 extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **);
 extern struct inode * minix_new_inode(const struct inode *, int, int *);
 extern void minix_free_inode(struct inode * inode);
-extern unsigned long minix_count_free_inodes(struct minix_sb_info *sbi);
+extern unsigned long minix_count_free_inodes(struct super_block *sb);
 extern int minix_new_block(struct inode * inode);
 extern void minix_free_block(struct inode *inode, unsigned long block);
-extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi);
+extern unsigned long minix_count_free_blocks(struct super_block *sb);
 extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len);
 
@@ -88,6 +88,11 @@ static inline struct minix_inode_info *minix_i(struct inode *inode)
        return list_entry(inode, struct minix_inode_info, vfs_inode);
 }
 
+static inline unsigned minix_blocks_needed(unsigned bits, unsigned blocksize)
+{
+       return DIV_ROUND_UP(bits, blocksize * 8);
+}
+
 #if defined(CONFIG_MINIX_FS_NATIVE_ENDIAN) && \
        defined(CONFIG_MINIX_FS_BIG_ENDIAN_16BIT_INDEXED)
 
@@ -125,7 +130,7 @@ static inline int minix_find_first_zero_bit(const void *vaddr, unsigned size)
        if (!size)
                return 0;
 
-       size = (size >> 4) + ((size & 15) > 0);
+       size >>= 4;
        while (*p++ == 0xffff) {
                if (--size == 0)
                        return (p - addr) << 4;
index e5e1c7d1839b791f0c52428a9ffe058bd7ded092..6d3a1963879b0f13fd4929195a19c958d9deb4bb 100644 (file)
@@ -2483,11 +2483,43 @@ struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt)
                __mnt_make_longterm(mnt);
                new_ns->root = mnt;
                list_add(&new_ns->list, &new_ns->root->mnt_list);
+       } else {
+               mntput(mnt);
        }
        return new_ns;
 }
 EXPORT_SYMBOL(create_mnt_ns);
 
+struct dentry *mount_subtree(struct vfsmount *mnt, const char *name)
+{
+       struct mnt_namespace *ns;
+       struct super_block *s;
+       struct path path;
+       int err;
+
+       ns = create_mnt_ns(mnt);
+       if (IS_ERR(ns))
+               return ERR_CAST(ns);
+
+       err = vfs_path_lookup(mnt->mnt_root, mnt,
+                       name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
+
+       put_mnt_ns(ns);
+
+       if (err)
+               return ERR_PTR(err);
+
+       /* trade a vfsmount reference for active sb one */
+       s = path.mnt->mnt_sb;
+       atomic_inc(&s->s_active);
+       mntput(path.mnt);
+       /* lock the sucker */
+       down_write(&s->s_umount);
+       /* ... and return the root of (sub)tree on it */
+       return path.dentry;
+}
+EXPORT_SYMBOL(mount_subtree);
+
 SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
                char __user *, type, unsigned long, flags, void __user *, data)
 {
index b238d95ac48c7b926ff1e02eae157ea09fa58a68..ac289909814768a626ad817dbf40627805e7899e 100644 (file)
@@ -1468,12 +1468,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                                res = NULL;
                                goto out;
                        /* This turned out not to be a regular file */
+                       case -EISDIR:
                        case -ENOTDIR:
                                goto no_open;
                        case -ELOOP:
                                if (!(nd->intent.open.flags & O_NOFOLLOW))
                                        goto no_open;
-                       /* case -EISDIR: */
                        /* case -EINVAL: */
                        default:
                                res = ERR_CAST(inode);
index 0a1f8312b4dcf0fe9272310f1ab6d00178cdd2a8..eca56d4b39c0ae82caf3abb117bb9ad5163ec1b3 100644 (file)
 
 #define NFSDBG_FACILITY                NFSDBG_FILE
 
-static int nfs_file_open(struct inode *, struct file *);
-static int nfs_file_release(struct inode *, struct file *);
-static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
-static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
-static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
-                                       struct pipe_inode_info *pipe,
-                                       size_t count, unsigned int flags);
-static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
-                               unsigned long nr_segs, loff_t pos);
-static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
-                                       struct file *filp, loff_t *ppos,
-                                       size_t count, unsigned int flags);
-static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
-                               unsigned long nr_segs, loff_t pos);
-static int  nfs_file_flush(struct file *, fl_owner_t id);
-static int  nfs_file_fsync(struct file *, loff_t, loff_t, int datasync);
-static int nfs_check_flags(int flags);
-static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
-static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
-static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
-
 static const struct vm_operations_struct nfs_file_vm_ops;
 
-const struct file_operations nfs_file_operations = {
-       .llseek         = nfs_file_llseek,
-       .read           = do_sync_read,
-       .write          = do_sync_write,
-       .aio_read       = nfs_file_read,
-       .aio_write      = nfs_file_write,
-       .mmap           = nfs_file_mmap,
-       .open           = nfs_file_open,
-       .flush          = nfs_file_flush,
-       .release        = nfs_file_release,
-       .fsync          = nfs_file_fsync,
-       .lock           = nfs_lock,
-       .flock          = nfs_flock,
-       .splice_read    = nfs_file_splice_read,
-       .splice_write   = nfs_file_splice_write,
-       .check_flags    = nfs_check_flags,
-       .setlease       = nfs_setlease,
-};
-
 const struct inode_operations nfs_file_inode_operations = {
        .permission     = nfs_permission,
        .getattr        = nfs_getattr,
@@ -886,3 +846,54 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
                        file->f_path.dentry->d_name.name, arg);
        return -EINVAL;
 }
+
+const struct file_operations nfs_file_operations = {
+       .llseek         = nfs_file_llseek,
+       .read           = do_sync_read,
+       .write          = do_sync_write,
+       .aio_read       = nfs_file_read,
+       .aio_write      = nfs_file_write,
+       .mmap           = nfs_file_mmap,
+       .open           = nfs_file_open,
+       .flush          = nfs_file_flush,
+       .release        = nfs_file_release,
+       .fsync          = nfs_file_fsync,
+       .lock           = nfs_lock,
+       .flock          = nfs_flock,
+       .splice_read    = nfs_file_splice_read,
+       .splice_write   = nfs_file_splice_write,
+       .check_flags    = nfs_check_flags,
+       .setlease       = nfs_setlease,
+};
+
+#ifdef CONFIG_NFS_V4
+static int
+nfs4_file_open(struct inode *inode, struct file *filp)
+{
+       /*
+        * NFSv4 opens are handled in d_lookup and d_revalidate. If we get to
+        * this point, then something is very wrong
+        */
+       dprintk("NFS: %s called! inode=%p filp=%p\n", __func__, inode, filp);
+       return -ENOTDIR;
+}
+
+const struct file_operations nfs4_file_operations = {
+       .llseek         = nfs_file_llseek,
+       .read           = do_sync_read,
+       .write          = do_sync_write,
+       .aio_read       = nfs_file_read,
+       .aio_write      = nfs_file_write,
+       .mmap           = nfs_file_mmap,
+       .open           = nfs4_file_open,
+       .flush          = nfs_file_flush,
+       .release        = nfs_file_release,
+       .fsync          = nfs_file_fsync,
+       .lock           = nfs_lock,
+       .flock          = nfs_flock,
+       .splice_read    = nfs_file_splice_read,
+       .splice_write   = nfs_file_splice_write,
+       .check_flags    = nfs_check_flags,
+       .setlease       = nfs_setlease,
+};
+#endif /* CONFIG_NFS_V4 */
index c07a55aec83867ee1489ff29134862bc891dfa82..50a15fa8cf985e41e21b786f4f6d9d9ed96cf37e 100644 (file)
@@ -291,7 +291,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                 */
                inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops;
                if (S_ISREG(inode->i_mode)) {
-                       inode->i_fop = &nfs_file_operations;
+                       inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
                        inode->i_data.a_ops = &nfs_file_aops;
                        inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info;
                } else if (S_ISDIR(inode->i_mode)) {
index c1a1bd8ddf1cbecfbba4f375fec6c78d5d36ae60..3f4d95751d52f3e152fc7f2dcb5d1a6d8fc2184b 100644 (file)
@@ -299,6 +299,8 @@ extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
 extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
                struct list_head *head);
 
+extern void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
+               struct inode *inode);
 extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
 extern void nfs_readdata_release(struct nfs_read_data *rdata);
 
index 85f1690ca08c110bcd1c1754e564f23619295a1a..d4bc9ed917484106dbed777942e0db096be08236 100644 (file)
@@ -853,6 +853,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
        .dentry_ops     = &nfs_dentry_operations,
        .dir_inode_ops  = &nfs3_dir_inode_operations,
        .file_inode_ops = &nfs3_file_inode_operations,
+       .file_ops       = &nfs_file_operations,
        .getroot        = nfs3_proc_get_root,
        .getattr        = nfs3_proc_getattr,
        .setattr        = nfs3_proc_setattr,
index b60fddf606f7d23e6f01305420446d74102001a7..be2bbac13817c7ec624363afb4caf8bdd65a72b4 100644 (file)
@@ -2464,8 +2464,7 @@ static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qst
                case -NFS4ERR_BADNAME:
                        return -ENOENT;
                case -NFS4ERR_MOVED:
-                       err = nfs4_get_referral(dir, name, fattr, fhandle);
-                       break;
+                       return nfs4_get_referral(dir, name, fattr, fhandle);
                case -NFS4ERR_WRONGSEC:
                        nfs_fixup_secinfo_attributes(fattr, fhandle);
                }
@@ -6253,6 +6252,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
        .dentry_ops     = &nfs4_dentry_operations,
        .dir_inode_ops  = &nfs4_dir_inode_operations,
        .file_inode_ops = &nfs4_file_inode_operations,
+       .file_ops       = &nfs4_file_operations,
        .getroot        = nfs4_proc_get_root,
        .getattr        = nfs4_proc_getattr,
        .setattr        = nfs4_proc_setattr,
index baf73536bc048e2085fabde5c2f523a6fbc3b523..8e672a2b2d693193e8ca7252d70c73578d739e0f 100644 (file)
@@ -1260,6 +1260,25 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
 }
 EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
 
+static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
+{
+       struct nfs_pageio_descriptor pgio;
+
+       put_lseg(data->lseg);
+       data->lseg = NULL;
+       dprintk("pnfs write error = %d\n", data->pnfs_error);
+
+       nfs_pageio_init_read_mds(&pgio, data->inode);
+
+       while (!list_empty(&data->pages)) {
+               struct nfs_page *req = nfs_list_entry(data->pages.next);
+
+               nfs_list_remove_request(req);
+               nfs_pageio_add_request(&pgio, req);
+       }
+       nfs_pageio_complete(&pgio);
+}
+
 /*
  * Called by non rpc-based layout drivers
  */
@@ -1268,11 +1287,8 @@ void pnfs_ld_read_done(struct nfs_read_data *data)
        if (likely(!data->pnfs_error)) {
                __nfs4_read_done_cb(data);
                data->mds_ops->rpc_call_done(&data->task, data);
-       } else {
-               put_lseg(data->lseg);
-               data->lseg = NULL;
-               dprintk("pnfs write error = %d\n", data->pnfs_error);
-       }
+       } else
+               pnfs_ld_handle_read_error(data);
        data->mds_ops->rpc_release(data);
 }
 EXPORT_SYMBOL_GPL(pnfs_ld_read_done);
index ac40b8535d7e0e7493f13063afdbe57169837c9e..f48125da198a2d5a50bc0861805212a129427920 100644 (file)
@@ -710,6 +710,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
        .dentry_ops     = &nfs_dentry_operations,
        .dir_inode_ops  = &nfs_dir_inode_operations,
        .file_inode_ops = &nfs_file_inode_operations,
+       .file_ops       = &nfs_file_operations,
        .getroot        = nfs_proc_get_root,
        .getattr        = nfs_proc_getattr,
        .setattr        = nfs_proc_setattr,
index 8b48ec63f7229de8cb9435cfe82cc9d9876e6268..cfa175c223dcfa5b79ebf17b3d609649fbd7188d 100644 (file)
@@ -109,7 +109,7 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data)
        }
 }
 
-static void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
+void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
                struct inode *inode)
 {
        nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops,
@@ -534,23 +534,13 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata)
 static void nfs_readpage_release_full(void *calldata)
 {
        struct nfs_read_data *data = calldata;
-       struct nfs_pageio_descriptor pgio;
 
-       if (data->pnfs_error) {
-               nfs_pageio_init_read_mds(&pgio, data->inode);
-               pgio.pg_recoalesce = 1;
-       }
        while (!list_empty(&data->pages)) {
                struct nfs_page *req = nfs_list_entry(data->pages.next);
 
                nfs_list_remove_request(req);
-               if (!data->pnfs_error)
-                       nfs_readpage_release(req);
-               else
-                       nfs_pageio_add_request(&pgio, req);
+               nfs_readpage_release(req);
        }
-       if (data->pnfs_error)
-               nfs_pageio_complete(&pgio);
        nfs_readdata_release(calldata);
 }
 
index 480b3b6bf71ef82f122a433cbf3ec62d789c033a..134777406ee31938271db7ad0af8c8cb444e6fc9 100644 (file)
@@ -2787,43 +2787,18 @@ static void nfs_referral_loop_unprotect(void)
 static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
                const char *export_path)
 {
-       struct mnt_namespace *ns_private;
-       struct super_block *s;
        struct dentry *dentry;
-       struct path path;
-       int ret;
-
-       ns_private = create_mnt_ns(root_mnt);
-       ret = PTR_ERR(ns_private);
-       if (IS_ERR(ns_private))
-               goto out_mntput;
-
-       ret = nfs_referral_loop_protect();
-       if (ret != 0)
-               goto out_put_mnt_ns;
+       int ret = nfs_referral_loop_protect();
 
-       ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt,
-                       export_path, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
+       if (ret) {
+               mntput(root_mnt);
+               return ERR_PTR(ret);
+       }
 
+       dentry = mount_subtree(root_mnt, export_path);
        nfs_referral_loop_unprotect();
-       put_mnt_ns(ns_private);
-
-       if (ret != 0)
-               goto out_err;
-
-       s = path.mnt->mnt_sb;
-       atomic_inc(&s->s_active);
-       dentry = dget(path.dentry);
 
-       path_put(&path);
-       down_write(&s->s_umount);
        return dentry;
-out_put_mnt_ns:
-       put_mnt_ns(ns_private);
-out_mntput:
-       mntput(root_mnt);
-out_err:
-       return ERR_PTR(ret);
 }
 
 static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
index ed553c60de827e0ebad24e3501e0e00d21c82cfc..3165aebb43c87934b743ecf08e5f02cef586d771 100644 (file)
@@ -5699,7 +5699,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
                                           OCFS2_JOURNAL_ACCESS_WRITE);
        if (ret) {
                mlog_errno(ret);
-               goto out;
+               goto out_commit;
        }
 
        dquot_free_space_nodirty(inode,
index c1efe939c774e2c9b909892f6c95434d6da760ee..78b68af3b0e32627b1874277d8ae58003501acb5 100644 (file)
@@ -290,7 +290,15 @@ static int ocfs2_readpage(struct file *file, struct page *page)
        }
 
        if (down_read_trylock(&oi->ip_alloc_sem) == 0) {
+               /*
+                * Unlock the page and cycle ip_alloc_sem so that we don't
+                * busyloop waiting for ip_alloc_sem to unlock
+                */
                ret = AOP_TRUNCATED_PAGE;
+               unlock_page(page);
+               unlock = 0;
+               down_read(&oi->ip_alloc_sem);
+               up_read(&oi->ip_alloc_sem);
                goto out_inode_unlock;
        }
 
@@ -563,6 +571,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
 {
        struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
        int level;
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
 
        /* this io's submitter should not have unlocked this before we could */
        BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
@@ -570,6 +579,15 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
        if (ocfs2_iocb_is_sem_locked(iocb))
                ocfs2_iocb_clear_sem_locked(iocb);
 
+       if (ocfs2_iocb_is_unaligned_aio(iocb)) {
+               ocfs2_iocb_clear_unaligned_aio(iocb);
+
+               if (atomic_dec_and_test(&OCFS2_I(inode)->ip_unaligned_aio) &&
+                   waitqueue_active(wq)) {
+                       wake_up_all(wq);
+               }
+       }
+
        ocfs2_iocb_clear_rw_locked(iocb);
 
        level = ocfs2_iocb_rw_locked_level(iocb);
@@ -862,6 +880,12 @@ struct ocfs2_write_ctxt {
        struct page                     *w_pages[OCFS2_MAX_CTXT_PAGES];
        struct page                     *w_target_page;
 
+       /*
+        * w_target_locked is used for page_mkwrite path indicating no unlocking
+        * against w_target_page in ocfs2_write_end_nolock.
+        */
+       unsigned int                    w_target_locked:1;
+
        /*
         * ocfs2_write_end() uses this to know what the real range to
         * write in the target should be.
@@ -895,6 +919,24 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
 
 static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
 {
+       int i;
+
+       /*
+        * w_target_locked is only set to true in the page_mkwrite() case.
+        * The intent is to allow us to lock the target page from write_begin()
+        * to write_end(). The caller must hold a ref on w_target_page.
+        */
+       if (wc->w_target_locked) {
+               BUG_ON(!wc->w_target_page);
+               for (i = 0; i < wc->w_num_pages; i++) {
+                       if (wc->w_target_page == wc->w_pages[i]) {
+                               wc->w_pages[i] = NULL;
+                               break;
+                       }
+               }
+               mark_page_accessed(wc->w_target_page);
+               page_cache_release(wc->w_target_page);
+       }
        ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
 
        brelse(wc->w_di_bh);
@@ -1132,20 +1174,17 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
                         */
                        lock_page(mmap_page);
 
+                       /* Exit and let the caller retry */
                        if (mmap_page->mapping != mapping) {
+                               WARN_ON(mmap_page->mapping);
                                unlock_page(mmap_page);
-                               /*
-                                * Sanity check - the locking in
-                                * ocfs2_pagemkwrite() should ensure
-                                * that this code doesn't trigger.
-                                */
-                               ret = -EINVAL;
-                               mlog_errno(ret);
+                               ret = -EAGAIN;
                                goto out;
                        }
 
                        page_cache_get(mmap_page);
                        wc->w_pages[i] = mmap_page;
+                       wc->w_target_locked = true;
                } else {
                        wc->w_pages[i] = find_or_create_page(mapping, index,
                                                             GFP_NOFS);
@@ -1160,6 +1199,8 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
                        wc->w_target_page = wc->w_pages[i];
        }
 out:
+       if (ret)
+               wc->w_target_locked = false;
        return ret;
 }
 
@@ -1817,11 +1858,23 @@ try_again:
         */
        ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
                                         cluster_of_pages, mmap_page);
-       if (ret) {
+       if (ret && ret != -EAGAIN) {
                mlog_errno(ret);
                goto out_quota;
        }
 
+       /*
+        * ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
+        * the target page. In this case, we exit with no error and no target
+        * page. This will trigger the caller, page_mkwrite(), to re-try
+        * the operation.
+        */
+       if (ret == -EAGAIN) {
+               BUG_ON(wc->w_target_page);
+               ret = 0;
+               goto out_quota;
+       }
+
        ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos,
                                          len);
        if (ret) {
index 75cf3ad987a66d911c15234a803243185ccc5a94..ffb2da370a99d05dd4b919fc64a5483dbc2df7a3 100644 (file)
@@ -78,6 +78,7 @@ enum ocfs2_iocb_lock_bits {
        OCFS2_IOCB_RW_LOCK = 0,
        OCFS2_IOCB_RW_LOCK_LEVEL,
        OCFS2_IOCB_SEM,
+       OCFS2_IOCB_UNALIGNED_IO,
        OCFS2_IOCB_NUM_LOCKS
 };
 
@@ -91,4 +92,17 @@ enum ocfs2_iocb_lock_bits {
        clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
 #define ocfs2_iocb_is_sem_locked(iocb) \
        test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
+
+#define ocfs2_iocb_set_unaligned_aio(iocb) \
+       set_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_clear_unaligned_aio(iocb) \
+       clear_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_is_unaligned_aio(iocb) \
+       test_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+
+#define OCFS2_IOEND_WQ_HASH_SZ 37
+#define ocfs2_ioend_wq(v)   (&ocfs2__ioend_wq[((unsigned long)(v)) %\
+                                           OCFS2_IOEND_WQ_HASH_SZ])
+extern wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 #endif /* OCFS2_FILE_H */
index 9a3e6bbff27bd4839b487c2c14282fd9ef1a4675..a4e855e3690e6ab844d37788b71649975321cb19 100644 (file)
@@ -216,6 +216,7 @@ struct o2hb_region {
 
        struct list_head        hr_all_item;
        unsigned                hr_unclean_stop:1,
+                               hr_aborted_start:1,
                                hr_item_pinned:1,
                                hr_item_dropped:1;
 
@@ -254,6 +255,10 @@ struct o2hb_region {
         * a more complete api that doesn't lead to this sort of fragility. */
        atomic_t                hr_steady_iterations;
 
+       /* terminate o2hb thread if it does not reach steady state
+        * (hr_steady_iterations == 0) within hr_unsteady_iterations */
+       atomic_t                hr_unsteady_iterations;
+
        char                    hr_dev_name[BDEVNAME_SIZE];
 
        unsigned int            hr_timeout_ms;
@@ -324,6 +329,10 @@ static void o2hb_write_timeout(struct work_struct *work)
 
 static void o2hb_arm_write_timeout(struct o2hb_region *reg)
 {
+       /* Arm writeout only after thread reaches steady state */
+       if (atomic_read(&reg->hr_steady_iterations) != 0)
+               return;
+
        mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n",
             O2HB_MAX_WRITE_TIMEOUT_MS);
 
@@ -537,9 +546,14 @@ static int o2hb_verify_crc(struct o2hb_region *reg,
        return read == computed;
 }
 
-/* We want to make sure that nobody is heartbeating on top of us --
- * this will help detect an invalid configuration. */
-static void o2hb_check_last_timestamp(struct o2hb_region *reg)
+/*
+ * Compare the slot data with what we wrote in the last iteration.
+ * If the match fails, print an appropriate error message. This is to
+ * detect errors like... another node hearting on the same slot,
+ * flaky device that is losing writes, etc.
+ * Returns 1 if check succeeds, 0 otherwise.
+ */
+static int o2hb_check_own_slot(struct o2hb_region *reg)
 {
        struct o2hb_disk_slot *slot;
        struct o2hb_disk_heartbeat_block *hb_block;
@@ -548,13 +562,13 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg)
        slot = &reg->hr_slots[o2nm_this_node()];
        /* Don't check on our 1st timestamp */
        if (!slot->ds_last_time)
-               return;
+               return 0;
 
        hb_block = slot->ds_raw_block;
        if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time &&
            le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation &&
            hb_block->hb_node == slot->ds_node_num)
-               return;
+               return 1;
 
 #define ERRSTR1                "Another node is heartbeating on device"
 #define ERRSTR2                "Heartbeat generation mismatch on device"
@@ -574,6 +588,8 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg)
             (unsigned long long)slot->ds_last_time, hb_block->hb_node,
             (unsigned long long)le64_to_cpu(hb_block->hb_generation),
             (unsigned long long)le64_to_cpu(hb_block->hb_seq));
+
+       return 0;
 }
 
 static inline void o2hb_prepare_block(struct o2hb_region *reg,
@@ -719,17 +735,24 @@ static void o2hb_shutdown_slot(struct o2hb_disk_slot *slot)
        o2nm_node_put(node);
 }
 
-static void o2hb_set_quorum_device(struct o2hb_region *reg,
-                                  struct o2hb_disk_slot *slot)
+static void o2hb_set_quorum_device(struct o2hb_region *reg)
 {
-       assert_spin_locked(&o2hb_live_lock);
-
        if (!o2hb_global_heartbeat_active())
                return;
 
-       if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+       /* Prevent race with o2hb_heartbeat_group_drop_item() */
+       if (kthread_should_stop())
+               return;
+
+       /* Tag region as quorum only after thread reaches steady state */
+       if (atomic_read(&reg->hr_steady_iterations) != 0)
                return;
 
+       spin_lock(&o2hb_live_lock);
+
+       if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+               goto unlock;
+
        /*
         * A region can be added to the quorum only when it sees all
         * live nodes heartbeat on it. In other words, the region has been
@@ -737,13 +760,10 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
         */
        if (memcmp(reg->hr_live_node_bitmap, o2hb_live_node_bitmap,
                   sizeof(o2hb_live_node_bitmap)))
-               return;
-
-       if (slot->ds_changed_samples < O2HB_LIVE_THRESHOLD)
-               return;
+               goto unlock;
 
-       printk(KERN_NOTICE "o2hb: Region %s is now a quorum device\n",
-              config_item_name(&reg->hr_item));
+       printk(KERN_NOTICE "o2hb: Region %s (%s) is now a quorum device\n",
+              config_item_name(&reg->hr_item), reg->hr_dev_name);
 
        set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
 
@@ -754,6 +774,8 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
        if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
                           O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF)
                o2hb_region_unpin(NULL);
+unlock:
+       spin_unlock(&o2hb_live_lock);
 }
 
 static int o2hb_check_slot(struct o2hb_region *reg,
@@ -925,8 +947,6 @@ fire_callbacks:
                slot->ds_equal_samples = 0;
        }
 out:
-       o2hb_set_quorum_device(reg, slot);
-
        spin_unlock(&o2hb_live_lock);
 
        o2hb_run_event_list(&event);
@@ -957,7 +977,8 @@ static int o2hb_highest_node(unsigned long *nodes,
 
 static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
 {
-       int i, ret, highest_node, change = 0;
+       int i, ret, highest_node;
+       int membership_change = 0, own_slot_ok = 0;
        unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];
        unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
        struct o2hb_bio_wait_ctxt write_wc;
@@ -966,7 +987,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
                                       sizeof(configured_nodes));
        if (ret) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        /*
@@ -982,8 +1003,9 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
 
        highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES);
        if (highest_node >= O2NM_MAX_NODES) {
-               mlog(ML_NOTICE, "ocfs2_heartbeat: no configured nodes found!\n");
-               return -EINVAL;
+               mlog(ML_NOTICE, "o2hb: No configured nodes found!\n");
+               ret = -EINVAL;
+               goto bail;
        }
 
        /* No sense in reading the slots of nodes that don't exist
@@ -993,29 +1015,27 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
        ret = o2hb_read_slots(reg, highest_node + 1);
        if (ret < 0) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        /* With an up to date view of the slots, we can check that no
         * other node has been improperly configured to heartbeat in
         * our slot. */
-       o2hb_check_last_timestamp(reg);
+       own_slot_ok = o2hb_check_own_slot(reg);
 
        /* fill in the proper info for our next heartbeat */
        o2hb_prepare_block(reg, reg->hr_generation);
 
-       /* And fire off the write. Note that we don't wait on this I/O
-        * until later. */
        ret = o2hb_issue_node_write(reg, &write_wc);
        if (ret < 0) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        i = -1;
        while((i = find_next_bit(configured_nodes,
                                 O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) {
-               change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
+               membership_change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
        }
 
        /*
@@ -1030,18 +1050,39 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
                 * disk */
                mlog(ML_ERROR, "Write error %d on device \"%s\"\n",
                     write_wc.wc_error, reg->hr_dev_name);
-               return write_wc.wc_error;
+               ret = write_wc.wc_error;
+               goto bail;
        }
 
-       o2hb_arm_write_timeout(reg);
+       /* Skip disarming the timeout if own slot has stale/bad data */
+       if (own_slot_ok) {
+               o2hb_set_quorum_device(reg);
+               o2hb_arm_write_timeout(reg);
+       }
 
+bail:
        /* let the person who launched us know when things are steady */
-       if (!change && (atomic_read(&reg->hr_steady_iterations) != 0)) {
-               if (atomic_dec_and_test(&reg->hr_steady_iterations))
+       if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               if (!ret && own_slot_ok && !membership_change) {
+                       if (atomic_dec_and_test(&reg->hr_steady_iterations))
+                               wake_up(&o2hb_steady_queue);
+               }
+       }
+
+       if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               if (atomic_dec_and_test(&reg->hr_unsteady_iterations)) {
+                       printk(KERN_NOTICE "o2hb: Unable to stabilize "
+                              "heartbeart on region %s (%s)\n",
+                              config_item_name(&reg->hr_item),
+                              reg->hr_dev_name);
+                       atomic_set(&reg->hr_steady_iterations, 0);
+                       reg->hr_aborted_start = 1;
                        wake_up(&o2hb_steady_queue);
+                       ret = -EIO;
+               }
        }
 
-       return 0;
+       return ret;
 }
 
 /* Subtract b from a, storing the result in a. a *must* have a larger
@@ -1095,7 +1136,8 @@ static int o2hb_thread(void *data)
        /* Pin node */
        o2nm_depend_this_node();
 
-       while (!kthread_should_stop() && !reg->hr_unclean_stop) {
+       while (!kthread_should_stop() &&
+              !reg->hr_unclean_stop && !reg->hr_aborted_start) {
                /* We track the time spent inside
                 * o2hb_do_disk_heartbeat so that we avoid more than
                 * hr_timeout_ms between disk writes. On busy systems
@@ -1103,10 +1145,7 @@ static int o2hb_thread(void *data)
                 * likely to time itself out. */
                do_gettimeofday(&before_hb);
 
-               i = 0;
-               do {
-                       ret = o2hb_do_disk_heartbeat(reg);
-               } while (ret && ++i < 2);
+               ret = o2hb_do_disk_heartbeat(reg);
 
                do_gettimeofday(&after_hb);
                elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
@@ -1117,7 +1156,8 @@ static int o2hb_thread(void *data)
                     after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
                     elapsed_msec);
 
-               if (elapsed_msec < reg->hr_timeout_ms) {
+               if (!kthread_should_stop() &&
+                   elapsed_msec < reg->hr_timeout_ms) {
                        /* the kthread api has blocked signals for us so no
                         * need to record the return value. */
                        msleep_interruptible(reg->hr_timeout_ms - elapsed_msec);
@@ -1134,20 +1174,20 @@ static int o2hb_thread(void *data)
         * to timeout on this region when we could just as easily
         * write a clear generation - thus indicating to them that
         * this node has left this region.
-        *
-        * XXX: Should we skip this on unclean_stop? */
-       o2hb_prepare_block(reg, 0);
-       ret = o2hb_issue_node_write(reg, &write_wc);
-       if (ret == 0) {
-               o2hb_wait_on_io(reg, &write_wc);
-       } else {
-               mlog_errno(ret);
+        */
+       if (!reg->hr_unclean_stop && !reg->hr_aborted_start) {
+               o2hb_prepare_block(reg, 0);
+               ret = o2hb_issue_node_write(reg, &write_wc);
+               if (ret == 0)
+                       o2hb_wait_on_io(reg, &write_wc);
+               else
+                       mlog_errno(ret);
        }
 
        /* Unpin node */
        o2nm_undepend_this_node();
 
-       mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread exiting\n");
+       mlog(ML_HEARTBEAT|ML_KTHREAD, "o2hb thread exiting\n");
 
        return 0;
 }
@@ -1158,6 +1198,7 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
        struct o2hb_debug_buf *db = inode->i_private;
        struct o2hb_region *reg;
        unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long lts;
        char *buf = NULL;
        int i = -1;
        int out = 0;
@@ -1194,9 +1235,11 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
 
        case O2HB_DB_TYPE_REGION_ELAPSED_TIME:
                reg = (struct o2hb_region *)db->db_data;
-               out += snprintf(buf + out, PAGE_SIZE - out, "%u\n",
-                               jiffies_to_msecs(jiffies -
-                                                reg->hr_last_timeout_start));
+               lts = reg->hr_last_timeout_start;
+               /* If 0, it has never been set before */
+               if (lts)
+                       lts = jiffies_to_msecs(jiffies - lts);
+               out += snprintf(buf + out, PAGE_SIZE - out, "%lu\n", lts);
                goto done;
 
        case O2HB_DB_TYPE_REGION_PINNED:
@@ -1426,6 +1469,8 @@ static void o2hb_region_release(struct config_item *item)
        struct page *page;
        struct o2hb_region *reg = to_o2hb_region(item);
 
+       mlog(ML_HEARTBEAT, "hb region release (%s)\n", reg->hr_dev_name);
+
        if (reg->hr_tmp_block)
                kfree(reg->hr_tmp_block);
 
@@ -1792,7 +1837,10 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                        live_threshold <<= 1;
                spin_unlock(&o2hb_live_lock);
        }
-       atomic_set(&reg->hr_steady_iterations, live_threshold + 1);
+       ++live_threshold;
+       atomic_set(&reg->hr_steady_iterations, live_threshold);
+       /* unsteady_iterations is double the steady_iterations */
+       atomic_set(&reg->hr_unsteady_iterations, (live_threshold << 1));
 
        hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s",
                              reg->hr_item.ci_name);
@@ -1809,14 +1857,12 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
        ret = wait_event_interruptible(o2hb_steady_queue,
                                atomic_read(&reg->hr_steady_iterations) == 0);
        if (ret) {
-               /* We got interrupted (hello ptrace!).  Clean up */
-               spin_lock(&o2hb_live_lock);
-               hb_task = reg->hr_task;
-               reg->hr_task = NULL;
-               spin_unlock(&o2hb_live_lock);
+               atomic_set(&reg->hr_steady_iterations, 0);
+               reg->hr_aborted_start = 1;
+       }
 
-               if (hb_task)
-                       kthread_stop(hb_task);
+       if (reg->hr_aborted_start) {
+               ret = -EIO;
                goto out;
        }
 
@@ -1833,8 +1879,8 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                ret = -EIO;
 
        if (hb_task && o2hb_global_heartbeat_active())
-               printk(KERN_NOTICE "o2hb: Heartbeat started on region %s\n",
-                      config_item_name(&reg->hr_item));
+               printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n",
+                      config_item_name(&reg->hr_item), reg->hr_dev_name);
 
 out:
        if (filp)
@@ -2092,13 +2138,6 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
 
        /* stop the thread when the user removes the region dir */
        spin_lock(&o2hb_live_lock);
-       if (o2hb_global_heartbeat_active()) {
-               clear_bit(reg->hr_region_num, o2hb_region_bitmap);
-               clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
-               if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
-                       quorum_region = 1;
-               clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
-       }
        hb_task = reg->hr_task;
        reg->hr_task = NULL;
        reg->hr_item_dropped = 1;
@@ -2107,19 +2146,30 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
        if (hb_task)
                kthread_stop(hb_task);
 
+       if (o2hb_global_heartbeat_active()) {
+               spin_lock(&o2hb_live_lock);
+               clear_bit(reg->hr_region_num, o2hb_region_bitmap);
+               clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
+               if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+                       quorum_region = 1;
+               clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
+               spin_unlock(&o2hb_live_lock);
+               printk(KERN_NOTICE "o2hb: Heartbeat %s on region %s (%s)\n",
+                      ((atomic_read(&reg->hr_steady_iterations) == 0) ?
+                       "stopped" : "start aborted"), config_item_name(item),
+                      reg->hr_dev_name);
+       }
+
        /*
         * If we're racing a dev_write(), we need to wake them.  They will
         * check reg->hr_task
         */
        if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               reg->hr_aborted_start = 1;
                atomic_set(&reg->hr_steady_iterations, 0);
                wake_up(&o2hb_steady_queue);
        }
 
-       if (o2hb_global_heartbeat_active())
-               printk(KERN_NOTICE "o2hb: Heartbeat stopped on region %s\n",
-                      config_item_name(&reg->hr_item));
-
        config_item_put(item);
 
        if (!o2hb_global_heartbeat_active() || !quorum_region)
index 3a5835904b3db4d522c561908171f528bb74f6bd..dc45deb19e6885e56a1f5be46cbd39444c46f810 100644 (file)
@@ -47,6 +47,7 @@
 #define SC_DEBUG_NAME          "sock_containers"
 #define NST_DEBUG_NAME         "send_tracking"
 #define STATS_DEBUG_NAME       "stats"
+#define NODES_DEBUG_NAME       "connected_nodes"
 
 #define SHOW_SOCK_CONTAINERS   0
 #define SHOW_SOCK_STATS                1
@@ -55,6 +56,7 @@ static struct dentry *o2net_dentry;
 static struct dentry *sc_dentry;
 static struct dentry *nst_dentry;
 static struct dentry *stats_dentry;
+static struct dentry *nodes_dentry;
 
 static DEFINE_SPINLOCK(o2net_debug_lock);
 
@@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = {
        .release = sc_fop_release,
 };
 
-int o2net_debugfs_init(void)
+static int o2net_fill_bitmap(char *buf, int len)
 {
-       o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
-       if (!o2net_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       int i = -1, out = 0;
 
-       nst_dentry = debugfs_create_file(NST_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                        o2net_dentry, NULL,
-                                        &nst_seq_fops);
-       if (!nst_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       o2net_fill_node_map(map, sizeof(map));
 
-       sc_dentry = debugfs_create_file(SC_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                       o2net_dentry, NULL,
-                                       &sc_seq_fops);
-       if (!sc_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES)
+               out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i);
+       out += snprintf(buf + out, PAGE_SIZE - out, "\n");
 
-       stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                          o2net_dentry, NULL,
-                                          &stats_seq_fops);
-       if (!stats_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       return out;
+}
+
+static int nodes_fop_open(struct inode *inode, struct file *file)
+{
+       char *buf;
+
+       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE));
+
+       file->private_data = buf;
 
        return 0;
-bail:
-       debugfs_remove(stats_dentry);
-       debugfs_remove(sc_dentry);
-       debugfs_remove(nst_dentry);
-       debugfs_remove(o2net_dentry);
-       return -ENOMEM;
 }
 
+static int o2net_debug_release(struct inode *inode, struct file *file)
+{
+       kfree(file->private_data);
+       return 0;
+}
+
+static ssize_t o2net_debug_read(struct file *file, char __user *buf,
+                               size_t nbytes, loff_t *ppos)
+{
+       return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+                                      i_size_read(file->f_mapping->host));
+}
+
+static const struct file_operations nodes_fops = {
+       .open           = nodes_fop_open,
+       .release        = o2net_debug_release,
+       .read           = o2net_debug_read,
+       .llseek         = generic_file_llseek,
+};
+
 void o2net_debugfs_exit(void)
 {
+       debugfs_remove(nodes_dentry);
        debugfs_remove(stats_dentry);
        debugfs_remove(sc_dentry);
        debugfs_remove(nst_dentry);
        debugfs_remove(o2net_dentry);
 }
 
+int o2net_debugfs_init(void)
+{
+       mode_t mode = S_IFREG|S_IRUSR;
+
+       o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
+       if (o2net_dentry)
+               nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &nst_seq_fops);
+       if (nst_dentry)
+               sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &sc_seq_fops);
+       if (sc_dentry)
+               stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &stats_seq_fops);
+       if (stats_dentry)
+               nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &nodes_fops);
+       if (nodes_dentry)
+               return 0;
+
+       o2net_debugfs_exit();
+       mlog_errno(-ENOMEM);
+       return -ENOMEM;
+}
+
 #endif /* CONFIG_DEBUG_FS */
index ad7d0c155de41a3912b5a6fa330b28ca48edf790..044e7b58d31c7662a75e29f636cfb86bf2846b67 100644 (file)
@@ -546,7 +546,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
        }
 
        if (was_valid && !valid) {
-               printk(KERN_NOTICE "o2net: no longer connected to "
+               printk(KERN_NOTICE "o2net: No longer connected to "
                       SC_NODEF_FMT "\n", SC_NODEF_ARGS(old_sc));
                o2net_complete_nodes_nsw(nn);
        }
@@ -556,7 +556,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
                cancel_delayed_work(&nn->nn_connect_expired);
                printk(KERN_NOTICE "o2net: %s " SC_NODEF_FMT "\n",
                       o2nm_this_node() > sc->sc_node->nd_num ?
-                               "connected to" : "accepted connection from",
+                      "Connected to" : "Accepted connection from",
                       SC_NODEF_ARGS(sc));
        }
 
@@ -644,7 +644,7 @@ static void o2net_state_change(struct sock *sk)
                        o2net_sc_queue_work(sc, &sc->sc_connect_work);
                        break;
                default:
-                       printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT
+                       printk(KERN_INFO "o2net: Connection to " SC_NODEF_FMT
                              " shutdown, state %d\n",
                              SC_NODEF_ARGS(sc), sk->sk_state);
                        o2net_sc_queue_work(sc, &sc->sc_shutdown_work);
@@ -1035,6 +1035,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn,
        return ret;
 }
 
+/* Get a map of all nodes to which this node is currently connected to */
+void o2net_fill_node_map(unsigned long *map, unsigned bytes)
+{
+       struct o2net_sock_container *sc;
+       int node, ret;
+
+       BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long)));
+
+       memset(map, 0, bytes);
+       for (node = 0; node < O2NM_MAX_NODES; ++node) {
+               o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret);
+               if (!ret) {
+                       set_bit(node, map);
+                       sc_put(sc);
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(o2net_fill_node_map);
+
 int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
                           size_t caller_veclen, u8 target_node, int *status)
 {
@@ -1285,11 +1304,11 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
        struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
 
        if (hand->protocol_version != cpu_to_be64(O2NET_PROTOCOL_VERSION)) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " advertised net protocol "
-                    "version %llu but %llu is required, disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    (unsigned long long)be64_to_cpu(hand->protocol_version),
-                    O2NET_PROTOCOL_VERSION);
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " Advertised net "
+                      "protocol version %llu but %llu is required. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      (unsigned long long)be64_to_cpu(hand->protocol_version),
+                      O2NET_PROTOCOL_VERSION);
 
                /* don't bother reconnecting if its the wrong version. */
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
@@ -1303,33 +1322,33 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
         */
        if (be32_to_cpu(hand->o2net_idle_timeout_ms) !=
                                o2net_idle_timeout()) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a network idle timeout of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2net_idle_timeout_ms),
-                    o2net_idle_timeout());
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a network "
+                      "idle timeout of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2net_idle_timeout_ms),
+                      o2net_idle_timeout());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2net_keepalive_delay_ms) !=
                        o2net_keepalive_delay()) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a keepalive delay of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2net_keepalive_delay_ms),
-                    o2net_keepalive_delay());
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a keepalive "
+                      "delay of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2net_keepalive_delay_ms),
+                      o2net_keepalive_delay());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) !=
                        O2HB_MAX_WRITE_TIMEOUT_MS) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a heartbeat timeout of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
-                    O2HB_MAX_WRITE_TIMEOUT_MS);
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a heartbeat "
+                      "timeout of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
+                      O2HB_MAX_WRITE_TIMEOUT_MS);
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
@@ -1540,28 +1559,16 @@ static void o2net_idle_timer(unsigned long data)
 {
        struct o2net_sock_container *sc = (struct o2net_sock_container *)data;
        struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
-
 #ifdef CONFIG_DEBUG_FS
-       ktime_t now = ktime_get();
+       unsigned long msecs = ktime_to_ms(ktime_get()) -
+               ktime_to_ms(sc->sc_tv_timer);
+#else
+       unsigned long msecs = o2net_idle_timeout();
 #endif
 
-       printk(KERN_NOTICE "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u "
-            "seconds, shutting it down.\n", SC_NODEF_ARGS(sc),
-                    o2net_idle_timeout() / 1000,
-                    o2net_idle_timeout() % 1000);
-
-#ifdef CONFIG_DEBUG_FS
-       mlog(ML_NOTICE, "Here are some times that might help debug the "
-            "situation: (Timer: %lld, Now %lld, DataReady %lld, Advance %lld-%lld, "
-            "Key 0x%08x, Func %u, FuncTime %lld-%lld)\n",
-            (long long)ktime_to_us(sc->sc_tv_timer), (long long)ktime_to_us(now),
-            (long long)ktime_to_us(sc->sc_tv_data_ready),
-            (long long)ktime_to_us(sc->sc_tv_advance_start),
-            (long long)ktime_to_us(sc->sc_tv_advance_stop),
-            sc->sc_msg_key, sc->sc_msg_type,
-            (long long)ktime_to_us(sc->sc_tv_func_start),
-            (long long)ktime_to_us(sc->sc_tv_func_stop));
-#endif
+       printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been "
+              "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc),
+              msecs / 1000, msecs % 1000);
 
        /*
         * Initialize the nn_timeout so that the next connection attempt
@@ -1694,8 +1701,8 @@ static void o2net_start_connect(struct work_struct *work)
 
 out:
        if (ret) {
-               mlog(ML_NOTICE, "connect attempt to " SC_NODEF_FMT " failed "
-                    "with errno %d\n", SC_NODEF_ARGS(sc), ret);
+               printk(KERN_NOTICE "o2net: Connect attempt to " SC_NODEF_FMT
+                      " failed with errno %d\n", SC_NODEF_ARGS(sc), ret);
                /* 0 err so that another will be queued and attempted
                 * from set_nn_state */
                if (sc)
@@ -1718,8 +1725,8 @@ static void o2net_connect_expired(struct work_struct *work)
 
        spin_lock(&nn->nn_lock);
        if (!nn->nn_sc_valid) {
-               mlog(ML_ERROR, "no connection established with node %u after "
-                    "%u.%u seconds, giving up and returning errors.\n",
+               printk(KERN_NOTICE "o2net: No connection established with "
+                      "node %u after %u.%u seconds, giving up.\n",
                     o2net_num_from_nn(nn),
                     o2net_idle_timeout() / 1000,
                     o2net_idle_timeout() % 1000);
@@ -1862,21 +1869,21 @@ static int o2net_accept_one(struct socket *sock)
 
        node = o2nm_get_node_by_ip(sin.sin_addr.s_addr);
        if (node == NULL) {
-               mlog(ML_NOTICE, "attempt to connect from unknown node at %pI4:%d\n",
-                    &sin.sin_addr.s_addr, ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Attempt to connect from unknown "
+                      "node at %pI4:%d\n", &sin.sin_addr.s_addr,
+                      ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
 
        if (o2nm_this_node() >= node->nd_num) {
                local_node = o2nm_get_node_by_num(o2nm_this_node());
-               mlog(ML_NOTICE, "unexpected connect attempt seen at node '%s' ("
-                    "%u, %pI4:%d) from node '%s' (%u, %pI4:%d)\n",
-                    local_node->nd_name, local_node->nd_num,
-                    &(local_node->nd_ipv4_address),
-                    ntohs(local_node->nd_ipv4_port),
-                    node->nd_name, node->nd_num, &sin.sin_addr.s_addr,
-                    ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Unexpected connect attempt seen "
+                      "at node '%s' (%u, %pI4:%d) from node '%s' (%u, "
+                      "%pI4:%d)\n", local_node->nd_name, local_node->nd_num,
+                      &(local_node->nd_ipv4_address),
+                      ntohs(local_node->nd_ipv4_port), node->nd_name,
+                      node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
@@ -1901,10 +1908,10 @@ static int o2net_accept_one(struct socket *sock)
                ret = 0;
        spin_unlock(&nn->nn_lock);
        if (ret) {
-               mlog(ML_NOTICE, "attempt to connect from node '%s' at "
-                    "%pI4:%d but it already has an open connection\n",
-                    node->nd_name, &sin.sin_addr.s_addr,
-                    ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' "
+                      "at %pI4:%d but it already has an open connection\n",
+                      node->nd_name, &sin.sin_addr.s_addr,
+                      ntohs(sin.sin_port));
                goto out;
        }
 
@@ -1984,7 +1991,7 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
 
        ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to create socket, ret=%d\n", ret);
+               printk(KERN_ERR "o2net: Error %d while creating socket\n", ret);
                goto out;
        }
 
@@ -2001,16 +2008,15 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
        sock->sk->sk_reuse = 1;
        ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to bind socket at %pI4:%u, "
-                    "ret=%d\n", &addr, ntohs(port), ret);
+               printk(KERN_ERR "o2net: Error %d while binding socket at "
+                      "%pI4:%u\n", ret, &addr, ntohs(port)); 
                goto out;
        }
 
        ret = sock->ops->listen(sock, 64);
-       if (ret < 0) {
-               mlog(ML_ERROR, "unable to listen on %pI4:%u, ret=%d\n",
-                    &addr, ntohs(port), ret);
-       }
+       if (ret < 0)
+               printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n",
+                      ret, &addr, ntohs(port));
 
 out:
        if (ret) {
index fd6179eb26d4cd2cfb43f4ff053237837712113e..5bada2a69b503cd365d626a25e4ae6d08ad50b7a 100644 (file)
@@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
                           struct list_head *unreg_list);
 void o2net_unregister_handler_list(struct list_head *list);
 
+void o2net_fill_node_map(unsigned long *map, unsigned bytes);
+
 struct o2nm_node;
 int o2net_register_hb_callbacks(void);
 void o2net_unregister_hb_callbacks(void);
index e2878b5895fb543a86c11f0128b025dbb0335c38..8fe4e2892ab9ccd983304a825c338df57a5376b8 100644 (file)
@@ -1184,8 +1184,7 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
                        if (pde)
                                le16_add_cpu(&pde->rec_len,
                                                le16_to_cpu(de->rec_len));
-                       else
-                               de->inode = 0;
+                       de->inode = 0;
                        dir->i_version++;
                        ocfs2_journal_dirty(handle, bh);
                        goto bail;
index d602abb51b610d525cc437daa05c25d2105fe0c3..a5952ceecba5a83147389ad4a1cd24972ee0bfbe 100644 (file)
@@ -859,8 +859,8 @@ void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);
 void dlm_wait_for_recovery(struct dlm_ctxt *dlm);
 void dlm_kick_recovery_thread(struct dlm_ctxt *dlm);
 int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node);
-int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
-int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
+void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
+void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
 
 void dlm_put(struct dlm_ctxt *dlm);
 struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm);
@@ -877,9 +877,8 @@ static inline void dlm_lockres_get(struct dlm_lock_resource *res)
        kref_get(&res->refs);
 }
 void dlm_lockres_put(struct dlm_lock_resource *res);
-void __dlm_unhash_lockres(struct dlm_lock_resource *res);
-void __dlm_insert_lockres(struct dlm_ctxt *dlm,
-                         struct dlm_lock_resource *res);
+void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
+void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
                                                     const char *name,
                                                     unsigned int len,
@@ -902,46 +901,15 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
                                          const char *name,
                                          unsigned int namelen);
 
-#define dlm_lockres_set_refmap_bit(bit,res)  \
-       __dlm_lockres_set_refmap_bit(bit,res,__FILE__,__LINE__)
-#define dlm_lockres_clear_refmap_bit(bit,res)  \
-       __dlm_lockres_clear_refmap_bit(bit,res,__FILE__,__LINE__)
+void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm,
+                               struct dlm_lock_resource *res, int bit);
+void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *res, int bit);
 
-static inline void __dlm_lockres_set_refmap_bit(int bit,
-                                               struct dlm_lock_resource *res,
-                                               const char *file,
-                                               int line)
-{
-       //printk("%s:%d:%.*s: setting bit %d\n", file, line,
-       //     res->lockname.len, res->lockname.name, bit);
-       set_bit(bit, res->refmap);
-}
-
-static inline void __dlm_lockres_clear_refmap_bit(int bit,
-                                                 struct dlm_lock_resource *res,
-                                                 const char *file,
-                                                 int line)
-{
-       //printk("%s:%d:%.*s: clearing bit %d\n", file, line,
-       //     res->lockname.len, res->lockname.name, bit);
-       clear_bit(bit, res->refmap);
-}
-
-void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  const char *file,
-                                  int line);
-void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  int new_lockres,
-                                  const char *file,
-                                  int line);
-#define dlm_lockres_drop_inflight_ref(d,r)  \
-       __dlm_lockres_drop_inflight_ref(d,r,__FILE__,__LINE__)
-#define dlm_lockres_grab_inflight_ref(d,r)  \
-       __dlm_lockres_grab_inflight_ref(d,r,0,__FILE__,__LINE__)
-#define dlm_lockres_grab_inflight_ref_new(d,r)  \
-       __dlm_lockres_grab_inflight_ref(d,r,1,__FILE__,__LINE__)
+void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res);
+void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res);
 
 void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
index 6ed6b95dcf935a6516e935b85a3ca9ffc0b8a9d8..92f2ead0fab6de22fa138cc4410dee6e1544216c 100644 (file)
@@ -157,16 +157,18 @@ static int dlm_protocol_compare(struct dlm_protocol_version *existing,
 
 static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm);
 
-void __dlm_unhash_lockres(struct dlm_lock_resource *lockres)
+void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
-       if (!hlist_unhashed(&lockres->hash_node)) {
-               hlist_del_init(&lockres->hash_node);
-               dlm_lockres_put(lockres);
-       }
+       if (hlist_unhashed(&res->hash_node))
+               return;
+
+       mlog(0, "%s: Unhash res %.*s\n", dlm->name, res->lockname.len,
+            res->lockname.name);
+       hlist_del_init(&res->hash_node);
+       dlm_lockres_put(res);
 }
 
-void __dlm_insert_lockres(struct dlm_ctxt *dlm,
-                      struct dlm_lock_resource *res)
+void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
        struct hlist_head *bucket;
        struct qstr *q;
@@ -180,6 +182,9 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
        dlm_lockres_get(res);
 
        hlist_add_head(&res->hash_node, bucket);
+
+       mlog(0, "%s: Hash res %.*s\n", dlm->name, res->lockname.len,
+            res->lockname.name);
 }
 
 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
@@ -539,17 +544,17 @@ again:
 
 static void __dlm_print_nodes(struct dlm_ctxt *dlm)
 {
-       int node = -1;
+       int node = -1, num = 0;
 
        assert_spin_locked(&dlm->spinlock);
 
-       printk(KERN_NOTICE "o2dlm: Nodes in domain %s: ", dlm->name);
-
+       printk("( ");
        while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES,
                                     node + 1)) < O2NM_MAX_NODES) {
                printk("%d ", node);
+               ++num;
        }
-       printk("\n");
+       printk(") %u nodes\n", num);
 }
 
 static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
@@ -566,11 +571,10 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
 
        node = exit_msg->node_idx;
 
-       printk(KERN_NOTICE "o2dlm: Node %u leaves domain %s\n", node, dlm->name);
-
        spin_lock(&dlm->spinlock);
        clear_bit(node, dlm->domain_map);
        clear_bit(node, dlm->exit_domain_map);
+       printk(KERN_NOTICE "o2dlm: Node %u leaves domain %s ", node, dlm->name);
        __dlm_print_nodes(dlm);
 
        /* notify anything attached to the heartbeat events */
@@ -755,6 +759,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm)
 
                dlm_mark_domain_leaving(dlm);
                dlm_leave_domain(dlm);
+               printk(KERN_NOTICE "o2dlm: Leaving domain %s\n", dlm->name);
                dlm_force_free_mles(dlm);
                dlm_complete_dlm_shutdown(dlm);
        }
@@ -970,7 +975,7 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data,
                clear_bit(assert->node_idx, dlm->exit_domain_map);
                __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
 
-               printk(KERN_NOTICE "o2dlm: Node %u joins domain %s\n",
+               printk(KERN_NOTICE "o2dlm: Node %u joins domain %s ",
                       assert->node_idx, dlm->name);
                __dlm_print_nodes(dlm);
 
@@ -1701,8 +1706,10 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
 bail:
        spin_lock(&dlm->spinlock);
        __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
-       if (!status)
+       if (!status) {
+               printk(KERN_NOTICE "o2dlm: Joining domain %s ", dlm->name);
                __dlm_print_nodes(dlm);
+       }
        spin_unlock(&dlm->spinlock);
 
        if (ctxt) {
@@ -2131,13 +2138,6 @@ struct dlm_ctxt * dlm_register_domain(const char *domain,
                goto leave;
        }
 
-       if (!o2hb_check_local_node_heartbeating()) {
-               mlog(ML_ERROR, "the local node has not been configured, or is "
-                    "not heartbeating\n");
-               ret = -EPROTO;
-               goto leave;
-       }
-
        mlog(0, "register called for domain \"%s\"\n", domain);
 
 retry:
index 8d39e0fd66f7379b8fb08ac40502efa0d4a51cc6..975810b98492a34f4576b9d3d3ac3e4421fb18c1 100644 (file)
@@ -183,10 +183,6 @@ static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm,
                        kick_thread = 1;
                }
        }
-       /* reduce the inflight count, this may result in the lockres
-        * being purged below during calc_usage */
-       if (lock->ml.node == dlm->node_num)
-               dlm_lockres_drop_inflight_ref(dlm, res);
 
        spin_unlock(&res->spinlock);
        wake_up(&res->wq);
@@ -231,10 +227,16 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm,
             lock->ml.type, res->lockname.len,
             res->lockname.name, flags);
 
+       /*
+        * Wait if resource is getting recovered, remastered, etc.
+        * If the resource was remastered and new owner is self, then exit.
+        */
        spin_lock(&res->spinlock);
-
-       /* will exit this call with spinlock held */
        __dlm_wait_on_lockres(res);
+       if (res->owner == dlm->node_num) {
+               spin_unlock(&res->spinlock);
+               return DLM_RECOVERING;
+       }
        res->state |= DLM_LOCK_RES_IN_PROGRESS;
 
        /* add lock to local (secondary) queue */
@@ -319,27 +321,23 @@ static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm,
        tmpret = o2net_send_message(DLM_CREATE_LOCK_MSG, dlm->key, &create,
                                    sizeof(create), res->owner, &status);
        if (tmpret >= 0) {
-               // successfully sent and received
-               ret = status;  // this is already a dlm_status
+               ret = status;
                if (ret == DLM_REJECTED) {
-                       mlog(ML_ERROR, "%s:%.*s: BUG.  this is a stale lockres "
-                            "no longer owned by %u.  that node is coming back "
-                            "up currently.\n", dlm->name, create.namelen,
+                       mlog(ML_ERROR, "%s: res %.*s, Stale lockres no longer "
+                            "owned by node %u. That node is coming back up "
+                            "currently.\n", dlm->name, create.namelen,
                             create.name, res->owner);
                        dlm_print_one_lock_resource(res);
                        BUG();
                }
        } else {
-               mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to "
-                    "node %u\n", tmpret, DLM_CREATE_LOCK_MSG, dlm->key,
-                    res->owner);
-               if (dlm_is_host_down(tmpret)) {
+               mlog(ML_ERROR, "%s: res %.*s, Error %d send CREATE LOCK to "
+                    "node %u\n", dlm->name, create.namelen, create.name,
+                    tmpret, res->owner);
+               if (dlm_is_host_down(tmpret))
                        ret = DLM_RECOVERING;
-                       mlog(0, "node %u died so returning DLM_RECOVERING "
-                            "from lock message!\n", res->owner);
-               } else {
+               else
                        ret = dlm_err_to_dlm_status(tmpret);
-               }
        }
 
        return ret;
@@ -440,7 +438,7 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
                /* zero memory only if kernel-allocated */
                lksb = kzalloc(sizeof(*lksb), GFP_NOFS);
                if (!lksb) {
-                       kfree(lock);
+                       kmem_cache_free(dlm_lock_cache, lock);
                        return NULL;
                }
                kernel_allocated = 1;
@@ -718,18 +716,10 @@ retry_lock:
 
                if (status == DLM_RECOVERING || status == DLM_MIGRATING ||
                    status == DLM_FORWARD) {
-                       mlog(0, "retrying lock with migration/"
-                            "recovery/in progress\n");
                        msleep(100);
-                       /* no waiting for dlm_reco_thread */
                        if (recovery) {
                                if (status != DLM_RECOVERING)
                                        goto retry_lock;
-
-                               mlog(0, "%s: got RECOVERING "
-                                    "for $RECOVERY lock, master "
-                                    "was %u\n", dlm->name,
-                                    res->owner);
                                /* wait to see the node go down, then
                                 * drop down and allow the lockres to
                                 * get cleaned up.  need to remaster. */
@@ -741,6 +731,14 @@ retry_lock:
                        }
                }
 
+               /* Inflight taken in dlm_get_lock_resource() is dropped here */
+               spin_lock(&res->spinlock);
+               dlm_lockres_drop_inflight_ref(dlm, res);
+               spin_unlock(&res->spinlock);
+
+               dlm_lockres_calc_usage(dlm, res);
+               dlm_kick_thread(dlm, res);
+
                if (status != DLM_NORMAL) {
                        lock->lksb->flags &= ~DLM_LKSB_GET_LVB;
                        if (status != DLM_NOTQUEUED)
index 11eefb8c12e98fb418f41c31a3b0a32201be3ca1..005261c333b090f5f53f376bd5bbed55b8e16ba7 100644 (file)
@@ -631,39 +631,54 @@ error:
        return NULL;
 }
 
-void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  int new_lockres,
-                                  const char *file,
-                                  int line)
+void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm,
+                               struct dlm_lock_resource *res, int bit)
 {
-       if (!new_lockres)
-               assert_spin_locked(&res->spinlock);
+       assert_spin_locked(&res->spinlock);
+
+       mlog(0, "res %.*s, set node %u, %ps()\n", res->lockname.len,
+            res->lockname.name, bit, __builtin_return_address(0));
+
+       set_bit(bit, res->refmap);
+}
+
+void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *res, int bit)
+{
+       assert_spin_locked(&res->spinlock);
+
+       mlog(0, "res %.*s, clr node %u, %ps()\n", res->lockname.len,
+            res->lockname.name, bit, __builtin_return_address(0));
+
+       clear_bit(bit, res->refmap);
+}
+
+
+void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res)
+{
+       assert_spin_locked(&res->spinlock);
 
-       if (!test_bit(dlm->node_num, res->refmap)) {
-               BUG_ON(res->inflight_locks != 0);
-               dlm_lockres_set_refmap_bit(dlm->node_num, res);
-       }
        res->inflight_locks++;
-       mlog(0, "%s:%.*s: inflight++: now %u\n",
-            dlm->name, res->lockname.len, res->lockname.name,
-            res->inflight_locks);
+
+       mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name,
+            res->lockname.len, res->lockname.name, res->inflight_locks,
+            __builtin_return_address(0));
 }
 
-void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  const char *file,
-                                  int line)
+void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res)
 {
        assert_spin_locked(&res->spinlock);
 
        BUG_ON(res->inflight_locks == 0);
+
        res->inflight_locks--;
-       mlog(0, "%s:%.*s: inflight--: now %u\n",
-            dlm->name, res->lockname.len, res->lockname.name,
-            res->inflight_locks);
-       if (res->inflight_locks == 0)
-               dlm_lockres_clear_refmap_bit(dlm->node_num, res);
+
+       mlog(0, "%s: res %.*s, inflight--: now %u, %ps()\n", dlm->name,
+            res->lockname.len, res->lockname.name, res->inflight_locks,
+            __builtin_return_address(0));
+
        wake_up(&res->wq);
 }
 
@@ -697,7 +712,6 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
        unsigned int hash;
        int tries = 0;
        int bit, wait_on_recovery = 0;
-       int drop_inflight_if_nonlocal = 0;
 
        BUG_ON(!lockid);
 
@@ -709,36 +723,33 @@ lookup:
        spin_lock(&dlm->spinlock);
        tmpres = __dlm_lookup_lockres_full(dlm, lockid, namelen, hash);
        if (tmpres) {
-               int dropping_ref = 0;
-
                spin_unlock(&dlm->spinlock);
-
                spin_lock(&tmpres->spinlock);
-               /* We wait for the other thread that is mastering the resource */
+               /* Wait on the thread that is mastering the resource */
                if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
                        __dlm_wait_on_lockres(tmpres);
                        BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN);
+                       spin_unlock(&tmpres->spinlock);
+                       dlm_lockres_put(tmpres);
+                       tmpres = NULL;
+                       goto lookup;
                }
 
-               if (tmpres->owner == dlm->node_num) {
-                       BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF);
-                       dlm_lockres_grab_inflight_ref(dlm, tmpres);
-               } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF)
-                       dropping_ref = 1;
-               spin_unlock(&tmpres->spinlock);
-
-               /* wait until done messaging the master, drop our ref to allow
-                * the lockres to be purged, start over. */
-               if (dropping_ref) {
-                       spin_lock(&tmpres->spinlock);
-                       __dlm_wait_on_lockres_flags(tmpres, DLM_LOCK_RES_DROPPING_REF);
+               /* Wait on the resource purge to complete before continuing */
+               if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) {
+                       BUG_ON(tmpres->owner == dlm->node_num);
+                       __dlm_wait_on_lockres_flags(tmpres,
+                                                   DLM_LOCK_RES_DROPPING_REF);
                        spin_unlock(&tmpres->spinlock);
                        dlm_lockres_put(tmpres);
                        tmpres = NULL;
                        goto lookup;
                }
 
-               mlog(0, "found in hash!\n");
+               /* Grab inflight ref to pin the resource */
+               dlm_lockres_grab_inflight_ref(dlm, tmpres);
+
+               spin_unlock(&tmpres->spinlock);
                if (res)
                        dlm_lockres_put(res);
                res = tmpres;
@@ -829,8 +840,8 @@ lookup:
                 * but they might own this lockres.  wait on them. */
                bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0);
                if (bit < O2NM_MAX_NODES) {
-                       mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to "
-                            "recover before lock mastery can begin\n",
+                       mlog(0, "%s: res %.*s, At least one node (%d) "
+                            "to recover before lock mastery can begin\n",
                             dlm->name, namelen, (char *)lockid, bit);
                        wait_on_recovery = 1;
                }
@@ -843,12 +854,11 @@ lookup:
 
        /* finally add the lockres to its hash bucket */
        __dlm_insert_lockres(dlm, res);
-       /* since this lockres is new it doesn't not require the spinlock */
-       dlm_lockres_grab_inflight_ref_new(dlm, res);
 
-       /* if this node does not become the master make sure to drop
-        * this inflight reference below */
-       drop_inflight_if_nonlocal = 1;
+       /* Grab inflight ref to pin the resource */
+       spin_lock(&res->spinlock);
+       dlm_lockres_grab_inflight_ref(dlm, res);
+       spin_unlock(&res->spinlock);
 
        /* get an extra ref on the mle in case this is a BLOCK
         * if so, the creator of the BLOCK may try to put the last
@@ -864,8 +874,8 @@ redo_request:
                 * dlm spinlock would be detectable be a change on the mle,
                 * so we only need to clear out the recovery map once. */
                if (dlm_is_recovery_lock(lockid, namelen)) {
-                       mlog(ML_NOTICE, "%s: recovery map is not empty, but "
-                            "must master $RECOVERY lock now\n", dlm->name);
+                       mlog(0, "%s: Recovery map is not empty, but must "
+                            "master $RECOVERY lock now\n", dlm->name);
                        if (!dlm_pre_master_reco_lockres(dlm, res))
                                wait_on_recovery = 0;
                        else {
@@ -883,8 +893,8 @@ redo_request:
                spin_lock(&dlm->spinlock);
                bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0);
                if (bit < O2NM_MAX_NODES) {
-                       mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to "
-                            "recover before lock mastery can begin\n",
+                       mlog(0, "%s: res %.*s, At least one node (%d) "
+                            "to recover before lock mastery can begin\n",
                             dlm->name, namelen, (char *)lockid, bit);
                        wait_on_recovery = 1;
                } else
@@ -913,8 +923,8 @@ redo_request:
                         * yet, keep going until it does.  this is how the
                         * master will know that asserts are needed back to
                         * the lower nodes. */
-                       mlog(0, "%s:%.*s: requests only up to %u but master "
-                            "is %u, keep going\n", dlm->name, namelen,
+                       mlog(0, "%s: res %.*s, Requests only up to %u but "
+                            "master is %u, keep going\n", dlm->name, namelen,
                             lockid, nodenum, mle->master);
                }
        }
@@ -924,13 +934,12 @@ wait:
        ret = dlm_wait_for_lock_mastery(dlm, res, mle, &blocked);
        if (ret < 0) {
                wait_on_recovery = 1;
-               mlog(0, "%s:%.*s: node map changed, redo the "
-                    "master request now, blocked=%d\n",
-                    dlm->name, res->lockname.len,
+               mlog(0, "%s: res %.*s, Node map changed, redo the master "
+                    "request now, blocked=%d\n", dlm->name, res->lockname.len,
                     res->lockname.name, blocked);
                if (++tries > 20) {
-                       mlog(ML_ERROR, "%s:%.*s: spinning on "
-                            "dlm_wait_for_lock_mastery, blocked=%d\n",
+                       mlog(ML_ERROR, "%s: res %.*s, Spinning on "
+                            "dlm_wait_for_lock_mastery, blocked = %d\n",
                             dlm->name, res->lockname.len,
                             res->lockname.name, blocked);
                        dlm_print_one_lock_resource(res);
@@ -940,7 +949,8 @@ wait:
                goto redo_request;
        }
 
-       mlog(0, "lockres mastered by %u\n", res->owner);
+       mlog(0, "%s: res %.*s, Mastered by %u\n", dlm->name, res->lockname.len,
+            res->lockname.name, res->owner);
        /* make sure we never continue without this */
        BUG_ON(res->owner == O2NM_MAX_NODES);
 
@@ -952,8 +962,6 @@ wait:
 
 wake_waiters:
        spin_lock(&res->spinlock);
-       if (res->owner != dlm->node_num && drop_inflight_if_nonlocal)
-               dlm_lockres_drop_inflight_ref(dlm, res);
        res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
        spin_unlock(&res->spinlock);
        wake_up(&res->wq);
@@ -1426,9 +1434,7 @@ way_up_top:
                }
 
                if (res->owner == dlm->node_num) {
-                       mlog(0, "%s:%.*s: setting bit %u in refmap\n",
-                            dlm->name, namelen, name, request->node_idx);
-                       dlm_lockres_set_refmap_bit(request->node_idx, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, request->node_idx);
                        spin_unlock(&res->spinlock);
                        response = DLM_MASTER_RESP_YES;
                        if (mle)
@@ -1493,10 +1499,8 @@ way_up_top:
                                 * go back and clean the mles on any
                                 * other nodes */
                                dispatch_assert = 1;
-                               dlm_lockres_set_refmap_bit(request->node_idx, res);
-                               mlog(0, "%s:%.*s: setting bit %u in refmap\n",
-                                    dlm->name, namelen, name,
-                                    request->node_idx);
+                               dlm_lockres_set_refmap_bit(dlm, res,
+                                                          request->node_idx);
                        } else
                                response = DLM_MASTER_RESP_NO;
                } else {
@@ -1702,7 +1706,7 @@ again:
                             "lockres, set the bit in the refmap\n",
                             namelen, lockname, to);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(to, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, to);
                        spin_unlock(&res->spinlock);
                }
        }
@@ -2187,8 +2191,6 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
        namelen = res->lockname.len;
        BUG_ON(namelen > O2NM_MAX_NAME_LEN);
 
-       mlog(0, "%s:%.*s: sending deref to %d\n",
-            dlm->name, namelen, lockname, res->owner);
        memset(&deref, 0, sizeof(deref));
        deref.node_idx = dlm->node_num;
        deref.namelen = namelen;
@@ -2197,14 +2199,12 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
        ret = o2net_send_message(DLM_DEREF_LOCKRES_MSG, dlm->key,
                                 &deref, sizeof(deref), res->owner, &r);
        if (ret < 0)
-               mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to "
-                    "node %u\n", ret, DLM_DEREF_LOCKRES_MSG, dlm->key,
-                    res->owner);
+               mlog(ML_ERROR, "%s: res %.*s, error %d send DEREF to node %u\n",
+                    dlm->name, namelen, lockname, ret, res->owner);
        else if (r < 0) {
                /* BAD.  other node says I did not have a ref. */
-               mlog(ML_ERROR,"while dropping ref on %s:%.*s "
-                   "(master=%u) got %d.\n", dlm->name, namelen,
-                   lockname, res->owner, r);
+               mlog(ML_ERROR, "%s: res %.*s, DEREF to node %u got %d\n",
+                    dlm->name, namelen, lockname, res->owner, r);
                dlm_print_one_lock_resource(res);
                BUG();
        }
@@ -2260,7 +2260,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
        else {
                BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF);
                if (test_bit(node, res->refmap)) {
-                       dlm_lockres_clear_refmap_bit(node, res);
+                       dlm_lockres_clear_refmap_bit(dlm, res, node);
                        cleared = 1;
                }
        }
@@ -2320,7 +2320,7 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
        BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF);
        if (test_bit(node, res->refmap)) {
                __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
-               dlm_lockres_clear_refmap_bit(node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, node);
                cleared = 1;
        }
        spin_unlock(&res->spinlock);
@@ -2802,7 +2802,8 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
                                BUG_ON(!list_empty(&lock->bast_list));
                                BUG_ON(lock->ast_pending);
                                BUG_ON(lock->bast_pending);
-                               dlm_lockres_clear_refmap_bit(lock->ml.node, res);
+                               dlm_lockres_clear_refmap_bit(dlm, res,
+                                                            lock->ml.node);
                                list_del_init(&lock->list);
                                dlm_lock_put(lock);
                                /* In a normal unlock, we would have added a
@@ -2823,7 +2824,7 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
                        mlog(0, "%s:%.*s: node %u had a ref to this "
                             "migrating lockres, clearing\n", dlm->name,
                             res->lockname.len, res->lockname.name, bit);
-                       dlm_lockres_clear_refmap_bit(bit, res);
+                       dlm_lockres_clear_refmap_bit(dlm, res, bit);
                }
                bit++;
        }
@@ -2916,9 +2917,9 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
                                         &migrate, sizeof(migrate), nodenum,
                                         &status);
                if (ret < 0) {
-                       mlog(ML_ERROR, "Error %d when sending message %u (key "
-                            "0x%x) to node %u\n", ret, DLM_MIGRATE_REQUEST_MSG,
-                            dlm->key, nodenum);
+                       mlog(ML_ERROR, "%s: res %.*s, Error %d send "
+                            "MIGRATE_REQUEST to node %u\n", dlm->name,
+                            migrate.namelen, migrate.name, ret, nodenum);
                        if (!dlm_is_host_down(ret)) {
                                mlog(ML_ERROR, "unhandled error=%d!\n", ret);
                                BUG();
@@ -2937,7 +2938,7 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
                             dlm->name, res->lockname.len, res->lockname.name,
                             nodenum);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(nodenum, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, nodenum);
                        spin_unlock(&res->spinlock);
                }
        }
@@ -3271,7 +3272,7 @@ int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
         * mastery reference here since old_master will briefly have
         * a reference after the migration completes */
        spin_lock(&res->spinlock);
-       dlm_lockres_set_refmap_bit(old_master, res);
+       dlm_lockres_set_refmap_bit(dlm, res, old_master);
        spin_unlock(&res->spinlock);
 
        mlog(0, "now time to do a migrate request to other nodes\n");
index 7efab6d28a21b4ee6a8376559d70f739a4e1da90..01ebfd0bdad72264b99345378f0c6febe246503d 100644 (file)
@@ -362,40 +362,38 @@ static int dlm_is_node_recovered(struct dlm_ctxt *dlm, u8 node)
 }
 
 
-int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout)
+void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout)
 {
-       if (timeout) {
-               mlog(ML_NOTICE, "%s: waiting %dms for notification of "
-                    "death of node %u\n", dlm->name, timeout, node);
+       if (dlm_is_node_dead(dlm, node))
+               return;
+
+       printk(KERN_NOTICE "o2dlm: Waiting on the death of node %u in "
+              "domain %s\n", node, dlm->name);
+
+       if (timeout)
                wait_event_timeout(dlm->dlm_reco_thread_wq,
-                          dlm_is_node_dead(dlm, node),
-                          msecs_to_jiffies(timeout));
-       } else {
-               mlog(ML_NOTICE, "%s: waiting indefinitely for notification "
-                    "of death of node %u\n", dlm->name, node);
+                                  dlm_is_node_dead(dlm, node),
+                                  msecs_to_jiffies(timeout));
+       else
                wait_event(dlm->dlm_reco_thread_wq,
                           dlm_is_node_dead(dlm, node));
-       }
-       /* for now, return 0 */
-       return 0;
 }
 
-int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout)
+void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout)
 {
-       if (timeout) {
-               mlog(0, "%s: waiting %dms for notification of "
-                    "recovery of node %u\n", dlm->name, timeout, node);
+       if (dlm_is_node_recovered(dlm, node))
+               return;
+
+       printk(KERN_NOTICE "o2dlm: Waiting on the recovery of node %u in "
+              "domain %s\n", node, dlm->name);
+
+       if (timeout)
                wait_event_timeout(dlm->dlm_reco_thread_wq,
-                          dlm_is_node_recovered(dlm, node),
-                          msecs_to_jiffies(timeout));
-       } else {
-               mlog(0, "%s: waiting indefinitely for notification "
-                    "of recovery of node %u\n", dlm->name, node);
+                                  dlm_is_node_recovered(dlm, node),
+                                  msecs_to_jiffies(timeout));
+       else
                wait_event(dlm->dlm_reco_thread_wq,
                           dlm_is_node_recovered(dlm, node));
-       }
-       /* for now, return 0 */
-       return 0;
 }
 
 /* callers of the top-level api calls (dlmlock/dlmunlock) should
@@ -430,6 +428,8 @@ static void dlm_begin_recovery(struct dlm_ctxt *dlm)
 {
        spin_lock(&dlm->spinlock);
        BUG_ON(dlm->reco.state & DLM_RECO_STATE_ACTIVE);
+       printk(KERN_NOTICE "o2dlm: Begin recovery on domain %s for node %u\n",
+              dlm->name, dlm->reco.dead_node);
        dlm->reco.state |= DLM_RECO_STATE_ACTIVE;
        spin_unlock(&dlm->spinlock);
 }
@@ -440,9 +440,18 @@ static void dlm_end_recovery(struct dlm_ctxt *dlm)
        BUG_ON(!(dlm->reco.state & DLM_RECO_STATE_ACTIVE));
        dlm->reco.state &= ~DLM_RECO_STATE_ACTIVE;
        spin_unlock(&dlm->spinlock);
+       printk(KERN_NOTICE "o2dlm: End recovery on domain %s\n", dlm->name);
        wake_up(&dlm->reco.event);
 }
 
+static void dlm_print_recovery_master(struct dlm_ctxt *dlm)
+{
+       printk(KERN_NOTICE "o2dlm: Node %u (%s) is the Recovery Master for the "
+              "dead node %u in domain %s\n", dlm->reco.new_master,
+              (dlm->node_num == dlm->reco.new_master ? "me" : "he"),
+              dlm->reco.dead_node, dlm->name);
+}
+
 static int dlm_do_recovery(struct dlm_ctxt *dlm)
 {
        int status = 0;
@@ -505,9 +514,8 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
                }
                mlog(0, "another node will master this recovery session.\n");
        }
-       mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n",
-            dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master,
-            dlm->node_num, dlm->reco.dead_node);
+
+       dlm_print_recovery_master(dlm);
 
        /* it is safe to start everything back up here
         * because all of the dead node's lock resources
@@ -518,15 +526,13 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
        return 0;
 
 master_here:
-       mlog(ML_NOTICE, "(%d) Node %u is the Recovery Master for the Dead Node "
-            "%u for Domain %s\n", task_pid_nr(dlm->dlm_reco_thread_task),
-            dlm->node_num, dlm->reco.dead_node, dlm->name);
+       dlm_print_recovery_master(dlm);
 
        status = dlm_remaster_locks(dlm, dlm->reco.dead_node);
        if (status < 0) {
                /* we should never hit this anymore */
-               mlog(ML_ERROR, "error %d remastering locks for node %u, "
-                    "retrying.\n", status, dlm->reco.dead_node);
+               mlog(ML_ERROR, "%s: Error %d remastering locks for node %u, "
+                    "retrying.\n", dlm->name, status, dlm->reco.dead_node);
                /* yield a bit to allow any final network messages
                 * to get handled on remaining nodes */
                msleep(100);
@@ -567,7 +573,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
                BUG_ON(ndata->state != DLM_RECO_NODE_DATA_INIT);
                ndata->state = DLM_RECO_NODE_DATA_REQUESTING;
 
-               mlog(0, "requesting lock info from node %u\n",
+               mlog(0, "%s: Requesting lock info from node %u\n", dlm->name,
                     ndata->node_num);
 
                if (ndata->node_num == dlm->node_num) {
@@ -640,7 +646,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
                spin_unlock(&dlm_reco_state_lock);
        }
 
-       mlog(0, "done requesting all lock info\n");
+       mlog(0, "%s: Done requesting all lock info\n", dlm->name);
 
        /* nodes should be sending reco data now
         * just need to wait */
@@ -802,10 +808,9 @@ static int dlm_request_all_locks(struct dlm_ctxt *dlm, u8 request_from,
 
        /* negative status is handled by caller */
        if (ret < 0)
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_LOCK_REQUEST_MSG,
-                    dlm->key, request_from);
-
+               mlog(ML_ERROR, "%s: Error %d send LOCK_REQUEST to node %u "
+                    "to recover dead node %u\n", dlm->name, ret,
+                    request_from, dead_node);
        // return from here, then
        // sleep until all received or error
        return ret;
@@ -956,9 +961,9 @@ static int dlm_send_all_done_msg(struct dlm_ctxt *dlm, u8 dead_node, u8 send_to)
        ret = o2net_send_message(DLM_RECO_DATA_DONE_MSG, dlm->key, &done_msg,
                                 sizeof(done_msg), send_to, &tmpret);
        if (ret < 0) {
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_RECO_DATA_DONE_MSG,
-                    dlm->key, send_to);
+               mlog(ML_ERROR, "%s: Error %d send RECO_DATA_DONE to node %u "
+                    "to recover dead node %u\n", dlm->name, ret, send_to,
+                    dead_node);
                if (!dlm_is_host_down(ret)) {
                        BUG();
                }
@@ -1127,9 +1132,11 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
        if (ret < 0) {
                /* XXX: negative status is not handled.
                 * this will end up killing this node. */
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_MIG_LOCKRES_MSG,
-                    dlm->key, send_to);
+               mlog(ML_ERROR, "%s: res %.*s, Error %d send MIG_LOCKRES to "
+                    "node %u (%s)\n", dlm->name, mres->lockname_len,
+                    mres->lockname, ret, send_to,
+                    (orig_flags & DLM_MRES_MIGRATION ?
+                     "migration" : "recovery"));
        } else {
                /* might get an -ENOMEM back here */
                ret = status;
@@ -1767,7 +1774,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
                             dlm->name, mres->lockname_len, mres->lockname,
                             from);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(from, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, from);
                        spin_unlock(&res->spinlock);
                        added++;
                        break;
@@ -1965,7 +1972,7 @@ skip_lvb:
                        mlog(0, "%s:%.*s: added lock for node %u, "
                             "setting refmap bit\n", dlm->name,
                             res->lockname.len, res->lockname.name, ml->node);
-                       dlm_lockres_set_refmap_bit(ml->node, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, ml->node);
                        added++;
                }
                spin_unlock(&res->spinlock);
@@ -2084,6 +2091,9 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
 
        list_for_each_entry_safe(res, next, &dlm->reco.resources, recovering) {
                if (res->owner == dead_node) {
+                       mlog(0, "%s: res %.*s, Changing owner from %u to %u\n",
+                            dlm->name, res->lockname.len, res->lockname.name,
+                            res->owner, new_master);
                        list_del_init(&res->recovering);
                        spin_lock(&res->spinlock);
                        /* new_master has our reference from
@@ -2105,40 +2115,30 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
        for (i = 0; i < DLM_HASH_BUCKETS; i++) {
                bucket = dlm_lockres_hash(dlm, i);
                hlist_for_each_entry(res, hash_iter, bucket, hash_node) {
-                       if (res->state & DLM_LOCK_RES_RECOVERING) {
-                               if (res->owner == dead_node) {
-                                       mlog(0, "(this=%u) res %.*s owner=%u "
-                                            "was not on recovering list, but "
-                                            "clearing state anyway\n",
-                                            dlm->node_num, res->lockname.len,
-                                            res->lockname.name, new_master);
-                               } else if (res->owner == dlm->node_num) {
-                                       mlog(0, "(this=%u) res %.*s owner=%u "
-                                            "was not on recovering list, "
-                                            "owner is THIS node, clearing\n",
-                                            dlm->node_num, res->lockname.len,
-                                            res->lockname.name, new_master);
-                               } else
-                                       continue;
+                       if (!(res->state & DLM_LOCK_RES_RECOVERING))
+                               continue;
 
-                               if (!list_empty(&res->recovering)) {
-                                       mlog(0, "%s:%.*s: lockres was "
-                                            "marked RECOVERING, owner=%u\n",
-                                            dlm->name, res->lockname.len,
-                                            res->lockname.name, res->owner);
-                                       list_del_init(&res->recovering);
-                                       dlm_lockres_put(res);
-                               }
-                               spin_lock(&res->spinlock);
-                               /* new_master has our reference from
-                                * the lock state sent during recovery */
-                               dlm_change_lockres_owner(dlm, res, new_master);
-                               res->state &= ~DLM_LOCK_RES_RECOVERING;
-                               if (__dlm_lockres_has_locks(res))
-                                       __dlm_dirty_lockres(dlm, res);
-                               spin_unlock(&res->spinlock);
-                               wake_up(&res->wq);
+                       if (res->owner != dead_node &&
+                           res->owner != dlm->node_num)
+                               continue;
+
+                       if (!list_empty(&res->recovering)) {
+                               list_del_init(&res->recovering);
+                               dlm_lockres_put(res);
                        }
+
+                       /* new_master has our reference from
+                        * the lock state sent during recovery */
+                       mlog(0, "%s: res %.*s, Changing owner from %u to %u\n",
+                            dlm->name, res->lockname.len, res->lockname.name,
+                            res->owner, new_master);
+                       spin_lock(&res->spinlock);
+                       dlm_change_lockres_owner(dlm, res, new_master);
+                       res->state &= ~DLM_LOCK_RES_RECOVERING;
+                       if (__dlm_lockres_has_locks(res))
+                               __dlm_dirty_lockres(dlm, res);
+                       spin_unlock(&res->spinlock);
+                       wake_up(&res->wq);
                }
        }
 }
@@ -2252,12 +2252,12 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm,
                             res->lockname.len, res->lockname.name, freed, dead_node);
                        __dlm_print_one_lock_resource(res);
                }
-               dlm_lockres_clear_refmap_bit(dead_node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, dead_node);
        } else if (test_bit(dead_node, res->refmap)) {
                mlog(0, "%s:%.*s: dead node %u had a ref, but had "
                     "no locks and had not purged before dying\n", dlm->name,
                     res->lockname.len, res->lockname.name, dead_node);
-               dlm_lockres_clear_refmap_bit(dead_node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, dead_node);
        }
 
        /* do not kick thread yet */
@@ -2324,9 +2324,9 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
                        dlm_revalidate_lvb(dlm, res, dead_node);
                        if (res->owner == dead_node) {
                                if (res->state & DLM_LOCK_RES_DROPPING_REF) {
-                                       mlog(ML_NOTICE, "Ignore %.*s for "
+                                       mlog(ML_NOTICE, "%s: res %.*s, Skip "
                                             "recovery as it is being freed\n",
-                                            res->lockname.len,
+                                            dlm->name, res->lockname.len,
                                             res->lockname.name);
                                } else
                                        dlm_move_lockres_to_recovery_list(dlm,
index 1d6d1d22c4715e3c89bef69570916cc5bf44c259..e73c833fc2a1a97cac35903f0439115cef813c69 100644 (file)
@@ -94,24 +94,26 @@ int __dlm_lockres_unused(struct dlm_lock_resource *res)
 {
        int bit;
 
+       assert_spin_locked(&res->spinlock);
+
        if (__dlm_lockres_has_locks(res))
                return 0;
 
+       /* Locks are in the process of being created */
+       if (res->inflight_locks)
+               return 0;
+
        if (!list_empty(&res->dirty) || res->state & DLM_LOCK_RES_DIRTY)
                return 0;
 
        if (res->state & DLM_LOCK_RES_RECOVERING)
                return 0;
 
+       /* Another node has this resource with this node as the master */
        bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
        if (bit < O2NM_MAX_NODES)
                return 0;
 
-       /*
-        * since the bit for dlm->node_num is not set, inflight_locks better
-        * be zero
-        */
-       BUG_ON(res->inflight_locks != 0);
        return 1;
 }
 
@@ -185,8 +187,6 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm,
                /* clear our bit from the master's refmap, ignore errors */
                ret = dlm_drop_lockres_ref(dlm, res);
                if (ret < 0) {
-                       mlog(ML_ERROR, "%s: deref %.*s failed %d\n", dlm->name,
-                            res->lockname.len, res->lockname.name, ret);
                        if (!dlm_is_host_down(ret))
                                BUG();
                }
@@ -209,7 +209,7 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm,
                BUG();
        }
 
-       __dlm_unhash_lockres(res);
+       __dlm_unhash_lockres(dlm, res);
 
        /* lockres is not in the hash now.  drop the flag and wake up
         * any processes waiting in dlm_get_lock_resource. */
index e1ed5e502ff25dc8afe39de464949ba13c2f9892..81a4cd22f80be84a06eac2b0fbf4348385d76262 100644 (file)
@@ -1692,7 +1692,7 @@ int ocfs2_open_lock(struct inode *inode)
        mlog(0, "inode %llu take PRMODE open lock\n",
             (unsigned long long)OCFS2_I(inode)->ip_blkno);
 
-       if (ocfs2_mount_local(osb))
+       if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb))
                goto out;
 
        lockres = &OCFS2_I(inode)->ip_open_lockres;
@@ -1718,6 +1718,12 @@ int ocfs2_try_open_lock(struct inode *inode, int write)
             (unsigned long long)OCFS2_I(inode)->ip_blkno,
             write ? "EXMODE" : "PRMODE");
 
+       if (ocfs2_is_hard_readonly(osb)) {
+               if (write)
+                       status = -EROFS;
+               goto out;
+       }
+
        if (ocfs2_mount_local(osb))
                goto out;
 
@@ -2298,7 +2304,7 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
        if (ocfs2_is_hard_readonly(osb)) {
                if (ex)
                        status = -EROFS;
-               goto bail;
+               goto getbh;
        }
 
        if (ocfs2_mount_local(osb))
@@ -2356,7 +2362,7 @@ local:
                        mlog_errno(status);
                goto bail;
        }
-
+getbh:
        if (ret_bh) {
                status = ocfs2_assign_bh(inode, ret_bh, local_bh);
                if (status < 0) {
@@ -2628,8 +2634,11 @@ int ocfs2_dentry_lock(struct dentry *dentry, int ex)
 
        BUG_ON(!dl);
 
-       if (ocfs2_is_hard_readonly(osb))
-               return -EROFS;
+       if (ocfs2_is_hard_readonly(osb)) {
+               if (ex)
+                       return -EROFS;
+               return 0;
+       }
 
        if (ocfs2_mount_local(osb))
                return 0;
@@ -2647,7 +2656,7 @@ void ocfs2_dentry_unlock(struct dentry *dentry, int ex)
        struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
        struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
 
-       if (!ocfs2_mount_local(osb))
+       if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb))
                ocfs2_cluster_unlock(osb, &dl->dl_lockres, level);
 }
 
index 23457b491e8ce53ac5b71d9cd5fc2a5e1400a07f..2f5b92ef0e533146007b49d21dd705a242125dc5 100644 (file)
@@ -832,6 +832,102 @@ out:
        return ret;
 }
 
+int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin)
+{
+       struct inode *inode = file->f_mapping->host;
+       int ret;
+       unsigned int is_last = 0, is_data = 0;
+       u16 cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits;
+       u32 cpos, cend, clen, hole_size;
+       u64 extoff, extlen;
+       struct buffer_head *di_bh = NULL;
+       struct ocfs2_extent_rec rec;
+
+       BUG_ON(origin != SEEK_DATA && origin != SEEK_HOLE);
+
+       ret = ocfs2_inode_lock(inode, &di_bh, 0);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
+       down_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+       if (*offset >= inode->i_size) {
+               ret = -ENXIO;
+               goto out_unlock;
+       }
+
+       if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+               if (origin == SEEK_HOLE)
+                       *offset = inode->i_size;
+               goto out_unlock;
+       }
+
+       clen = 0;
+       cpos = *offset >> cs_bits;
+       cend = ocfs2_clusters_for_bytes(inode->i_sb, inode->i_size);
+
+       while (cpos < cend && !is_last) {
+               ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos, &hole_size,
+                                                &rec, &is_last);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out_unlock;
+               }
+
+               extoff = cpos;
+               extoff <<= cs_bits;
+
+               if (rec.e_blkno == 0ULL) {
+                       clen = hole_size;
+                       is_data = 0;
+               } else {
+                       clen = le16_to_cpu(rec.e_leaf_clusters) -
+                               (cpos - le32_to_cpu(rec.e_cpos));
+                       is_data = (rec.e_flags & OCFS2_EXT_UNWRITTEN) ?  0 : 1;
+               }
+
+               if ((!is_data && origin == SEEK_HOLE) ||
+                   (is_data && origin == SEEK_DATA)) {
+                       if (extoff > *offset)
+                               *offset = extoff;
+                       goto out_unlock;
+               }
+
+               if (!is_last)
+                       cpos += clen;
+       }
+
+       if (origin == SEEK_HOLE) {
+               extoff = cpos;
+               extoff <<= cs_bits;
+               extlen = clen;
+               extlen <<=  cs_bits;
+
+               if ((extoff + extlen) > inode->i_size)
+                       extlen = inode->i_size - extoff;
+               extoff += extlen;
+               if (extoff > *offset)
+                       *offset = extoff;
+               goto out_unlock;
+       }
+
+       ret = -ENXIO;
+
+out_unlock:
+
+       brelse(di_bh);
+
+       up_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+       ocfs2_inode_unlock(inode, 0);
+out:
+       if (ret && ret != -ENXIO)
+               ret = -ENXIO;
+       return ret;
+}
+
 int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr,
                           struct buffer_head *bhs[], int flags,
                           int (*validate)(struct super_block *sb,
index e79d41c2c90972fe801a99ec040b229a92debe98..67ea57d2fd594da7e456c1103bb1652fa68b5f69 100644 (file)
@@ -53,6 +53,8 @@ int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
 int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                 u64 map_start, u64 map_len);
 
+int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin);
+
 int ocfs2_xattr_get_clusters(struct inode *inode, u32 v_cluster,
                             u32 *p_cluster, u32 *num_clusters,
                             struct ocfs2_extent_list *el,
index de4ea1af041b654f8f1b4f1a000f6492226f701f..6e396683c3d48af7321f77b8658754982586cb35 100644 (file)
@@ -1950,6 +1950,9 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
        if (ret < 0)
                mlog_errno(ret);
 
+       if (file->f_flags & O_SYNC)
+               handle->h_sync = 1;
+
        ocfs2_commit_trans(osb, handle);
 
 out_inode_unlock:
@@ -2052,6 +2055,23 @@ out:
        return ret;
 }
 
+static void ocfs2_aiodio_wait(struct inode *inode)
+{
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
+
+       wait_event(*wq, (atomic_read(&OCFS2_I(inode)->ip_unaligned_aio) == 0));
+}
+
+static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos)
+{
+       int blockmask = inode->i_sb->s_blocksize - 1;
+       loff_t final_size = pos + count;
+
+       if ((pos & blockmask) || (final_size & blockmask))
+               return 1;
+       return 0;
+}
+
 static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
                                            struct file *file,
                                            loff_t pos, size_t count,
@@ -2230,6 +2250,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        int full_coherency = !(osb->s_mount_opt &
                               OCFS2_MOUNT_COHERENCY_BUFFERED);
+       int unaligned_dio = 0;
 
        trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
                (unsigned long long)OCFS2_I(inode)->ip_blkno,
@@ -2297,6 +2318,10 @@ relock:
                goto out;
        }
 
+       if (direct_io && !is_sync_kiocb(iocb))
+               unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_left,
+                                                     *ppos);
+
        /*
         * We can't complete the direct I/O as requested, fall back to
         * buffered I/O.
@@ -2311,6 +2336,18 @@ relock:
                goto relock;
        }
 
+       if (unaligned_dio) {
+               /*
+                * Wait on previous unaligned aio to complete before
+                * proceeding.
+                */
+               ocfs2_aiodio_wait(inode);
+
+               /* Mark the iocb as needing a decrement in ocfs2_dio_end_io */
+               atomic_inc(&OCFS2_I(inode)->ip_unaligned_aio);
+               ocfs2_iocb_set_unaligned_aio(iocb);
+       }
+
        /*
         * To later detect whether a journal commit for sync writes is
         * necessary, we sample i_size, and cluster count here.
@@ -2382,8 +2419,12 @@ out_dio:
        if ((ret == -EIOCBQUEUED) || (!ocfs2_iocb_is_rw_locked(iocb))) {
                rw_level = -1;
                have_alloc_sem = 0;
+               unaligned_dio = 0;
        }
 
+       if (unaligned_dio)
+               atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio);
+
 out:
        if (rw_level != -1)
                ocfs2_rw_unlock(inode, rw_level);
@@ -2591,6 +2632,57 @@ bail:
        return ret;
 }
 
+/* Refer generic_file_llseek_unlocked() */
+static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int origin)
+{
+       struct inode *inode = file->f_mapping->host;
+       int ret = 0;
+
+       mutex_lock(&inode->i_mutex);
+
+       switch (origin) {
+       case SEEK_SET:
+               break;
+       case SEEK_END:
+               offset += inode->i_size;
+               break;
+       case SEEK_CUR:
+               if (offset == 0) {
+                       offset = file->f_pos;
+                       goto out;
+               }
+               offset += file->f_pos;
+               break;
+       case SEEK_DATA:
+       case SEEK_HOLE:
+               ret = ocfs2_seek_data_hole_offset(file, &offset, origin);
+               if (ret)
+                       goto out;
+               break;
+       default:
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
+               ret = -EINVAL;
+       if (!ret && offset > inode->i_sb->s_maxbytes)
+               ret = -EINVAL;
+       if (ret)
+               goto out;
+
+       if (offset != file->f_pos) {
+               file->f_pos = offset;
+               file->f_version = 0;
+       }
+
+out:
+       mutex_unlock(&inode->i_mutex);
+       if (ret)
+               return ret;
+       return offset;
+}
+
 const struct inode_operations ocfs2_file_iops = {
        .setattr        = ocfs2_setattr,
        .getattr        = ocfs2_getattr,
@@ -2615,7 +2707,7 @@ const struct inode_operations ocfs2_special_file_iops = {
  * ocfs2_fops_no_plocks and ocfs2_dops_no_plocks!
  */
 const struct file_operations ocfs2_fops = {
-       .llseek         = generic_file_llseek,
+       .llseek         = ocfs2_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
        .mmap           = ocfs2_mmap,
@@ -2663,7 +2755,7 @@ const struct file_operations ocfs2_dops = {
  * the cluster.
  */
 const struct file_operations ocfs2_fops_no_plocks = {
-       .llseek         = generic_file_llseek,
+       .llseek         = ocfs2_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
        .mmap           = ocfs2_mmap,
index a22d2c098890a9ca67e2056976bfc9869d74a325..17454a904d7bf488093de9f3db61dc529e0f8e3c 100644 (file)
@@ -951,7 +951,7 @@ static void ocfs2_cleanup_delete_inode(struct inode *inode,
        trace_ocfs2_cleanup_delete_inode(
                (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data);
        if (sync_data)
-               write_inode_now(inode, 1);
+               filemap_write_and_wait(inode->i_mapping);
        truncate_inode_pages(&inode->i_data, 0);
 }
 
index 1c508b149b3ac1bd4325fd33a9aae6bdb70e024a..88924a3133fae7c15ca3f5a5259b64eecd97022e 100644 (file)
@@ -43,6 +43,9 @@ struct ocfs2_inode_info
        /* protects extended attribute changes on this inode */
        struct rw_semaphore             ip_xattr_sem;
 
+       /* Number of outstanding AIO's which are not page aligned */
+       atomic_t                        ip_unaligned_aio;
+
        /* These fields are protected by ip_lock */
        spinlock_t                      ip_lock;
        u32                             ip_open_count;
index bc91072b72196fd335c4b7cbc02ba08cb67254e6..726ff265b296bc3365cfe46e94588c1ee4f6ed6a 100644 (file)
@@ -122,7 +122,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
        if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) &
                (OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) {
                if (!capable(CAP_LINUX_IMMUTABLE))
-                       goto bail_unlock;
+                       goto bail_commit;
        }
 
        ocfs2_inode->ip_attr = flags;
@@ -132,6 +132,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
        if (status < 0)
                mlog_errno(status);
 
+bail_commit:
        ocfs2_commit_trans(osb, handle);
 bail_unlock:
        ocfs2_inode_unlock(inode, 1);
@@ -381,7 +382,7 @@ int ocfs2_info_handle_freeinode(struct inode *inode,
        if (!oifi) {
                status = -ENOMEM;
                mlog_errno(status);
-               goto bail;
+               goto out_err;
        }
 
        if (o2info_from_user(*oifi, req))
@@ -431,7 +432,7 @@ bail:
                o2info_set_request_error(&oifi->ifi_req, req);
 
        kfree(oifi);
-
+out_err:
        return status;
 }
 
@@ -666,7 +667,7 @@ int ocfs2_info_handle_freefrag(struct inode *inode,
        if (!oiff) {
                status = -ENOMEM;
                mlog_errno(status);
-               goto bail;
+               goto out_err;
        }
 
        if (o2info_from_user(*oiff, req))
@@ -716,7 +717,7 @@ bail:
                o2info_set_request_error(&oiff->iff_req, req);
 
        kfree(oiff);
-
+out_err:
        return status;
 }
 
index 295d56454e8b23b6e9d97a6bd258e6170311c8f5..0a42ae96dca7d4a0f662505e0e51206895ce4156 100644 (file)
@@ -1544,9 +1544,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
        /* we need to run complete recovery for offline orphan slots */
        ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
 
-       mlog(ML_NOTICE, "Recovering node %d from slot %d on device (%u,%u)\n",
-            node_num, slot_num,
-            MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
+       printk(KERN_NOTICE "ocfs2: Begin replay journal (node %d, slot %d) on "\
+              "device (%u,%u)\n", node_num, slot_num, MAJOR(osb->sb->s_dev),
+              MINOR(osb->sb->s_dev));
 
        OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
 
@@ -1601,6 +1601,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
 
        jbd2_journal_destroy(journal);
 
+       printk(KERN_NOTICE "ocfs2: End replay journal (node %d, slot %d) on "\
+              "device (%u,%u)\n", node_num, slot_num, MAJOR(osb->sb->s_dev),
+              MINOR(osb->sb->s_dev));
 done:
        /* drop the lock on this nodes journal */
        if (got_lock)
@@ -1808,6 +1811,20 @@ static inline unsigned long ocfs2_orphan_scan_timeout(void)
  * every slot, queuing a recovery of the slot on the ocfs2_wq thread. This
  * is done to catch any orphans that are left over in orphan directories.
  *
+ * It scans all slots, even ones that are in use. It does so to handle the
+ * case described below:
+ *
+ *   Node 1 has an inode it was using. The dentry went away due to memory
+ *   pressure.  Node 1 closes the inode, but it's on the free list. The node
+ *   has the open lock.
+ *   Node 2 unlinks the inode. It grabs the dentry lock to notify others,
+ *   but node 1 has no dentry and doesn't get the message. It trylocks the
+ *   open lock, sees that another node has a PR, and does nothing.
+ *   Later node 2 runs its orphan dir. It igets the inode, trylocks the
+ *   open lock, sees the PR still, and does nothing.
+ *   Basically, we have to trigger an orphan iput on node 1. The only way
+ *   for this to happen is if node 1 runs node 2's orphan dir.
+ *
  * ocfs2_queue_orphan_scan gets called every ORPHAN_SCAN_SCHEDULE_TIMEOUT
  * seconds.  It gets an EX lock on os_lockres and checks sequence number
  * stored in LVB. If the sequence number has changed, it means some other
index 68cf2f6d3c6a40b22dda3e2d4f7e2d44349167fa..a3385b63ff5e542bcfaabe59744fa3af38b537e4 100644 (file)
@@ -441,10 +441,11 @@ static inline int ocfs2_mknod_credits(struct super_block *sb, int is_dir,
 #define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)
 
 /* file update (nlink, etc) + directory mtime/ctime + dir entry block + quota
- * update on dir + index leaf + dx root update for free list */
+ * update on dir + index leaf + dx root update for free list +
+ * previous dirblock update in the free list */
 static inline int ocfs2_link_credits(struct super_block *sb)
 {
-       return 2*OCFS2_INODE_UPDATE_CREDITS + 3 +
+       return 2*OCFS2_INODE_UPDATE_CREDITS + 4 +
               ocfs2_quota_trans_credits(sb);
 }
 
index 3e9393ca39ebd823772ae910cda1b4516d46fa62..9cd41083e99123eca1c48085fb39809e6b906b40 100644 (file)
@@ -61,7 +61,7 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
 static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
                                struct page *page)
 {
-       int ret;
+       int ret = VM_FAULT_NOPAGE;
        struct inode *inode = file->f_path.dentry->d_inode;
        struct address_space *mapping = inode->i_mapping;
        loff_t pos = page_offset(page);
@@ -71,32 +71,25 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
        void *fsdata;
        loff_t size = i_size_read(inode);
 
-       /*
-        * Another node might have truncated while we were waiting on
-        * cluster locks.
-        * We don't check size == 0 before the shift. This is borrowed
-        * from do_generic_file_read.
-        */
        last_index = (size - 1) >> PAGE_CACHE_SHIFT;
-       if (unlikely(!size || page->index > last_index)) {
-               ret = -EINVAL;
-               goto out;
-       }
 
        /*
-        * The i_size check above doesn't catch the case where nodes
-        * truncated and then re-extended the file. We'll re-check the
-        * page mapping after taking the page lock inside of
-        * ocfs2_write_begin_nolock().
+        * There are cases that lead to the page no longer bebongs to the
+        * mapping.
+        * 1) pagecache truncates locally due to memory pressure.
+        * 2) pagecache truncates when another is taking EX lock against 
+        * inode lock. see ocfs2_data_convert_worker.
+        * 
+        * The i_size check doesn't catch the case where nodes truncated and
+        * then re-extended the file. We'll re-check the page mapping after
+        * taking the page lock inside of ocfs2_write_begin_nolock().
+        *
+        * Let VM retry with these cases.
         */
-       if (!PageUptodate(page) || page->mapping != inode->i_mapping) {
-               /*
-                * the page has been umapped in ocfs2_data_downconvert_worker.
-                * So return 0 here and let VFS retry.
-                */
-               ret = 0;
+       if ((page->mapping != inode->i_mapping) ||
+           (!PageUptodate(page)) ||
+           (page_offset(page) >= size))
                goto out;
-       }
 
        /*
         * Call ocfs2_write_begin() and ocfs2_write_end() to take
@@ -116,17 +109,21 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
        if (ret) {
                if (ret != -ENOSPC)
                        mlog_errno(ret);
+               if (ret == -ENOMEM)
+                       ret = VM_FAULT_OOM;
+               else
+                       ret = VM_FAULT_SIGBUS;
                goto out;
        }
 
-       ret = ocfs2_write_end_nolock(mapping, pos, len, len, locked_page,
-                                    fsdata);
-       if (ret < 0) {
-               mlog_errno(ret);
+       if (!locked_page) {
+               ret = VM_FAULT_NOPAGE;
                goto out;
        }
+       ret = ocfs2_write_end_nolock(mapping, pos, len, len, locked_page,
+                                    fsdata);
        BUG_ON(ret != len);
-       ret = 0;
+       ret = VM_FAULT_LOCKED;
 out:
        return ret;
 }
@@ -168,8 +165,6 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 
 out:
        ocfs2_unblock_signals(&oldset);
-       if (ret)
-               ret = VM_FAULT_SIGBUS;
        return ret;
 }
 
index d53cb706f14c27dfc5ec754dc6d0f846e424421c..184c76b8c293907368f325316da04f57801d87eb 100644 (file)
@@ -745,7 +745,7 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context,
         */
        ocfs2_probe_alloc_group(inode, gd_bh, &goal_bit, len, move_max_hop,
                                new_phys_cpos);
-       if (!new_phys_cpos) {
+       if (!*new_phys_cpos) {
                ret = -ENOSPC;
                goto out_commit;
        }
index 409285854f647e2357223bc7a8d24c36b376a6bb..d355e6e36b366bfe7dc8cc91cbabdad05976ba2c 100644 (file)
@@ -836,18 +836,65 @@ static inline unsigned int ocfs2_clusters_to_megabytes(struct super_block *sb,
 
 static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap)
 {
-       __test_and_set_bit_le(bit, bitmap);
+       __set_bit_le(bit, bitmap);
 }
 #define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr))
 
 static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap)
 {
-       __test_and_clear_bit_le(bit, bitmap);
+       __clear_bit_le(bit, bitmap);
 }
 #define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr))
 
 #define ocfs2_test_bit test_bit_le
 #define ocfs2_find_next_zero_bit find_next_zero_bit_le
 #define ocfs2_find_next_bit find_next_bit_le
+
+static inline void *correct_addr_and_bit_unaligned(int *bit, void *addr)
+{
+#if BITS_PER_LONG == 64
+       *bit += ((unsigned long) addr & 7UL) << 3;
+       addr = (void *) ((unsigned long) addr & ~7UL);
+#elif BITS_PER_LONG == 32
+       *bit += ((unsigned long) addr & 3UL) << 3;
+       addr = (void *) ((unsigned long) addr & ~3UL);
+#else
+#error "how many bits you are?!"
+#endif
+       return addr;
+}
+
+static inline void ocfs2_set_bit_unaligned(int bit, void *bitmap)
+{
+       bitmap = correct_addr_and_bit_unaligned(&bit, bitmap);
+       ocfs2_set_bit(bit, bitmap);
+}
+
+static inline void ocfs2_clear_bit_unaligned(int bit, void *bitmap)
+{
+       bitmap = correct_addr_and_bit_unaligned(&bit, bitmap);
+       ocfs2_clear_bit(bit, bitmap);
+}
+
+static inline int ocfs2_test_bit_unaligned(int bit, void *bitmap)
+{
+       bitmap = correct_addr_and_bit_unaligned(&bit, bitmap);
+       return ocfs2_test_bit(bit, bitmap);
+}
+
+static inline int ocfs2_find_next_zero_bit_unaligned(void *bitmap, int max,
+                                                       int start)
+{
+       int fix = 0, ret, tmpmax;
+       bitmap = correct_addr_and_bit_unaligned(&fix, bitmap);
+       tmpmax = max + fix;
+       start += fix;
+
+       ret = ocfs2_find_next_zero_bit(bitmap, tmpmax, start) - fix;
+       if (ret > max)
+               return max;
+       return ret;
+}
+
 #endif  /* OCFS2_H */
 
index dc8007fc924718c6d461b22cee52e4a8fbd6ae7d..f100bf70a9066ed1b917b8ec0451c27231840f92 100644 (file)
@@ -404,7 +404,9 @@ struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
        int status = 0;
        struct ocfs2_quota_recovery *rec;
 
-       mlog(ML_NOTICE, "Beginning quota recovery in slot %u\n", slot_num);
+       printk(KERN_NOTICE "ocfs2: Beginning quota recovery on device (%s) for "
+              "slot %u\n", osb->dev_str, slot_num);
+
        rec = ocfs2_alloc_quota_recovery();
        if (!rec)
                return ERR_PTR(-ENOMEM);
@@ -549,8 +551,8 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
                                goto out_commit;
                        }
                        lock_buffer(qbh);
-                       WARN_ON(!ocfs2_test_bit(bit, dchunk->dqc_bitmap));
-                       ocfs2_clear_bit(bit, dchunk->dqc_bitmap);
+                       WARN_ON(!ocfs2_test_bit_unaligned(bit, dchunk->dqc_bitmap));
+                       ocfs2_clear_bit_unaligned(bit, dchunk->dqc_bitmap);
                        le32_add_cpu(&dchunk->dqc_free, 1);
                        unlock_buffer(qbh);
                        ocfs2_journal_dirty(handle, qbh);
@@ -596,7 +598,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
        struct inode *lqinode;
        unsigned int flags;
 
-       mlog(ML_NOTICE, "Finishing quota recovery in slot %u\n", slot_num);
+       printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
+              "slot %u\n", osb->dev_str, slot_num);
+
        mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
        for (type = 0; type < MAXQUOTAS; type++) {
                if (list_empty(&(rec->r_list[type])))
@@ -612,8 +616,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
                /* Someone else is holding the lock? Then he must be
                 * doing the recovery. Just skip the file... */
                if (status == -EAGAIN) {
-                       mlog(ML_NOTICE, "skipping quota recovery for slot %d "
-                            "because quota file is locked.\n", slot_num);
+                       printk(KERN_NOTICE "ocfs2: Skipping quota recovery on "
+                              "device (%s) for slot %d because quota file is "
+                              "locked.\n", osb->dev_str, slot_num);
                        status = 0;
                        goto out_put;
                } else if (status < 0) {
@@ -944,7 +949,7 @@ static struct ocfs2_quota_chunk *ocfs2_find_free_entry(struct super_block *sb,
                      * ol_quota_entries_per_block(sb);
        }
 
-       found = ocfs2_find_next_zero_bit(dchunk->dqc_bitmap, len, 0);
+       found = ocfs2_find_next_zero_bit_unaligned(dchunk->dqc_bitmap, len, 0);
        /* We failed? */
        if (found == len) {
                mlog(ML_ERROR, "Did not find empty entry in chunk %d with %u"
@@ -1208,7 +1213,7 @@ static void olq_alloc_dquot(struct buffer_head *bh, void *private)
        struct ocfs2_local_disk_chunk *dchunk;
 
        dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
-       ocfs2_set_bit(*offset, dchunk->dqc_bitmap);
+       ocfs2_set_bit_unaligned(*offset, dchunk->dqc_bitmap);
        le32_add_cpu(&dchunk->dqc_free, -1);
 }
 
@@ -1289,7 +1294,7 @@ int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot)
                        (od->dq_chunk->qc_headerbh->b_data);
        /* Mark structure as freed */
        lock_buffer(od->dq_chunk->qc_headerbh);
-       ocfs2_clear_bit(offset, dchunk->dqc_bitmap);
+       ocfs2_clear_bit_unaligned(offset, dchunk->dqc_bitmap);
        le32_add_cpu(&dchunk->dqc_free, 1);
        unlock_buffer(od->dq_chunk->qc_headerbh);
        ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh);
index 26fc0014d50936137d0afb898b7c9541e8026087..1424c151cccce0170819ce4e0f36dad7d97461b8 100644 (file)
@@ -493,8 +493,8 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
                        goto bail;
                }
        } else
-               mlog(ML_NOTICE, "slot %d is already allocated to this node!\n",
-                    slot);
+               printk(KERN_INFO "ocfs2: Slot %d on device (%s) was already "
+                      "allocated to this node!\n", slot, osb->dev_str);
 
        ocfs2_set_slot(si, slot, osb->node_num);
        osb->slot_num = slot;
index 19965b00c43caee7df4e09428775a55150ba9f8c..94368017edb378ce1e3961d1976408c954677c9a 100644 (file)
@@ -28,6 +28,7 @@
 #include "cluster/masklog.h"
 #include "cluster/nodemanager.h"
 #include "cluster/heartbeat.h"
+#include "cluster/tcp.h"
 
 #include "stackglue.h"
 
@@ -255,6 +256,61 @@ static void o2cb_dump_lksb(struct ocfs2_dlm_lksb *lksb)
        dlm_print_one_lock(lksb->lksb_o2dlm.lockid);
 }
 
+/*
+ * Check if this node is heartbeating and is connected to all other
+ * heartbeating nodes.
+ */
+static int o2cb_cluster_check(void)
+{
+       u8 node_num;
+       int i;
+       unsigned long hbmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long netmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+
+       node_num = o2nm_this_node();
+       if (node_num == O2NM_MAX_NODES) {
+               printk(KERN_ERR "o2cb: This node has not been configured.\n");
+               return -EINVAL;
+       }
+
+       /*
+        * o2dlm expects o2net sockets to be created. If not, then
+        * dlm_join_domain() fails with a stack of errors which are both cryptic
+        * and incomplete. The idea here is to detect upfront whether we have
+        * managed to connect to all nodes or not. If not, then list the nodes
+        * to allow the user to check the configuration (incorrect IP, firewall,
+        * etc.) Yes, this is racy. But its not the end of the world.
+        */
+#define        O2CB_MAP_STABILIZE_COUNT        60
+       for (i = 0; i < O2CB_MAP_STABILIZE_COUNT; ++i) {
+               o2hb_fill_node_map(hbmap, sizeof(hbmap));
+               if (!test_bit(node_num, hbmap)) {
+                       printk(KERN_ERR "o2cb: %s heartbeat has not been "
+                              "started.\n", (o2hb_global_heartbeat_active() ?
+                                             "Global" : "Local"));
+                       return -EINVAL;
+               }
+               o2net_fill_node_map(netmap, sizeof(netmap));
+               /* Force set the current node to allow easy compare */
+               set_bit(node_num, netmap);
+               if (!memcmp(hbmap, netmap, sizeof(hbmap)))
+                       return 0;
+               if (i < O2CB_MAP_STABILIZE_COUNT)
+                       msleep(1000);
+       }
+
+       printk(KERN_ERR "o2cb: This node could not connect to nodes:");
+       i = -1;
+       while ((i = find_next_bit(hbmap, O2NM_MAX_NODES,
+                                 i + 1)) < O2NM_MAX_NODES) {
+               if (!test_bit(i, netmap))
+                       printk(" %u", i);
+       }
+       printk(".\n");
+
+       return -ENOTCONN;
+}
+
 /*
  * Called from the dlm when it's about to evict a node. This is how the
  * classic stack signals node death.
@@ -263,8 +319,8 @@ static void o2dlm_eviction_cb(int node_num, void *data)
 {
        struct ocfs2_cluster_connection *conn = data;
 
-       mlog(ML_NOTICE, "o2dlm has evicted node %d from group %.*s\n",
-            node_num, conn->cc_namelen, conn->cc_name);
+       printk(KERN_NOTICE "o2cb: o2dlm has evicted node %d from domain %.*s\n",
+              node_num, conn->cc_namelen, conn->cc_name);
 
        conn->cc_recovery_handler(node_num, conn->cc_recovery_data);
 }
@@ -280,12 +336,11 @@ static int o2cb_cluster_connect(struct ocfs2_cluster_connection *conn)
        BUG_ON(conn == NULL);
        BUG_ON(conn->cc_proto == NULL);
 
-       /* for now we only have one cluster/node, make sure we see it
-        * in the heartbeat universe */
-       if (!o2hb_check_local_node_heartbeating()) {
-               if (o2hb_global_heartbeat_active())
-                       mlog(ML_ERROR, "Global heartbeat not started\n");
-               rc = -EINVAL;
+       /* Ensure cluster stack is up and all nodes are connected */
+       rc = o2cb_cluster_check();
+       if (rc) {
+               printk(KERN_ERR "o2cb: Cluster check failed. Fix errors "
+                      "before retrying.\n");
                goto out;
        }
 
index 56f61027236b696fce1ccde3e1edaf86acee59a0..4994f8b0e60410ff576fa63299e29e430192080a 100644 (file)
@@ -54,6 +54,7 @@
 #include "ocfs1_fs_compat.h"
 
 #include "alloc.h"
+#include "aops.h"
 #include "blockcheck.h"
 #include "dlmglue.h"
 #include "export.h"
@@ -1107,9 +1108,9 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 
                ocfs2_set_ro_flag(osb, 1);
 
-               printk(KERN_NOTICE "Readonly device detected. No cluster "
-                      "services will be utilized for this mount. Recovery "
-                      "will be skipped.\n");
+               printk(KERN_NOTICE "ocfs2: Readonly device (%s) detected. "
+                      "Cluster services will not be used for this mount. "
+                      "Recovery will be skipped.\n", osb->dev_str);
        }
 
        if (!ocfs2_is_hard_readonly(osb)) {
@@ -1616,12 +1617,17 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
        return 0;
 }
 
+wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 static int __init ocfs2_init(void)
 {
-       int status;
+       int status, i;
 
        ocfs2_print_version();
 
+       for (i = 0; i < OCFS2_IOEND_WQ_HASH_SZ; i++)
+               init_waitqueue_head(&ocfs2__ioend_wq[i]);
+
        status = init_ocfs2_uptodate_cache();
        if (status < 0) {
                mlog_errno(status);
@@ -1760,7 +1766,7 @@ static void ocfs2_inode_init_once(void *data)
        ocfs2_extent_map_init(&oi->vfs_inode);
        INIT_LIST_HEAD(&oi->ip_io_markers);
        oi->ip_dir_start_lookup = 0;
-
+       atomic_set(&oi->ip_unaligned_aio, 0);
        init_rwsem(&oi->ip_alloc_sem);
        init_rwsem(&oi->ip_xattr_sem);
        mutex_init(&oi->ip_io_mutex);
@@ -1974,7 +1980,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
         * If we failed before we got a uuid_str yet, we can't stop
         * heartbeat.  Otherwise, do it.
         */
-       if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str)
+       if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str &&
+           !ocfs2_is_hard_readonly(osb))
                hangup_needed = 1;
 
        if (osb->cconn)
@@ -2353,7 +2360,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
                mlog_errno(status);
                goto bail;
        }
-       cleancache_init_shared_fs((char *)&uuid_net_key, sb);
+       cleancache_init_shared_fs((char *)&di->id2.i_super.s_uuid, sb);
 
 bail:
        return status;
@@ -2462,8 +2469,8 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
                        goto finally;
                }
        } else {
-               mlog(ML_NOTICE, "File system was not unmounted cleanly, "
-                    "recovering volume.\n");
+               printk(KERN_NOTICE "ocfs2: File system on device (%s) was not "
+                      "unmounted cleanly, recovering it.\n", osb->dev_str);
        }
 
        local = ocfs2_mount_local(osb);
index 194fb22ef79d590580f3245b522d0b095ef3794c..aa9e8777b09a5e345b081b0e495db378485a30e7 100644 (file)
@@ -2376,16 +2376,18 @@ static int ocfs2_remove_value_outside(struct inode*inode,
                }
 
                ret = ocfs2_xattr_value_truncate(inode, vb, 0, &ctxt);
-               if (ret < 0) {
-                       mlog_errno(ret);
-                       break;
-               }
 
                ocfs2_commit_trans(osb, ctxt.handle);
                if (ctxt.meta_ac) {
                        ocfs2_free_alloc_context(ctxt.meta_ac);
                        ctxt.meta_ac = NULL;
                }
+
+               if (ret < 0) {
+                       mlog_errno(ret);
+                       break;
+               }
+
        }
 
        if (ctxt.meta_ac)
index 2bd620f0d796cf5dee01590c65b7ac8802e33bf9..57bbf9078ac8f327be28e88b38e10eeff1f9bfc0 100644 (file)
@@ -167,6 +167,7 @@ int pstore_register(struct pstore_info *psi)
        }
 
        psinfo = psi;
+       mutex_init(&psinfo->read_mutex);
        spin_unlock(&pstore_lock);
 
        if (owner && !try_module_get(owner)) {
@@ -195,30 +196,32 @@ EXPORT_SYMBOL_GPL(pstore_register);
 void pstore_get_records(int quiet)
 {
        struct pstore_info *psi = psinfo;
+       char                    *buf = NULL;
        ssize_t                 size;
        u64                     id;
        enum pstore_type_id     type;
        struct timespec         time;
        int                     failed = 0, rc;
-       unsigned long           flags;
 
        if (!psi)
                return;
 
-       spin_lock_irqsave(&psinfo->buf_lock, flags);
+       mutex_lock(&psi->read_mutex);
        rc = psi->open(psi);
        if (rc)
                goto out;
 
-       while ((size = psi->read(&id, &type, &time, psi)) > 0) {
-               rc = pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size,
+       while ((size = psi->read(&id, &type, &time, &buf, psi)) > 0) {
+               rc = pstore_mkfile(type, psi->name, id, buf, (size_t)size,
                                  time, psi);
+               kfree(buf);
+               buf = NULL;
                if (rc && (rc != -EEXIST || !quiet))
                        failed++;
        }
        psi->close(psi);
 out:
-       spin_unlock_irqrestore(&psinfo->buf_lock, flags);
+       mutex_unlock(&psi->read_mutex);
 
        if (failed)
                printk(KERN_WARNING "pstore: failed to load %d record(s) from '%s'\n",
index 5cff443f6cdb782f4d89cfed6e767bdb24a32e06..0bbb1a41998bc95563813ef8a584e104aad5c462 100644 (file)
@@ -674,7 +674,8 @@ xfs_qm_dqattach_one(
         * disk and we didn't ask it to allocate;
         * ESRCH if quotas got turned off suddenly.
         */
-       error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp);
+       error = xfs_qm_dqget(ip->i_mount, ip, id, type,
+                            doalloc | XFS_QMOPT_DOWARN, &dqp);
        if (error)
                return error;
 
index d30bedfeb7efd22a288b2323b870d40593f56124..ddd46db65b57257164f13d703186bb7da5e7bb3a 100644 (file)
@@ -235,6 +235,8 @@ struct drm_mode_fb_cmd {
 #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
 #define DRM_MODE_FB_DIRTY_FLAGS         0x03
 
+#define DRM_MODE_FB_DIRTY_MAX_CLIPS     256
+
 /*
  * Mark a region of a framebuffer as dirty.
  *
index 3d53efd25ab906889e081acb8ae10f1065ef180a..f81676f1b3105636bde40ebd0c99d5e7265f7600 100644 (file)
@@ -4,6 +4,7 @@
 */
 #define radeon_PCI_IDS \
        {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+       {0x1002, 0x3151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
@@ -55,6 +56,7 @@
        {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
        {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
        {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
+       {0x1002, 0x4C6E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
        {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
        {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
        {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
index 1d161cb3aca5c098b76dcc1fdd47bdd8de579814..12050434d57a248909d695a80445e958dea81e32 100644 (file)
 /**
  * User-desired buffer creation information structure.
  *
- * @size: requested size for the object.
+ * @size: user-desired memory allocation size.
  *     - this size value would be page-aligned internally.
  * @flags: user request for setting memory type or cache attributes.
- * @handle: returned handle for the object.
- * @pad: just padding to be 64-bit aligned.
+ * @handle: returned a handle to created gem object.
+ *     - this handle will be set by gem module of kernel side.
  */
 struct drm_exynos_gem_create {
-       unsigned int size;
+       uint64_t size;
        unsigned int flags;
        unsigned int handle;
-       unsigned int pad;
 };
 
 /**
index b65be6054a183efe7b0ea5daa7c8afd7b1aa6a72..be94be6d6f17afdd027b3cf61679c73651ac6f9e 100644 (file)
@@ -874,6 +874,10 @@ struct drm_radeon_gem_pwrite {
 
 #define RADEON_CHUNK_ID_RELOCS 0x01
 #define RADEON_CHUNK_ID_IB     0x02
+#define RADEON_CHUNK_ID_FLAGS  0x03
+
+/* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */
+#define RADEON_CS_KEEP_TILING_FLAGS 0x01
 
 struct drm_radeon_cs_chunk {
        uint32_t                chunk_id;
index a3c071c9e18934765e44b84d8330e9fd979d6dc4..847994aef0e9755a3a39d76dd42f87c9f43d23be 100644 (file)
@@ -211,8 +211,8 @@ extern void bio_pair_release(struct bio_pair *dbio);
 extern struct bio_set *bioset_create(unsigned int, unsigned int);
 extern void bioset_free(struct bio_set *);
 
-extern struct bio *bio_alloc(gfp_t, int);
-extern struct bio *bio_kmalloc(gfp_t, int);
+extern struct bio *bio_alloc(gfp_t, unsigned int);
+extern struct bio *bio_kmalloc(gfp_t, unsigned int);
 extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *);
 extern void bio_put(struct bio *);
 extern void bio_free(struct bio *, struct bio_set *);
@@ -519,7 +519,11 @@ extern void bio_integrity_init(void);
 #define bioset_integrity_create(a, b)  (0)
 #define bio_integrity_prep(a)          (0)
 #define bio_integrity_enabled(a)       (0)
-#define bio_integrity_clone(a, b, c, d)        (0)
+static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
+                                     gfp_t gfp_mask, struct bio_set *bs)
+{
+       return 0;
+}
 #define bioset_integrity_free(a)       do { } while (0)
 #define bio_integrity_free(a, b)       do { } while (0)
 #define bio_integrity_endio(a, b)      do { } while (0)
index f88eacb111d4151dc5491797fe0e03faaadc26a9..7c05ac202d90650069d4713ac2e13b3be9b86024 100644 (file)
 #include "osdmap.h"
 #include "messenger.h"
 
+/* 
+ * Maximum object name size 
+ * (must be at least as big as RBD_MAX_MD_NAME_LEN -- currently 100) 
+ */
+#define MAX_OBJ_NAME_SIZE 100
+
 struct ceph_msg;
 struct ceph_snap_context;
 struct ceph_osd_request;
@@ -75,7 +81,7 @@ struct ceph_osd_request {
        struct inode *r_inode;                /* for use by callbacks */
        void *r_priv;                         /* ditto */
 
-       char              r_oid[40];          /* object name */
+       char              r_oid[MAX_OBJ_NAME_SIZE];          /* object name */
        int               r_oid_len;
        unsigned long     r_stamp;            /* send OR check time */
 
index 139c4db55f1736eebc35cc4601ee98d0d10a40c7..c86c940d1de3a58b73fd4027b80524daca997478 100644 (file)
@@ -156,6 +156,7 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
  * @mult:              cycle to nanosecond multiplier
  * @shift:             cycle to nanosecond divisor (power of two)
  * @max_idle_ns:       max idle time permitted by the clocksource (nsecs)
+ * @maxadj             maximum adjustment value to mult (~11%)
  * @flags:             flags describing special properties
  * @archdata:          arch-specific data
  * @suspend:           suspend function for the clocksource, if necessary
@@ -172,7 +173,7 @@ struct clocksource {
        u32 mult;
        u32 shift;
        u64 max_idle_ns;
-
+       u32 maxadj;
 #ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
        struct arch_clocksource_data archdata;
 #endif
index ffbcf95cd97dbb3b7e12f9be778c90f1977a9a1a..3136ede5a1e1bb8434a0e2d52840f84de39647de 100644 (file)
@@ -69,7 +69,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
  * @resume:    Called to bring a device on this bus out of sleep mode.
  * @pm:                Power management operations of this bus, callback the specific
  *             device driver's pm-ops.
- * @iommu_ops   IOMMU specific operations for this bus, used to attach IOMMU
+ * @iommu_ops:  IOMMU specific operations for this bus, used to attach IOMMU
  *              driver implementations to a bus and allow the driver to do
  *              bus-specific setup
  * @p:         The private data of the driver core, only the driver core can
@@ -682,6 +682,11 @@ static inline bool device_async_suspend_enabled(struct device *dev)
        return !!dev->power.async_suspend;
 }
 
+static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
+{
+       dev->power.ignore_children = enable;
+}
+
 static inline void device_lock(struct device *dev)
 {
        mutex_lock(&dev->mutex);
index 0c4df261af7e6a32d5b5c80633fa6a643e2d6285..e3130220ce3e3ddf7837c64b5fdadb0342f9f690 100644 (file)
@@ -1886,6 +1886,7 @@ extern struct dentry *mount_single(struct file_system_type *fs_type,
 extern struct dentry *mount_nodev(struct file_system_type *fs_type,
        int flags, void *data,
        int (*fill_super)(struct super_block *, void *, int));
+extern struct dentry *mount_subtree(struct vfsmount *mnt, const char *path);
 void generic_shutdown_super(struct super_block *sb);
 void kill_block_super(struct super_block *sb);
 void kill_anon_super(struct super_block *sb);
index 9de31bc98c8803bc96bac1f0751da3ca695bf8df..6d18f3531f180f401d35e8028b3395b339182c2e 100644 (file)
@@ -21,8 +21,6 @@
 #define dev_to_part(device)    container_of((device), struct hd_struct, __dev)
 #define disk_to_dev(disk)      (&(disk)->part0.__dev)
 #define part_to_dev(part)      (&((part)->__dev))
-#define alias_name(disk)       ((disk)->alias ? (disk)->alias : \
-                                                (disk)->disk_name)
 
 extern struct device_type part_type;
 extern struct kobject *block_depr;
@@ -60,7 +58,6 @@ enum {
 
 #define DISK_MAX_PARTS                 256
 #define DISK_NAME_LEN                  32
-#define ALIAS_LEN                      256
 
 #include <linux/major.h>
 #include <linux/device.h>
@@ -166,7 +163,6 @@ struct gendisk {
                                          * disks that can't be partitioned. */
 
        char disk_name[DISK_NAME_LEN];  /* name of major driver */
-       char *alias;                    /* alias name of disk */
        char *(*devnode)(struct gendisk *gd, mode_t *mode);
 
        unsigned int events;            /* supported events */
index 19644e0016bdbb4837e1fa8f28cd276797fd00a4..d9d6c868b86bc01226031d63ce5ee72eb44ebed6 100644 (file)
@@ -110,11 +110,6 @@ static inline void copy_huge_page(struct page *dst, struct page *src)
 
 #define hugetlb_change_protection(vma, address, end, newprot)
 
-#ifndef HPAGE_MASK
-#define HPAGE_MASK     PAGE_MASK               /* Keep the compiler happy */
-#define HPAGE_SIZE     PAGE_SIZE
-#endif
-
 #endif /* !CONFIG_HUGETLB_PAGE */
 
 #define HUGETLB_ANON_FILE "anon_hugepage"
index a81bf6d23b3e6ad62333696032e0b49317115667..07d103a06d64a04e17e06a2b9011f773ef60d8f1 100644 (file)
@@ -432,9 +432,6 @@ void i2c_unlock_adapter(struct i2c_adapter *);
 /* Internal numbers to terminate lists */
 #define I2C_CLIENT_END         0xfffeU
 
-/* The numbers to use to set I2C bus address */
-#define ANY_I2C_BUS            0xffff
-
 /* Construct an I2C_CLIENT_END-terminated array of i2c addresses */
 #define I2C_ADDRS(addr, addrs...) \
        ((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END })
index 80b480c97532f25801c952fef3d515df907b9c8e..abf5028db98193bb36c5a4c590ac588cc2b1b9ca 100644 (file)
@@ -98,9 +98,10 @@ enum {
        INET_DIAG_VEGASINFO,
        INET_DIAG_CONG,
        INET_DIAG_TOS,
+       INET_DIAG_TCLASS,
 };
 
-#define INET_DIAG_MAX INET_DIAG_TOS
+#define INET_DIAG_MAX INET_DIAG_TCLASS
 
 
 /* INET_DIAG_MEM */
index 08ffab01e76c357cc47b378fd07f2895561f6cc3..94b1e356c02ab4fa808b5dd43d1ed9f57afbe50f 100644 (file)
@@ -184,7 +184,6 @@ extern struct cred init_cred;
                [PIDTYPE_SID]  = INIT_PID_LINK(PIDTYPE_SID),            \
        },                                                              \
        .thread_group   = LIST_HEAD_INIT(tsk.thread_group),             \
-       .dirties = INIT_PROP_LOCAL_SINGLE(dirties),                     \
        INIT_IDS                                                        \
        INIT_PERF_EVENTS(tsk)                                           \
        INIT_TRACE_IRQFLAGS                                             \
index f47fcd30273dd2ce904b6ac0cf11fb963c04826c..c3892fc1d5389c86c664a43ca57bffa0f008d4b8 100644 (file)
@@ -555,7 +555,6 @@ struct kvm_ppc_pvinfo {
 #define KVM_CAP_PPC_SMT 64
 #define KVM_CAP_PPC_RMA        65
 #define KVM_CAP_MAX_VCPUS 66       /* returns max vcpus per vm */
-#define KVM_CAP_PPC_HIOR 67
 #define KVM_CAP_PPC_PAPR 68
 #define KVM_CAP_S390_GMAP 71
 
index 82b4c8801a4fc673fc4c7c0451bdb11330c821c7..8bf2cb9502dd7ba492680d371279577392c6d3fe 100644 (file)
 
 
 /*Registers VDD1, VDD2 voltage values definitions */
-#define VDD1_2_NUM_VOLTS                               73
+#define VDD1_2_NUM_VOLT_FINE                           73
+#define VDD1_2_NUM_VOLT_COARSE                         3
 #define VDD1_2_MIN_VOLT                                        6000
 #define VDD1_2_OFFSET                                  125
 
index ab2c6343361ae3e82f242df7880f292c189e442d..92ecf5585facf20511cd865db281d33ea828bdad 100644 (file)
@@ -410,6 +410,9 @@ extern const struct inode_operations nfs_file_inode_operations;
 extern const struct inode_operations nfs3_file_inode_operations;
 #endif /* CONFIG_NFS_V3 */
 extern const struct file_operations nfs_file_operations;
+#ifdef CONFIG_NFS_V4
+extern const struct file_operations nfs4_file_operations;
+#endif /* CONFIG_NFS_V4 */
 extern const struct address_space_operations nfs_file_aops;
 extern const struct address_space_operations nfs_dir_aops;
 
index c74595ba70947926d2b1a99f4157ca7f485dbd13..2a7c533be5dd8aa2f584fde1faad94c558130d75 100644 (file)
@@ -1192,6 +1192,7 @@ struct nfs_rpc_ops {
        const struct dentry_operations *dentry_ops;
        const struct inode_operations *dir_inode_ops;
        const struct inode_operations *file_inode_ops;
+       const struct file_operations *file_ops;
 
        int     (*getroot) (struct nfs_server *, struct nfs_fh *,
                            struct nfs_fsinfo *);
index e3d0b3890249163881eec330894cdd8bb945295a..7ef68724f0f054f88427d2dbc18c63b962a16394 100644 (file)
@@ -12,7 +12,7 @@ struct pci_ats {
        unsigned int is_enabled:1;      /* Enable bit is set */
 };
 
-#ifdef CONFIG_PCI_IOV
+#ifdef CONFIG_PCI_ATS
 
 extern int pci_enable_ats(struct pci_dev *dev, int ps);
 extern void pci_disable_ats(struct pci_dev *dev);
@@ -29,7 +29,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
        return dev->ats && dev->ats->is_enabled;
 }
 
-#else /* CONFIG_PCI_IOV */
+#else /* CONFIG_PCI_ATS */
 
 static inline int pci_enable_ats(struct pci_dev *dev, int ps)
 {
@@ -50,7 +50,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
        return 0;
 }
 
-#endif /* CONFIG_PCI_IOV */
+#endif /* CONFIG_PCI_ATS */
 
 #ifdef CONFIG_PCI_PRI
 
index 337df0d5d5f7eb2e80410e4e0980afe4ef4ed83a..7cda65b5f79806005af9aada8831f8403a519db7 100644 (file)
@@ -338,7 +338,7 @@ struct pci_dev {
        struct list_head msi_list;
 #endif
        struct pci_vpd *vpd;
-#ifdef CONFIG_PCI_IOV
+#ifdef CONFIG_PCI_ATS
        union {
                struct pci_sriov *sriov;        /* SR-IOV capability related */
                struct pci_dev *physfn; /* the PF this VF is associated with */
index f15acb64681351b72c5b1c460bf0174ad2f33749..3f3ed83a9aa52cf69df6fd7a925d521cbca96f6d 100644 (file)
@@ -54,118 +54,145 @@ typedef struct pm_message {
 /**
  * struct dev_pm_ops - device PM callbacks
  *
- * Several driver power state transitions are externally visible, affecting
+ * Several device power state transitions are externally visible, affecting
  * the state of pending I/O queues and (for drivers that touch hardware)
  * interrupts, wakeups, DMA, and other hardware state.  There may also be
- * internal transitions to various low power modes, which are transparent
+ * internal transitions to various low-power modes which are transparent
  * to the rest of the driver stack (such as a driver that's ON gating off
  * clocks which are not in active use).
  *
- * The externally visible transitions are handled with the help of the following
- * callbacks included in this structure:
- *
- * @prepare: Prepare the device for the upcoming transition, but do NOT change
- *     its hardware state.  Prevent new children of the device from being
- *     registered after @prepare() returns (the driver's subsystem and
- *     generally the rest of the kernel is supposed to prevent new calls to the
- *     probe method from being made too once @prepare() has succeeded).  If
- *     @prepare() detects a situation it cannot handle (e.g. registration of a
- *     child already in progress), it may return -EAGAIN, so that the PM core
- *     can execute it once again (e.g. after the new child has been registered)
- *     to recover from the race condition.  This method is executed for all
- *     kinds of suspend transitions and is followed by one of the suspend
- *     callbacks: @suspend(), @freeze(), or @poweroff().
- *     The PM core executes @prepare() for all devices before starting to
- *     execute suspend callbacks for any of them, so drivers may assume all of
- *     the other devices to be present and functional while @prepare() is being
- *     executed.  In particular, it is safe to make GFP_KERNEL memory
- *     allocations from within @prepare().  However, drivers may NOT assume
- *     anything about the availability of the user space at that time and it
- *     is not correct to request firmware from within @prepare() (it's too
- *     late to do that).  [To work around this limitation, drivers may
- *     register suspend and hibernation notifiers that are executed before the
- *     freezing of tasks.]
+ * The externally visible transitions are handled with the help of callbacks
+ * included in this structure in such a way that two levels of callbacks are
+ * involved.  First, the PM core executes callbacks provided by PM domains,
+ * device types, classes and bus types.  They are the subsystem-level callbacks
+ * supposed to execute callbacks provided by device drivers, although they may
+ * choose not to do that.  If the driver callbacks are executed, they have to
+ * collaborate with the subsystem-level callbacks to achieve the goals
+ * appropriate for the given system transition, given transition phase and the
+ * subsystem the device belongs to.
+ *
+ * @prepare: The principal role of this callback is to prevent new children of
+ *     the device from being registered after it has returned (the driver's
+ *     subsystem and generally the rest of the kernel is supposed to prevent
+ *     new calls to the probe method from being made too once @prepare() has
+ *     succeeded).  If @prepare() detects a situation it cannot handle (e.g.
+ *     registration of a child already in progress), it may return -EAGAIN, so
+ *     that the PM core can execute it once again (e.g. after a new child has
+ *     been registered) to recover from the race condition.
+ *     This method is executed for all kinds of suspend transitions and is
+ *     followed by one of the suspend callbacks: @suspend(), @freeze(), or
+ *     @poweroff().  The PM core executes subsystem-level @prepare() for all
+ *     devices before starting to invoke suspend callbacks for any of them, so
+ *     generally devices may be assumed to be functional or to respond to
+ *     runtime resume requests while @prepare() is being executed.  However,
+ *     device drivers may NOT assume anything about the availability of user
+ *     space at that time and it is NOT valid to request firmware from within
+ *     @prepare() (it's too late to do that).  It also is NOT valid to allocate
+ *     substantial amounts of memory from @prepare() in the GFP_KERNEL mode.
+ *     [To work around these limitations, drivers may register suspend and
+ *     hibernation notifiers to be executed before the freezing of tasks.]
  *
  * @complete: Undo the changes made by @prepare().  This method is executed for
  *     all kinds of resume transitions, following one of the resume callbacks:
  *     @resume(), @thaw(), @restore().  Also called if the state transition
- *     fails before the driver's suspend callback (@suspend(), @freeze(),
- *     @poweroff()) can be executed (e.g. if the suspend callback fails for one
+ *     fails before the driver's suspend callback: @suspend(), @freeze() or
+ *     @poweroff(), can be executed (e.g. if the suspend callback fails for one
  *     of the other devices that the PM core has unsuccessfully attempted to
  *     suspend earlier).
- *     The PM core executes @complete() after it has executed the appropriate
- *     resume callback for all devices.
+ *     The PM core executes subsystem-level @complete() after it has executed
+ *     the appropriate resume callbacks for all devices.
  *
  * @suspend: Executed before putting the system into a sleep state in which the
- *     contents of main memory are preserved.  Quiesce the device, put it into
- *     a low power state appropriate for the upcoming system state (such as
- *     PCI_D3hot), and enable wakeup events as appropriate.
+ *     contents of main memory are preserved.  The exact action to perform
+ *     depends on the device's subsystem (PM domain, device type, class or bus
+ *     type), but generally the device must be quiescent after subsystem-level
+ *     @suspend() has returned, so that it doesn't do any I/O or DMA.
+ *     Subsystem-level @suspend() is executed for all devices after invoking
+ *     subsystem-level @prepare() for all of them.
  *
  * @resume: Executed after waking the system up from a sleep state in which the
- *     contents of main memory were preserved.  Put the device into the
- *     appropriate state, according to the information saved in memory by the
- *     preceding @suspend().  The driver starts working again, responding to
- *     hardware events and software requests.  The hardware may have gone
- *     through a power-off reset, or it may have maintained state from the
- *     previous suspend() which the driver may rely on while resuming.  On most
- *     platforms, there are no restrictions on availability of resources like
- *     clocks during @resume().
+ *     contents of main memory were preserved.  The exact action to perform
+ *     depends on the device's subsystem, but generally the driver is expected
+ *     to start working again, responding to hardware events and software
+ *     requests (the device itself may be left in a low-power state, waiting
+ *     for a runtime resume to occur).  The state of the device at the time its
+ *     driver's @resume() callback is run depends on the platform and subsystem
+ *     the device belongs to.  On most platforms, there are no restrictions on
+ *     availability of resources like clocks during @resume().
+ *     Subsystem-level @resume() is executed for all devices after invoking
+ *     subsystem-level @resume_noirq() for all of them.
  *
  * @freeze: Hibernation-specific, executed before creating a hibernation image.
- *     Quiesce operations so that a consistent image can be created, but do NOT
- *     otherwise put the device into a low power device state and do NOT emit
- *     system wakeup events.  Save in main memory the device settings to be
- *     used by @restore() during the subsequent resume from hibernation or by
- *     the subsequent @thaw(), if the creation of the image or the restoration
- *     of main memory contents from it fails.
+ *     Analogous to @suspend(), but it should not enable the device to signal
+ *     wakeup events or change its power state.  The majority of subsystems
+ *     (with the notable exception of the PCI bus type) expect the driver-level
+ *     @freeze() to save the device settings in memory to be used by @restore()
+ *     during the subsequent resume from hibernation.
+ *     Subsystem-level @freeze() is executed for all devices after invoking
+ *     subsystem-level @prepare() for all of them.
  *
  * @thaw: Hibernation-specific, executed after creating a hibernation image OR
- *     if the creation of the image fails.  Also executed after a failing
+ *     if the creation of an image has failed.  Also executed after a failing
  *     attempt to restore the contents of main memory from such an image.
  *     Undo the changes made by the preceding @freeze(), so the device can be
  *     operated in the same way as immediately before the call to @freeze().
+ *     Subsystem-level @thaw() is executed for all devices after invoking
+ *     subsystem-level @thaw_noirq() for all of them.  It also may be executed
+ *     directly after @freeze() in case of a transition error.
  *
  * @poweroff: Hibernation-specific, executed after saving a hibernation image.
- *     Quiesce the device, put it into a low power state appropriate for the
- *     upcoming system state (such as PCI_D3hot), and enable wakeup events as
- *     appropriate.
+ *     Analogous to @suspend(), but it need not save the device's settings in
+ *     memory.
+ *     Subsystem-level @poweroff() is executed for all devices after invoking
+ *     subsystem-level @prepare() for all of them.
  *
  * @restore: Hibernation-specific, executed after restoring the contents of main
- *     memory from a hibernation image.  Driver starts working again,
- *     responding to hardware events and software requests.  Drivers may NOT
- *     make ANY assumptions about the hardware state right prior to @restore().
- *     On most platforms, there are no restrictions on availability of
- *     resources like clocks during @restore().
- *
- * @suspend_noirq: Complete the operations of ->suspend() by carrying out any
- *     actions required for suspending the device that need interrupts to be
- *     disabled
- *
- * @resume_noirq: Prepare for the execution of ->resume() by carrying out any
- *     actions required for resuming the device that need interrupts to be
- *     disabled
- *
- * @freeze_noirq: Complete the operations of ->freeze() by carrying out any
- *     actions required for freezing the device that need interrupts to be
- *     disabled
- *
- * @thaw_noirq: Prepare for the execution of ->thaw() by carrying out any
- *     actions required for thawing the device that need interrupts to be
- *     disabled
- *
- * @poweroff_noirq: Complete the operations of ->poweroff() by carrying out any
- *     actions required for handling the device that need interrupts to be
- *     disabled
- *
- * @restore_noirq: Prepare for the execution of ->restore() by carrying out any
- *     actions required for restoring the operations of the device that need
- *     interrupts to be disabled
+ *     memory from a hibernation image, analogous to @resume().
+ *
+ * @suspend_noirq: Complete the actions started by @suspend().  Carry out any
+ *     additional operations required for suspending the device that might be
+ *     racing with its driver's interrupt handler, which is guaranteed not to
+ *     run while @suspend_noirq() is being executed.
+ *     It generally is expected that the device will be in a low-power state
+ *     (appropriate for the target system sleep state) after subsystem-level
+ *     @suspend_noirq() has returned successfully.  If the device can generate
+ *     system wakeup signals and is enabled to wake up the system, it should be
+ *     configured to do so at that time.  However, depending on the platform
+ *     and device's subsystem, @suspend() may be allowed to put the device into
+ *     the low-power state and configure it to generate wakeup signals, in
+ *     which case it generally is not necessary to define @suspend_noirq().
+ *
+ * @resume_noirq: Prepare for the execution of @resume() by carrying out any
+ *     operations required for resuming the device that might be racing with
+ *     its driver's interrupt handler, which is guaranteed not to run while
+ *     @resume_noirq() is being executed.
+ *
+ * @freeze_noirq: Complete the actions started by @freeze().  Carry out any
+ *     additional operations required for freezing the device that might be
+ *     racing with its driver's interrupt handler, which is guaranteed not to
+ *     run while @freeze_noirq() is being executed.
+ *     The power state of the device should not be changed by either @freeze()
+ *     or @freeze_noirq() and it should not be configured to signal system
+ *     wakeup by any of these callbacks.
+ *
+ * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any
+ *     operations required for thawing the device that might be racing with its
+ *     driver's interrupt handler, which is guaranteed not to run while
+ *     @thaw_noirq() is being executed.
+ *
+ * @poweroff_noirq: Complete the actions started by @poweroff().  Analogous to
+ *     @suspend_noirq(), but it need not save the device's settings in memory.
+ *
+ * @restore_noirq: Prepare for the execution of @restore() by carrying out any
+ *     operations required for thawing the device that might be racing with its
+ *     driver's interrupt handler, which is guaranteed not to run while
+ *     @restore_noirq() is being executed.  Analogous to @resume_noirq().
  *
  * All of the above callbacks, except for @complete(), return error codes.
  * However, the error codes returned by the resume operations, @resume(),
- * @thaw(), @restore(), @resume_noirq(), @thaw_noirq(), and @restore_noirq() do
+ * @thaw(), @restore(), @resume_noirq(), @thaw_noirq(), and @restore_noirq(), do
  * not cause the PM core to abort the resume transition during which they are
- * returned.  The error codes returned in that cases are only printed by the PM
+ * returned.  The error codes returned in those cases are only printed by the PM
  * core to the system logs for debugging purposes.  Still, it is recommended
  * that drivers only return error codes from their resume methods in case of an
  * unrecoverable failure (i.e. when the device being handled refuses to resume
@@ -174,31 +201,43 @@ typedef struct pm_message {
  * their children.
  *
  * It is allowed to unregister devices while the above callbacks are being
- * executed.  However, it is not allowed to unregister a device from within any
- * of its own callbacks.
+ * executed.  However, a callback routine must NOT try to unregister the device
+ * it was called for, although it may unregister children of that device (for
+ * example, if it detects that a child was unplugged while the system was
+ * asleep).
+ *
+ * Refer to Documentation/power/devices.txt for more information about the role
+ * of the above callbacks in the system suspend process.
  *
- * There also are the following callbacks related to run-time power management
- * of devices:
+ * There also are callbacks related to runtime power management of devices.
+ * Again, these callbacks are executed by the PM core only for subsystems
+ * (PM domains, device types, classes and bus types) and the subsystem-level
+ * callbacks are supposed to invoke the driver callbacks.  Moreover, the exact
+ * actions to be performed by a device driver's callbacks generally depend on
+ * the platform and subsystem the device belongs to.
  *
  * @runtime_suspend: Prepare the device for a condition in which it won't be
  *     able to communicate with the CPU(s) and RAM due to power management.
- *     This need not mean that the device should be put into a low power state.
+ *     This need not mean that the device should be put into a low-power state.
  *     For example, if the device is behind a link which is about to be turned
  *     off, the device may remain at full power.  If the device does go to low
- *     power and is capable of generating run-time wake-up events, remote
- *     wake-up (i.e., a hardware mechanism allowing the device to request a
- *     change of its power state via a wake-up event, such as PCI PME) should
- *     be enabled for it.
+ *     power and is capable of generating runtime wakeup events, remote wakeup
+ *     (i.e., a hardware mechanism allowing the device to request a change of
+ *     its power state via an interrupt) should be enabled for it.
  *
  * @runtime_resume: Put the device into the fully active state in response to a
- *     wake-up event generated by hardware or at the request of software.  If
- *     necessary, put the device into the full power state and restore its
+ *     wakeup event generated by hardware or at the request of software.  If
+ *     necessary, put the device into the full-power state and restore its
  *     registers, so that it is fully operational.
  *
- * @runtime_idle: Device appears to be inactive and it might be put into a low
- *     power state if all of the necessary conditions are satisfied.  Check
+ * @runtime_idle: Device appears to be inactive and it might be put into a
+ *     low-power state if all of the necessary conditions are satisfied.  Check
  *     these conditions and handle the device as appropriate, possibly queueing
  *     a suspend request for it.  The return value is ignored by the PM core.
+ *
+ * Refer to Documentation/power/runtime_pm.txt for more information about the
+ * role of the above callbacks in device runtime power management.
+ *
  */
 
 struct dev_pm_ops {
@@ -447,6 +486,7 @@ struct dev_pm_info {
        unsigned int            async_suspend:1;
        bool                    is_prepared:1;  /* Owned by the PM core */
        bool                    is_suspended:1; /* Ditto */
+       bool                    ignore_children:1;
        spinlock_t              lock;
 #ifdef CONFIG_PM_SLEEP
        struct list_head        entry;
@@ -464,7 +504,6 @@ struct dev_pm_info {
        atomic_t                usage_count;
        atomic_t                child_count;
        unsigned int            disable_depth:3;
-       unsigned int            ignore_children:1;
        unsigned int            idle_notification:1;
        unsigned int            request_pending:1;
        unsigned int            deferred_resume:1;
index d8d90361964216f771ed62e5d17fb083451e2796..d3085e72a0ee9b43bbd024bf33b93939e1535d42 100644 (file)
@@ -52,11 +52,6 @@ static inline bool pm_children_suspended(struct device *dev)
                || !atomic_read(&dev->power.child_count);
 }
 
-static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
-{
-       dev->power.ignore_children = enable;
-}
-
 static inline void pm_runtime_get_noresume(struct device *dev)
 {
        atomic_inc(&dev->power.usage_count);
@@ -130,7 +125,6 @@ static inline void pm_runtime_allow(struct device *dev) {}
 static inline void pm_runtime_forbid(struct device *dev) {}
 
 static inline bool pm_children_suspended(struct device *dev) { return false; }
-static inline void pm_suspend_ignore_children(struct device *dev, bool en) {}
 static inline void pm_runtime_get_noresume(struct device *dev) {}
 static inline void pm_runtime_put_noidle(struct device *dev) {}
 static inline bool device_run_wake(struct device *dev) { return false; }
index ea567321ae3c3b2ac02967680f99de1687f99982..2ca8cde5459d3445b2897c02d58ac2d12dba5bba 100644 (file)
@@ -35,10 +35,12 @@ struct pstore_info {
        spinlock_t      buf_lock;       /* serialize access to 'buf' */
        char            *buf;
        size_t          bufsize;
+       struct mutex    read_mutex;     /* serialize open/read/close */
        int             (*open)(struct pstore_info *psi);
        int             (*close)(struct pstore_info *psi);
        ssize_t         (*read)(u64 *id, enum pstore_type_id *type,
-                       struct timespec *time, struct pstore_info *psi);
+                       struct timespec *time, char **buf,
+                       struct pstore_info *psi);
        int             (*write)(enum pstore_type_id type, u64 *id,
                        unsigned int part, size_t size, struct pstore_info *psi);
        int             (*erase)(enum pstore_type_id type, u64 id,
index 68daf4f27e2c337102258d71450eabc5a14178dd..1c4f3e9b9bc50e52ea57623f5b886691fb52db14 100644 (file)
@@ -1521,7 +1521,6 @@ struct task_struct {
 #ifdef CONFIG_FAULT_INJECTION
        int make_it_fail;
 #endif
-       struct prop_local_single dirties;
        /*
         * when (nr_dirtied >= nr_dirtied_pause), it's time to call
         * balance_dirty_pages() for some dirty throttling pause
index 97ff8e27a6cccfdc0678211db90b1fcde056f1da..3d86517fe7d5bf71f16efa468cec3fb9b4485c17 100644 (file)
@@ -207,13 +207,15 @@ struct serial_icounter_struct {
 
 struct serial_rs485 {
        __u32   flags;                  /* RS485 feature flags */
-#define SER_RS485_ENABLED              (1 << 0)
-#define SER_RS485_RTS_ON_SEND          (1 << 1)
-#define SER_RS485_RTS_AFTER_SEND       (1 << 2)
-#define SER_RS485_RTS_BEFORE_SEND      (1 << 3)
+#define SER_RS485_ENABLED              (1 << 0)        /* If enabled */
+#define SER_RS485_RTS_ON_SEND          (1 << 1)        /* Logical level for
+                                                          RTS pin when
+                                                          sending */
+#define SER_RS485_RTS_AFTER_SEND       (1 << 2)        /* Logical level for
+                                                          RTS pin after sent*/
 #define SER_RS485_RX_DURING_TX         (1 << 4)
-       __u32   delay_rts_before_send;  /* Milliseconds */
-       __u32   delay_rts_after_send;   /* Milliseconds */
+       __u32   delay_rts_before_send;  /* Delay before send (milliseconds) */
+       __u32   delay_rts_after_send;   /* Delay after send (milliseconds) */
        __u32   padding[5];             /* Memory is cheap, new structs
                                           are a royal PITA .. */
 };
index add4790b21fe4ee18635db9456a43db71bb39997..e9e72bda1b72b89b8f4354b507f7b392291ec0ec 100644 (file)
@@ -85,6 +85,8 @@
  * @reset: reset the device
  *     vdev: the virtio device
  *     After this, status and feature negotiation must be done again
+ *     Device must not be reset from its vq/config callbacks, or in
+ *     parallel with being added/removed.
  * @find_vqs: find virtqueues and instantiate them.
  *     vdev: the virtio_device
  *     nvqs: the number of virtqueues to find
index 27c7edefbc86ea6cad445f3503de9970b1088bf7..5c7b6f0daef8f1f228c6daed124e589acdfdb649 100644 (file)
@@ -63,7 +63,7 @@
 #define VIRTIO_MMIO_GUEST_FEATURES     0x020
 
 /* Activated features set selector - Write Only */
-#define VIRTIO_MMIO_GUEST_FEATURES_SET 0x024
+#define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024
 
 /* Guest's memory page size in bytes - Write Only */
 #define VIRTIO_MMIO_GUEST_PAGE_SIZE    0x028
index 687fb11e20107d9c22467e1923d5e736bde16d3e..4bde182fcf93f23bb8f1b8b68d2a087ba20ae2c3 100644 (file)
@@ -119,7 +119,7 @@ unmap_kernel_range(unsigned long addr, unsigned long size)
 #endif
 
 /* Allocate/destroy a 'vmalloc' VM area. */
-extern struct vm_struct *alloc_vm_area(size_t size);
+extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes);
 extern void free_vm_area(struct vm_struct *area);
 
 /* for /dev/kmem */
index ab90ae0970a69b2f3646c712aac0b56e2332509e..6cc18f37167519260e15d1ad20d7bf2f145c86c5 100644 (file)
 #define L2CAP_DEFAULT_ACK_TO           200
 #define L2CAP_LE_DEFAULT_MTU           23
 
-#define L2CAP_CONN_TIMEOUT     (40000) /* 40 seconds */
-#define L2CAP_INFO_TIMEOUT     (4000)  /*  4 seconds */
+#define L2CAP_DISC_TIMEOUT             (100)
+#define L2CAP_DISC_REJ_TIMEOUT         (5000)  /*  5 seconds */
+#define L2CAP_ENC_TIMEOUT              (5000)  /*  5 seconds */
+#define L2CAP_CONN_TIMEOUT             (40000) /* 40 seconds */
+#define L2CAP_INFO_TIMEOUT             (4000)  /*  4 seconds */
 
 /* L2CAP socket address */
 struct sockaddr_l2 {
index 92cf1c2c30c9f0a94d193753a037cb851f8a60cd..95852e36713b5e302e365033957d16910de01952 100644 (file)
@@ -456,6 +456,9 @@ enum station_parameters_apply_mask {
  *     as the AC bitmap in the QoS info field
  * @max_sp: max Service Period. same format as the MAX_SP in the
  *     QoS info field (but already shifted down)
+ * @sta_modify_mask: bitmap indicating which parameters changed
+ *     (for those that don't have a natural "no change" value),
+ *     see &enum station_parameters_apply_mask
  */
 struct station_parameters {
        u8 *supported_rates;
@@ -615,6 +618,7 @@ struct sta_bss_parameters {
  *     user space MLME/SME implementation. The information is provided for
  *     the cfg80211_new_sta() calls to notify user space of the IEs.
  * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
+ * @sta_flags: station flags mask & values
  */
 struct station_info {
        u32 filled;
index b66ebb2032c6d6b87c928876cab69c235d2425f3..378c7ed6760be0563b501971df2a60e03a672ea7 100644 (file)
@@ -307,15 +307,8 @@ struct omap_dss_board_info {
        void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask);
 };
 
-#if defined(CONFIG_OMAP2_DSS_MODULE) || defined(CONFIG_OMAP2_DSS)
 /* Init with the board info */
 extern int omap_display_init(struct omap_dss_board_info *board_data);
-#else
-static inline int omap_display_init(struct omap_dss_board_info *board_data)
-{
-       return 0;
-}
-#endif
 
 struct omap_display_platform_data {
        struct omap_dss_board_info *board_data;
index a785a3b0c8c7d89d9a46e1a1d90300cb91da5308..438c256c274b3b7984155399f87e26cd13d27cd7 100644 (file)
@@ -29,8 +29,7 @@
 static inline int xen_must_unplug_nics(void) {
 #if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \
                defined(CONFIG_XEN_NETDEV_FRONTEND_MODULE)) && \
-               (defined(CONFIG_XEN_PLATFORM_PCI) || \
-                defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
+               defined(CONFIG_XEN_PVHVM)
         return 1;
 #else
         return 0;
@@ -40,8 +39,7 @@ static inline int xen_must_unplug_nics(void) {
 static inline int xen_must_unplug_disks(void) {
 #if (defined(CONFIG_XEN_BLKDEV_FRONTEND) || \
                defined(CONFIG_XEN_BLKDEV_FRONTEND_MODULE)) && \
-               (defined(CONFIG_XEN_PLATFORM_PCI) || \
-                defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
+               defined(CONFIG_XEN_PVHVM)
         return 1;
 #else
         return 0;
index 5e828a2ca8e64641749da837fe093cefcfc958dc..213c0351dad8fc8315d6d79a5bf3706a59c823bd 100644 (file)
@@ -153,6 +153,13 @@ static void freezer_destroy(struct cgroup_subsys *ss,
        kfree(cgroup_freezer(cgroup));
 }
 
+/* task is frozen or will freeze immediately when next it gets woken */
+static bool is_task_frozen_enough(struct task_struct *task)
+{
+       return frozen(task) ||
+               (task_is_stopped_or_traced(task) && freezing(task));
+}
+
 /*
  * The call to cgroup_lock() in the freezer.state write method prevents
  * a write to that file racing against an attach, and hence the
@@ -231,7 +238,7 @@ static void update_if_frozen(struct cgroup *cgroup,
        cgroup_iter_start(cgroup, &it);
        while ((task = cgroup_iter_next(cgroup, &it))) {
                ntotal++;
-               if (frozen(task))
+               if (is_task_frozen_enough(task))
                        nfrozen++;
        }
 
@@ -284,7 +291,7 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
        while ((task = cgroup_iter_next(cgroup, &it))) {
                if (!freeze_task(task, true))
                        continue;
-               if (frozen(task))
+               if (is_task_frozen_enough(task))
                        continue;
                if (!freezing(task) && !freezer_should_skip(task))
                        num_cant_freeze_now++;
index ba0d172613296047a24918106d90eff09f2a5bb8..da4a6a10d088d2d575c4eeae9438f832efc6f41b 100644 (file)
@@ -162,7 +162,6 @@ static void account_kernel_stack(struct thread_info *ti, int account)
 
 void free_task(struct task_struct *tsk)
 {
-       prop_local_destroy_single(&tsk->dirties);
        account_kernel_stack(tsk->stack, -1);
        free_thread_info(tsk->stack);
        rt_mutex_debug_task_free(tsk);
@@ -274,10 +273,6 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
 
        tsk->stack = ti;
 
-       err = prop_local_init_single(&tsk->dirties);
-       if (err)
-               goto out;
-
        setup_thread_stack(tsk, orig);
        clear_user_return_notifier(tsk);
        clear_tsk_need_resched(tsk);
index 422e567eecf63636a7c349b6319e6d541c6f3818..ae34bf51682b4a204de93f62943055350cd5c4d0 100644 (file)
@@ -885,10 +885,13 @@ static void __remove_hrtimer(struct hrtimer *timer,
                             struct hrtimer_clock_base *base,
                             unsigned long newstate, int reprogram)
 {
+       struct timerqueue_node *next_timer;
        if (!(timer->state & HRTIMER_STATE_ENQUEUED))
                goto out;
 
-       if (&timer->node == timerqueue_getnext(&base->active)) {
+       next_timer = timerqueue_getnext(&base->active);
+       timerqueue_del(&base->active, &timer->node);
+       if (&timer->node == next_timer) {
 #ifdef CONFIG_HIGH_RES_TIMERS
                /* Reprogram the clock event device. if enabled */
                if (reprogram && hrtimer_hres_active()) {
@@ -901,7 +904,6 @@ static void __remove_hrtimer(struct hrtimer *timer,
                }
 #endif
        }
-       timerqueue_del(&base->active, &timer->node);
        if (!timerqueue_getnext(&base->active))
                base->cpu_base->active_bases &= ~(1 << base->index);
 out:
index 67ce837ae52cdd70115a8ce436f923e96a26adc4..0e2b179bc7b371ea8aa60f52899ae60ff1cb5ec2 100644 (file)
@@ -1596,7 +1596,7 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler,
                return -ENOMEM;
 
        action->handler = handler;
-       action->flags = IRQF_PERCPU;
+       action->flags = IRQF_PERCPU | IRQF_NO_SUSPEND;
        action->name = devname;
        action->percpu_dev_id = dev_id;
 
index aa57d5da18c1de65e807098702ad9b841fa3788d..dc813a948be2379fe20a0218e1d270212b8408d3 100644 (file)
@@ -84,7 +84,9 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force)
         */
        action = desc->action;
        if (!action || !(action->flags & IRQF_SHARED) ||
-           (action->flags & __IRQF_TIMER) || !action->next)
+           (action->flags & __IRQF_TIMER) ||
+           (action->handler(irq, action->dev_id) == IRQ_HANDLED) ||
+           !action->next)
                goto out;
 
        /* Already running on another processor */
@@ -115,7 +117,7 @@ static int misrouted_irq(int irq)
        struct irq_desc *desc;
        int i, ok = 0;
 
-       if (atomic_inc_return(&irq_poll_active) == 1)
+       if (atomic_inc_return(&irq_poll_active) != 1)
                goto out;
 
        irq_poll_cpu = smp_processor_id();
index b4511b6d3ef93ef5e2d12a097c3a63fa058de423..a6b0503574ee714b2cbe6c871741d298ad9ce5f7 100644 (file)
@@ -55,6 +55,8 @@ enum {
 
 static int hibernation_mode = HIBERNATION_SHUTDOWN;
 
+static bool freezer_test_done;
+
 static const struct platform_hibernation_ops *hibernation_ops;
 
 /**
@@ -345,11 +347,24 @@ int hibernation_snapshot(int platform_mode)
 
        error = freeze_kernel_threads();
        if (error)
-               goto Close;
+               goto Cleanup;
+
+       if (hibernation_test(TEST_FREEZER) ||
+               hibernation_testmode(HIBERNATION_TESTPROC)) {
+
+               /*
+                * Indicate to the caller that we are returning due to a
+                * successful freezer test.
+                */
+               freezer_test_done = true;
+               goto Cleanup;
+       }
 
        error = dpm_prepare(PMSG_FREEZE);
-       if (error)
-               goto Complete_devices;
+       if (error) {
+               dpm_complete(msg);
+               goto Cleanup;
+       }
 
        suspend_console();
        pm_restrict_gfp_mask();
@@ -378,8 +393,6 @@ int hibernation_snapshot(int platform_mode)
                pm_restore_gfp_mask();
 
        resume_console();
-
- Complete_devices:
        dpm_complete(msg);
 
  Close:
@@ -389,6 +402,10 @@ int hibernation_snapshot(int platform_mode)
  Recover_platform:
        platform_recover(platform_mode);
        goto Resume_devices;
+
+ Cleanup:
+       swsusp_free();
+       goto Close;
 }
 
 /**
@@ -641,15 +658,13 @@ int hibernate(void)
        if (error)
                goto Finish;
 
-       if (hibernation_test(TEST_FREEZER))
-               goto Thaw;
-
-       if (hibernation_testmode(HIBERNATION_TESTPROC))
-               goto Thaw;
-
        error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
        if (error)
                goto Thaw;
+       if (freezer_test_done) {
+               freezer_test_done = false;
+               goto Thaw;
+       }
 
        if (in_suspend) {
                unsigned int flags = 0;
index 71f49fe4377e907c85c6d5712335aa56b579a79a..36e0f0903c3245e60d2994121d1aaa28c8fc0a23 100644 (file)
@@ -290,13 +290,14 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
                if (*s && len == strlen(*s) && !strncmp(buf, *s, len))
                        break;
        }
-       if (state < PM_SUSPEND_MAX && *s)
+       if (state < PM_SUSPEND_MAX && *s) {
                error = enter_state(state);
                if (error) {
                        suspend_stats.fail++;
                        dpm_save_failed_errno(error);
                } else
                        suspend_stats.success++;
+       }
 #endif
 
  Exit:
index cf52fda2e0966d005e152ff8747d5d44db5fbd7a..cfc65e1eb9fbba411fad95fabee1b78f0e6517f3 100644 (file)
@@ -491,6 +491,22 @@ void clocksource_touch_watchdog(void)
        clocksource_resume_watchdog();
 }
 
+/**
+ * clocksource_max_adjustment- Returns max adjustment amount
+ * @cs:         Pointer to clocksource
+ *
+ */
+static u32 clocksource_max_adjustment(struct clocksource *cs)
+{
+       u64 ret;
+       /*
+        * We won't try to correct for more then 11% adjustments (110,000 ppm),
+        */
+       ret = (u64)cs->mult * 11;
+       do_div(ret,100);
+       return (u32)ret;
+}
+
 /**
  * clocksource_max_deferment - Returns max time the clocksource can be deferred
  * @cs:         Pointer to clocksource
@@ -503,25 +519,28 @@ static u64 clocksource_max_deferment(struct clocksource *cs)
        /*
         * Calculate the maximum number of cycles that we can pass to the
         * cyc2ns function without overflowing a 64-bit signed result. The
-        * maximum number of cycles is equal to ULLONG_MAX/cs->mult which
-        * is equivalent to the below.
-        * max_cycles < (2^63)/cs->mult
-        * max_cycles < 2^(log2((2^63)/cs->mult))
-        * max_cycles < 2^(log2(2^63) - log2(cs->mult))
-        * max_cycles < 2^(63 - log2(cs->mult))
-        * max_cycles < 1 << (63 - log2(cs->mult))
+        * maximum number of cycles is equal to ULLONG_MAX/(cs->mult+cs->maxadj)
+        * which is equivalent to the below.
+        * max_cycles < (2^63)/(cs->mult + cs->maxadj)
+        * max_cycles < 2^(log2((2^63)/(cs->mult + cs->maxadj)))
+        * max_cycles < 2^(log2(2^63) - log2(cs->mult + cs->maxadj))
+        * max_cycles < 2^(63 - log2(cs->mult + cs->maxadj))
+        * max_cycles < 1 << (63 - log2(cs->mult + cs->maxadj))
         * Please note that we add 1 to the result of the log2 to account for
         * any rounding errors, ensure the above inequality is satisfied and
         * no overflow will occur.
         */
-       max_cycles = 1ULL << (63 - (ilog2(cs->mult) + 1));
+       max_cycles = 1ULL << (63 - (ilog2(cs->mult + cs->maxadj) + 1));
 
        /*
         * The actual maximum number of cycles we can defer the clocksource is
         * determined by the minimum of max_cycles and cs->mask.
+        * Note: Here we subtract the maxadj to make sure we don't sleep for
+        * too long if there's a large negative adjustment.
         */
        max_cycles = min_t(u64, max_cycles, (u64) cs->mask);
-       max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult, cs->shift);
+       max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult - cs->maxadj,
+                                       cs->shift);
 
        /*
         * To ensure that the clocksource does not wrap whilst we are idle,
@@ -640,7 +659,6 @@ static void clocksource_enqueue(struct clocksource *cs)
 void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
 {
        u64 sec;
-
        /*
         * Calc the maximum number of seconds which we can run before
         * wrapping around. For clocksources which have a mask > 32bit
@@ -661,6 +679,20 @@ void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
 
        clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
                               NSEC_PER_SEC / scale, sec * scale);
+
+       /*
+        * for clocksources that have large mults, to avoid overflow.
+        * Since mult may be adjusted by ntp, add an safety extra margin
+        *
+        */
+       cs->maxadj = clocksource_max_adjustment(cs);
+       while ((cs->mult + cs->maxadj < cs->mult)
+               || (cs->mult - cs->maxadj > cs->mult)) {
+               cs->mult >>= 1;
+               cs->shift--;
+               cs->maxadj = clocksource_max_adjustment(cs);
+       }
+
        cs->max_idle_ns = clocksource_max_deferment(cs);
 }
 EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
@@ -701,6 +733,12 @@ EXPORT_SYMBOL_GPL(__clocksource_register_scale);
  */
 int clocksource_register(struct clocksource *cs)
 {
+       /* calculate max adjustment for given mult/shift */
+       cs->maxadj = clocksource_max_adjustment(cs);
+       WARN_ONCE(cs->mult + cs->maxadj < cs->mult,
+               "Clocksource %s might overflow on 11%% adjustment\n",
+               cs->name);
+
        /* calculate max idle time permitted for this clocksource */
        cs->max_idle_ns = clocksource_max_deferment(cs);
 
index 2b021b0e8507e7e4f9951780c88877bb2d4d56bd..237841378c031ef0f2fa6c492559e695a111b74f 100644 (file)
@@ -249,6 +249,8 @@ ktime_t ktime_get(void)
                secs = xtime.tv_sec + wall_to_monotonic.tv_sec;
                nsecs = xtime.tv_nsec + wall_to_monotonic.tv_nsec;
                nsecs += timekeeping_get_ns();
+               /* If arch requires, add in gettimeoffset() */
+               nsecs += arch_gettimeoffset();
 
        } while (read_seqretry(&xtime_lock, seq));
        /*
@@ -280,6 +282,8 @@ void ktime_get_ts(struct timespec *ts)
                *ts = xtime;
                tomono = wall_to_monotonic;
                nsecs = timekeeping_get_ns();
+               /* If arch requires, add in gettimeoffset() */
+               nsecs += arch_gettimeoffset();
 
        } while (read_seqretry(&xtime_lock, seq));
 
@@ -802,14 +806,44 @@ static void timekeeping_adjust(s64 offset)
        s64 error, interval = timekeeper.cycle_interval;
        int adj;
 
+       /*
+        * The point of this is to check if the error is greater then half
+        * an interval.
+        *
+        * First we shift it down from NTP_SHIFT to clocksource->shifted nsecs.
+        *
+        * Note we subtract one in the shift, so that error is really error*2.
+        * This "saves" dividing(shifting) intererval twice, but keeps the
+        * (error > interval) comparision as still measuring if error is
+        * larger then half an interval.
+        *
+        * Note: It does not "save" on aggrivation when reading the code.
+        */
        error = timekeeper.ntp_error >> (timekeeper.ntp_error_shift - 1);
        if (error > interval) {
+               /*
+                * We now divide error by 4(via shift), which checks if
+                * the error is greater then twice the interval.
+                * If it is greater, we need a bigadjust, if its smaller,
+                * we can adjust by 1.
+                */
                error >>= 2;
+               /*
+                * XXX - In update_wall_time, we round up to the next
+                * nanosecond, and store the amount rounded up into
+                * the error. This causes the likely below to be unlikely.
+                *
+                * The properfix is to avoid rounding up by using
+                * the high precision timekeeper.xtime_nsec instead of
+                * xtime.tv_nsec everywhere. Fixing this will take some
+                * time.
+                */
                if (likely(error <= interval))
                        adj = 1;
                else
                        adj = timekeeping_bigadjust(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;
@@ -817,9 +851,65 @@ static void timekeeping_adjust(s64 offset)
                        offset = -offset;
                } else
                        adj = timekeeping_bigadjust(error, &interval, &offset);
-       } else
+       } else /* No adjustment needed */
                return;
 
+       WARN_ONCE(timekeeper.clock->maxadj &&
+                       (timekeeper.mult + adj > timekeeper.clock->mult +
+                                               timekeeper.clock->maxadj),
+                       "Adjusting %s more then 11%% (%ld vs %ld)\n",
+                       timekeeper.clock->name, (long)timekeeper.mult + adj,
+                       (long)timekeeper.clock->mult +
+                               timekeeper.clock->maxadj);
+       /*
+        * So the following can be confusing.
+        *
+        * To keep things simple, lets assume adj == 1 for now.
+        *
+        * When adj != 1, remember that the interval and offset values
+        * have been appropriately scaled so the math is the same.
+        *
+        * The basic idea here is that we're increasing the multiplier
+        * by one, this causes the xtime_interval to be incremented by
+        * one cycle_interval. This is because:
+        *      xtime_interval = cycle_interval * mult
+        * So if mult is being incremented by one:
+        *      xtime_interval = cycle_interval * (mult + 1)
+        * Its the same as:
+        *      xtime_interval = (cycle_interval * mult) + cycle_interval
+        * Which can be shortened to:
+        *      xtime_interval += cycle_interval
+        *
+        * So offset stores the non-accumulated cycles. Thus the current
+        * time (in shifted nanoseconds) is:
+        *      now = (offset * adj) + xtime_nsec
+        * Now, even though we're adjusting the clock frequency, we have
+        * to keep time consistent. In other words, we can't jump back
+        * in time, and we also want to avoid jumping forward in time.
+        *
+        * So given the same offset value, we need the time to be the same
+        * both before and after the freq adjustment.
+        *      now = (offset * adj_1) + xtime_nsec_1
+        *      now = (offset * adj_2) + xtime_nsec_2
+        * So:
+        *      (offset * adj_1) + xtime_nsec_1 =
+        *              (offset * adj_2) + xtime_nsec_2
+        * And we know:
+        *      adj_2 = adj_1 + 1
+        * So:
+        *      (offset * adj_1) + xtime_nsec_1 =
+        *              (offset * (adj_1+1)) + xtime_nsec_2
+        *      (offset * adj_1) + xtime_nsec_1 =
+        *              (offset * adj_1) + offset + xtime_nsec_2
+        * Canceling the sides:
+        *      xtime_nsec_1 = offset + xtime_nsec_2
+        * Which gives us:
+        *      xtime_nsec_2 = xtime_nsec_1 - offset
+        * Which simplfies to:
+        *      xtime_nsec -= offset
+        *
+        * XXX - TODO: Doc ntp_error calculation.
+        */
        timekeeper.mult += adj;
        timekeeper.xtime_interval += interval;
        timekeeper.xtime_nsec -= offset;
index a0860640378d87b40827bdb4a89ec271c5c8f35c..71034f41a2ba92ca17c902e2f9b75d568294987f 100644 (file)
@@ -724,6 +724,14 @@ void bdi_destroy(struct backing_dev_info *bdi)
 
        bdi_unregister(bdi);
 
+       /*
+        * If bdi_unregister() had already been called earlier, the
+        * wakeup_timer could still be armed because bdi_prune_sb()
+        * can race with the bdi_wakeup_thread_delayed() calls from
+        * __mark_inode_dirty().
+        */
+       del_timer_sync(&bdi->wb.wakeup_timer);
+
        for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
                percpu_counter_destroy(&bdi->bdi_stat[i]);
 
index dae27ba3be2c8523cd032ad330e2f5a32fbffaf3..bb28a5f9db8ddbf2f65391fe9206ca99b46a256b 100644 (file)
@@ -2422,6 +2422,8 @@ retry_avoidcopy:
         * anon_vma prepared.
         */
        if (unlikely(anon_vma_prepare(vma))) {
+               page_cache_release(new_page);
+               page_cache_release(old_page);
                /* Caller expects lock to be held */
                spin_lock(&mm->page_table_lock);
                return VM_FAULT_OOM;
index 73419c55eda6ddbbdfb3ece3e6d6e477ebd78600..b982290fd962dc2745c423d44e7b92f9c1db247a 100644 (file)
@@ -454,7 +454,7 @@ void  __attribute__((weak)) vmalloc_sync_all(void)
  *     between processes, it syncs the pagetable across all
  *     processes.
  */
-struct vm_struct *alloc_vm_area(size_t size)
+struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
 {
        BUG();
        return NULL;
index 471dedb463ab30f9e57d793c5367cac966098c06..76f2c5ae908e85a858c006d932edcdf9128e0cc2 100644 (file)
@@ -185,6 +185,11 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem,
        if (!p)
                return 0;
 
+       if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) {
+               task_unlock(p);
+               return 0;
+       }
+
        /*
         * The memory controller may have a limit of 0 bytes, so avoid a divide
         * by zero, if necessary.
index a3278f005230a07ac5bf42717ae55bfb114f0239..71252486bc6f1f161b87592ded6e8b7e6c0dc8ee 100644 (file)
@@ -128,7 +128,6 @@ unsigned long global_dirty_limit;
  *
  */
 static struct prop_descriptor vm_completions;
-static struct prop_descriptor vm_dirties;
 
 /*
  * couple the period to the dirty_ratio:
@@ -154,7 +153,6 @@ static void update_completion_period(void)
 {
        int shift = calc_period_shift();
        prop_change_shift(&vm_completions, shift);
-       prop_change_shift(&vm_dirties, shift);
 
        writeback_set_ratelimit();
 }
@@ -235,11 +233,6 @@ void bdi_writeout_inc(struct backing_dev_info *bdi)
 }
 EXPORT_SYMBOL_GPL(bdi_writeout_inc);
 
-void task_dirty_inc(struct task_struct *tsk)
-{
-       prop_inc_single(&vm_dirties, &tsk->dirties);
-}
-
 /*
  * Obtain an accurate fraction of the BDI's portion.
  */
@@ -1133,17 +1126,17 @@ pause:
                                          pages_dirtied,
                                          pause,
                                          start_time);
-               __set_current_state(TASK_UNINTERRUPTIBLE);
+               __set_current_state(TASK_KILLABLE);
                io_schedule_timeout(pause);
 
-               dirty_thresh = hard_dirty_limit(dirty_thresh);
                /*
-                * max-pause area. If dirty exceeded but still within this
-                * area, no need to sleep for more than 200ms: (a) 8 pages per
-                * 200ms is typically more than enough to curb heavy dirtiers;
-                * (b) the pause time limit makes the dirtiers more responsive.
+                * This is typically equal to (nr_dirty < dirty_thresh) and can
+                * also keep "1000+ dd on a slow USB stick" under control.
                 */
-               if (nr_dirty < dirty_thresh)
+               if (task_ratelimit)
+                       break;
+
+               if (fatal_signal_pending(current))
                        break;
        }
 
@@ -1395,7 +1388,6 @@ void __init page_writeback_init(void)
 
        shift = calc_period_shift();
        prop_descriptor_init(&vm_completions, shift);
-       prop_descriptor_init(&vm_dirties, shift);
 }
 
 /**
@@ -1724,7 +1716,6 @@ void account_page_dirtied(struct page *page, struct address_space *mapping)
                __inc_zone_page_state(page, NR_DIRTIED);
                __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);
                __inc_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED);
-               task_dirty_inc(current);
                task_io_account_write(PAGE_CACHE_SIZE);
        }
 }
index ea534960a04bcda7e87a18cacf67bd2eb1fc5fe0..12a48a88c0d8cb00dd55b2adcea3e536493dee1a 100644 (file)
@@ -50,14 +50,13 @@ static struct page **pcpu_get_pages_and_bitmap(struct pcpu_chunk *chunk,
 
        if (!pages || !bitmap) {
                if (may_alloc && !pages)
-                       pages = pcpu_mem_alloc(pages_size);
+                       pages = pcpu_mem_zalloc(pages_size);
                if (may_alloc && !bitmap)
-                       bitmap = pcpu_mem_alloc(bitmap_size);
+                       bitmap = pcpu_mem_zalloc(bitmap_size);
                if (!pages || !bitmap)
                        return NULL;
        }
 
-       memset(pages, 0, pages_size);
        bitmap_copy(bitmap, chunk->populated, pcpu_unit_pages);
 
        *bitmapp = bitmap;
@@ -143,8 +142,8 @@ static void pcpu_pre_unmap_flush(struct pcpu_chunk *chunk,
                                 int page_start, int page_end)
 {
        flush_cache_vunmap(
-               pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
-               pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+               pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start),
+               pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end));
 }
 
 static void __pcpu_unmap_pages(unsigned long addr, int nr_pages)
@@ -206,8 +205,8 @@ static void pcpu_post_unmap_tlb_flush(struct pcpu_chunk *chunk,
                                      int page_start, int page_end)
 {
        flush_tlb_kernel_range(
-               pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
-               pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+               pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start),
+               pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end));
 }
 
 static int __pcpu_map_pages(unsigned long addr, struct page **pages,
@@ -284,8 +283,8 @@ static void pcpu_post_map_flush(struct pcpu_chunk *chunk,
                                int page_start, int page_end)
 {
        flush_cache_vmap(
-               pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
-               pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+               pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start),
+               pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end));
 }
 
 /**
index bf80e55dbed7e66fcd28f6dbc46c86fbd222a008..3bb810a72006cd65e345e16fd124b61e029964db 100644 (file)
@@ -116,9 +116,9 @@ static int pcpu_atom_size __read_mostly;
 static int pcpu_nr_slots __read_mostly;
 static size_t pcpu_chunk_struct_size __read_mostly;
 
-/* cpus with the lowest and highest unit numbers */
-static unsigned int pcpu_first_unit_cpu __read_mostly;
-static unsigned int pcpu_last_unit_cpu __read_mostly;
+/* cpus with the lowest and highest unit addresses */
+static unsigned int pcpu_low_unit_cpu __read_mostly;
+static unsigned int pcpu_high_unit_cpu __read_mostly;
 
 /* the address of the first chunk which starts with the kernel static area */
 void *pcpu_base_addr __read_mostly;
@@ -273,11 +273,11 @@ static void __maybe_unused pcpu_next_pop(struct pcpu_chunk *chunk,
             (rs) = (re) + 1, pcpu_next_pop((chunk), &(rs), &(re), (end)))
 
 /**
- * pcpu_mem_alloc - allocate memory
+ * pcpu_mem_zalloc - allocate memory
  * @size: bytes to allocate
  *
  * Allocate @size bytes.  If @size is smaller than PAGE_SIZE,
- * kzalloc() is used; otherwise, vmalloc() is used.  The returned
+ * kzalloc() is used; otherwise, vzalloc() is used.  The returned
  * memory is always zeroed.
  *
  * CONTEXT:
@@ -286,7 +286,7 @@ static void __maybe_unused pcpu_next_pop(struct pcpu_chunk *chunk,
  * RETURNS:
  * Pointer to the allocated area on success, NULL on failure.
  */
-static void *pcpu_mem_alloc(size_t size)
+static void *pcpu_mem_zalloc(size_t size)
 {
        if (WARN_ON_ONCE(!slab_is_available()))
                return NULL;
@@ -302,7 +302,7 @@ static void *pcpu_mem_alloc(size_t size)
  * @ptr: memory to free
  * @size: size of the area
  *
- * Free @ptr.  @ptr should have been allocated using pcpu_mem_alloc().
+ * Free @ptr.  @ptr should have been allocated using pcpu_mem_zalloc().
  */
 static void pcpu_mem_free(void *ptr, size_t size)
 {
@@ -384,7 +384,7 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc)
        size_t old_size = 0, new_size = new_alloc * sizeof(new[0]);
        unsigned long flags;
 
-       new = pcpu_mem_alloc(new_size);
+       new = pcpu_mem_zalloc(new_size);
        if (!new)
                return -ENOMEM;
 
@@ -604,11 +604,12 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void)
 {
        struct pcpu_chunk *chunk;
 
-       chunk = pcpu_mem_alloc(pcpu_chunk_struct_size);
+       chunk = pcpu_mem_zalloc(pcpu_chunk_struct_size);
        if (!chunk)
                return NULL;
 
-       chunk->map = pcpu_mem_alloc(PCPU_DFL_MAP_ALLOC * sizeof(chunk->map[0]));
+       chunk->map = pcpu_mem_zalloc(PCPU_DFL_MAP_ALLOC *
+                                               sizeof(chunk->map[0]));
        if (!chunk->map) {
                kfree(chunk);
                return NULL;
@@ -977,6 +978,17 @@ bool is_kernel_percpu_address(unsigned long addr)
  * address.  The caller is responsible for ensuring @addr stays valid
  * until this function finishes.
  *
+ * percpu allocator has special setup for the first chunk, which currently
+ * supports either embedding in linear address space or vmalloc mapping,
+ * and, from the second one, the backing allocator (currently either vm or
+ * km) provides translation.
+ *
+ * The addr can be tranlated simply without checking if it falls into the
+ * first chunk. But the current code reflects better how percpu allocator
+ * actually works, and the verification can discover both bugs in percpu
+ * allocator itself and per_cpu_ptr_to_phys() callers. So we keep current
+ * code.
+ *
  * RETURNS:
  * The physical address for @addr.
  */
@@ -984,19 +996,19 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr)
 {
        void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr);
        bool in_first_chunk = false;
-       unsigned long first_start, first_end;
+       unsigned long first_low, first_high;
        unsigned int cpu;
 
        /*
-        * The following test on first_start/end isn't strictly
+        * The following test on unit_low/high isn't strictly
         * necessary but will speed up lookups of addresses which
         * aren't in the first chunk.
         */
-       first_start = pcpu_chunk_addr(pcpu_first_chunk, pcpu_first_unit_cpu, 0);
-       first_end = pcpu_chunk_addr(pcpu_first_chunk, pcpu_last_unit_cpu,
-                                   pcpu_unit_pages);
-       if ((unsigned long)addr >= first_start &&
-           (unsigned long)addr < first_end) {
+       first_low = pcpu_chunk_addr(pcpu_first_chunk, pcpu_low_unit_cpu, 0);
+       first_high = pcpu_chunk_addr(pcpu_first_chunk, pcpu_high_unit_cpu,
+                                    pcpu_unit_pages);
+       if ((unsigned long)addr >= first_low &&
+           (unsigned long)addr < first_high) {
                for_each_possible_cpu(cpu) {
                        void *start = per_cpu_ptr(base, cpu);
 
@@ -1233,7 +1245,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 
        for (cpu = 0; cpu < nr_cpu_ids; cpu++)
                unit_map[cpu] = UINT_MAX;
-       pcpu_first_unit_cpu = NR_CPUS;
+
+       pcpu_low_unit_cpu = NR_CPUS;
+       pcpu_high_unit_cpu = NR_CPUS;
 
        for (group = 0, unit = 0; group < ai->nr_groups; group++, unit += i) {
                const struct pcpu_group_info *gi = &ai->groups[group];
@@ -1253,9 +1267,13 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
                        unit_map[cpu] = unit + i;
                        unit_off[cpu] = gi->base_offset + i * ai->unit_size;
 
-                       if (pcpu_first_unit_cpu == NR_CPUS)
-                               pcpu_first_unit_cpu = cpu;
-                       pcpu_last_unit_cpu = cpu;
+                       /* determine low/high unit_cpu */
+                       if (pcpu_low_unit_cpu == NR_CPUS ||
+                           unit_off[cpu] < unit_off[pcpu_low_unit_cpu])
+                               pcpu_low_unit_cpu = cpu;
+                       if (pcpu_high_unit_cpu == NR_CPUS ||
+                           unit_off[cpu] > unit_off[pcpu_high_unit_cpu])
+                               pcpu_high_unit_cpu = cpu;
                }
        }
        pcpu_nr_units = unit;
@@ -1889,7 +1907,7 @@ void __init percpu_init_late(void)
 
                BUILD_BUG_ON(size > PAGE_SIZE);
 
-               map = pcpu_mem_alloc(size);
+               map = pcpu_mem_zalloc(size);
                BUG_ON(!map);
 
                spin_lock_irqsave(&pcpu_lock, flags);
index 7d2a996c307e4306bd233f4ae340a02d6915ffb1..ed3334d9b6da77f64796f1933f7672284b159fc2 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1862,7 +1862,7 @@ static void unfreeze_partials(struct kmem_cache *s)
 {
        struct kmem_cache_node *n = NULL;
        struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
-       struct page *page;
+       struct page *page, *discard_page = NULL;
 
        while ((page = c->partial)) {
                enum slab_modes { M_PARTIAL, M_FREE };
@@ -1904,7 +1904,8 @@ static void unfreeze_partials(struct kmem_cache *s)
                                if (l == M_PARTIAL)
                                        remove_partial(n, page);
                                else
-                                       add_partial(n, page, 1);
+                                       add_partial(n, page,
+                                               DEACTIVATE_TO_TAIL);
 
                                l = m;
                        }
@@ -1915,14 +1916,22 @@ static void unfreeze_partials(struct kmem_cache *s)
                                "unfreezing slab"));
 
                if (m == M_FREE) {
-                       stat(s, DEACTIVATE_EMPTY);
-                       discard_slab(s, page);
-                       stat(s, FREE_SLAB);
+                       page->next = discard_page;
+                       discard_page = page;
                }
        }
 
        if (n)
                spin_unlock(&n->list_lock);
+
+       while (discard_page) {
+               page = discard_page;
+               discard_page = discard_page->next;
+
+               stat(s, DEACTIVATE_EMPTY);
+               discard_slab(s, page);
+               stat(s, FREE_SLAB);
+       }
 }
 
 /*
@@ -1969,7 +1978,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
                page->pobjects = pobjects;
                page->next = oldpage;
 
-       } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage);
+       } while (irqsafe_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage);
        stat(s, CPU_PARTIAL_FREE);
        return pobjects;
 }
@@ -4435,30 +4444,31 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
 
                for_each_possible_cpu(cpu) {
                        struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
+                       int node = ACCESS_ONCE(c->node);
                        struct page *page;
 
-                       if (!c || c->node < 0)
+                       if (node < 0)
                                continue;
-
-                       if (c->page) {
-                                       if (flags & SO_TOTAL)
-                                               x = c->page->objects;
+                       page = ACCESS_ONCE(c->page);
+                       if (page) {
+                               if (flags & SO_TOTAL)
+                                       x = page->objects;
                                else if (flags & SO_OBJECTS)
-                                       x = c->page->inuse;
+                                       x = page->inuse;
                                else
                                        x = 1;
 
                                total += x;
-                               nodes[c->node] += x;
+                               nodes[node] += x;
                        }
                        page = c->partial;
 
                        if (page) {
                                x = page->pobjects;
-                                total += x;
-                                nodes[c->node] += x;
+                               total += x;
+                               nodes[node] += x;
                        }
-                       per_cpu[c->node]++;
+                       per_cpu[node]++;
                }
        }
 
index b669aa6f6caff34f41fac15a527a791576f9026a..3231bf3328781b023c9e3b0b772aa1685c940d31 100644 (file)
@@ -2141,23 +2141,30 @@ void  __attribute__((weak)) vmalloc_sync_all(void)
 
 static int f(pte_t *pte, pgtable_t table, unsigned long addr, void *data)
 {
-       /* apply_to_page_range() does all the hard work. */
+       pte_t ***p = data;
+
+       if (p) {
+               *(*p) = pte;
+               (*p)++;
+       }
        return 0;
 }
 
 /**
  *     alloc_vm_area - allocate a range of kernel address space
  *     @size:          size of the area
+ *     @ptes:          returns the PTEs for the address space
  *
  *     Returns:        NULL on failure, vm_struct on success
  *
  *     This function reserves a range of kernel address space, and
  *     allocates pagetables to map that range.  No actual mappings
- *     are created.  If the kernel address space is not shared
- *     between processes, it syncs the pagetable across all
- *     processes.
+ *     are created.
+ *
+ *     If @ptes is non-NULL, pointers to the PTEs (in init_mm)
+ *     allocated for the VM area are returned.
  */
-struct vm_struct *alloc_vm_area(size_t size)
+struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
 {
        struct vm_struct *area;
 
@@ -2171,19 +2178,11 @@ struct vm_struct *alloc_vm_area(size_t size)
         * of kernel virtual address space and mapped into init_mm.
         */
        if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
-                               area->size, f, NULL)) {
+                               size, f, ptes ? &ptes : NULL)) {
                free_vm_area(area);
                return NULL;
        }
 
-       /*
-        * If the allocated address space is passed to a hypercall
-        * before being used then we cannot rely on a page fault to
-        * trigger an update of the page tables.  So sync all the page
-        * tables here.
-        */
-       vmalloc_sync_all();
-
        return area;
 }
 EXPORT_SYMBOL_GPL(alloc_vm_area);
index c1c597e3e198e9ffba26dd4dcf2e59e2ffc923c3..e0af7237cd9245fedfc8886ec446f670ddc48500 100644 (file)
@@ -673,7 +673,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
                goto encrypt;
 
 auth:
-       if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+       if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
                return 0;
 
        if (!hci_conn_auth(conn, sec_level, auth_type))
index 8cd12917733b2cb37f21670edd846c9071e19459..5ea94a1eecf2f9a4338aa116d645b03b77fa7bd6 100644 (file)
@@ -251,7 +251,7 @@ static void l2cap_chan_timeout(unsigned long arg)
 
        if (sock_owned_by_user(sk)) {
                /* sk is owned by user. Try again later */
-               __set_chan_timer(chan, HZ / 5);
+               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                bh_unlock_sock(sk);
                chan_put(chan);
                return;
@@ -2488,7 +2488,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
                if (sock_owned_by_user(sk)) {
                        l2cap_state_change(chan, BT_DISCONN);
                        __clear_chan_timer(chan);
-                       __set_chan_timer(chan, HZ / 5);
+                       __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                        break;
                }
 
@@ -2661,7 +2661,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
        default:
                sk->sk_err = ECONNRESET;
-               __set_chan_timer(chan, HZ * 5);
+               __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
                l2cap_send_disconn_req(conn, chan, ECONNRESET);
                goto done;
        }
@@ -2718,7 +2718,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
        if (sock_owned_by_user(sk)) {
                l2cap_state_change(chan, BT_DISCONN);
                __clear_chan_timer(chan);
-               __set_chan_timer(chan, HZ / 5);
+               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                bh_unlock_sock(sk);
                return 0;
        }
@@ -2752,7 +2752,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
        if (sock_owned_by_user(sk)) {
                l2cap_state_change(chan,BT_DISCONN);
                __clear_chan_timer(chan);
-               __set_chan_timer(chan, HZ / 5);
+               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                bh_unlock_sock(sk);
                return 0;
        }
@@ -3998,7 +3998,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
        if (encrypt == 0x00) {
                if (chan->sec_level == BT_SECURITY_MEDIUM) {
                        __clear_chan_timer(chan);
-                       __set_chan_timer(chan, HZ * 5);
+                       __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
                } else if (chan->sec_level == BT_SECURITY_HIGH)
                        l2cap_chan_close(chan, ECONNREFUSED);
        } else {
@@ -4066,7 +4066,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                        L2CAP_CONN_REQ, sizeof(req), &req);
                        } else {
                                __clear_chan_timer(chan);
-                               __set_chan_timer(chan, HZ / 10);
+                               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                        }
                } else if (chan->state == BT_CONNECT2) {
                        struct l2cap_conn_rsp rsp;
@@ -4086,7 +4086,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                }
                        } else {
                                l2cap_state_change(chan, BT_DISCONN);
-                               __set_chan_timer(chan, HZ / 10);
+                               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                                res = L2CAP_CR_SEC_BLOCK;
                                stat = L2CAP_CS_NO_INFO;
                        }
index 995cbe0ac0b2b1e74f2b4762d61a13102d9f66bb..a5f4e5769809c74f96c1a93ab67ade401fb022d7 100644 (file)
@@ -1501,6 +1501,8 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
 
        __skb_pull(skb2, offset);
        skb_reset_transport_header(skb2);
+       skb_postpull_rcsum(skb2, skb_network_header(skb2),
+                          skb_network_header_len(skb2));
 
        icmp6_type = icmp6_hdr(skb2)->icmp6_type;
 
@@ -1770,7 +1772,7 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
        int err = 0;
        struct net_bridge_mdb_htable *mdb;
 
-       spin_lock(&br->multicast_lock);
+       spin_lock_bh(&br->multicast_lock);
        if (br->multicast_disabled == !val)
                goto unlock;
 
@@ -1806,7 +1808,7 @@ rollback:
        }
 
 unlock:
-       spin_unlock(&br->multicast_lock);
+       spin_unlock_bh(&br->multicast_lock);
 
        return err;
 }
index 733e46008b89d6e67397d779edf9ccb5cb3e5c8a..f4f3f58f5234c1a5ce5eb4b54638c730f571ffb9 100644 (file)
@@ -244,7 +244,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
                ceph_pagelist_init(req->r_trail);
        }
        /* create request message; allow space for oid */
-       msg_size += 40;
+       msg_size += MAX_OBJ_NAME_SIZE;
        if (snapc)
                msg_size += sizeof(u64) * snapc->num_snaps;
        if (use_mempool)
index c1f4154552fc582320e276e6768831ed9ec32548..36d14406261e8c9ad486103127ae1106baca4678 100644 (file)
@@ -136,8 +136,6 @@ static void ah_output_done(struct crypto_async_request *base, int err)
                memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr));
        }
 
-       err = ah->nexthdr;
-
        kfree(AH_SKB_CB(skb)->tmp);
        xfrm_output_resume(skb, err);
 }
@@ -264,12 +262,12 @@ static void ah_input_done(struct crypto_async_request *base, int err)
        if (err)
                goto out;
 
+       err = ah->nexthdr;
+
        skb->network_header += ah_hlen;
        memcpy(skb_network_header(skb), work_iph, ihl);
        __skb_pull(skb, ah_hlen + ihl);
        skb_set_transport_header(skb, -ihl);
-
-       err = ah->nexthdr;
 out:
        kfree(AH_SKB_CB(skb)->tmp);
        xfrm_input_resume(skb, err);
@@ -371,8 +369,6 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
                if (err == -EINPROGRESS)
                        goto out;
 
-               if (err == -EBUSY)
-                       err = NET_XMIT_DROP;
                goto out_free;
        }
 
index f5e2bdaef9495eb52524089f6d9b341cd5503137..68e8ac5143834b80e09cc4bbbbdaecf05a3a2710 100644 (file)
@@ -133,8 +133,8 @@ static int inet_csk_diag_fill(struct sock *sk,
                               &np->rcv_saddr);
                ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
                               &np->daddr);
-               if (ext & (1 << (INET_DIAG_TOS - 1)))
-                       RTA_PUT_U8(skb, INET_DIAG_TOS, np->tclass);
+               if (ext & (1 << (INET_DIAG_TCLASS - 1)))
+                       RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass);
        }
 #endif
 
index ec93335901ddc45d09f7c85c53270ea9a6772207..05d20cca9d66efd2500268a3d0ba4a31117739e7 100644 (file)
@@ -640,6 +640,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
        }
        if (srrptr <= srrspace) {
                opt->srr_is_hit = 1;
+               iph->daddr = nexthop;
                opt->is_changed = 1;
        }
        return 0;
index a06f73fdb3c014e793e50a9ba06363862b3c5eab..43d4c3b223699aee36de3c3c79c6d82b5236a4c0 100644 (file)
@@ -339,7 +339,6 @@ void ping_err(struct sk_buff *skb, u32 info)
        sk = ping_v4_lookup(net, iph->daddr, iph->saddr,
                            ntohs(icmph->un.echo.id), skb->dev->ifindex);
        if (sk == NULL) {
-               ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
                pr_debug("no socket, dropping\n");
                return; /* No socket for error */
        }
@@ -679,7 +678,6 @@ static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
        pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
                inet_sk(sk), inet_sk(sk)->inet_num, skb);
        if (sock_queue_rcv_skb(sk, skb) < 0) {
-               ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_INERRORS);
                kfree_skb(skb);
                pr_debug("ping_queue_rcv_skb -> failed\n");
                return -1;
index 155138d8ec8bb9d7ef0e907b36b0725e0910394d..0c74da8a04732ce9702e9c1c8d80496f1c8df423 100644 (file)
@@ -1304,16 +1304,42 @@ static void rt_del(unsigned hash, struct rtable *rt)
        spin_unlock_bh(rt_hash_lock_addr(hash));
 }
 
+static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
+{
+       struct rtable *rt = (struct rtable *) dst;
+       __be32 orig_gw = rt->rt_gateway;
+       struct neighbour *n, *old_n;
+
+       dst_confirm(&rt->dst);
+
+       rt->rt_gateway = peer->redirect_learned.a4;
+
+       n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
+       if (IS_ERR(n))
+               return PTR_ERR(n);
+       old_n = xchg(&rt->dst._neighbour, n);
+       if (old_n)
+               neigh_release(old_n);
+       if (!n || !(n->nud_state & NUD_VALID)) {
+               if (n)
+                       neigh_event_send(n, NULL);
+               rt->rt_gateway = orig_gw;
+               return -EAGAIN;
+       } else {
+               rt->rt_flags |= RTCF_REDIRECTED;
+               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
+       }
+       return 0;
+}
+
 /* called in rcu_read_lock() section */
 void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                    __be32 saddr, struct net_device *dev)
 {
        int s, i;
        struct in_device *in_dev = __in_dev_get_rcu(dev);
-       struct rtable *rt;
        __be32 skeys[2] = { saddr, 0 };
        int    ikeys[2] = { dev->ifindex, 0 };
-       struct flowi4 fl4;
        struct inet_peer *peer;
        struct net *net;
 
@@ -1336,33 +1362,42 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                        goto reject_redirect;
        }
 
-       memset(&fl4, 0, sizeof(fl4));
-       fl4.daddr = daddr;
        for (s = 0; s < 2; s++) {
                for (i = 0; i < 2; i++) {
-                       fl4.flowi4_oif = ikeys[i];
-                       fl4.saddr = skeys[s];
-                       rt = __ip_route_output_key(net, &fl4);
-                       if (IS_ERR(rt))
-                               continue;
-
-                       if (rt->dst.error || rt->dst.dev != dev ||
-                           rt->rt_gateway != old_gw) {
-                               ip_rt_put(rt);
-                               continue;
-                       }
+                       unsigned int hash;
+                       struct rtable __rcu **rthp;
+                       struct rtable *rt;
+
+                       hash = rt_hash(daddr, skeys[s], ikeys[i], rt_genid(net));
+
+                       rthp = &rt_hash_table[hash].chain;
+
+                       while ((rt = rcu_dereference(*rthp)) != NULL) {
+                               rthp = &rt->dst.rt_next;
+
+                               if (rt->rt_key_dst != daddr ||
+                                   rt->rt_key_src != skeys[s] ||
+                                   rt->rt_oif != ikeys[i] ||
+                                   rt_is_input_route(rt) ||
+                                   rt_is_expired(rt) ||
+                                   !net_eq(dev_net(rt->dst.dev), net) ||
+                                   rt->dst.error ||
+                                   rt->dst.dev != dev ||
+                                   rt->rt_gateway != old_gw)
+                                       continue;
 
-                       if (!rt->peer)
-                               rt_bind_peer(rt, rt->rt_dst, 1);
+                               if (!rt->peer)
+                                       rt_bind_peer(rt, rt->rt_dst, 1);
 
-                       peer = rt->peer;
-                       if (peer) {
-                               peer->redirect_learned.a4 = new_gw;
-                               atomic_inc(&__rt_peer_genid);
+                               peer = rt->peer;
+                               if (peer) {
+                                       if (peer->redirect_learned.a4 != new_gw) {
+                                               peer->redirect_learned.a4 = new_gw;
+                                               atomic_inc(&__rt_peer_genid);
+                                       }
+                                       check_peer_redir(&rt->dst, peer);
+                               }
                        }
-
-                       ip_rt_put(rt);
-                       return;
                }
        }
        return;
@@ -1649,33 +1684,6 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
        }
 }
 
-static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
-{
-       struct rtable *rt = (struct rtable *) dst;
-       __be32 orig_gw = rt->rt_gateway;
-       struct neighbour *n, *old_n;
-
-       dst_confirm(&rt->dst);
-
-       rt->rt_gateway = peer->redirect_learned.a4;
-
-       n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
-       if (IS_ERR(n))
-               return PTR_ERR(n);
-       old_n = xchg(&rt->dst._neighbour, n);
-       if (old_n)
-               neigh_release(old_n);
-       if (!n || !(n->nud_state & NUD_VALID)) {
-               if (n)
-                       neigh_event_send(n, NULL);
-               rt->rt_gateway = orig_gw;
-               return -EAGAIN;
-       } else {
-               rt->rt_flags |= RTCF_REDIRECTED;
-               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
-       }
-       return 0;
-}
 
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
 {
@@ -2845,7 +2853,7 @@ static int rt_fill_info(struct net *net,
        struct rtable *rt = skb_rtable(skb);
        struct rtmsg *r;
        struct nlmsghdr *nlh;
-       long expires = 0;
+       unsigned long expires = 0;
        const struct inet_peer *peer = rt->peer;
        u32 id = 0, ts = 0, tsage = 0, error;
 
@@ -2902,8 +2910,12 @@ static int rt_fill_info(struct net *net,
                        tsage = get_seconds() - peer->tcp_ts_stamp;
                }
                expires = ACCESS_ONCE(peer->pmtu_expires);
-               if (expires)
-                       expires -= jiffies;
+               if (expires) {
+                       if (time_before(jiffies, expires))
+                               expires -= jiffies;
+                       else
+                               expires = 0;
+               }
        }
 
        if (rt_is_input_route(rt)) {
index a7443159c400450e73ff9b83230fe40a48d0da39..a9db4b1a22156dc944addbf661187b2e71070875 100644 (file)
@@ -1510,6 +1510,7 @@ exit:
        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
        return NULL;
 put_and_exit:
+       tcp_clear_xmit_timers(newsk);
        bh_unlock_sock(newsk);
        sock_put(newsk);
        goto exit;
index 980b98f6288c3f82f85da0ac61f74ecfa0cbc12b..63170e29754003c78b2cce548425ae1710c317c4 100644 (file)
@@ -1382,7 +1382,7 @@ static inline int tcp_minshall_check(const struct tcp_sock *tp)
 /* Return 0, if packet can be sent now without violation Nagle's rules:
  * 1. It is full sized.
  * 2. Or it contains FIN. (already checked by caller)
- * 3. Or TCP_NODELAY was set.
+ * 3. Or TCP_CORK is not set, and TCP_NODELAY is set.
  * 4. Or TCP_CORK is not set, and all sent packets are ACKed.
  *    With Minshall's modification: all sent small packets are ACKed.
  */
index 2195ae651923e0e3242c3e61738fed91d19711ff..4c0f894d08432564899bb5611483f5dab3d2ae59 100644 (file)
@@ -324,8 +324,6 @@ static void ah6_output_done(struct crypto_async_request *base, int err)
 #endif
        }
 
-       err = ah->nexthdr;
-
        kfree(AH_SKB_CB(skb)->tmp);
        xfrm_output_resume(skb, err);
 }
@@ -466,12 +464,12 @@ static void ah6_input_done(struct crypto_async_request *base, int err)
        if (err)
                goto out;
 
+       err = ah->nexthdr;
+
        skb->network_header += ah_hlen;
        memcpy(skb_network_header(skb), work_iph, hdr_len);
        __skb_pull(skb, ah_hlen + hdr_len);
        skb_set_transport_header(skb, -hdr_len);
-
-       err = ah->nexthdr;
 out:
        kfree(AH_SKB_CB(skb)->tmp);
        xfrm_input_resume(skb, err);
@@ -583,8 +581,6 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
                if (err == -EINPROGRESS)
                        goto out;
 
-               if (err == -EBUSY)
-                       err = NET_XMIT_DROP;
                goto out_free;
        }
 
index 027c7ff6f1e5370bc0e84d8e3daeb996875a431c..a46c64eb0a660b47b132e4b2346e1c112cc05759 100644 (file)
@@ -111,6 +111,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
            ipv6_addr_loopback(&hdr->daddr))
                goto err;
 
+       /*
+        * RFC4291 2.7
+        * Multicast addresses must not be used as source addresses in IPv6
+        * packets or appear in any Routing header.
+        */
+       if (ipv6_addr_is_multicast(&hdr->saddr))
+               goto err;
+
        skb->transport_header = skb->network_header + sizeof(*hdr);
        IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
 
index bdc15c9003d781fbdb3d0288cf8b88aa84f71742..4e2e9ff67ef29701d4add34b20a63559aa950b4f 100644 (file)
@@ -289,6 +289,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
        if ((err = register_netdevice(dev)) < 0)
                goto failed_free;
 
+       strcpy(t->parms.name, dev->name);
+
        dev_hold(dev);
        ip6_tnl_link(ip6n, t);
        return t;
@@ -1407,7 +1409,6 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
        struct ip6_tnl *t = netdev_priv(dev);
 
        t->dev = dev;
-       strcpy(t->parms.name, dev->name);
        dev->tstats = alloc_percpu(struct pcpu_tstats);
        if (!dev->tstats)
                return -ENOMEM;
@@ -1487,6 +1488,7 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
 static int __net_init ip6_tnl_init_net(struct net *net)
 {
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+       struct ip6_tnl *t = NULL;
        int err;
 
        ip6n->tnls[0] = ip6n->tnls_wc;
@@ -1507,6 +1509,10 @@ static int __net_init ip6_tnl_init_net(struct net *net)
        err = register_netdev(ip6n->fb_tnl_dev);
        if (err < 0)
                goto err_register;
+
+       t = netdev_priv(ip6n->fb_tnl_dev);
+
+       strcpy(t->parms.name, ip6n->fb_tnl_dev->name);
        return 0;
 
 err_register:
index bf8d50c67931e8e588520b7c49ad49fca51b40b3..cf0f308abf5e7324aa05a40cfffd4eee166b0d51 100644 (file)
@@ -756,9 +756,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
                goto error;
        }
 
-       /* Point to L2TP header */
-       optr = ptr = skb->data;
-
        /* Trace packet contents, if enabled */
        if (tunnel->debug & L2TP_MSG_DATA) {
                length = min(32u, skb->len);
@@ -769,12 +766,15 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
 
                offset = 0;
                do {
-                       printk(" %02X", ptr[offset]);
+                       printk(" %02X", skb->data[offset]);
                } while (++offset < length);
 
                printk("\n");
        }
 
+       /* Point to L2TP header */
+       optr = ptr = skb->data;
+
        /* Get L2TP header flags */
        hdrflags = ntohs(*(__be16 *) ptr);
 
index 72c8bea81a6cc8f7b321c0700e3aa619a9a2c444..b1b1bb368f701f61b47da0040ce9b0b477d09deb 100644 (file)
@@ -1487,6 +1487,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
        int i, j, err;
        bool have_higher_than_11mbit = false;
        u16 ap_ht_cap_flags;
+       int min_rate = INT_MAX, min_rate_index = -1;
 
        /* AssocResp and ReassocResp have identical structure */
 
@@ -1553,6 +1554,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
                                rates |= BIT(j);
                                if (is_basic)
                                        basic_rates |= BIT(j);
+                               if (rate < min_rate) {
+                                       min_rate = rate;
+                                       min_rate_index = j;
+                               }
                                break;
                        }
                }
@@ -1570,11 +1575,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
                                rates |= BIT(j);
                                if (is_basic)
                                        basic_rates |= BIT(j);
+                               if (rate < min_rate) {
+                                       min_rate = rate;
+                                       min_rate_index = j;
+                               }
                                break;
                        }
                }
        }
 
+       /*
+        * some buggy APs don't advertise basic_rates. use the lowest
+        * supported rate instead.
+        */
+       if (unlikely(!basic_rates) && min_rate_index >= 0) {
+               printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
+                      "Using min supported rate instead.\n", sdata->name);
+               basic_rates = BIT(min_rate_index);
+       }
+
        sta->sta.supp_rates[wk->chan->band] = rates;
        sdata->vif.bss_conf.basic_rates = basic_rates;
 
@@ -2269,6 +2288,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
 
        cancel_work_sync(&ifmgd->request_smps_work);
 
+       cancel_work_sync(&ifmgd->monitor_work);
        cancel_work_sync(&ifmgd->beacon_connection_loss_work);
        if (del_timer_sync(&ifmgd->timer))
                set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
@@ -2277,7 +2297,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
        if (del_timer_sync(&ifmgd->chswitch_timer))
                set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
 
-       cancel_work_sync(&ifmgd->monitor_work);
        /* these will just be re-established on connection */
        del_timer_sync(&ifmgd->conn_mon_timer);
        del_timer_sync(&ifmgd->bcn_mon_timer);
index bb53726cb04a6d1395f7738e87e58845df3716bf..fb123e2e081a4c51495331f4d8cad945e53c3f40 100644 (file)
@@ -141,8 +141,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        pos++;
 
        /* IEEE80211_RADIOTAP_RATE */
-       if (status->flag & RX_FLAG_HT) {
+       if (!rate || status->flag & RX_FLAG_HT) {
                /*
+                * Without rate information don't add it. If we have,
                 * MCS information is a separate field in radiotap,
                 * added below. The byte here is needed as padding
                 * for the channel though, so initialise it to 0.
@@ -163,12 +164,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        else if (status->flag & RX_FLAG_HT)
                put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
                                   pos);
-       else if (rate->flags & IEEE80211_RATE_ERP_G)
+       else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
                put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
                                   pos);
-       else
+       else if (rate)
                put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
                                   pos);
+       else
+               put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos);
        pos += 2;
 
        /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
index ce962d2c8782e5ec148884ca1ef90a0aaa8e6c18..8eaa746ec7a26d7281e28d42ed3064eb970c874c 100644 (file)
@@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
                         * Use MoreData flag to indicate whether there are
                         * more buffered frames for this STA
                         */
-                       if (!more_data)
-                               hdr->frame_control &=
-                                       cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
-                       else
+                       if (more_data || !skb_queue_empty(&frames))
                                hdr->frame_control |=
                                        cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+                       else
+                               hdr->frame_control &=
+                                       cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
 
                        if (ieee80211_is_data_qos(hdr->frame_control) ||
                            ieee80211_is_qos_nullfunc(hdr->frame_control))
index 51e256c5fb78801f8fd570192a78c38367ec9bf2..eca0fad09709518266d9aed37c61f75e2f05afcf 100644 (file)
@@ -881,6 +881,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
        skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
                                     ssid, ssid_len,
                                     buf, buf_len);
+       if (!skb)
+               goto out;
 
        if (dst) {
                mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -889,6 +891,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
        }
 
        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+
+ out:
        kfree(buf);
 
        return skb;
index 4cf6dc7910e4b0c13a2baf32447bd9000feb1f19..ec753b3ae72ade6005cecee012ec1e2759a7fb45 100644 (file)
@@ -9,7 +9,6 @@ config RDS
 
 config RDS_RDMA
        tristate "RDS over Infiniband and iWARP"
-       select LLIST
        depends on RDS && INFINIBAND && INFINIBAND_ADDR_TRANS
        ---help---
          Allow RDS to use Infiniband and iWARP as a transport.
index d7f97ef265904f0ddc0d691360f1e920dc63210b..55472c48825e6fd43c3357a2f58b398231a2767e 100644 (file)
@@ -496,7 +496,7 @@ static int xs_nospace(struct rpc_task *task)
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_xprt *xprt = req->rq_xprt;
        struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
-       int ret = 0;
+       int ret = -EAGAIN;
 
        dprintk("RPC: %5u xmit incomplete (%u left of %u)\n",
                        task->tk_pid, req->rq_slen - req->rq_bytes_sent,
@@ -508,7 +508,6 @@ static int xs_nospace(struct rpc_task *task)
        /* Don't race with disconnect */
        if (xprt_connected(xprt)) {
                if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) {
-                       ret = -EAGAIN;
                        /*
                         * Notify TCP that we're limited by the application
                         * window size
@@ -2530,8 +2529,10 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
                int err;
                err = xs_init_anyaddr(args->dstaddr->sa_family,
                                        (struct sockaddr *)&new->srcaddr);
-               if (err != 0)
+               if (err != 0) {
+                       xprt_free(xprt);
                        return ERR_PTR(err);
+               }
        }
 
        return xprt;
index 48260c2d092a820873f10769b9100a7864e8d2e0..b3a476fe82725f738f5215b32cdf2296970451d2 100644 (file)
@@ -132,8 +132,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
        [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
 
-       [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
-                                        .len = NL80211_HT_CAPABILITY_LEN },
+       [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
 
        [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
        [NL80211_ATTR_IE] = { .type = NLA_BINARY,
@@ -1253,6 +1252,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                        goto bad_res;
                }
 
+               if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+                   netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
+                       result = -EINVAL;
+                       goto bad_res;
+               }
+
                nla_for_each_nested(nl_txq_params,
                                    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
                                    rem_txq_params) {
index 6acba9d18cc873cb97b6c190d526985704371876..e71f5a66574e31cb1d4e44429402ddcb5a61a529 100644 (file)
@@ -2265,6 +2265,9 @@ void /* __init_or_exit */ regulatory_exit(void)
 
        kfree(last_request);
 
+       last_request = NULL;
+       dev_set_uevent_suppress(&reg_pdev->dev, true);
+
        platform_device_unregister(reg_pdev);
 
        spin_lock_bh(&reg_pending_beacons_lock);
index 0fb1424104047ced0d99949be89388509e05fc5c..dc23b31594e0f54758d0b59ffa5854c6e426e2e8 100644 (file)
@@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
 {
        const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
        const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
-       int r;
 
+       /* equal if both missing */
        if (!ie1 && !ie2)
                return 0;
-       if (!ie1 || !ie2)
+       /* sort missing IE before (left of) present IE */
+       if (!ie1)
                return -1;
+       if (!ie2)
+               return 1;
 
-       r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
-       if (r == 0 && ie1[1] != ie2[1])
+       /* sort by length first, then by contents */
+       if (ie1[1] != ie2[1])
                return ie2[1] - ie1[1];
-       return r;
+       return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
 }
 
 static bool is_bss(struct cfg80211_bss *a,
index 6bc7a86d1027cbf5f78b67804448f577e869d093..d6f8433250a5a37db4543b61c1b73303f92be574 100644 (file)
@@ -2,5 +2,9 @@
 # Makefile for encrypted keys
 #
 
-obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o ecryptfs_format.o
-obj-$(CONFIG_TRUSTED_KEYS) += masterkey_trusted.o
+obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted-keys.o
+
+encrypted-keys-y := encrypted.o ecryptfs_format.o
+masterkey-$(CONFIG_TRUSTED_KEYS) := masterkey_trusted.o
+masterkey-$(CONFIG_TRUSTED_KEYS)-$(CONFIG_ENCRYPTED_KEYS) := masterkey_trusted.o
+encrypted-keys-y += $(masterkey-y) $(masterkey-m-m)
index dcc843cb0f80de0f899ada23d8bf80d25e023e5e..41144f71d6154f612570f8f2c5243269becf68a4 100644 (file)
@@ -444,7 +444,7 @@ static struct key *request_master_key(struct encrypted_key_payload *epayload,
                goto out;
 
        if (IS_ERR(mkey)) {
-               int ret = PTR_ERR(epayload);
+               int ret = PTR_ERR(mkey);
 
                if (ret == -ENOTSUPP)
                        pr_info("encrypted_key: key %s not supported",
index b6ade8945250c0b3f13913c56ee5b9686a3f39d1..8136a2d44c63ddb3a76f30f35b6780ff19b74ae9 100644 (file)
@@ -2,7 +2,8 @@
 #define __ENCRYPTED_KEY_H
 
 #define ENCRYPTED_DEBUG 0
-#ifdef CONFIG_TRUSTED_KEYS
+#if defined(CONFIG_TRUSTED_KEYS) || \
+  (defined(CONFIG_TRUSTED_KEYS_MODULE) && defined(CONFIG_ENCRYPTED_KEYS_MODULE))
 extern struct key *request_trusted_key(const char *trusted_desc,
                                       u8 **master_key, size_t *master_keylen);
 #else
index 5b366d7af3c4dc17b595c67af3dbe99d5fd69df1..69ff52c08e97bb0eab715b1ea61c709e4f80faad 100644 (file)
@@ -102,7 +102,8 @@ int user_update(struct key *key, const void *data, size_t datalen)
                key->expiry = 0;
        }
 
-       kfree_rcu(zap, rcu);
+       if (zap)
+               kfree_rcu(zap, rcu);
 
 error:
        return ret;
index 6aceef518a41fe7cd095bf8f860afe210abeb6ce..5c32f36ff70618dfb08e3040c94060238dfa44da 100644 (file)
@@ -102,9 +102,6 @@ static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
 
 const char *smack_cipso_option = SMACK_CIPSO_OPTION;
 
-
-#define        SEQ_READ_FINISHED       ((loff_t)-1)
-
 /*
  * Values for parsing cipso rules
  * SMK_DIGITLEN: Length of a digit field in a rule.
@@ -357,10 +354,12 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
 
        rc = count;
        /*
+        * If this is "load" as opposed to "load-self" and a new rule
+        * it needs to get added for reporting.
         * smk_set_access returns true if there was already a rule
         * for the subject/object pair, and false if it was new.
         */
-       if (!smk_set_access(rule, rule_list, rule_lock)) {
+       if (load && !smk_set_access(rule, rule_list, rule_lock)) {
                smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
                if (smlp != NULL) {
                        smlp->smk_rule = rule;
@@ -377,12 +376,12 @@ out:
        return rc;
 }
 
-
 /*
- * Seq_file read operations for /smack/load
+ * Core logic for smackfs seq list operations.
  */
 
-static void *load_seq_start(struct seq_file *s, loff_t *pos)
+static void *smk_seq_start(struct seq_file *s, loff_t *pos,
+                               struct list_head *head)
 {
        struct list_head *list;
 
@@ -390,7 +389,7 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos)
         * This is 0 the first time through.
         */
        if (s->index == 0)
-               s->private = &smack_rule_list;
+               s->private = head;
 
        if (s->private == NULL)
                return NULL;
@@ -404,11 +403,12 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos)
        return list;
 }
 
-static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
+static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos,
+                               struct list_head *head)
 {
        struct list_head *list = v;
 
-       if (list_is_last(list, &smack_rule_list)) {
+       if (list_is_last(list, head)) {
                s->private = NULL;
                return NULL;
        }
@@ -416,6 +416,25 @@ static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
        return list->next;
 }
 
+static void smk_seq_stop(struct seq_file *s, void *v)
+{
+       /* No-op */
+}
+
+/*
+ * Seq_file read operations for /smack/load
+ */
+
+static void *load_seq_start(struct seq_file *s, loff_t *pos)
+{
+       return smk_seq_start(s, pos, &smack_rule_list);
+}
+
+static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+       return smk_seq_next(s, v, pos, &smack_rule_list);
+}
+
 static int load_seq_show(struct seq_file *s, void *v)
 {
        struct list_head *list = v;
@@ -446,16 +465,11 @@ static int load_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static void load_seq_stop(struct seq_file *s, void *v)
-{
-       /* No-op */
-}
-
 static const struct seq_operations load_seq_ops = {
        .start = load_seq_start,
        .next  = load_seq_next,
        .show  = load_seq_show,
-       .stop  = load_seq_stop,
+       .stop  = smk_seq_stop,
 };
 
 /**
@@ -574,28 +588,12 @@ static void smk_unlbl_ambient(char *oldambient)
 
 static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
 {
-       if (*pos == SEQ_READ_FINISHED)
-               return NULL;
-       if (list_empty(&smack_known_list))
-               return NULL;
-
-       return smack_known_list.next;
+       return smk_seq_start(s, pos, &smack_known_list);
 }
 
 static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-       struct list_head  *list = v;
-
-       /*
-        * labels with no associated cipso value wont be printed
-        * in cipso_seq_show
-        */
-       if (list_is_last(list, &smack_known_list)) {
-               *pos = SEQ_READ_FINISHED;
-               return NULL;
-       }
-
-       return list->next;
+       return smk_seq_next(s, v, pos, &smack_known_list);
 }
 
 /*
@@ -634,16 +632,11 @@ static int cipso_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static void cipso_seq_stop(struct seq_file *s, void *v)
-{
-       /* No-op */
-}
-
 static const struct seq_operations cipso_seq_ops = {
        .start = cipso_seq_start,
-       .stop  = cipso_seq_stop,
        .next  = cipso_seq_next,
        .show  = cipso_seq_show,
+       .stop  = smk_seq_stop,
 };
 
 /**
@@ -788,23 +781,12 @@ static const struct file_operations smk_cipso_ops = {
 
 static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos)
 {
-       if (*pos == SEQ_READ_FINISHED)
-               return NULL;
-       if (list_empty(&smk_netlbladdr_list))
-               return NULL;
-       return smk_netlbladdr_list.next;
+       return smk_seq_start(s, pos, &smk_netlbladdr_list);
 }
 
 static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-       struct list_head *list = v;
-
-       if (list_is_last(list, &smk_netlbladdr_list)) {
-               *pos = SEQ_READ_FINISHED;
-               return NULL;
-       }
-
-       return list->next;
+       return smk_seq_next(s, v, pos, &smk_netlbladdr_list);
 }
 #define BEBITS (sizeof(__be32) * 8)
 
@@ -828,16 +810,11 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static void netlbladdr_seq_stop(struct seq_file *s, void *v)
-{
-       /* No-op */
-}
-
 static const struct seq_operations netlbladdr_seq_ops = {
        .start = netlbladdr_seq_start,
-       .stop  = netlbladdr_seq_stop,
        .next  = netlbladdr_seq_next,
        .show  = netlbladdr_seq_show,
+       .stop  = smk_seq_stop,
 };
 
 /**
@@ -1405,23 +1382,14 @@ static void *load_self_seq_start(struct seq_file *s, loff_t *pos)
 {
        struct task_smack *tsp = current_security();
 
-       if (*pos == SEQ_READ_FINISHED)
-               return NULL;
-       if (list_empty(&tsp->smk_rules))
-               return NULL;
-       return tsp->smk_rules.next;
+       return smk_seq_start(s, pos, &tsp->smk_rules);
 }
 
 static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
        struct task_smack *tsp = current_security();
-       struct list_head *list = v;
 
-       if (list_is_last(list, &tsp->smk_rules)) {
-               *pos = SEQ_READ_FINISHED;
-               return NULL;
-       }
-       return list->next;
+       return smk_seq_next(s, v, pos, &tsp->smk_rules);
 }
 
 static int load_self_seq_show(struct seq_file *s, void *v)
@@ -1453,16 +1421,11 @@ static int load_self_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static void load_self_seq_stop(struct seq_file *s, void *v)
-{
-       /* No-op */
-}
-
 static const struct seq_operations load_self_seq_ops = {
        .start = load_self_seq_start,
        .next  = load_self_seq_next,
        .show  = load_self_seq_show,
-       .stop  = load_self_seq_stop,
+       .stop  = smk_seq_stop,
 };
 
 
index e083122ca55af550f6d4b72e6d5cea5c8c2e1a05..dbf94b189e7576b6e8a3194c5612b0397e6060ee 100644 (file)
@@ -148,7 +148,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
                struct cs5535audio_dma_desc *desc =
                        &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i];
                desc->addr = cpu_to_le32(addr);
-               desc->size = cpu_to_le32(period_bytes);
+               desc->size = cpu_to_le16(period_bytes);
                desc->ctlreserved = cpu_to_le16(PRD_EOP);
                desc_addr += sizeof(struct cs5535audio_dma_desc);
                addr += period_bytes;
index e44b107fdc7594c47df5458b7acc0c6440454561..4562e9de6a1ab0dc7015e28d7be14c2eafa5a6b3 100644 (file)
@@ -4046,9 +4046,9 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
 
        /* Search for codec ID */
        for (q = tbl; q->subvendor; q++) {
-               unsigned long vendorid = (q->subdevice) | (q->subvendor << 16);
-
-               if (vendorid == codec->subsystem_id)
+               unsigned int mask = 0xffff0000 | q->subdevice_mask;
+               unsigned int id = (q->subdevice | (q->subvendor << 16)) & mask;
+               if ((codec->subsystem_id & mask) == id)
                        break;
        }
 
index 1c8ddf547a2dde5b1426fdfb6d26261ea35e6872..c1da422e085a5230d8b7eb837925772b11ea4328 100644 (file)
@@ -297,10 +297,18 @@ static int hdmi_update_eld(struct hdmi_eld *e,
                                        buf + ELD_FIXED_BYTES + mnl + 3 * i);
        }
 
+       /*
+        * HDMI sink's ELD info cannot always be retrieved for now, e.g.
+        * in console or for audio devices. Assume the highest speakers
+        * configuration, to _not_ prohibit multi-channel audio playback.
+        */
+       if (!e->spk_alloc)
+               e->spk_alloc = 0xffff;
+
+       e->eld_valid = true;
        return 0;
 
 out_fail:
-       e->eld_ver = 0;
        return -EINVAL;
 }
 
@@ -323,9 +331,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
         * ELD is valid, actual eld_size is assigned in hdmi_update_eld()
         */
 
-       if (!eld->eld_valid)
-               return -ENOENT;
-
        size = snd_hdmi_get_eld_size(codec, nid);
        if (size == 0) {
                /* wfg: workaround for ASUS P5E-VM HDMI board */
@@ -342,18 +347,28 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
 
        for (i = 0; i < size; i++) {
                unsigned int val = hdmi_get_eld_data(codec, nid, i);
+               /*
+                * Graphics driver might be writing to ELD buffer right now.
+                * Just abort. The caller will repoll after a while.
+                */
                if (!(val & AC_ELDD_ELD_VALID)) {
-                       if (!i) {
-                               snd_printd(KERN_INFO
-                                          "HDMI: invalid ELD data\n");
-                               ret = -EINVAL;
-                               goto error;
-                       }
                        snd_printd(KERN_INFO
                                  "HDMI: invalid ELD data byte %d\n", i);
-                       val = 0;
-               } else
-                       val &= AC_ELDD_ELD_DATA;
+                       ret = -EINVAL;
+                       goto error;
+               }
+               val &= AC_ELDD_ELD_DATA;
+               /*
+                * The first byte cannot be zero. This can happen on some DVI
+                * connections. Some Intel chips may also need some 250ms delay
+                * to return non-zero ELD data, even when the graphics driver
+                * correctly writes ELD content before setting ELD_valid bit.
+                */
+               if (!val && !i) {
+                       snd_printdd(KERN_INFO "HDMI: 0 ELD data\n");
+                       ret = -EINVAL;
+                       goto error;
+               }
                buf[i] = val;
        }
 
index 6579e0f2bb57d6b6c99814cb06b9f1c194eedb66..618ddad172369b22062ad97114dd783841ccde43 100644 (file)
@@ -653,6 +653,9 @@ struct hdmi_eld {
        int     spk_alloc;
        int     sad_count;
        struct cea_sad sad[ELD_MAX_SAD];
+       /*
+        * all fields above eld_buffer will be cleared before updating ELD
+        */
        char    eld_buffer[ELD_MAX_SIZE];
 #ifdef CONFIG_PROC_FS
        struct snd_info_entry *proc_entry;
index 2a2d8645ba0933e8e9e20ef3bd33a656f1bb69c5..70a7abda7e225744bf93d90f795c86bfcd95dac6 100644 (file)
@@ -58,6 +58,8 @@ struct cs_spec {
        unsigned int gpio_mask;
        unsigned int gpio_dir;
        unsigned int gpio_data;
+       unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */
+       unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */
 
        struct hda_pcm pcm_rec[2];      /* PCM information */
 
@@ -76,6 +78,7 @@ enum {
        CS420X_MBP53,
        CS420X_MBP55,
        CS420X_IMAC27,
+       CS420X_APPLE,
        CS420X_AUTO,
        CS420X_MODELS
 };
@@ -237,6 +240,15 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
 }
 
+static void cs_update_input_select(struct hda_codec *codec)
+{
+       struct cs_spec *spec = codec->spec;
+       if (spec->cur_adc)
+               snd_hda_codec_write(codec, spec->cur_adc, 0,
+                                   AC_VERB_SET_CONNECT_SEL,
+                                   spec->adc_idx[spec->cur_input]);
+}
+
 /*
  * Analog capture
  */
@@ -250,6 +262,7 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
        spec->cur_adc = spec->adc_nid[spec->cur_input];
        spec->cur_adc_stream_tag = stream_tag;
        spec->cur_adc_format = format;
+       cs_update_input_select(codec);
        snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
        return 0;
 }
@@ -689,10 +702,8 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx,
                                           spec->cur_adc_stream_tag, 0,
                                           spec->cur_adc_format);
        }
-       snd_hda_codec_write(codec, spec->cur_adc, 0,
-                           AC_VERB_SET_CONNECT_SEL,
-                           spec->adc_idx[idx]);
        spec->cur_input = idx;
+       cs_update_input_select(codec);
        return 1;
 }
 
@@ -920,10 +931,9 @@ static void cs_automute(struct hda_codec *codec)
                                        spdif_present ? 0 : PIN_OUT);
                }
        }
-       if (spec->board_config == CS420X_MBP53 ||
-           spec->board_config == CS420X_MBP55 ||
-           spec->board_config == CS420X_IMAC27) {
-               unsigned int gpio = hp_present ? 0x02 : 0x08;
+       if (spec->gpio_eapd_hp) {
+               unsigned int gpio = hp_present ?
+                       spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
                snd_hda_codec_write(codec, 0x01, 0,
                                    AC_VERB_SET_GPIO_DATA, gpio);
        }
@@ -973,10 +983,7 @@ static void cs_automic(struct hda_codec *codec)
                } else  {
                        spec->cur_input = spec->last_input;
                }
-
-               snd_hda_codec_write_cache(codec, spec->cur_adc, 0,
-                                       AC_VERB_SET_CONNECT_SEL,
-                                       spec->adc_idx[spec->cur_input]);
+               cs_update_input_select(codec);
        } else {
                if (present)
                        change_cur_input(codec, spec->automic_idx, 0);
@@ -1073,9 +1080,7 @@ static void init_input(struct hda_codec *codec)
                        cs_automic(codec);
                else  {
                        spec->cur_adc = spec->adc_nid[spec->cur_input];
-                       snd_hda_codec_write(codec, spec->cur_adc, 0,
-                                       AC_VERB_SET_CONNECT_SEL,
-                                       spec->adc_idx[spec->cur_input]);
+                       cs_update_input_select(codec);
                }
        } else {
                change_cur_input(codec, spec->cur_input, 1);
@@ -1273,6 +1278,7 @@ static const char * const cs420x_models[CS420X_MODELS] = {
        [CS420X_MBP53] = "mbp53",
        [CS420X_MBP55] = "mbp55",
        [CS420X_IMAC27] = "imac27",
+       [CS420X_APPLE] = "apple",
        [CS420X_AUTO] = "auto",
 };
 
@@ -1282,7 +1288,13 @@ static const struct snd_pci_quirk cs420x_cfg_tbl[] = {
        SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
        SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
        SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
-       SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),
+       /* this conflicts with too many other models */
+       /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/
+       {} /* terminator */
+};
+
+static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = {
+       SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
        {} /* terminator */
 };
 
@@ -1364,6 +1376,10 @@ static int patch_cs420x(struct hda_codec *codec)
        spec->board_config =
                snd_hda_check_board_config(codec, CS420X_MODELS,
                                           cs420x_models, cs420x_cfg_tbl);
+       if (spec->board_config < 0)
+               spec->board_config =
+                       snd_hda_check_board_codec_sid_config(codec,
+                               CS420X_MODELS, NULL, cs420x_codec_cfg_tbl);
        if (spec->board_config >= 0)
                fix_pincfg(codec, spec->board_config, cs_pincfgs);
 
@@ -1371,10 +1387,11 @@ static int patch_cs420x(struct hda_codec *codec)
        case CS420X_IMAC27:
        case CS420X_MBP53:
        case CS420X_MBP55:
-               /* GPIO1 = headphones */
-               /* GPIO3 = speakers */
-               spec->gpio_mask = 0x0a;
-               spec->gpio_dir = 0x0a;
+       case CS420X_APPLE:
+               spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */
+               spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
+               spec->gpio_mask = spec->gpio_dir =
+                       spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
                break;
        }
 
index 81b7b791b3c36a09adef820b4ef4e5e837577121..c505fd5d338cc91d1de2199143c8141f24890355 100644 (file)
@@ -65,7 +65,11 @@ struct hdmi_spec_per_pin {
        hda_nid_t pin_nid;
        int num_mux_nids;
        hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
+
+       struct hda_codec *codec;
        struct hdmi_eld sink_eld;
+       struct delayed_work work;
+       int repoll_count;
 };
 
 struct hdmi_spec {
@@ -745,8 +749,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
  * Unsolicited events
  */
 
-static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
-                              struct hdmi_eld *eld);
+static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
 
 static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
 {
@@ -755,7 +758,6 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
        int pd = !!(res & AC_UNSOL_RES_PD);
        int eldv = !!(res & AC_UNSOL_RES_ELDV);
        int pin_idx;
-       struct hdmi_eld *eld;
 
        printk(KERN_INFO
                "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
@@ -764,17 +766,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
        pin_idx = pin_nid_to_pin_index(spec, pin_nid);
        if (pin_idx < 0)
                return;
-       eld = &spec->pins[pin_idx].sink_eld;
-
-       hdmi_present_sense(codec, pin_nid, eld);
 
-       /*
-        * HDMI sink's ELD info cannot always be retrieved for now, e.g.
-        * in console or for audio devices. Assume the highest speakers
-        * configuration, to _not_ prohibit multi-channel audio playback.
-        */
-       if (!eld->spk_alloc)
-               eld->spk_alloc = 0xffff;
+       hdmi_present_sense(&spec->pins[pin_idx], 1);
 }
 
 static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -968,9 +961,11 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
        return 0;
 }
 
-static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
-                              struct hdmi_eld *eld)
+static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
 {
+       struct hda_codec *codec = per_pin->codec;
+       struct hdmi_eld *eld = &per_pin->sink_eld;
+       hda_nid_t pin_nid = per_pin->pin_nid;
        /*
         * Always execute a GetPinSense verb here, even when called from
         * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited
@@ -980,26 +975,42 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
         * the unsolicited response to avoid custom WARs.
         */
        int present = snd_hda_pin_sense(codec, pin_nid);
+       bool eld_valid = false;
 
-       memset(eld, 0, sizeof(*eld));
+       memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer));
 
        eld->monitor_present    = !!(present & AC_PINSENSE_PRESENCE);
        if (eld->monitor_present)
-               eld->eld_valid  = !!(present & AC_PINSENSE_ELDV);
-       else
-               eld->eld_valid  = 0;
+               eld_valid       = !!(present & AC_PINSENSE_ELDV);
 
        printk(KERN_INFO
                "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
-               codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
+               codec->addr, pin_nid, eld->monitor_present, eld_valid);
 
-       if (eld->eld_valid)
+       if (eld_valid) {
                if (!snd_hdmi_get_eld(eld, codec, pin_nid))
                        snd_hdmi_show_eld(eld);
+               else if (repoll) {
+                       queue_delayed_work(codec->bus->workq,
+                                          &per_pin->work,
+                                          msecs_to_jiffies(300));
+               }
+       }
 
        snd_hda_input_jack_report(codec, pin_nid);
 }
 
+static void hdmi_repoll_eld(struct work_struct *work)
+{
+       struct hdmi_spec_per_pin *per_pin =
+       container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work);
+
+       if (per_pin->repoll_count++ > 6)
+               per_pin->repoll_count = 0;
+
+       hdmi_present_sense(per_pin, per_pin->repoll_count);
+}
+
 static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
 {
        struct hdmi_spec *spec = codec->spec;
@@ -1228,7 +1239,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
        if (err < 0)
                return err;
 
-       hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld);
+       hdmi_present_sense(per_pin, 0);
        return 0;
 }
 
@@ -1279,6 +1290,8 @@ static int generic_hdmi_init(struct hda_codec *codec)
                                    AC_VERB_SET_UNSOLICITED_ENABLE,
                                    AC_USRSP_EN | pin_nid);
 
+               per_pin->codec = codec;
+               INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
                snd_hda_eld_proc_new(codec, eld, pin_idx);
        }
        return 0;
@@ -1293,10 +1306,12 @@ static void generic_hdmi_free(struct hda_codec *codec)
                struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
                struct hdmi_eld *eld = &per_pin->sink_eld;
 
+               cancel_delayed_work(&per_pin->work);
                snd_hda_eld_proc_free(codec, eld);
        }
        snd_hda_input_jack_free(codec);
 
+       flush_workqueue(codec->bus->workq);
        kfree(spec);
 }
 
index 308bb575bc06464978ee7f6c44dd2ecb1f588434..cbde019d3d52b985e4c8a95b5f74386ac34eef69 100644 (file)
@@ -277,6 +277,12 @@ static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
        return false;
 }
 
+static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
+{
+       return spec->capsrc_nids ?
+               spec->capsrc_nids[idx] : spec->adc_nids[idx];
+}
+
 /* select the given imux item; either unmute exclusively or select the route */
 static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
                          unsigned int idx, bool force)
@@ -303,8 +309,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
                adc_idx = spec->dyn_adc_idx[idx];
        }
 
-       nid = spec->capsrc_nids ?
-               spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
+       nid = get_capsrc(spec, adc_idx);
 
        /* no selection? */
        num_conns = snd_hda_get_conn_list(codec, nid, NULL);
@@ -1054,8 +1059,19 @@ static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
        spec->imux_pins[2] = spec->dock_mic_pin;
        for (i = 0; i < 3; i++) {
                strcpy(imux->items[i].label, texts[i]);
-               if (spec->imux_pins[i])
+               if (spec->imux_pins[i]) {
+                       hda_nid_t pin = spec->imux_pins[i];
+                       int c;
+                       for (c = 0; c < spec->num_adc_nids; c++) {
+                               hda_nid_t cap = get_capsrc(spec, c);
+                               int idx = get_connection_index(codec, cap, pin);
+                               if (idx >= 0) {
+                                       imux->items[i].index = idx;
+                                       break;
+                               }
+                       }
                        imux->num_items = i + 1;
+               }
        }
        spec->num_mux_defs = 1;
        spec->input_mux = imux;
@@ -1452,7 +1468,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action)
                switch (fix->type) {
                case ALC_FIXUP_SKU:
                        if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
-                               break;;
+                               break;
                        snd_printdd(KERN_INFO "hda_codec: %s: "
                                    "Apply sku override for %s\n",
                                    codec->chip_name, modelname);
@@ -1957,10 +1973,8 @@ static int alc_build_controls(struct hda_codec *codec)
                if (!kctl)
                        kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
                for (i = 0; kctl && i < kctl->count; i++) {
-                       const hda_nid_t *nids = spec->capsrc_nids;
-                       if (!nids)
-                               nids = spec->adc_nids;
-                       err = snd_hda_add_nid(codec, kctl, i, nids[i]);
+                       err = snd_hda_add_nid(codec, kctl, i,
+                                             get_capsrc(spec, i));
                        if (err < 0)
                                return err;
                }
@@ -2747,8 +2761,7 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec)
                }
 
                for (c = 0; c < num_adcs; c++) {
-                       hda_nid_t cap = spec->capsrc_nids ?
-                               spec->capsrc_nids[c] : spec->adc_nids[c];
+                       hda_nid_t cap = get_capsrc(spec, c);
                        idx = get_connection_index(codec, cap, pin);
                        if (idx >= 0) {
                                spec->imux_pins[imux->num_items] = pin;
@@ -3694,8 +3707,7 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
        if (!pin)
                return 0;
        for (i = 0; i < spec->num_adc_nids; i++) {
-               hda_nid_t cap = spec->capsrc_nids ?
-                       spec->capsrc_nids[i] : spec->adc_nids[i];
+               hda_nid_t cap = get_capsrc(spec, i);
                int idx;
 
                idx = get_connection_index(codec, cap, pin);
index edc2b7bc177c6bca0c6999c66d732b84230d054a..f3658658548e35179c70069cb31a498cabc155f7 100644 (file)
@@ -227,7 +227,6 @@ struct sigmatel_spec {
 
        /* power management */
        unsigned int num_pwrs;
-       const unsigned int *pwr_mapping;
        const hda_nid_t *pwr_nids;
        const hda_nid_t *dac_list;
 
@@ -374,18 +373,15 @@ static const unsigned long stac92hd73xx_capvols[] = {
 
 #define STAC92HD83_DAC_COUNT 3
 
-static const hda_nid_t stac92hd83xxx_pwr_nids[4] = {
-       0xa, 0xb, 0xd, 0xe,
+static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
+       0x0a, 0x0b, 0x0c, 0xd, 0x0e,
+       0x0f, 0x10
 };
 
 static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
        0x1e, 0,
 };
 
-static const unsigned int stac92hd83xxx_pwr_mapping[4] = {
-       0x03, 0x0c, 0x20, 0x40,
-};
-
 static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
                0x11, 0x20,
 };
@@ -1645,6 +1641,8 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
                      "Alienware M17x", STAC_ALIENWARE_M17X),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
                      "Alienware M17x", STAC_ALIENWARE_M17X),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
+                     "Alienware M17x", STAC_ALIENWARE_M17X),
        {} /* terminator */
 };
 
@@ -4470,8 +4468,12 @@ static int stac92xx_init(struct hda_codec *codec)
                                stac_toggle_power_map(codec, nid, 1);
                        continue;
                }
-               if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
+               if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
                        stac_issue_unsol_event(codec, nid);
+                       continue;
+               }
+               /* none of the above, turn the port OFF */
+               stac_toggle_power_map(codec, nid, 0);
        }
 
        /* sync mute LED */
@@ -4727,11 +4729,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
        if (idx >= spec->num_pwrs)
                return;
 
-       /* several codecs have two power down bits */
-       if (spec->pwr_mapping)
-               idx = spec->pwr_mapping[idx];
-       else
-               idx = 1 << idx;
+       idx = 1 << idx;
 
        val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff;
        if (enable)
@@ -5629,9 +5627,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
                snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
        }
 
-       /* reset pin power-down; Windows may leave these bits after reboot */
-       snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0);
-       snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
        codec->no_trigger_sense = 1;
        codec->spec = spec;
 
@@ -5641,7 +5636,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
        codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
        spec->digbeep_nid = 0x21;
        spec->pwr_nids = stac92hd83xxx_pwr_nids;
-       spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
        spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
        spec->multiout.dac_nids = spec->dac_nids;
        spec->init = stac92hd83xxx_core_init;
@@ -5658,9 +5652,6 @@ again:
                stac92xx_set_config_regs(codec,
                                stac92hd83xxx_brd_tbl[spec->board_config]);
 
-       if (spec->board_config != STAC_92HD83XXX_PWR_REF)
-               spec->num_pwrs = 0;
-
        codec->patch_ops = stac92xx_patch_ops;
 
        if (find_mute_led_gpio(codec, 0))
@@ -5869,8 +5860,6 @@ again:
                    (codec->revision_id & 0xf) == 1)
                        spec->stream_delay = 40; /* 40 milliseconds */
 
-               /* no output amps */
-               spec->num_pwrs = 0;
                /* disable VSW */
                spec->init = stac92hd71bxx_core_init;
                unmute_init++;
@@ -5885,8 +5874,6 @@ again:
                if ((codec->revision_id & 0xf) == 1)
                        spec->stream_delay = 40; /* 40 milliseconds */
 
-               /* no output amps */
-               spec->num_pwrs = 0;
                /* fallthru */
        default:
                spec->init = stac92hd71bxx_core_init;
index 431c0d417eeb61500c3332c687568a7851307201..b5137629f8e942a75a941e0e183cef98fb58db02 100644 (file)
@@ -208,6 +208,7 @@ struct via_spec {
        /* work to check hp jack state */
        struct hda_codec *codec;
        struct delayed_work vt1708_hp_work;
+       int hp_work_active;
        int vt1708_jack_detect;
        int vt1708_hp_present;
 
@@ -305,27 +306,35 @@ enum {
 static void analog_low_current_mode(struct hda_codec *codec);
 static bool is_aa_path_mute(struct hda_codec *codec);
 
-static void vt1708_start_hp_work(struct via_spec *spec)
+#define hp_detect_with_aa(codec) \
+       (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \
+        !is_aa_path_mute(codec))
+
+static void vt1708_stop_hp_work(struct via_spec *spec)
 {
        if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
                return;
-       snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
-                           !spec->vt1708_jack_detect);
-       if (!delayed_work_pending(&spec->vt1708_hp_work))
-               schedule_delayed_work(&spec->vt1708_hp_work,
-                                     msecs_to_jiffies(100));
+       if (spec->hp_work_active) {
+               snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1);
+               cancel_delayed_work_sync(&spec->vt1708_hp_work);
+               spec->hp_work_active = 0;
+       }
 }
 
-static void vt1708_stop_hp_work(struct via_spec *spec)
+static void vt1708_update_hp_work(struct via_spec *spec)
 {
        if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
                return;
-       if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
-           && !is_aa_path_mute(spec->codec))
-               return;
-       snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
-                           !spec->vt1708_jack_detect);
-       cancel_delayed_work_sync(&spec->vt1708_hp_work);
+       if (spec->vt1708_jack_detect &&
+           (spec->active_streams || hp_detect_with_aa(spec->codec))) {
+               if (!spec->hp_work_active) {
+                       snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0);
+                       schedule_delayed_work(&spec->vt1708_hp_work,
+                                             msecs_to_jiffies(100));
+                       spec->hp_work_active = 1;
+               }
+       } else if (!hp_detect_with_aa(spec->codec))
+               vt1708_stop_hp_work(spec);
 }
 
 static void set_widgets_power_state(struct hda_codec *codec)
@@ -343,12 +352,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
 
        set_widgets_power_state(codec);
        analog_low_current_mode(snd_kcontrol_chip(kcontrol));
-       if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
-               if (is_aa_path_mute(codec))
-                       vt1708_start_hp_work(codec->spec);
-               else
-                       vt1708_stop_hp_work(codec->spec);
-       }
+       vt1708_update_hp_work(codec->spec);
        return change;
 }
 
@@ -1154,7 +1158,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
        spec->cur_dac_stream_tag = stream_tag;
        spec->cur_dac_format = format;
        mutex_unlock(&spec->config_mutex);
-       vt1708_start_hp_work(spec);
+       vt1708_update_hp_work(spec);
        return 0;
 }
 
@@ -1174,7 +1178,7 @@ static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
        spec->cur_hp_stream_tag = stream_tag;
        spec->cur_hp_format = format;
        mutex_unlock(&spec->config_mutex);
-       vt1708_start_hp_work(spec);
+       vt1708_update_hp_work(spec);
        return 0;
 }
 
@@ -1188,7 +1192,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
        snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
        spec->active_streams &= ~STREAM_MULTI_OUT;
        mutex_unlock(&spec->config_mutex);
-       vt1708_stop_hp_work(spec);
+       vt1708_update_hp_work(spec);
        return 0;
 }
 
@@ -1203,7 +1207,7 @@ static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
                snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
        spec->active_streams &= ~STREAM_INDEP_HP;
        mutex_unlock(&spec->config_mutex);
-       vt1708_stop_hp_work(spec);
+       vt1708_update_hp_work(spec);
        return 0;
 }
 
@@ -1645,7 +1649,8 @@ static void via_hp_automute(struct hda_codec *codec)
        int nums;
        struct via_spec *spec = codec->spec;
 
-       if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0])
+       if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] &&
+           (spec->codec_type != VT1708 || spec->vt1708_jack_detect))
                present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
 
        if (spec->smart51_enabled)
@@ -2612,8 +2617,6 @@ static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
 
        if (spec->codec_type != VT1708)
                return 0;
-       spec->vt1708_jack_detect =
-               !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
        ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
        return 0;
 }
@@ -2623,18 +2626,22 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct via_spec *spec = codec->spec;
-       int change;
+       int val;
 
        if (spec->codec_type != VT1708)
                return 0;
-       spec->vt1708_jack_detect = ucontrol->value.integer.value[0];
-       change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
-               == !spec->vt1708_jack_detect;
-       if (spec->vt1708_jack_detect) {
+       val = !!ucontrol->value.integer.value[0];
+       if (spec->vt1708_jack_detect == val)
+               return 0;
+       spec->vt1708_jack_detect = val;
+       if (spec->vt1708_jack_detect &&
+           snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) {
                mute_aa_path(codec, 1);
                notify_aa_path_ctls(codec);
        }
-       return change;
+       via_hp_automute(codec);
+       vt1708_update_hp_work(spec);
+       return 1;
 }
 
 static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
@@ -2771,6 +2778,7 @@ static int via_init(struct hda_codec *codec)
        via_auto_init_unsol_event(codec);
 
        via_hp_automute(codec);
+       vt1708_update_hp_work(spec);
 
        return 0;
 }
@@ -2787,7 +2795,9 @@ static void vt1708_update_hp_jack_state(struct work_struct *work)
                spec->vt1708_hp_present ^= 1;
                via_hp_automute(spec->codec);
        }
-       vt1708_start_hp_work(spec);
+       if (spec->vt1708_jack_detect)
+               schedule_delayed_work(&spec->vt1708_hp_work,
+                                     msecs_to_jiffies(100));
 }
 
 static int get_mux_nids(struct hda_codec *codec)
index 5c8717e29eebdbc4983933dcccaee36492457e41..8c3e7fcefd99c91c38d39f92fd0cae8323cee210 100644 (file)
@@ -78,10 +78,15 @@ unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port)
        return ioread32(address);
 }
 
-void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len)
+static void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data,
+                              u32 len)
 {
-       void __iomem *address = lx_dsp_register(chip, port);
-       memcpy_fromio(data, address, len*sizeof(u32));
+       u32 __iomem *address = lx_dsp_register(chip, port);
+       int i;
+
+       /* we cannot use memcpy_fromio */
+       for (i = 0; i != len; ++i)
+               data[i] = ioread32(address + i);
 }
 
 
@@ -91,11 +96,15 @@ void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data)
        iowrite32(data, address);
 }
 
-void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data,
-                        u32 len)
+static void lx_dsp_reg_writebuf(struct lx6464es *chip, int port,
+                               const u32 *data, u32 len)
 {
-       void __iomem *address = lx_dsp_register(chip, port);
-       memcpy_toio(address, data, len*sizeof(u32));
+       u32 __iomem *address = lx_dsp_register(chip, port);
+       int i;
+
+       /* we cannot use memcpy_to */
+       for (i = 0; i != len; ++i)
+               iowrite32(data[i], address + i);
 }
 
 
index 1dd562980b6c3595c233beffe49012c6352c605c..4d7ff797a6468abf5b5499cdfd92dab430d9948f 100644 (file)
@@ -72,10 +72,7 @@ enum {
 };
 
 unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port);
-void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len);
 void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data);
-void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data,
-                        u32 len);
 
 /* plx register access */
 enum {
index e760adad9523ebf82db4f07dbc259c73d8d44326..19ee2203cbb50fe7250bca2bad79c14e15a6069b 100644 (file)
@@ -6518,7 +6518,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
                        hdspm->io_type = AES32;
                        hdspm->card_name = "RME AES32";
                        hdspm->midiPorts = 2;
-               } else if ((hdspm->firmware_rev == 0xd5) ||
+               } else if ((hdspm->firmware_rev == 0xd2) ||
                        ((hdspm->firmware_rev >= 0xc8)  &&
                                (hdspm->firmware_rev <= 0xcf))) {
                        hdspm->io_type = MADI;
index 1ccf8dd47576ce4c746ffb54461c19f196acff43..45c63028b40d1636b56f6aa3e5f13e0d110b9a5d 100644 (file)
@@ -245,7 +245,7 @@ static const char *adau1373_bass_hpf_cutoff_text[] = {
 };
 
 static const unsigned int adau1373_bass_tlv[] = {
-       TLV_DB_RANGE_HEAD(4),
+       TLV_DB_RANGE_HEAD(3),
        0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1),
        3, 4, TLV_DB_SCALE_ITEM(950, 250, 0),
        5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0),
index 23d1bd5dadda36185e2c56702e7fd17a739f9a1a..69fde1506fe1fde2fe312ff80176723171ccef07 100644 (file)
@@ -434,7 +434,8 @@ static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
 {
        int ret;
        /* Set power-down bit */
-       ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN);
+       ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN,
+                                 CS4271_MODE2_PDN);
        if (ret < 0)
                return ret;
        return 0;
@@ -501,8 +502,9 @@ static int cs4271_probe(struct snd_soc_codec *codec)
                return ret;
        }
 
-       ret = snd_soc_update_bits(codec, CS4271_MODE2, 0,
-               CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
+       ret = snd_soc_update_bits(codec, CS4271_MODE2,
+                                 CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
+                                 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
        if (ret < 0)
                return ret;
        ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
index 27a078cbb6eb2542cb6bc0fa0be372b5a77cabac..4646e808b90a334e0d59935a1e93244672d276be 100644 (file)
@@ -177,7 +177,7 @@ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0);
 static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
 /* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */
 static unsigned int mic_bst_tlv[] = {
-       TLV_DB_RANGE_HEAD(6),
+       TLV_DB_RANGE_HEAD(7),
        0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
        1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
        2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
index d15695d1c27397a7b3f2966c1806584e5e9a39bc..bbcf921166f7470fad24577d2aa52d1cf85258f4 100644 (file)
@@ -365,7 +365,7 @@ static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
 
 /* tlv for mic gain, 0db 20db 30db 40db */
 static const unsigned int mic_gain_tlv[] = {
-       TLV_DB_RANGE_HEAD(4),
+       TLV_DB_RANGE_HEAD(2),
        0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
        1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
 };
index bb82408ab8e1bb93f187dac610e5a1141501bd72..d2f37152f940cebc67f93a5bff140e64a67a07e7 100644 (file)
@@ -76,6 +76,8 @@ struct sta32x_priv {
 
        unsigned int mclk;
        unsigned int format;
+
+       u32 coef_shadow[STA32X_COEF_COUNT];
 };
 
 static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
@@ -227,6 +229,7 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
        unsigned int cfud;
@@ -239,6 +242,11 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
        snd_soc_write(codec, STA32X_CFUD, cfud);
 
        snd_soc_write(codec, STA32X_CFADDR2, index);
+       for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++)
+               sta32x->coef_shadow[index + i] =
+                         (ucontrol->value.bytes.data[3 * i] << 16)
+                       | (ucontrol->value.bytes.data[3 * i + 1] << 8)
+                       | (ucontrol->value.bytes.data[3 * i + 2]);
        for (i = 0; i < 3 * numcoef; i++)
                snd_soc_write(codec, STA32X_B1CF1 + i,
                              ucontrol->value.bytes.data[i]);
@@ -252,6 +260,48 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
+{
+       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       unsigned int cfud;
+       int i;
+
+       /* preserve reserved bits in STA32X_CFUD */
+       cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
+
+       for (i = 0; i < STA32X_COEF_COUNT; i++) {
+               snd_soc_write(codec, STA32X_CFADDR2, i);
+               snd_soc_write(codec, STA32X_B1CF1,
+                             (sta32x->coef_shadow[i] >> 16) & 0xff);
+               snd_soc_write(codec, STA32X_B1CF2,
+                             (sta32x->coef_shadow[i] >> 8) & 0xff);
+               snd_soc_write(codec, STA32X_B1CF3,
+                             (sta32x->coef_shadow[i]) & 0xff);
+               /* chip documentation does not say if the bits are
+                * self-clearing, so do it explicitly */
+               snd_soc_write(codec, STA32X_CFUD, cfud);
+               snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
+       }
+       return 0;
+}
+
+int sta32x_cache_sync(struct snd_soc_codec *codec)
+{
+       unsigned int mute;
+       int rc;
+
+       if (!codec->cache_sync)
+               return 0;
+
+       /* mute during register sync */
+       mute = snd_soc_read(codec, STA32X_MMUTE);
+       snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
+       sta32x_sync_coef_shadow(codec);
+       rc = snd_soc_cache_sync(codec);
+       snd_soc_write(codec, STA32X_MMUTE, mute);
+       return rc;
+}
+
 #define SINGLE_COEF(xname, index) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
        .info = sta32x_coefficient_info, \
@@ -661,7 +711,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
                                return ret;
                        }
 
-                       snd_soc_cache_sync(codec);
+                       sta32x_cache_sync(codec);
                }
 
                /* Power up to mute */
@@ -790,6 +840,17 @@ static int sta32x_probe(struct snd_soc_codec *codec)
                            STA32X_CxCFG_OM_MASK,
                            2 << STA32X_CxCFG_OM_SHIFT);
 
+       /* initialize coefficient shadow RAM with reset values */
+       for (i = 4; i <= 49; i += 5)
+               sta32x->coef_shadow[i] = 0x400000;
+       for (i = 50; i <= 54; i++)
+               sta32x->coef_shadow[i] = 0x7fffff;
+       sta32x->coef_shadow[55] = 0x5a9df7;
+       sta32x->coef_shadow[56] = 0x7fffff;
+       sta32x->coef_shadow[59] = 0x7fffff;
+       sta32x->coef_shadow[60] = 0x400000;
+       sta32x->coef_shadow[61] = 0x400000;
+
        sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
        /* Bias level configuration will have done an extra enable */
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
index b97ee5a75667399e77a5bcd7493432407d554cc2..d8e32a6262ee087ec13e73d24e57b936eefaa42b 100644 (file)
@@ -19,6 +19,7 @@
 /* STA326 register addresses */
 
 #define STA32X_REGISTER_COUNT  0x2d
+#define STA32X_COEF_COUNT 62
 
 #define STA32X_CONFA   0x00
 #define STA32X_CONFB    0x01
index 7e5ec03f6f8dd579d1bd43413fd1d007a1989bcb..a7c9ae17fc7eb0e743a8dbfb27db88fea58a456e 100644 (file)
@@ -453,6 +453,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
                snd_soc_write(codec, WM8731_PWR, 0xffff);
                regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
                                       wm8731->supplies);
+               codec->cache_sync = 1;
                break;
        }
        codec->dapm.bias_level = level;
index a9504710bb692e806655e785e5f35121ecf4afc1..3a629d0d690ed1fbe8129f096e0edf492faf9eb2 100644 (file)
@@ -190,6 +190,9 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
        struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
        u16 ioctl;
 
+       if (wm8753->dai_func == ucontrol->value.integer.value[0])
+               return 0;
+
        if (codec->active)
                return -EBUSY;
 
index 91d3c6dbeba3317758d747a6c6568cae625ea79e..53edd9a8c758f24943de1219b37cb45602fc11ef 100644 (file)
@@ -1973,7 +1973,7 @@ static int wm8962_reset(struct snd_soc_codec *codec)
 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
 static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0);
 static const unsigned int mixinpga_tlv[] = {
-       TLV_DB_RANGE_HEAD(7),
+       TLV_DB_RANGE_HEAD(5),
        0, 1, TLV_DB_SCALE_ITEM(0, 600, 0),
        2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0),
        3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0),
@@ -1988,7 +1988,7 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
 static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0);
 static const unsigned int classd_tlv[] = {
-       TLV_DB_RANGE_HEAD(7),
+       TLV_DB_RANGE_HEAD(2),
        0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
        7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
 };
index eec8e143511665a538c6950a4f679ad217aad827..d1a142f48b09f03fb565a5c4a6419842a854c6f6 100644 (file)
@@ -512,7 +512,7 @@ static const DECLARE_TLV_DB_SCALE(drc_comp_threash, -4500, 75, 0);
 static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0);
 static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0);
 static const unsigned int drc_max_tlv[] = {
-       TLV_DB_RANGE_HEAD(4),
+       TLV_DB_RANGE_HEAD(2),
        0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
        3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0),
 };
index 3cd35a02c28c7164f525f00f7375ac5ef4d6bbb1..4a398c3bfe84aea9ef4f6c8540f09b8b2bf34282 100644 (file)
@@ -807,7 +807,6 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
                        mdelay(100);
 
                        /* Normal bias enable & soft start off */
-                       reg |= WM9081_BIAS_ENA;
                        reg &= ~WM9081_VMID_RAMP;
                        snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
 
@@ -818,7 +817,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
                }
 
                /* VMID 2*240k */
-               reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
+               reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
                reg &= ~WM9081_VMID_SEL_MASK;
                reg |= 0x04;
                snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
@@ -830,14 +829,15 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               /* Startup bias source */
+               /* Startup bias source and disable bias */
                reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
                reg |= WM9081_BIAS_SRC;
+               reg &= ~WM9081_BIAS_ENA;
                snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
 
-               /* Disable VMID and biases with soft ramping */
+               /* Disable VMID with soft ramping */
                reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
-               reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA);
+               reg &= ~WM9081_VMID_SEL_MASK;
                reg |= WM9081_VMID_RAMP;
                snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
 
index 2b5252c9e37774963a55626e284878e7ff777414..f94c06057c64c31ac6e4bd70fbf80799cc52837d 100644 (file)
@@ -177,19 +177,19 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
 }
 
 static const unsigned int in_tlv[] = {
-       TLV_DB_RANGE_HEAD(6),
+       TLV_DB_RANGE_HEAD(3),
        0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
        1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0),
        4, 6, TLV_DB_SCALE_ITEM(600, 600, 0),
 };
 static const unsigned int mix_tlv[] = {
-       TLV_DB_RANGE_HEAD(4),
+       TLV_DB_RANGE_HEAD(2),
        0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0),
        3, 3, TLV_DB_SCALE_ITEM(0, 0, 0),
 };
 static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
 static const unsigned int spkboost_tlv[] = {
-       TLV_DB_RANGE_HEAD(7),
+       TLV_DB_RANGE_HEAD(2),
        0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
        7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
 };
index 84f33d4ea2cd5ec5461d0f8518c2462c3a58d544..48e61e912400fb2d2cca4ad74d9faf17a3075444 100644 (file)
@@ -40,7 +40,7 @@ static const DECLARE_TLV_DB_SCALE(outmix_tlv, -2100, 300, 0);
 static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1);
 static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0);
 static const unsigned int spkboost_tlv[] = {
-       TLV_DB_RANGE_HEAD(7),
+       TLV_DB_RANGE_HEAD(2),
        0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
        7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
 };
index 0268cf989736f303a224fbd26b0db2e8bf97f2ed..83c4bd5b2dd76bbf3f401c5a6bf0159d337f29b4 100644 (file)
@@ -694,6 +694,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
 
        /* Initialize the the device_attribute structure */
        dev_attr = &ssi_private->dev_attr;
+       sysfs_attr_init(&dev_attr->attr);
        dev_attr->attr.name = "statistics";
        dev_attr->attr.mode = S_IRUGO;
        dev_attr->show = fsl_sysfs_ssi_show;
index 9c0edad90d8b4b3591c7c3a23f4c03b9e42594c1..a4e3237956e26dc499602f9b7397cf196c7ee5ec 100644 (file)
@@ -365,7 +365,8 @@ static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
        if (ret)
                goto out3;
 
-       mfp_set_groupg(nuc900_audio->dev); /* enbale ac97 multifunction pin*/
+       /* enbale ac97 multifunction pin */
+       mfp_set_groupg(nuc900_audio->dev, "nuc900-audio");
 
        return 0;
 
index 30e2befd6f2a237b7a04bd1125386ffa26c7a3ac..8b4c2535b266a2abe17d3ad495b3a0fdfa8855a9 100755 (executable)
@@ -747,6 +747,18 @@ sub __eval_option {
     # Add space to evaluate the character before $
     $option = " $option";
     my $retval = "";
+    my $repeated = 0;
+    my $parent = 0;
+
+    foreach my $test (keys %repeat_tests) {
+       if ($i >= $test &&
+           $i < $test + $repeat_tests{$test}) {
+
+           $repeated = 1;
+           $parent = $test;
+           last;
+       }
+    }
 
     while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
        my $start = $1;
@@ -760,10 +772,14 @@ sub __eval_option {
        # otherwise see if the default OPT (without [$i]) exists.
 
        my $o = "$var\[$i\]";
+       my $parento = "$var\[$parent\]";
 
        if (defined($opt{$o})) {
            $o = $opt{$o};
            $retval = "$retval$o";
+       } elsif ($repeated && defined($opt{$parento})) {
+           $o = $opt{$parento};
+           $retval = "$retval$o";
        } elsif (defined($opt{$var})) {
            $o = $opt{$var};
            $retval = "$retval$o";