]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Thu, 3 May 2012 15:23:15 +0000 (11:23 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 3 May 2012 15:23:15 +0000 (11:23 -0400)
724 files changed:
Documentation/ABI/stable/sysfs-driver-usb-usbtmc
Documentation/ABI/testing/sysfs-block-rssd [new file with mode: 0644]
Documentation/ABI/testing/sysfs-cfq-target-latency [new file with mode: 0644]
Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
Documentation/cgroups/memory.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/vfs.txt
Documentation/networking/ip-sysctl.txt
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/usb/URB.txt
Documentation/usb/usbmon.txt
MAINTAINERS
Makefile
arch/alpha/include/asm/atomic.h
arch/alpha/include/asm/cmpxchg.h [new file with mode: 0644]
arch/alpha/include/asm/xchg.h
arch/arm/boot/compressed/atags_to_fdt.c
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/at91sam9g20.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/db8500.dtsi
arch/arm/boot/dts/highbank.dts
arch/arm/common/vic.c
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/include/asm/jump_label.h
arch/arm/kernel/setup.c
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/at91rm9200_time.c
arch/arm/mach-at91/board-rm9200ek.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/clock.c
arch/arm/mach-at91/include/mach/at91_pmc.h
arch/arm/mach-at91/setup.c
arch/arm/mach-bcmring/core.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/include/mach/irqs.h
arch/arm/mach-exynos/include/mach/map.h
arch/arm/mach-exynos/include/mach/regs-clock.h
arch/arm/mach-exynos/mach-exynos5-dt.c
arch/arm/mach-exynos/mach-nuri.c
arch/arm/mach-exynos/mach-universal_c210.c
arch/arm/mach-imx/imx27-dt.c
arch/arm/mach-imx/mm-imx5.c
arch/arm/mach-msm/board-halibut.c
arch/arm/mach-msm/board-trout-panel.c
arch/arm/mach-msm/board-trout.c
arch/arm/mach-msm/proc_comm.c
arch/arm/mach-omap1/mux.c
arch/arm/mach-omap1/timer.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock.h
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_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/twl-common.c
arch/arm/mach-omap2/twl-common.h
arch/arm/mach-s5pv210/dma.c
arch/arm/mach-s5pv210/mach-aquila.c
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/platsmp.c
arch/arm/mm/Kconfig
arch/arm/mm/fault.c
arch/arm/mm/nommu.c
arch/arm/mm/proc-v7.S
arch/arm/plat-omap/clock.c
arch/arm/plat-omap/include/plat/clock.h
arch/arm/plat-omap/include/plat/omap_hwmod.h
arch/arm/plat-omap/sram.c
arch/arm/plat-samsung/Kconfig
arch/c6x/include/asm/irq.h
arch/c6x/kernel/irq.c
arch/ia64/include/asm/cmpxchg.h
arch/ia64/include/asm/futex.h
arch/ia64/include/asm/intrinsics.h
arch/ia64/kernel/perfmon.c
arch/m68k/configs/m5275evb_defconfig
arch/m68k/platform/527x/config.c
arch/m68k/platform/68EZ328/Makefile
arch/m68k/platform/68VZ328/Makefile
arch/m68k/platform/68VZ328/bootlogo.h [moved from arch/m68k/platform/68EZ328/bootlogo.h with 99% similarity]
arch/m68k/platform/coldfire/device.c
arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi
arch/powerpc/include/asm/irq.h
arch/powerpc/include/asm/mpic.h
arch/powerpc/include/asm/mpic_msgr.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kvm/book3s_hv_builtin.c
arch/powerpc/kvm/book3s_hv_interrupts.S
arch/powerpc/kvm/book3s_interrupts.S
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/booke_interrupts.S
arch/powerpc/net/bpf_jit.h
arch/powerpc/net/bpf_jit_64.S
arch/powerpc/net/bpf_jit_comp.c
arch/powerpc/platforms/85xx/common.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/85xx/p1022_ds.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/beat_interrupt.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/ps3/interrupt.c
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/mpic_msgr.c
arch/s390/Kconfig
arch/s390/defconfig
arch/s390/include/asm/facility.h
arch/s390/include/asm/pgalloc.h
arch/s390/include/asm/swab.h
arch/s390/include/asm/tlb.h
arch/s390/kernel/head.S
arch/s390/kernel/irq.c
arch/s390/kernel/perf_cpum_cf.c
arch/s390/mm/maccess.c
arch/s390/mm/pgtable.c
arch/sh/Kconfig.debug
arch/sh/boards/board-sh7785lcr.c
arch/sh/boards/mach-hp6xx/pm.c
arch/sh/drivers/dma/dma-sysfs.c
arch/sh/kernel/cpu/fpu.c
arch/sh/kernel/cpu/sh2a/fpu.c
arch/sh/kernel/cpu/sh4/fpu.c
arch/sh/kernel/cpu/sh4a/clock-sh7757.c
arch/sh/kernel/cpu/shmobile/pm.c
arch/sh/kernel/idle.c
arch/sh/kernel/kgdb.c
arch/sh/kernel/process_32.c
arch/sh/kernel/smp.c
arch/sh/kernel/vsyscall/vsyscall-sigreturn.S
arch/sh/kernel/vsyscall/vsyscall-trapa.S
arch/sh/mm/cache-sh4.c
arch/sh/mm/flush-sh4.c
arch/sh/mm/sram.c
arch/sparc/kernel/ds.c
arch/sparc/kernel/leon_pci.c
arch/sparc/kernel/leon_smp.c
arch/sparc/kernel/rtrap_64.S
arch/sparc/kernel/sys_sparc_64.c
arch/sparc/mm/fault_32.c
arch/sparc/mm/fault_64.c
arch/tile/Kconfig
arch/tile/Makefile
arch/tile/include/arch/spr_def.h
arch/tile/include/asm/atomic.h
arch/tile/include/asm/atomic_32.h
arch/tile/include/asm/bitops_64.h
arch/tile/include/asm/cmpxchg.h [new file with mode: 0644]
arch/tile/include/asm/irq.h
arch/tile/include/asm/spinlock_64.h
arch/tile/include/asm/stack.h
arch/tile/include/asm/traps.h
arch/tile/kernel/entry.S
arch/tile/kernel/intvec_32.S
arch/tile/kernel/intvec_64.S
arch/tile/kernel/module.c
arch/tile/kernel/proc.c
arch/tile/kernel/process.c
arch/tile/kernel/setup.c
arch/tile/kernel/single_step.c
arch/tile/kernel/smp.c
arch/tile/kernel/smpboot.c
arch/tile/kernel/stack.c
arch/tile/kernel/traps.c
arch/tile/lib/Makefile
arch/tile/lib/cacheflush.c
arch/tile/lib/memcpy_user_64.c
arch/tile/lib/spinlock_common.h
arch/tile/mm/fault.c
arch/tile/mm/homecache.c
arch/tile/mm/init.c
arch/tile/mm/pgtable.c
arch/um/drivers/cow.h
arch/um/drivers/cow_user.c
arch/um/drivers/mconsole_kern.c
arch/um/include/asm/Kbuild
arch/um/kernel/Makefile
arch/um/kernel/process.c
arch/um/kernel/skas/mmu.c
arch/x86/Makefile.um
arch/x86/ia32/ia32_aout.c
arch/x86/include/asm/cmpxchg.h
arch/x86/include/asm/uaccess.h
arch/x86/include/asm/uaccess_32.h
arch/x86/include/asm/uaccess_64.h
arch/x86/kernel/kvm.c
arch/x86/kernel/vsyscall_64.c
arch/x86/kvm/pmu.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/lib/insn.c
arch/x86/lib/usercopy.c
arch/x86/lib/usercopy_32.c
arch/x86/lib/usercopy_64.c
arch/x86/um/asm/barrier.h [new file with mode: 0644]
arch/x86/um/asm/system.h [deleted file]
arch/x86/xen/mmu.c
arch/x86/xen/smp.c
block/blk-core.c
block/blk-throttle.c
block/cfq-iosched.c
crypto/Kconfig
crypto/sha512_generic.c
drivers/acpi/acpica/hwxface.c
drivers/acpi/osl.c
drivers/acpi/processor_idle.c
drivers/acpi/reboot.c
drivers/amba/bus.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-transport.c
drivers/ata/libata.h
drivers/ata/sata_mv.c
drivers/base/regmap/regcache-rbtree.c
drivers/base/regmap/regcache.c
drivers/base/soc.c
drivers/block/cciss_scsi.c
drivers/block/mtip32xx/Kconfig
drivers/block/mtip32xx/mtip32xx.c
drivers/block/mtip32xx/mtip32xx.h
drivers/block/virtio_blk.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/block/xen-blkfront.c
drivers/char/hpet.c
drivers/char/random.c
drivers/char/tile-srom.c
drivers/clocksource/acpi_pm.c
drivers/cpufreq/Kconfig.arm
drivers/cpuidle/cpuidle.c
drivers/crypto/ixp4xx_crypto.c
drivers/crypto/talitos.c
drivers/dma/Kconfig
drivers/dma/dmaengine.c
drivers/dma/ioat/dma.c
drivers/dma/ioat/dma.h
drivers/dma/ioat/dma_v2.c
drivers/dma/ioat/dma_v2.h
drivers/dma/ioat/dma_v3.c
drivers/dma/iop-adma.c
drivers/edac/tile_edac.c
drivers/gpio/Kconfig
drivers/gpio/gpio-adp5588.c
drivers/gpio/gpio-samsung.c
drivers/gpio/gpio-sodaville.c
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_usb.c
drivers/gpu/drm/exynos/exynos_drm_buf.c
drivers/gpu/drm/exynos/exynos_drm_core.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
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/exynos/exynos_drm_hdmi.c
drivers/gpu/drm/exynos/exynos_drm_hdmi.h
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/gma500/mdfld_dsi_output.h
drivers/gpu/drm/i810/i810_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/nouveau/nouveau_pm.c
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_cp.c
drivers/gpu/drm/radeon/radeon_clocks.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/savage/savage_state.c
drivers/hid/Kconfig
drivers/hid/hid-tivo.c
drivers/hwmon/acpi_power_meter.c
drivers/hwmon/ads1015.c
drivers/hwmon/fam15h_power.c
drivers/hwmon/pmbus/pmbus_core.c
drivers/hwmon/smsc47b397.c
drivers/hwmon/smsc47m1.c
drivers/i2c/busses/i2c-designware-pcidrv.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/input/misc/Kconfig
drivers/input/misc/da9052_onkey.c
drivers/input/misc/twl6040-vibra.c
drivers/input/mouse/elantech.c
drivers/input/mouse/gpio_mouse.c
drivers/input/mouse/sentelic.c
drivers/input/mouse/trackpoint.c
drivers/input/touchscreen/tps6507x-ts.c
drivers/isdn/gigaset/interface.c
drivers/leds/leds-atmel-pwm.c
drivers/md/bitmap.c
drivers/md/dm-raid.c
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/media/common/tuners/xc5000.c
drivers/media/common/tuners/xc5000.h
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-usb/it913x.c
drivers/media/dvb/frontends/drxk_hard.c
drivers/media/rc/winbond-cir.c
drivers/media/video/Kconfig
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/mt9m032.c
drivers/media/video/uvc/uvc_video.c
drivers/mfd/Kconfig
drivers/mfd/asic3.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/omap-usb-host.c
drivers/mfd/rc5t583.c
drivers/mfd/twl6040-core.c
drivers/mmc/card/block.c
drivers/mmc/card/queue.c
drivers/mmc/core/bus.c
drivers/mmc/core/cd-gpio.c
drivers/mmc/core/core.c
drivers/mmc/core/mmc.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/host/atmel-mci-regs.h
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/dw_mmc.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-dove.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci-s3c.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sh_mmcif.c
drivers/mtd/mtdchar.c
drivers/net/arcnet/arc-rimi.c
drivers/net/caif/caif_hsi.c
drivers/net/can/usb/peak_usb/pcan_usb_pro.c
drivers/net/dummy.c
drivers/net/ethernet/atheros/atlx/atl1.c
drivers/net/ethernet/atheros/atlx/atl1.h
drivers/net/ethernet/atheros/atlx/atlx.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
drivers/net/ethernet/dlink/dl2k.c
drivers/net/ethernet/dlink/dl2k.h
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/ethernet/freescale/ucc_geth.h
drivers/net/ethernet/ibm/ehea/ehea_main.c
drivers/net/ethernet/ibm/ehea/ehea_phyp.h
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/e1000e/param.c
drivers/net/ethernet/intel/igbvf/netdev.c
drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/marvell/sky2.c
drivers/net/ethernet/marvell/sky2.h
drivers/net/ethernet/micrel/ks8851.c
drivers/net/ethernet/micrel/ks8851_mll.c
drivers/net/ethernet/micrel/ksz884x.c
drivers/net/ethernet/realtek/8139cp.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/sun/sungem.c
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/ethernet/ti/davinci_mdio.c
drivers/net/ethernet/ti/tlan.c
drivers/net/ethernet/tile/tilepro.c
drivers/net/ethernet/xilinx/xilinx_axienet.h
drivers/net/ethernet/xilinx/xilinx_axienet_main.c
drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/phy/icplus.c
drivers/net/ppp/ppp_generic.c
drivers/net/usb/asix.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/smsc75xx.c
drivers/net/usb/smsc95xx.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/wan/farsync.c
drivers/net/xen-netfront.c
drivers/of/gpio.c
drivers/pci/pci.c
drivers/pci/xen-pcifront.c
drivers/pinctrl/core.c
drivers/regulator/anatop-regulator.c
drivers/rtc/rtc-efi.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-r9701.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-twl.c
drivers/s390/block/dasd_eckd.c
drivers/s390/char/vmur.c
drivers/s390/net/qeth_core_main.c
drivers/scsi/scsi_error.c
drivers/spi/spi-davinci.c
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-imx.c
drivers/spi/spi-pl022.c
drivers/staging/android/Kconfig
drivers/staging/android/lowmemorykiller.c
drivers/staging/android/persistent_ram.c
drivers/staging/android/timed_gpio.c
drivers/staging/iio/inkern.c
drivers/staging/iio/magnetometer/ak8975.c
drivers/staging/iio/magnetometer/hmc5843.c
drivers/staging/media/as102/as102_fw.c
drivers/staging/omapdrm/omap_drv.c
drivers/staging/ozwpan/TODO
drivers/staging/ramster/Kconfig
drivers/staging/rts_pstor/ms.c
drivers/staging/rts_pstor/rtsx.c
drivers/staging/rts_pstor/rtsx_transport.c
drivers/staging/sep/sep_main.c
drivers/staging/vme/devices/vme_pio2_core.c
drivers/staging/vt6655/key.c
drivers/staging/vt6656/ioctl.c
drivers/staging/vt6656/key.c
drivers/staging/xgifb/vb_init.c
drivers/staging/xgifb/vb_setmode.c
drivers/staging/xgifb/vb_table.h
drivers/staging/zsmalloc/zsmalloc-main.c
drivers/target/tcm_fc/tcm_fc.h
drivers/target/tcm_fc/tfc_cmd.c
drivers/target/tcm_fc/tfc_conf.c
drivers/target/tcm_fc/tfc_io.c
drivers/tty/amiserial.c
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/Kconfig
drivers/tty/serial/altera_uart.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/clps711x.c
drivers/tty/serial/omap-serial.c
drivers/tty/serial/pch_uart.c
drivers/tty/serial/samsung.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sh-sci.h
drivers/tty/vt/vt.c
drivers/usb/Kconfig
drivers/usb/core/driver.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/urb.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/ep0.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_rndis.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/g_ffs.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/udc-core.c
drivers/usb/gadget/uvc_queue.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ehci.h
drivers/usb/host/ohci-at91.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/uhci-hub.c
drivers/usb/host/xhci-dbg.c
drivers/usb/host/xhci-ext-caps.h
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/usbtest.c
drivers/usb/misc/yurex.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_host.c
drivers/usb/musb/omap2430.c
drivers/usb/serial/bus.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/metro-usb.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/sierra.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/usb.c
drivers/uwb/hwa-rc.c
drivers/uwb/neh.c
drivers/vhost/net.c
drivers/vhost/test.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/video/au1100fb.c
drivers/video/au1200fb.c
drivers/video/kyro/STG4000Reg.h
drivers/video/msm/mddi.c
drivers/video/uvesafb.c
drivers/virtio/virtio_balloon.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
drivers/xen/manage.c
drivers/xen/xen-pciback/pciback_ops.c
drivers/xen/xenbus/xenbus_probe_frontend.c
fs/aio.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/binfmt_flat.c
fs/binfmt_som.c
fs/btrfs/compression.c
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/free-space-cache.c
fs/btrfs/scrub.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c
fs/cifs/connect.c
fs/dlm/lock.c
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/super.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/inode.c
fs/gfs2/Kconfig
fs/gfs2/aops.c
fs/gfs2/bmap.c
fs/gfs2/dir.c
fs/gfs2/inode.c
fs/gfs2/rgrp.c
fs/gfs2/xattr.c
fs/libfs.c
fs/lockd/clnt4xdr.c
fs/lockd/clntxdr.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/vfs.c
fs/ocfs2/alloc.c
fs/ocfs2/refcounttree.c
fs/ocfs2/suballoc.c
fs/proc/stat.c
fs/sysfs/dir.c
fs/sysfs/group.c
include/drm/exynos_drm.h
include/linux/amba/bus.h
include/linux/amba/pl022.h
include/linux/blkdev.h
include/linux/dmaengine.h
include/linux/fuse.h
include/linux/i2c/twl.h
include/linux/irq.h
include/linux/irqdomain.h
include/linux/kconfig.h
include/linux/kvm_host.h
include/linux/mfd/db5500-prcmu.h
include/linux/mfd/rc5t583.h
include/linux/mfd/twl6040.h
include/linux/mm.h
include/linux/mmc/card.h
include/linux/netfilter_bridge.h
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/nfsd/Kbuild
include/linux/pinctrl/machine.h
include/linux/serial_core.h
include/linux/skbuff.h
include/linux/stddef.h
include/linux/types.h
include/linux/usb/otg.h
include/linux/usb/serial.h
include/linux/vgaarb.h
include/net/dst.h
include/net/ip6_fib.h
include/net/ip_vs.h
include/net/red.h
include/net/sock.h
include/scsi/scsi_cmnd.h
include/sound/core.h
kernel/cred.c
kernel/irq/Kconfig
kernel/irq/irqdomain.c
kernel/irq_work.c
kernel/itimer.c
kernel/panic.c
kernel/sysctl.c
kernel/time/Kconfig
kernel/time/tick-broadcast.c
kernel/time/tick-sched.c
lib/kobject.c
lib/mpi/mpi-bit.c
mm/hugetlb.c
mm/memblock.c
mm/memcontrol.c
mm/mmap.c
mm/nommu.c
mm/swap_state.c
mm/vmscan.c
net/ax25/af_ax25.c
net/bridge/br_forward.c
net/bridge/br_multicast.c
net/bridge/br_netfilter.c
net/bridge/br_private.h
net/caif/chnl_net.c
net/core/dev.c
net/core/drop_monitor.c
net/core/net_namespace.c
net/core/skbuff.c
net/ieee802154/6lowpan.c
net/ipv4/inet_diag.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp_diag.c
net/ipv6/addrconf.c
net/ipv6/ip6_fib.c
net/ipv6/ndisc.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/key/af_key.c
net/l2tp/l2tp_ip.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_ftp.c
net/netfilter/ipvs/ip_vs_lblc.c
net/netfilter/ipvs/ip_vs_lblcr.c
net/netfilter/ipvs/ip_vs_proto.c
net/netfilter/ipvs/ip_vs_proto_sctp.c
net/netfilter/ipvs/ip_vs_proto_tcp.c
net/netfilter/ipvs/ip_vs_proto_udp.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/xt_CT.c
net/phonet/pn_dev.c
net/sched/sch_gred.c
net/sched/sch_netem.c
scripts/checkpatch.pl
scripts/kconfig/confdata.c
scripts/mod/file2alias.c
scripts/mod/modpost.c
scripts/mod/modpost.h
scripts/xz_wrap.sh
security/commoncap.c
security/smack/smack_lsm.c
security/smack/smackfs.c
sound/core/vmaster.c
sound/isa/sscape.c
sound/last.c
sound/oss/msnd_pinnacle.c
sound/pci/Kconfig
sound/pci/asihpi/hpi_internal.h
sound/pci/asihpi/hpios.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_proc.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/codecs/Kconfig
sound/soc/codecs/ak4642.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/twl6040.c
sound/soc/imx/imx-audmux.c
sound/soc/omap/Kconfig
sound/soc/pxa/pxa2xx-i2s.c
sound/soc/soc-core.c
sound/soc/tegra/tegra_i2s.c
sound/soc/tegra/tegra_spdif.c
tools/perf/.gitignore
tools/perf/Makefile
tools/perf/builtin-sched.c
tools/perf/builtin-top.c
tools/perf/perf-archive.sh
tools/perf/util/annotate.c
tools/perf/util/hist.c
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/session.c
tools/perf/util/ui/browsers/hists.c
virt/kvm/iommu.c
virt/kvm/kvm_main.c

index 2a7f9a00cb0a6a0acef8fc46bbb6f290f4d0dc67..e960cd027e1e9685a83f3275ca859da7a793e116 100644 (file)
@@ -1,5 +1,5 @@
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities
+What:          /sys/bus/usb/drivers/usbtmc/*/interface_capabilities
+What:          /sys/bus/usb/drivers/usbtmc/*/device_capabilities
 Date:          August 2008
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
@@ -12,8 +12,8 @@ Description:
                The files are read only.
 
 
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities
+What:          /sys/bus/usb/drivers/usbtmc/*/usb488_interface_capabilities
+What:          /sys/bus/usb/drivers/usbtmc/*/usb488_device_capabilities
 Date:          August 2008
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
@@ -27,7 +27,7 @@ Description:
                The files are read only.
 
 
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/TermChar
+What:          /sys/bus/usb/drivers/usbtmc/*/TermChar
 Date:          August 2008
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
@@ -40,7 +40,7 @@ Description:
                sent to the device or not.
 
 
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled
+What:          /sys/bus/usb/drivers/usbtmc/*/TermCharEnabled
 Date:          August 2008
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
@@ -51,7 +51,7 @@ Description:
                published by the USB-IF.
 
 
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/auto_abort
+What:          /sys/bus/usb/drivers/usbtmc/*/auto_abort
 Date:          August 2008
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
diff --git a/Documentation/ABI/testing/sysfs-block-rssd b/Documentation/ABI/testing/sysfs-block-rssd
new file mode 100644 (file)
index 0000000..d535757
--- /dev/null
@@ -0,0 +1,18 @@
+What:           /sys/block/rssd*/registers
+Date:           March 2012
+KernelVersion:  3.3
+Contact:        Asai Thambi S P <asamymuthupa@micron.com>
+Description:    This is a read-only file. Dumps below driver information and
+                hardware registers.
+                    - S ACTive
+                    - Command Issue
+                    - Allocated
+                    - Completed
+                    - PORT IRQ STAT
+                    - HOST IRQ STAT
+
+What:           /sys/block/rssd*/status
+Date:           April 2012
+KernelVersion:  3.4
+Contact:        Asai Thambi S P <asamymuthupa@micron.com>
+Description:   This is a read-only file. Indicates the status of the device.
diff --git a/Documentation/ABI/testing/sysfs-cfq-target-latency b/Documentation/ABI/testing/sysfs-cfq-target-latency
new file mode 100644 (file)
index 0000000..df0f782
--- /dev/null
@@ -0,0 +1,8 @@
+What:          /sys/block/<device>/iosched/target_latency
+Date:          March 2012
+contact:       Tao Ma <boyu.mt@taobao.com>
+Description:
+               The /sys/block/<device>/iosched/target_latency only exists
+               when the user sets cfq to /sys/block/<device>/scheduler.
+               It contains an estimated latency time for the cfq. cfq will
+               use it to calculate the time slice used for every task.
index 3fd3ce5df270563a7e9e1bfc26fa968498e9b1f4..5274c24d11e0a94ce55a05d166580f5cda50196f 100644 (file)
@@ -1,6 +1,6 @@
     <refentry id="V4L2-PIX-FMT-NV12M">
       <refmeta>
-       <refentrytitle>V4L2_PIX_FMT_NV12M ('NV12M')</refentrytitle>
+       <refentrytitle>V4L2_PIX_FMT_NV12M ('NM12')</refentrytitle>
        &manvol;
       </refmeta>
       <refnamediv>
index 9957863daf18d4a4627a74b52fbfe3bd1141b87e..60308f1eefdfea59a33d83f30d32747c8f5c1aa4 100644 (file)
@@ -1,6 +1,6 @@
     <refentry id="V4L2-PIX-FMT-YUV420M">
       <refmeta>
-       <refentrytitle>V4L2_PIX_FMT_YUV420M ('YU12M')</refentrytitle>
+       <refentrytitle>V4L2_PIX_FMT_YUV420M ('YM12')</refentrytitle>
        &manvol;
       </refmeta>
       <refnamediv>
index 4c95c0034a4bbbffdae12a99ff2ddbd0798ca09c..9b1067afb2245f702d962ca4a93c241af6641a02 100644 (file)
@@ -34,8 +34,7 @@ Current Status: linux-2.6.34-mmotm(development version of 2010/April)
 
 Features:
  - accounting anonymous pages, file caches, swap caches usage and limiting them.
- - private LRU and reclaim routine. (system's global LRU and private LRU
-   work independently from each other)
+ - pages are linked to per-memcg LRU exclusively, and there is no global LRU.
  - optionally, memory+swap usage can be accounted and limited.
  - hierarchical accounting
  - soft limit
@@ -154,7 +153,7 @@ updated. page_cgroup has its own LRU on cgroup.
 2.2.1 Accounting details
 
 All mapped anon pages (RSS) and cache pages (Page Cache) are accounted.
-Some pages which are never reclaimable and will not be on the global LRU
+Some pages which are never reclaimable and will not be on the LRU
 are not accounted. We just account pages under usual VM management.
 
 RSS pages are accounted at page_fault unless they've already been accounted
index 709e08e9a222fd9f89a6eb91edf9f5b3326df536..03ca210406edfcbe90fc58cd006ef0e7d313b42f 100644 (file)
@@ -531,3 +531,11 @@ Why:       There appear to be no production users of the get_robust_list syscall,
        of ASLR. It was only ever intended for debugging, so it should be
        removed.
 Who:   Kees Cook <keescook@chromium.org>
+
+----------------------------
+
+What:  setitimer accepts user NULL pointer (value)
+When:  3.6
+Why:   setitimer is not returning -EFAULT if user pointer is NULL. This
+       violates the spec.
+Who:   Sasikantha Babu <sasikanth.v19@gmail.com>
index e916e3d36488d982b4cc1a8580ea5f0529af79d2..0d0492028082c0ecda1a0931cc5100765624a80a 100644 (file)
@@ -114,7 +114,7 @@ members are defined:
 struct file_system_type {
        const char *name;
        int fs_flags;
-        struct dentry (*mount) (struct file_system_type *, int,
+        struct dentry *(*mount) (struct file_system_type *, int,
                        const char *, void *);
         void (*kill_sb) (struct super_block *);
         struct module *owner;
index bd80ba5847d2b8b44548180c7cd9f912832bc4f1..1619a8c8087341477621388701fec82ca832b70b 100644 (file)
@@ -147,7 +147,7 @@ tcp_adv_win_scale - INTEGER
        (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
        if it is <= 0.
        Possible values are [-31, 31], inclusive.
-       Default: 2
+       Default: 1
 
 tcp_allowed_congestion_control - STRING
        Show/set the congestion control choices available to non-privileged
@@ -410,7 +410,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
        net.core.rmem_max.  Calling setsockopt() with SO_RCVBUF disables
        automatic tuning of that socket's receive buffer size, in which
        case this value is ignored.
-       Default: between 87380B and 4MB, depending on RAM size.
+       Default: between 87380B and 6MB, depending on RAM size.
 
 tcp_sack - BOOLEAN
        Enable select acknowledgments (SACKS).
index d97d992ced14f97a5d423f79f1ae9b9f230fc55e..03f7897c641425346e674c360df2ccf97b5b59d3 100644 (file)
@@ -43,7 +43,9 @@ ALC680
 
 ALC882/883/885/888/889
 ======================
-  N/A
+  acer-aspire-4930g    Acer Aspire 4930G/5930G/6530G/6930G/7730G
+  acer-aspire-8930g    Acer Aspire 8330G/6935G
+  acer-aspire          Acer Aspire others
 
 ALC861/660
 ==========
index 8ffce746d496fc41de3cfadf7ad02af5f7fa6637..00d2c644068e9ae5d0e0044150289f0976a0ae9d 100644 (file)
@@ -168,6 +168,28 @@ that if the completion handler or anyone else tries to resubmit it
 they will get a -EPERM error.  Thus you can be sure that when
 usb_kill_urb() returns, the URB is totally idle.
 
+There is a lifetime issue to consider.  An URB may complete at any
+time, and the completion handler may free the URB.  If this happens
+while usb_unlink_urb or usb_kill_urb is running, it will cause a
+memory-access violation.  The driver is responsible for avoiding this,
+which often means some sort of lock will be needed to prevent the URB
+from being deallocated while it is still in use.
+
+On the other hand, since usb_unlink_urb may end up calling the
+completion handler, the handler must not take any lock that is held
+when usb_unlink_urb is invoked.  The general solution to this problem
+is to increment the URB's reference count while holding the lock, then
+drop the lock and call usb_unlink_urb or usb_kill_urb, and then
+decrement the URB's reference count.  You increment the reference
+count by calling
+
+       struct urb *usb_get_urb(struct urb *urb)
+
+(ignore the return value; it is the same as the argument) and
+decrement the reference count by calling usb_free_urb.  Of course,
+none of this is necessary if there's no danger of the URB being freed
+by the completion handler.
+
 
 1.7. What about the completion handler?
 
index 5335fa8b06eb4f2b632126bd9fd95878b6efdce0..c42bb9cd3b43749837f1c784a2571cb6d42bf03f 100644 (file)
@@ -183,10 +183,10 @@ An input control transfer to get a port status.
 d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 <
 d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000
 
-An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper
-to a storage device at address 5:
+An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte
+Bulk wrapper to a storage device at address 5:
 
-dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000
+dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000
 dd65f0e8 4128379808 C Bo:1:005:2 0 31 >
 
 * Raw binary format and API
index f6dfba3d96a7ba5a2020298d4fa4f5597f822069..57bc6770f37aba3010f03fd2a1f56f7e760316e5 100644 (file)
@@ -228,7 +228,7 @@ M:  Len Brown <lenb@kernel.org>
 L:     linux-acpi@vger.kernel.org
 W:     http://www.lesswatts.org/projects/acpi/
 Q:     http://patchwork.kernel.org/project/linux-acpi/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
 S:     Supported
 F:     drivers/acpi/
 F:     drivers/pnp/pnpacpi/
@@ -2321,9 +2321,9 @@ S:        Supported
 F:     drivers/acpi/dock.c
 
 DOCUMENTATION
-M:     Randy Dunlap <rdunlap@xenotime.net>
+M:     Rob Landley <rob@landley.net>
 L:     linux-doc@vger.kernel.org
-T:     quilt http://xenotime.net/kernel-doc-patches/current/
+T:     TBD
 S:     Maintained
 F:     Documentation/
 
@@ -2450,17 +2450,17 @@ F:      fs/ecryptfs/
 
 EDAC-CORE
 M:     Doug Thompson <dougthompson@xmission.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Supported
 F:     Documentation/edac.txt
-F:     drivers/edac/edac_*
+F:     drivers/edac/
 F:     include/linux/edac.h
 
 EDAC-AMD64
 M:     Doug Thompson <dougthompson@xmission.com>
 M:     Borislav Petkov <borislav.petkov@amd.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Supported
 F:     drivers/edac/amd64_edac*
@@ -2468,35 +2468,35 @@ F:      drivers/edac/amd64_edac*
 EDAC-E752X
 M:     Mark Gross <mark.gross@intel.com>
 M:     Doug Thompson <dougthompson@xmission.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Maintained
 F:     drivers/edac/e752x_edac.c
 
 EDAC-E7XXX
 M:     Doug Thompson <dougthompson@xmission.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Maintained
 F:     drivers/edac/e7xxx_edac.c
 
 EDAC-I82443BXGX
 M:     Tim Small <tim@buttersideup.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Maintained
 F:     drivers/edac/i82443bxgx_edac.c
 
 EDAC-I3000
 M:     Jason Uhlenkott <juhlenko@akamai.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Maintained
 F:     drivers/edac/i3000_edac.c
 
 EDAC-I5000
 M:     Doug Thompson <dougthompson@xmission.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Maintained
 F:     drivers/edac/i5000_edac.c
@@ -2525,21 +2525,21 @@ F:      drivers/edac/i7core_edac.c
 EDAC-I82975X
 M:     Ranganathan Desikan <ravi@jetztechnologies.com>
 M:     "Arvind R." <arvino55@gmail.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Maintained
 F:     drivers/edac/i82975x_edac.c
 
 EDAC-PASEMI
 M:     Egor Martovetsky <egor@pasemi.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Maintained
 F:     drivers/edac/pasemi_edac.c
 
 EDAC-R82600
 M:     Tim Small <tim@buttersideup.com>
-L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
 S:     Maintained
 F:     drivers/edac/r82600_edac.c
@@ -4534,8 +4534,7 @@ S:        Supported
 F:     drivers/net/ethernet/myricom/myri10ge/
 
 NATSEMI ETHERNET DRIVER (DP8381x)
-M:     Tim Hockin <thockin@hockin.org>
-S:     Maintained
+S:     Orphan
 F:     drivers/net/ethernet/natsemi/natsemi.c
 
 NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
@@ -4804,6 +4803,7 @@ F:        arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
 F:     arch/arm/mach-omap2/clockdomain44xx.c
 
 OMAP AUDIO SUPPORT
+M:     Peter Ujfalusi <peter.ujfalusi@ti.com>
 M:     Jarkko Nikula <jarkko.nikula@bitmer.com>
 L:     alsa-devel@alsa-project.org (subscribers-only)
 L:     linux-omap@vger.kernel.org
@@ -5118,6 +5118,11 @@ F:       drivers/i2c/busses/i2c-pca-*
 F:     include/linux/i2c-algo-pca.h
 F:     include/linux/i2c-pca-platform.h
 
+PCDP - PRIMARY CONSOLE AND DEBUG PORT
+M:     Khalid Aziz <khalid.aziz@hp.com>
+S:     Maintained
+F:     drivers/firmware/pcdp.*
+
 PCI ERROR RECOVERY
 M:     Linas Vepstas <linasvepstas@gmail.com>
 L:     linux-pci@vger.kernel.org
@@ -5887,11 +5892,11 @@ F:      Documentation/scsi/st.txt
 F:     drivers/scsi/st*
 
 SCTP PROTOCOL
-M:     Vlad Yasevich <vladislav.yasevich@hp.com>
+M:     Vlad Yasevich <vyasevich@gmail.com>
 M:     Sridhar Samudrala <sri@us.ibm.com>
 L:     linux-sctp@vger.kernel.org
 W:     http://lksctp.sourceforge.net
-S:     Supported
+S:     Maintained
 F:     Documentation/networking/sctp.txt
 F:     include/linux/sctp.h
 F:     include/net/sctp/
@@ -6467,6 +6472,7 @@ S:        Odd Fixes
 F:     drivers/staging/olpc_dcon/
 
 STAGING - OZMO DEVICES USB OVER WIFI DRIVER
+M:     Rupesh Gujare <rgujare@ozmodevices.com>
 M:     Chris Kelly <ckelly@ozmodevices.com>
 S:     Maintained
 F:     drivers/staging/ozwpan/
@@ -7462,8 +7468,7 @@ F:        include/linux/wm97xx.h
 
 WOLFSON MICROELECTRONICS DRIVERS
 M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
-M:     Ian Lartey <ian@opensource.wolfsonmicro.com>
-M:     Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+L:     patches@opensource.wolfsonmicro.com
 T:     git git://opensource.wolfsonmicro.com/linux-2.6-asoc
 T:     git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
 W:     http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
@@ -7574,8 +7579,8 @@ F:        Documentation/filesystems/xfs.txt
 F:     fs/xfs/
 
 XILINX AXI ETHERNET DRIVER
-M:     Ariane Keller <ariane.keller@tik.ee.ethz.ch>
-M:     Daniel Borkmann <daniel.borkmann@tik.ee.ethz.ch>
+M:     Anirudha Sarangi <anirudh@xilinx.com>
+M:     John Linn <John.Linn@xilinx.com>
 S:     Maintained
 F:     drivers/net/ethernet/xilinx/xilinx_axienet*
 
index 5e637c23974e6e1d57721c4051cc3b253a43d579..afc868e6c75dd26dbbf28c3511cbcf29c0471573 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc4
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
index f62251e82ffac39579e26c0ee6f77f58c1bd9ac5..3bb7ffeae3bc610010bb54a3eaba698c513c0c7d 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/types.h>
 #include <asm/barrier.h>
+#include <asm/cmpxchg.h>
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
@@ -168,73 +169,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
        return result;
 }
 
-/*
- * Atomic exchange routines.
- */
-
-#define __ASM__MB
-#define ____xchg(type, args...)                __xchg ## type ## _local(args)
-#define ____cmpxchg(type, args...)     __cmpxchg ## type ## _local(args)
-#include <asm/xchg.h>
-
-#define xchg_local(ptr,x)                                              \
-  ({                                                                   \
-     __typeof__(*(ptr)) _x_ = (x);                                     \
-     (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,      \
-                                      sizeof(*(ptr)));                 \
-  })
-
-#define cmpxchg_local(ptr, o, n)                                       \
-  ({                                                                   \
-     __typeof__(*(ptr)) _o_ = (o);                                     \
-     __typeof__(*(ptr)) _n_ = (n);                                     \
-     (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,   \
-                                         (unsigned long)_n_,           \
-                                         sizeof(*(ptr)));              \
-  })
-
-#define cmpxchg64_local(ptr, o, n)                                     \
-  ({                                                                   \
-       BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
-       cmpxchg_local((ptr), (o), (n));                                 \
-  })
-
-#ifdef CONFIG_SMP
-#undef __ASM__MB
-#define __ASM__MB      "\tmb\n"
-#endif
-#undef ____xchg
-#undef ____cmpxchg
-#define ____xchg(type, args...)                __xchg ##type(args)
-#define ____cmpxchg(type, args...)     __cmpxchg ##type(args)
-#include <asm/xchg.h>
-
-#define xchg(ptr,x)                                                    \
-  ({                                                                   \
-     __typeof__(*(ptr)) _x_ = (x);                                     \
-     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_,            \
-                                sizeof(*(ptr)));                       \
-  })
-
-#define cmpxchg(ptr, o, n)                                             \
-  ({                                                                   \
-     __typeof__(*(ptr)) _o_ = (o);                                     \
-     __typeof__(*(ptr)) _n_ = (n);                                     \
-     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,         \
-                                   (unsigned long)_n_, sizeof(*(ptr)));\
-  })
-
-#define cmpxchg64(ptr, o, n)                                           \
-  ({                                                                   \
-       BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
-       cmpxchg((ptr), (o), (n));                                       \
-  })
-
-#undef __ASM__MB
-#undef ____cmpxchg
-
-#define __HAVE_ARCH_CMPXCHG 1
-
 #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
 #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
 
diff --git a/arch/alpha/include/asm/cmpxchg.h b/arch/alpha/include/asm/cmpxchg.h
new file mode 100644 (file)
index 0000000..429e8cd
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef _ALPHA_CMPXCHG_H
+#define _ALPHA_CMPXCHG_H
+
+/*
+ * Atomic exchange routines.
+ */
+
+#define __ASM__MB
+#define ____xchg(type, args...)                __xchg ## type ## _local(args)
+#define ____cmpxchg(type, args...)     __cmpxchg ## type ## _local(args)
+#include <asm/xchg.h>
+
+#define xchg_local(ptr, x)                                             \
+({                                                                     \
+       __typeof__(*(ptr)) _x_ = (x);                                   \
+       (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,    \
+                                      sizeof(*(ptr)));                 \
+})
+
+#define cmpxchg_local(ptr, o, n)                                       \
+({                                                                     \
+       __typeof__(*(ptr)) _o_ = (o);                                   \
+       __typeof__(*(ptr)) _n_ = (n);                                   \
+       (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
+                                         (unsigned long)_n_,           \
+                                         sizeof(*(ptr)));              \
+})
+
+#define cmpxchg64_local(ptr, o, n)                                     \
+({                                                                     \
+       BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
+       cmpxchg_local((ptr), (o), (n));                                 \
+})
+
+#ifdef CONFIG_SMP
+#undef __ASM__MB
+#define __ASM__MB      "\tmb\n"
+#endif
+#undef ____xchg
+#undef ____cmpxchg
+#define ____xchg(type, args...)                __xchg ##type(args)
+#define ____cmpxchg(type, args...)     __cmpxchg ##type(args)
+#include <asm/xchg.h>
+
+#define xchg(ptr, x)                                                   \
+({                                                                     \
+       __typeof__(*(ptr)) _x_ = (x);                                   \
+       (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_,          \
+                                sizeof(*(ptr)));                       \
+})
+
+#define cmpxchg(ptr, o, n)                                             \
+({                                                                     \
+       __typeof__(*(ptr)) _o_ = (o);                                   \
+       __typeof__(*(ptr)) _n_ = (n);                                   \
+       (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,       \
+                                   (unsigned long)_n_, sizeof(*(ptr)));\
+})
+
+#define cmpxchg64(ptr, o, n)                                           \
+({                                                                     \
+       BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
+       cmpxchg((ptr), (o), (n));                                       \
+})
+
+#undef __ASM__MB
+#undef ____cmpxchg
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+#endif /* _ALPHA_CMPXCHG_H */
index 1d1b436fbff252bc867c8e577c7b8759bc55cc20..0ca9724597c1603024ff26d366013bc2da92387b 100644 (file)
@@ -1,10 +1,10 @@
-#ifndef _ALPHA_ATOMIC_H
+#ifndef _ALPHA_CMPXCHG_H
 #error Do not include xchg.h directly!
 #else
 /*
  * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code
  * except that local version do not have the expensive memory barrier.
- * So this file is included twice from asm/system.h.
+ * So this file is included twice from asm/cmpxchg.h.
  */
 
 /*
index 6ce11c4811786389b830d497814c5338983cc723..797f04bedb47e4175ed8cdc707efe12a71ec0693 100644 (file)
@@ -77,6 +77,8 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space)
                } else if (atag->hdr.tag == ATAG_MEM) {
                        if (memcount >= sizeof(mem_reg_property)/4)
                                continue;
+                       if (!atag->u.mem.size)
+                               continue;
                        mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
                        mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
                } else if (atag->hdr.tag == ATAG_INITRD2) {
index 5f6045f1766cc758a94c14d2de2d01164179637a..dc7e8ce8e6bed9ad10a696de4c8bbecdb909fdad 100644 (file)
@@ -273,7 +273,7 @@ restart:    adr     r0, LC0
                add     r0, r0, #0x100
                mov     r1, r6
                sub     r2, sp, r6
-               blne    atags_to_fdt
+               bleq    atags_to_fdt
 
                ldmfd   sp!, {r0-r3, ip, lr}
                sub     sp, sp, #0x10000
index 799ad1889b51d6232026b716b3a75205e1042c6f..773ef484037a91fd5613d26b2029a7c89f083eed 100644 (file)
@@ -55,7 +55,6 @@
                                #interrupt-cells = <2>;
                                compatible = "atmel,at91rm9200-aic";
                                interrupt-controller;
-                               interrupt-parent;
                                reg = <0xfffff000 0x200>;
                        };
 
index 9e6eb6ecea0e3898bc6a0883c4d4bf443ca126c7..c8042147eaa2d39cc7470dd3525063a0e45563a0 100644 (file)
@@ -56,7 +56,6 @@
                                #interrupt-cells = <2>;
                                compatible = "atmel,at91rm9200-aic";
                                interrupt-controller;
-                               interrupt-parent;
                                reg = <0xfffff000 0x200>;
                        };
 
index 70ab3a4e026f0fb0c7d50f335cf893e120d8277a..dd4ed748469a2e576a84562fd212328b4716623e 100644 (file)
@@ -54,7 +54,6 @@
                                #interrupt-cells = <2>;
                                compatible = "atmel,at91rm9200-aic";
                                interrupt-controller;
-                               interrupt-parent;
                                reg = <0xfffff000 0x200>;
                        };
 
index d73dce6456679de2281c121225b677930ba85a83..14bc307050999d278cda3684b98da6577e6d6371 100644 (file)
@@ -24,7 +24,6 @@
                        #interrupt-cells = <3>;
                        #address-cells = <1>;
                        interrupt-controller;
-                       interrupt-parent;
                        reg = <0xa0411000 0x1000>,
                              <0xa0410100 0x100>;
                };
index 37c0ff9c8b90cb03f0ebb7fb2e1ce961ee4c141c..83e72294aefb1211c1bc3cdecab273750baa3294 100644 (file)
@@ -89,7 +89,6 @@
                        #size-cells = <0>;
                        #address-cells = <1>;
                        interrupt-controller;
-                       interrupt-parent;
                        reg = <0xfff11000 0x1000>,
                              <0xfff10100 0x100>;
                };
index 7a66311f306666bf7c7ff07ffcbe4e501c93f236..7e288f96cedf01fa782b3326788d40305c551e0d 100644 (file)
@@ -427,19 +427,18 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
 
 /*
  * Handle each interrupt in a single VIC.  Returns non-zero if we've
- * handled at least one interrupt.  This does a single read of the
- * status register and handles all interrupts in order from LSB first.
+ * handled at least one interrupt.  This reads the status register
+ * before handling each interrupt, which is necessary given that
+ * handle_IRQ may briefly re-enable interrupts for soft IRQ handling.
  */
 static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
 {
        u32 stat, irq;
        int handled = 0;
 
-       stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
-       while (stat) {
+       while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
                irq = ffs(stat) - 1;
                handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
-               stat &= ~(1 << irq);
                handled = 1;
        }
 
index b5ac644e12af9121985b0eadeecfdefaaf85c33b..6b31cb60daabd516579d55f1cb2b5a7198cb3776 100644 (file)
@@ -112,6 +112,7 @@ CONFIG_WATCHDOG=y
 CONFIG_IMX2_WDT=y
 CONFIG_MFD_MC13XXX=y
 CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_FB=y
index 889d73ac1ae11e6870a7a345fb402b8e54ce8070..7e84f453e8a6f07e76c182badb2ee055eda1bde6 100644 (file)
@@ -8,8 +8,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_U8500=y
-CONFIG_UX500_SOC_DB5500=y
-CONFIG_UX500_SOC_DB8500=y
 CONFIG_MACH_HREFV60=y
 CONFIG_MACH_SNOWBALL=y
 CONFIG_MACH_U5500=y
@@ -39,7 +37,6 @@ CONFIG_CAIF=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=65536
-CONFIG_MISC_DEVICES=y
 CONFIG_AB8500_PWM=y
 CONFIG_SENSORS_BH1780=y
 CONFIG_NETDEVICES=y
@@ -65,16 +62,18 @@ CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_NOMADIK=y
-CONFIG_I2C=y
-CONFIG_I2C_NOMADIK=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_TC3589X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_AB8500_BM=y
+CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_TC3589X=y
 CONFIG_AB5500_CORE=y
 CONFIG_AB8500_CORE=y
+CONFIG_REGULATOR=y
 CONFIG_REGULATOR_AB8500=y
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_GADGET=y
index 5c5ca2ea62b04753c49b6d64eb8d9ca9214049a5..bfc198c759130109d44b73b4506ea853d01fba28 100644 (file)
@@ -14,7 +14,7 @@
 #define JUMP_LABEL_NOP "nop"
 #endif
 
-static __always_inline bool arch_static_branch(struct jump_label_key *key)
+static __always_inline bool arch_static_branch(struct static_key *key)
 {
        asm goto("1:\n\t"
                 JUMP_LABEL_NOP "\n\t"
index b91411371ae19b1ae75c2184b4b26ec6c9b06193..ebfac782593f048c9cf81a5619f0b3d24900ca8c 100644 (file)
@@ -523,7 +523,21 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size)
         */
        size -= start & ~PAGE_MASK;
        bank->start = PAGE_ALIGN(start);
-       bank->size  = size & PAGE_MASK;
+
+#ifndef CONFIG_LPAE
+       if (bank->start + size < bank->start) {
+               printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in "
+                       "32-bit physical address space\n", (long long)start);
+               /*
+                * To ensure bank->start + bank->size is representable in
+                * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB.
+                * This means we lose a page after masking.
+                */
+               size = ULONG_MAX - bank->start;
+       }
+#endif
+
+       bank->size = size & PAGE_MASK;
 
        /*
         * Check whether this memory region has non-zero size or
index 99ce5c955e39d94d24f50005b875459739ef6ce5..05774e5b1cbaf32488a142b4060a1adc452c8177 100644 (file)
@@ -1173,7 +1173,6 @@ void __init at91_add_device_serial(void)
                printk(KERN_INFO "AT91: No default serial console defined.\n");
 }
 #else
-void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
 void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
index dd7f782b0b91731202c3d8e10f02597b7d89518c..104ca40d8d18908cb463e7ae1cd56790c926d971 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/clockchips.h>
+#include <linux/export.h>
 
 #include <asm/mach/time.h>
 
@@ -176,6 +177,7 @@ static struct clock_event_device clkevt = {
 };
 
 void __iomem *at91_st_base;
+EXPORT_SYMBOL_GPL(at91_st_base);
 
 void __init at91rm9200_ioremap_st(u32 addr)
 {
index 11cbaa8946fe0e269877104aac08da9fe03818e9..b2e4fe21f346cf6217dfb78b5e8b3f6553e76fe6 100644 (file)
@@ -117,7 +117,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = {
 };
 
 #define EK_FLASH_BASE  AT91_CHIPSELECT_0
-#define EK_FLASH_SIZE  SZ_2M
+#define EK_FLASH_SIZE  SZ_8M
 
 static struct physmap_flash_data ek_flash_data = {
        .width          = 2,
index c3f9944628642050c34c0a5f31388854511921e4..065fed342424902bbe15aa67101fd524397eaa7b 100644 (file)
@@ -85,8 +85,6 @@ static struct resource dm9000_resource[] = {
                .flags  = IORESOURCE_MEM
        },
        [2] = {
-               .start  = AT91_PIN_PC11,
-               .end    = AT91_PIN_PC11,
                .flags  = IORESOURCE_IRQ
                        | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE,
        }
@@ -130,6 +128,8 @@ static struct sam9_smc_config __initdata dm9000_smc_config = {
 
 static void __init ek_add_device_dm9000(void)
 {
+       struct resource *r = &dm9000_resource[2];
+
        /* Configure chip-select 2 (DM9000) */
        sam9_smc_configure(0, 2, &dm9000_smc_config);
 
@@ -139,6 +139,7 @@ static void __init ek_add_device_dm9000(void)
        /* Configure Interrupt pin as input, no pull-up */
        at91_set_gpio_input(AT91_PIN_PC11, 0);
 
+       r->start = r->end = gpio_to_irq(AT91_PIN_PC11);
        platform_device_register(&dm9000_device);
 }
 #else
index a0f4d7424cdcf4cfbebbc0c81185fb615862e9b5..6b692824c9885555fffe031ead3bafcdf71d141d 100644 (file)
@@ -35,6 +35,7 @@
 #include "generic.h"
 
 void __iomem *at91_pmc_base;
+EXPORT_SYMBOL_GPL(at91_pmc_base);
 
 /*
  * There's a lot more which can be done with clocks, including cpufreq
index 36604782a78f0e52d4bed0d6af21c787dacf418f..ea2c57a86ca6ebf389aaa406bffeb5441e65a067 100644 (file)
@@ -25,7 +25,7 @@ extern void __iomem *at91_pmc_base;
 #define at91_pmc_write(field, value) \
        __raw_writel(value, at91_pmc_base + field)
 #else
-.extern at91_aic_base
+.extern at91_pmc_base
 #endif
 
 #define        AT91_PMC_SCER           0x00                    /* System Clock Enable Register */
index 97cc04dc807302d635e9fe56176d34e0d9210c4f..f44a2e7272e33f8e8568c4bc597db0bc0b38f5b5 100644 (file)
@@ -54,6 +54,7 @@ void __init at91_init_interrupts(unsigned int *priority)
 }
 
 void __iomem *at91_ramc_base[2];
+EXPORT_SYMBOL_GPL(at91_ramc_base);
 
 void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
 {
@@ -292,6 +293,7 @@ void __init at91_ioremap_rstc(u32 base_addr)
 }
 
 void __iomem *at91_matrix_base;
+EXPORT_SYMBOL_GPL(at91_matrix_base);
 
 void __init at91_ioremap_matrix(u32 base_addr)
 {
index 22e4e0a28ad1eae0e549f43e47e548b9a36945dd..adbfb1994582ee1352a511501279f5b58c378bfc 100644 (file)
@@ -52,8 +52,8 @@
 #include <mach/csp/chipcHw_inline.h>
 #include <mach/csp/tmrHw_reg.h>
 
-static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL);
-static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL);
+static AMBA_APB_DEVICE(uartA, "uartA", 0, MM_ADDR_IO_UARTA, {IRQ_UARTA}, NULL);
+static AMBA_APB_DEVICE(uartB, "uartB", 0, MM_ADDR_IO_UARTB, {IRQ_UARTB}, NULL);
 
 static struct clk pll1_clk = {
        .name = "PLL1",
index 0491ceef1cda8a77bbaf60409416d906fc701620..e81c35f936b595e5d332e9cdcdd1229d2ac21670 100644 (file)
@@ -368,6 +368,7 @@ comment "Flattened Device Tree based board for EXYNOS SoCs"
 
 config MACH_EXYNOS4_DT
        bool "Samsung Exynos4 Machine using device tree"
+       depends on ARCH_EXYNOS4
        select CPU_EXYNOS4210
        select USE_OF
        select ARM_AMBA
@@ -380,6 +381,7 @@ config MACH_EXYNOS4_DT
 
 config MACH_EXYNOS5_DT
        bool "SAMSUNG EXYNOS5 Machine using device tree"
+       depends on ARCH_EXYNOS5
        select SOC_EXYNOS5250
        select USE_OF
        select ARM_AMBA
index 9bee8535d9e0aa994960de244002b198975a8709..591e78521a9f11f6de5114c8f717933efe4c9fd7 100644 (file)
 #define IRQ_MFC                                EXYNOS4_IRQ_MFC
 #define IRQ_SDO                                EXYNOS4_IRQ_SDO
 
+#define IRQ_I2S0                       EXYNOS4_IRQ_I2S0
+
 #define IRQ_ADC                                EXYNOS4_IRQ_ADC0
 #define IRQ_TC                         EXYNOS4_IRQ_PEN0
 
index 024d38ff17183fed96447aebcbeb27f1cc04fb62..6e6d11ff352a30b131db307b8d2910c9c0c6282b 100644 (file)
 #define EXYNOS4_PA_MDMA1               0x12840000
 #define EXYNOS4_PA_PDMA0               0x12680000
 #define EXYNOS4_PA_PDMA1               0x12690000
+#define EXYNOS5_PA_MDMA0               0x10800000
+#define EXYNOS5_PA_MDMA1               0x11C10000
+#define EXYNOS5_PA_PDMA0               0x121A0000
+#define EXYNOS5_PA_PDMA1               0x121B0000
 
 #define EXYNOS4_PA_SYSMMU_MDMA         0x10A40000
 #define EXYNOS4_PA_SYSMMU_SSS          0x10A50000
index e141c1fd68d84ce00a4dcca450c2e904867709f7..d9578a58ae7f573b35d7065609ae4d090884acbf 100644 (file)
 
 /* For EXYNOS5250 */
 
+#define EXYNOS5_APLL_LOCK                      EXYNOS_CLKREG(0x00000)
 #define EXYNOS5_APLL_CON0                      EXYNOS_CLKREG(0x00100)
 #define EXYNOS5_CLKSRC_CPU                     EXYNOS_CLKREG(0x00200)
+#define EXYNOS5_CLKMUX_STATCPU                 EXYNOS_CLKREG(0x00400)
 #define EXYNOS5_CLKDIV_CPU0                    EXYNOS_CLKREG(0x00500)
+#define EXYNOS5_CLKDIV_CPU1                    EXYNOS_CLKREG(0x00504)
+#define EXYNOS5_CLKDIV_STATCPU0                        EXYNOS_CLKREG(0x00600)
+#define EXYNOS5_CLKDIV_STATCPU1                        EXYNOS_CLKREG(0x00604)
+
 #define EXYNOS5_MPLL_CON0                      EXYNOS_CLKREG(0x04100)
 #define EXYNOS5_CLKSRC_CORE1                   EXYNOS_CLKREG(0x04204)
 
index 0d26f50081ad9e44e0d5cd3a9e962c391b3382f4..4711c8920e37830d7bda8cb32ee03ed1ae70730a 100644 (file)
@@ -45,7 +45,7 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
                                "exynos4210-uart.3", NULL),
        OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
        OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
-       OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.2", NULL),
+       OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
        {},
 };
 
index b3982c867c9c5e9243c505d41b9914b69c130b30..b4f1f902ce6d06a82cd9f9f00d90caa0e9548782 100644 (file)
@@ -307,49 +307,7 @@ static struct i2c_board_info i2c1_devs[] __initdata = {
 };
 
 /* TSP */
-static u8 mxt_init_vals[] = {
-       /* MXT_GEN_COMMAND(6) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_GEN_POWER(7) */
-       0x20, 0xff, 0x32,
-       /* MXT_GEN_ACQUIRE(8) */
-       0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
-       /* MXT_TOUCH_MULTI(9) */
-       0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
-       0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00,
-       /* MXT_TOUCH_KEYARRAY(15) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
-       0x00,
-       /* MXT_SPT_GPIOPWM(19) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_PROCI_GRIPFACE(20) */
-       0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
-       0x0f, 0x0a,
-       /* MXT_PROCG_NOISE(22) */
-       0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
-       0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
-       /* MXT_TOUCH_PROXIMITY(23) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_PROCI_ONETOUCH(24) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_SPT_SELFTEST(25) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00,
-       /* MXT_PROCI_TWOTOUCH(27) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_SPT_CTECONFIG(28) */
-       0x00, 0x00, 0x02, 0x08, 0x10, 0x00,
-};
-
 static struct mxt_platform_data mxt_platform_data = {
-       .config                 = mxt_init_vals,
-       .config_length          = ARRAY_SIZE(mxt_init_vals),
-
        .x_line                 = 18,
        .y_line                 = 11,
        .x_size                 = 1024,
@@ -571,7 +529,7 @@ static struct regulator_init_data __initdata max8997_ldo7_data = {
 
 static struct regulator_init_data __initdata max8997_ldo8_data = {
        .constraints    = {
-               .name           = "VUSB/VDAC_3.3V_C210",
+               .name           = "VUSB+VDAC_3.3V_C210",
                .min_uV         = 3300000,
                .max_uV         = 3300000,
                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -1347,6 +1305,7 @@ static struct platform_device *nuri_devices[] __initdata = {
 
 static void __init nuri_map_io(void)
 {
+       clk_xusbxti.rate = 24000000;
        exynos_init_io(NULL, 0);
        s3c24xx_init_clocks(24000000);
        s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
@@ -1379,7 +1338,6 @@ static void __init nuri_machine_init(void)
        nuri_camera_init();
 
        nuri_ehci_init();
-       clk_xusbxti.rate = 24000000;
 
        /* Last */
        platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
index 6bb9dbdd73fdde842bcad0cb75f4713316c4a760..7ebf79c2ab348bd273099716d9bd1b4df6cdc572 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/mach-types.h>
 
 #include <plat/regs-serial.h>
+#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/iic.h>
@@ -1057,6 +1058,7 @@ static struct platform_device *universal_devices[] __initdata = {
 
 static void __init universal_map_io(void)
 {
+       clk_xusbxti.rate = 24000000;
        exynos_init_io(NULL, 0);
        s3c24xx_init_clocks(24000000);
        s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
index 861ceb8232d60ca468cb361a749e34574bdb7961..ed38d03c61f22296acb782e7e4cc9c8dfde20344 100644 (file)
@@ -35,7 +35,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = {
 static int __init imx27_avic_add_irq_domain(struct device_node *np,
                                struct device_node *interrupt_parent)
 {
-       irq_domain_add_simple(np, 0);
+       irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL);
        return 0;
 }
 
@@ -44,7 +44,9 @@ static int __init imx27_gpio_add_irq_domain(struct device_node *np,
 {
        static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
-       irq_domain_add_simple(np, gpio_irq_base);
+       gpio_irq_base -= 32;
+       irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
+                               NULL);
 
        return 0;
 }
index 05250aed61fbbc7f73f9e7b1c5b4bca00000f6fd..e10f3914fcfe6b1d2c59f9296d373805b4740901 100644 (file)
@@ -35,7 +35,7 @@ static void imx5_idle(void)
        }
        clk_enable(gpc_dvfs_clk);
        mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
-       if (tzic_enable_wake() != 0)
+       if (!tzic_enable_wake())
                cpu_do_idle();
        clk_disable(gpc_dvfs_clk);
 }
index 3698a370d6360051f00cb02bbfc62cb861568e6d..26aac363a06405f865e76ea8c0db6324af8d85aa 100644 (file)
@@ -86,9 +86,6 @@ static void __init halibut_init(void)
 static void __init halibut_fixup(struct tag *tags, char **cmdline,
                                 struct meminfo *mi)
 {
-       mi->nr_banks=1;
-       mi->bank[0].start = PHYS_OFFSET;
-       mi->bank[0].size = (101*1024*1024);
 }
 
 static void __init halibut_map_io(void)
index 25105c1027fe44c1862b94605ca8d6fd520ff3c1..89bf6b426699863d8230d9fcdf2b9d66bfa3cdc3 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
+#include <asm/system_info.h>
 
 #include <mach/msm_fb.h>
 #include <mach/vreg.h>
index 5414f76ec0a948578b6c2c28c2058acbb2ccf133..d4060a37e23d39776456974e97b361ac6522b1e5 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/clkdev.h>
 
+#include <asm/system_info.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 67e701c7f183746c923d722163ec3c9dfc94cecf..9980dc736e7bb690c31f93560efcdd2925d74ffe 100644 (file)
@@ -121,7 +121,7 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
  * and unknown state. This function should be called early to
  * wait on the ARM9.
  */
-void __init proc_comm_boot_wait(void)
+void __devinit proc_comm_boot_wait(void)
 {
        void __iomem *base = MSM_SHARED_RAM_BASE;
  
index 087dba0df47e305fd059b97885c68f696d4c8ea5..e9cc52d4cb2869964b933b8a4a74ee844bb003d8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 
+#include <mach/hardware.h>
 
 #include <plat/mux.h>
 
index 6e90665a7c47f6d4ed929b57dd6a79d9c7ed4f2a..fb202af01d0dc2fbb1f9622d220b90335e939de8 100644 (file)
@@ -47,9 +47,9 @@ static int omap1_dm_timer_set_src(struct platform_device *pdev,
        int n = (pdev->id - 1) << 1;
        u32 l;
 
-       l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
+       l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
        l |= source << n;
-       __raw_writel(l, MOD_CONF_CTRL_1);
+       omap_writel(l, MOD_CONF_CTRL_1);
 
        return 0;
 }
index a39fc4bbd2b8ffb9cb8bb06c1c91f1c40e120333..130ab00c09a2b00751f7c3e90dfa2ffb8eac7882 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/usb/otg.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
 #include <linux/gpio_keys.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
@@ -560,7 +561,7 @@ static struct regulator_init_data sdp4430_vusim = {
        },
 };
 
-static struct twl4030_codec_data twl6040_codec = {
+static struct twl6040_codec_data twl6040_codec = {
        /* single-step ramp for headset and handsfree */
        .hs_left_step   = 0x0f,
        .hs_right_step  = 0x0f,
@@ -568,7 +569,7 @@ static struct twl4030_codec_data twl6040_codec = {
        .hf_right_step  = 0x1d,
 };
 
-static struct twl4030_vibra_data twl6040_vibra = {
+static struct twl6040_vibra_data twl6040_vibra = {
        .vibldrv_res = 8,
        .vibrdrv_res = 3,
        .viblmotor_res = 10,
@@ -577,16 +578,14 @@ static struct twl4030_vibra_data twl6040_vibra = {
        .vddvibr_uV = 0,        /* fixed volt supply - VBAT */
 };
 
-static struct twl4030_audio_data twl6040_audio = {
+static struct twl6040_platform_data twl6040_data = {
        .codec          = &twl6040_codec,
        .vibra          = &twl6040_vibra,
        .audpwron_gpio  = 127,
-       .naudint_irq    = OMAP44XX_IRQ_SYS_2N,
        .irq_base       = TWL6040_CODEC_IRQ_BASE,
 };
 
 static struct twl4030_platform_data sdp4430_twldata = {
-       .audio          = &twl6040_audio,
        /* Regulators */
        .vusim          = &sdp4430_vusim,
        .vaux1          = &sdp4430_vaux1,
@@ -617,7 +616,8 @@ static int __init omap4_i2c_init(void)
                        TWL_COMMON_REGULATOR_VCXIO |
                        TWL_COMMON_REGULATOR_VUSB |
                        TWL_COMMON_REGULATOR_CLK32KG);
-       omap4_pmic_init("twl6030", &sdp4430_twldata);
+       omap4_pmic_init("twl6030", &sdp4430_twldata,
+                       &twl6040_data, OMAP44XX_IRQ_SYS_2N);
        omap_register_i2c_bus(2, 400, NULL, 0);
        omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
                                ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
index 74e1687b51706317672694d80ac79aa92f0c416f..098d183a008655c6dd66895346033d76da74ecbe 100644 (file)
@@ -137,7 +137,7 @@ static struct twl4030_platform_data sdp4430_twldata = {
 
 static void __init omap4_i2c_init(void)
 {
-       omap4_pmic_init("twl6030", &sdp4430_twldata);
+       omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0);
 }
 
 static void __init omap4_init(void)
index d8c0e89f0126a2b4a7ba2a87d49641d1cf05c57c..1b782ba534336f6f3d3236e10316733f0f1b2abc 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/gpio.h>
 #include <linux/usb/otg.h>
 #include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 #include <linux/wl12xx.h>
@@ -284,7 +285,7 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
        return 0;
 }
 
-static struct twl4030_codec_data twl6040_codec = {
+static struct twl6040_codec_data twl6040_codec = {
        /* single-step ramp for headset and handsfree */
        .hs_left_step   = 0x0f,
        .hs_right_step  = 0x0f,
@@ -292,17 +293,14 @@ static struct twl4030_codec_data twl6040_codec = {
        .hf_right_step  = 0x1d,
 };
 
-static struct twl4030_audio_data twl6040_audio = {
+static struct twl6040_platform_data twl6040_data = {
        .codec          = &twl6040_codec,
        .audpwron_gpio  = 127,
-       .naudint_irq    = OMAP44XX_IRQ_SYS_2N,
        .irq_base       = TWL6040_CODEC_IRQ_BASE,
 };
 
 /* Panda board uses the common PMIC configuration */
-static struct twl4030_platform_data omap4_panda_twldata = {
-       .audio          = &twl6040_audio,
-};
+static struct twl4030_platform_data omap4_panda_twldata;
 
 /*
  * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
@@ -326,7 +324,8 @@ static int __init omap4_panda_i2c_init(void)
                        TWL_COMMON_REGULATOR_VCXIO |
                        TWL_COMMON_REGULATOR_VUSB |
                        TWL_COMMON_REGULATOR_CLK32KG);
-       omap4_pmic_init("twl6030", &omap4_panda_twldata);
+       omap4_pmic_init("twl6030", &omap4_panda_twldata,
+                       &twl6040_data, OMAP44XX_IRQ_SYS_2N);
        omap_register_i2c_bus(2, 400, NULL, 0);
        /*
         * Bus 3 is attached to the DVI port where devices like the pico DLP
index 7072e0d651b12356ec889158dde5102c5e7d6100..3d9d746b221ae0669fc01b1020ce0716c4f73a97 100644 (file)
@@ -165,83 +165,3 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
 
        return 0;
 }
-
-#ifdef CONFIG_CPU_FREQ
-/*
- * Walk PRCM rate table and fillout cpufreq freq_table
- * XXX This should be replaced by an OPP layer in the near future
- */
-static struct cpufreq_frequency_table *freq_table;
-
-void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-       const struct prcm_config *prcm;
-       int i = 0;
-       int tbl_sz = 0;
-
-       if (!cpu_is_omap24xx())
-               return;
-
-       for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-               if (!(prcm->flags & cpu_mask))
-                       continue;
-               if (prcm->xtal_speed != sclk->rate)
-                       continue;
-
-               /* don't put bypass rates in table */
-               if (prcm->dpll_speed == prcm->xtal_speed)
-                       continue;
-
-               tbl_sz++;
-       }
-
-       /*
-        * XXX Ensure that we're doing what CPUFreq expects for this error
-        * case and the following one
-        */
-       if (tbl_sz == 0) {
-               pr_warning("%s: no matching entries in rate_table\n",
-                          __func__);
-               return;
-       }
-
-       /* Include the CPUFREQ_TABLE_END terminator entry */
-       tbl_sz++;
-
-       freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
-                            GFP_ATOMIC);
-       if (!freq_table) {
-               pr_err("%s: could not kzalloc frequency table\n", __func__);
-               return;
-       }
-
-       for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-               if (!(prcm->flags & cpu_mask))
-                       continue;
-               if (prcm->xtal_speed != sclk->rate)
-                       continue;
-
-               /* don't put bypass rates in table */
-               if (prcm->dpll_speed == prcm->xtal_speed)
-                       continue;
-
-               freq_table[i].index = i;
-               freq_table[i].frequency = prcm->mpu_speed / 1000;
-               i++;
-       }
-
-       freq_table[i].index = i;
-       freq_table[i].frequency = CPUFREQ_TABLE_END;
-
-       *table = &freq_table[0];
-}
-
-void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-       if (!cpu_is_omap24xx())
-               return;
-
-       kfree(freq_table);
-}
-
-#endif
index f57ed5baeccf78f93c6b7f0a012a7b0da083c193..d9f4931513f97b4ba9020853ccbad621615d430f 100644 (file)
@@ -536,10 +536,5 @@ struct clk_functions omap2_clk_functions = {
        .clk_set_rate           = omap2_clk_set_rate,
        .clk_set_parent         = omap2_clk_set_parent,
        .clk_disable_unused     = omap2_clk_disable_unused,
-#ifdef CONFIG_CPU_FREQ
-       /* These will be removed when the OPP code is integrated */
-       .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
-       .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table,
-#endif
 };
 
index b8c2a686481ca313298253246e789e1ce844feea..a1bb23a23351262600d242873d71536c9e4de134 100644 (file)
@@ -146,14 +146,6 @@ extern const struct clksel_rate gpt_sys_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
 extern const struct clksel_rate dsp_ick_rates[];
 
-#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
-extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
-extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
-#else
-#define omap2_clk_init_cpufreq_table   0
-#define omap2_clk_exit_cpufreq_table   0
-#endif
-
 extern const struct clkops clkops_omap2_iclk_dflt_wait;
 extern const struct clkops clkops_omap2_iclk_dflt;
 extern const struct clkops clkops_omap2_iclk_idle_only;
index 2c27fdb61e6665f1037956307f718e224c1301d0..7144ae651d3defcb6e74f9f59ce7f38207691bf4 100644 (file)
@@ -1422,6 +1422,9 @@ static int _ocp_softreset(struct omap_hwmod *oh)
                goto dis_opt_clks;
        _write_sysconfig(v, oh);
 
+       if (oh->class->sysc->srst_udelay)
+               udelay(oh->class->sysc->srst_udelay);
+
        if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
                omap_test_timeout((omap_hwmod_read(oh,
                                                    oh->class->sysc->syss_offs)
@@ -1903,10 +1906,20 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs)
  */
 int omap_hwmod_softreset(struct omap_hwmod *oh)
 {
-       if (!oh)
+       u32 v;
+       int ret;
+
+       if (!oh || !(oh->_sysc_cache))
                return -EINVAL;
 
-       return _ocp_softreset(oh);
+       v = oh->_sysc_cache;
+       ret = _set_softreset(oh, &v);
+       if (ret)
+               goto error;
+       _write_sysconfig(v, oh);
+
+error:
+       return ret;
 }
 
 /**
index a5409ce3f3233eaac531ed070fc1f9cf74e8398f..a6bde34e443a7719fcefcbf447779ea16c9202b0 100644 (file)
@@ -1000,7 +1000,6 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = {
                        .flags  = OMAP_FIREWALL_L4,
                }
        },
-       .flags          = OCPIF_SWSUP_IDLE,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
index c4f56cb60d7d676ddda36e232c8b385a58fef6ba..04a3885f4475f6e6ff865c4624a19d58b061a7f4 100644 (file)
@@ -1049,7 +1049,6 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = {
        .slave          = &omap2430_dss_venc_hwmod,
        .clk            = "dss_ick",
        .addr           = omap2_dss_venc_addrs,
-       .flags          = OCPIF_SWSUP_IDLE,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
index 34b9766d1d231845356b2c71626fa234a731bee6..db86ce90c69fbc769fd1c63005a5ad188e43f33b 100644 (file)
@@ -1676,7 +1676,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = {
                        .flags  = OMAP_FIREWALL_L4,
                }
        },
-       .flags          = OCPIF_SWSUP_IDLE,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
index cc9bd106a854beca49128200825748833201fe61..6abc75753e42b2048ab7e7a4e4d158064efcce8b 100644 (file)
@@ -2594,6 +2594,15 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
 static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = {
        .rev_offs       = 0x0000,
        .sysc_offs      = 0x0010,
+       /*
+        * ISS needs 100 OCP clk cycles delay after a softreset before
+        * accessing sysconfig again.
+        * The lowest frequency at the moment for L3 bus is 100 MHz, so
+        * 1usec delay is needed. Add an x2 margin to be safe (2 usecs).
+        *
+        * TODO: Indicate errata when available.
+        */
+       .srst_udelay    = 2,
        .sysc_flags     = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
                           SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
        .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
index 0cdd359a128ee855e357daee257ec38231a05658..9fc2f44188cbb5fa0657f45ee5b5f3e14662569b 100644 (file)
@@ -108,8 +108,14 @@ static void omap_uart_set_noidle(struct platform_device *pdev)
 static void omap_uart_set_smartidle(struct platform_device *pdev)
 {
        struct omap_device *od = to_omap_device(pdev);
+       u8 idlemode;
 
-       omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART);
+       if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+               idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+       else
+               idlemode = HWMOD_IDLEMODE_SMART;
+
+       omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode);
 }
 
 #else
@@ -120,124 +126,8 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {}
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_OMAP_MUX
-static struct omap_device_pad default_uart1_pads[] __initdata = {
-       {
-               .name   = "uart1_cts.uart1_cts",
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart1_rts.uart1_rts",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart1_tx.uart1_tx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart1_rx.uart1_rx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-               .idle   = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-};
-
-static struct omap_device_pad default_uart2_pads[] __initdata = {
-       {
-               .name   = "uart2_cts.uart2_cts",
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart2_rts.uart2_rts",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart2_tx.uart2_tx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart2_rx.uart2_rx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-               .idle   = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-};
-
-static struct omap_device_pad default_uart3_pads[] __initdata = {
-       {
-               .name   = "uart3_cts_rctx.uart3_cts_rctx",
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart3_rts_sd.uart3_rts_sd",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart3_tx_irtx.uart3_tx_irtx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart3_rx_irrx.uart3_rx_irrx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
-               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
-       },
-};
-
-static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
-       {
-               .name   = "gpmc_wait2.uart4_tx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "gpmc_wait3.uart4_rx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
-               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
-       },
-};
-
-static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
-       {
-               .name   = "uart4_tx.uart4_tx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart4_rx.uart4_rx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
-               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
-       },
-};
-
 static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
 {
-       switch (bdata->id) {
-       case 0:
-               bdata->pads = default_uart1_pads;
-               bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads);
-               break;
-       case 1:
-               bdata->pads = default_uart2_pads;
-               bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads);
-               break;
-       case 2:
-               bdata->pads = default_uart3_pads;
-               bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads);
-               break;
-       case 3:
-               if (cpu_is_omap44xx()) {
-                       bdata->pads = default_omap4_uart4_pads;
-                       bdata->pads_cnt =
-                               ARRAY_SIZE(default_omap4_uart4_pads);
-               } else if (cpu_is_omap3630()) {
-                       bdata->pads = default_omap36xx_uart4_pads;
-                       bdata->pads_cnt =
-                               ARRAY_SIZE(default_omap36xx_uart4_pads);
-               }
-               break;
-       default:
-               break;
-       }
 }
 #else
 static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
index 4b57757bf9d1200cf4e47e099734ec424cad47d2..7a7b89304c48eeb2e1af9f9b87f77d9d5dd5a6f1 100644 (file)
@@ -37,6 +37,16 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = {
        .flags          = I2C_CLIENT_WAKE,
 };
 
+static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {
+       {
+               .addr           = 0x48,
+               .flags          = I2C_CLIENT_WAKE,
+       },
+       {
+               I2C_BOARD_INFO("twl6040", 0x4b),
+       },
+};
+
 void __init omap_pmic_init(int bus, u32 clkrate,
                           const char *pmic_type, int pmic_irq,
                           struct twl4030_platform_data *pmic_data)
@@ -49,14 +59,31 @@ void __init omap_pmic_init(int bus, u32 clkrate,
        omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
 }
 
+void __init omap4_pmic_init(const char *pmic_type,
+                   struct twl4030_platform_data *pmic_data,
+                   struct twl6040_platform_data *twl6040_data, int twl6040_irq)
+{
+       /* PMIC part*/
+       strncpy(omap4_i2c1_board_info[0].type, pmic_type,
+               sizeof(omap4_i2c1_board_info[0].type));
+       omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N;
+       omap4_i2c1_board_info[0].platform_data = pmic_data;
+
+       /* TWL6040 audio IC part */
+       omap4_i2c1_board_info[1].irq = twl6040_irq;
+       omap4_i2c1_board_info[1].platform_data = twl6040_data;
+
+       omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2);
+
+}
+
 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 (pmic_i2c_board_info.irq)
+               omap3_twl_init();
+       if (omap4_i2c1_board_info[0].irq)
+               omap4_twl_init();
 }
 
 #if defined(CONFIG_ARCH_OMAP3)
index 275dde8cb27aa789ce4d9bfa89c8ed92fb122711..09627483a57f917a3a1c74c39b232b951de1594f 100644 (file)
@@ -29,6 +29,7 @@
 
 
 struct twl4030_platform_data;
+struct twl6040_platform_data;
 
 void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
                    struct twl4030_platform_data *pmic_data);
@@ -46,12 +47,9 @@ static inline void omap3_pmic_init(const char *pmic_type,
        omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data);
 }
 
-static inline void omap4_pmic_init(const char *pmic_type,
-                                  struct twl4030_platform_data *pmic_data)
-{
-       /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */
-       omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data);
-}
+void omap4_pmic_init(const char *pmic_type,
+                   struct twl4030_platform_data *pmic_data,
+                   struct twl6040_platform_data *audio_data, int twl6040_irq);
 
 void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
                           u32 pdata_flags, u32 regulators_flags);
index 86ce62f66190fe5a67c2c5dad4f092db67b4818e..b8337e248b0985587806fa9dab8b3759dd5c1ce3 100644 (file)
@@ -33,8 +33,6 @@
 #include <mach/irqs.h>
 #include <mach/dma.h>
 
-static u64 dma_dmamask = DMA_BIT_MASK(32);
-
 static u8 pdma0_peri[] = {
        DMACH_UART0_RX,
        DMACH_UART0_TX,
index a9ea64e0da0d2758e7775a8590d431fc5725d563..48d018f2332bc020239ca49f7d42986dd30134f8 100644 (file)
@@ -484,8 +484,8 @@ static struct wm8994_pdata wm8994_platform_data = {
        .gpio_defaults[8] = 0x0100,
        .gpio_defaults[9] = 0x0100,
        .gpio_defaults[10] = 0x0100,
-       .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
-       .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+       .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data },       /* XM0FRNB_2 */
+       .ldo[1] = { 0, &wm8994_ldo2_data },
 };
 
 /* GPIO I2C PMIC */
index 2cf5ed75f3906ed21f6e5c028b7faaeb9f0c7bef..a8933de3d627ca922c3560d1a907c7761f054097 100644 (file)
@@ -674,8 +674,8 @@ static struct wm8994_pdata wm8994_platform_data = {
        .gpio_defaults[8] = 0x0100,
        .gpio_defaults[9] = 0x0100,
        .gpio_defaults[10] = 0x0100,
-       .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
-       .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+       .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data },       /* XM0FRNB_2 */
+       .ldo[1] = { 0, &wm8994_ldo2_data },
 };
 
 /* GPIO I2C PMIC */
index 880d02ec89d4e598afb2ef6014ab7f03e9b0a56f..ef7099eea0f29a6a593106c482154b37a2d1a4e5 100644 (file)
@@ -17,6 +17,7 @@ config UX500_SOC_DB5500
 config UX500_SOC_DB8500
        bool
        select MFD_DB8500_PRCMU
+       select REGULATOR
        select REGULATOR_DB8500_PRCMU
        select CPU_FREQ_TABLE if CPU_FREQ
 
index d2058ef8345fd4518874d2ab409ae3daa376d5df..eff5842f6232a8f7d0af9e29a87477508ce9f455 100644 (file)
@@ -99,7 +99,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
         */
        write_pen_release(cpu_logical_map(cpu));
 
-       gic_raise_softirq(cpumask_of(cpu), 1);
+       smp_send_reschedule(cpu);
 
        timeout = jiffies + (1 * HZ);
        while (time_before(jiffies, timeout)) {
index 7edef9121632ed94c8e477d64385625040da92a7..7c8a7d8467bf0b40fff40eb01a6533a83e10a18f 100644 (file)
@@ -723,7 +723,7 @@ config CPU_HIGH_VECTOR
        bool "Select the High exception vector"
        help
          Say Y here to select high exception vector(0xFFFF0000~).
-         The exception vector can be vary depending on the platform
+         The exception vector can vary depending on the platform
          design in nommu mode. If your platform needs to select
          high exception vector, say Y.
          Otherwise or if you are unsure, say N, and the low exception
index 9055b5a84ec5614914ab19dc5ed54004a821370f..f0746753336546448a3512e297444fe3137f1c07 100644 (file)
@@ -320,7 +320,7 @@ retry:
         */
 
        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
-       if (flags & FAULT_FLAG_ALLOW_RETRY) {
+       if (!(fault & VM_FAULT_ERROR) && flags & FAULT_FLAG_ALLOW_RETRY) {
                if (fault & VM_FAULT_MAJOR) {
                        tsk->maj_flt++;
                        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
index 6486d2f253cdd9dba5758d4402b11746dc0bda0a..d51225f90ae2d5d3af909ec87d29910bea4f23d5 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/sections.h>
 #include <asm/page.h>
 #include <asm/setup.h>
+#include <asm/traps.h>
 #include <asm/mach/arch.h>
 
 #include "mm.h"
@@ -39,6 +40,7 @@ void __init sanity_check_meminfo(void)
  */
 void __init paging_init(struct machine_desc *mdesc)
 {
+       early_trap_init((void *)CONFIG_VECTORS_BASE);
        bootmem_init();
 }
 
index f1c8486f750169b0ffe8974b35e1b5555e53ad32..c2e2b66f72b5cd08648085c28ffc5d8c2ee8359a 100644 (file)
@@ -254,6 +254,18 @@ __v7_setup:
        ldr     r6, =NMRR                       @ NMRR
        mcr     p15, 0, r5, c10, c2, 0          @ write PRRR
        mcr     p15, 0, r6, c10, c2, 1          @ write NMRR
+#endif
+#ifndef CONFIG_ARM_THUMBEE
+       mrc     p15, 0, r0, c0, c1, 0           @ read ID_PFR0 for ThumbEE
+       and     r0, r0, #(0xf << 12)            @ ThumbEE enabled field
+       teq     r0, #(1 << 12)                  @ check if ThumbEE is present
+       bne     1f
+       mov     r5, #0
+       mcr     p14, 6, r5, c1, c0, 0           @ Initialize TEEHBR to 0
+       mrc     p14, 6, r0, c0, c0, 0           @ load TEECR
+       orr     r0, r0, #1                      @ set the 1st bit in order to
+       mcr     p14, 6, r0, c0, c0, 0           @ stop userspace TEEHBR access
+1:
 #endif
        adr     r5, v7_crval
        ldmia   r5, {r5, r6}
index 8506cbb7fea4a61ac99332986f1a1760b4db848a..62ec5c452792706407922b5ea0173009f6247622 100644 (file)
@@ -398,32 +398,6 @@ struct clk dummy_ck = {
        .ops    = &clkops_null,
 };
 
-#ifdef CONFIG_CPU_FREQ
-void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-       unsigned long flags;
-
-       if (!arch_clock || !arch_clock->clk_init_cpufreq_table)
-               return;
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       arch_clock->clk_init_cpufreq_table(table);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-
-void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-       unsigned long flags;
-
-       if (!arch_clock || !arch_clock->clk_exit_cpufreq_table)
-               return;
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       arch_clock->clk_exit_cpufreq_table(table);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-#endif
-
 /*
  *
  */
index 240a7b9fd946ed95de93fd8b1685e4207acada20..d0ef57c1d71b8d674fd649342f3241eed5d0ba53 100644 (file)
@@ -272,8 +272,6 @@ struct clk {
 #endif
 };
 
-struct cpufreq_frequency_table;
-
 struct clk_functions {
        int             (*clk_enable)(struct clk *clk);
        void            (*clk_disable)(struct clk *clk);
@@ -283,10 +281,6 @@ struct clk_functions {
        void            (*clk_allow_idle)(struct clk *clk);
        void            (*clk_deny_idle)(struct clk *clk);
        void            (*clk_disable_unused)(struct clk *clk);
-#ifdef CONFIG_CPU_FREQ
-       void            (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **);
-       void            (*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **);
-#endif
 };
 
 extern int mpurate;
@@ -301,10 +295,6 @@ extern void recalculate_root_clocks(void);
 extern unsigned long followparent_recalc(struct clk *clk);
 extern void clk_enable_init_clocks(void);
 unsigned long omap_fixed_divisor_recalc(struct clk *clk);
-#ifdef CONFIG_CPU_FREQ
-extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
-extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
-#endif
 extern struct clk *omap_clk_get_by_name(const char *name);
 extern int omap_clk_enable_autoidle_all(void);
 extern int omap_clk_disable_autoidle_all(void);
index 8070145ccb9802b951b6b2c124e5f4d562807db3..3f26db4ee8e671531bb4239acc60852cb0448295 100644 (file)
@@ -305,6 +305,7 @@ struct omap_hwmod_sysc_fields {
  * @rev_offs: IP block revision register offset (from module base addr)
  * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
  * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
+ * @srst_udelay: Delay needed after doing a softreset in usecs
  * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
  * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
  * @clockact: the default value of the module CLOCKACTIVITY bits
@@ -330,9 +331,10 @@ struct omap_hwmod_class_sysconfig {
        u16 sysc_offs;
        u16 syss_offs;
        u16 sysc_flags;
+       struct omap_hwmod_sysc_fields *sysc_fields;
+       u8 srst_udelay;
        u8 idlemodes;
        u8 clockact;
-       struct omap_hwmod_sysc_fields *sysc_fields;
 };
 
 /**
index eec98afa0f8328b2023f855879fa8a2ff34890ac..f9a8c5341ee93e41138f2adb5a6a6f4ce09d48d5 100644 (file)
@@ -348,7 +348,6 @@ u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc,
                        sdrc_actim_ctrl_b_1, sdrc_mr_1);
 }
 
-#ifdef CONFIG_PM
 void omap3_sram_restore_context(void)
 {
        omap_sram_ceil = omap_sram_base + omap_sram_size;
@@ -358,17 +357,18 @@ void omap3_sram_restore_context(void)
                               omap3_sram_configure_core_dpll_sz);
        omap_push_sram_idle();
 }
-#endif /* CONFIG_PM */
-
-#endif /* CONFIG_ARCH_OMAP3 */
 
 static inline int omap34xx_sram_init(void)
 {
-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
        omap3_sram_restore_context();
-#endif
        return 0;
 }
+#else
+static inline int omap34xx_sram_init(void)
+{
+       return 0;
+}
+#endif /* CONFIG_ARCH_OMAP3 */
 
 static inline int am33xx_sram_init(void)
 {
index 71553f410016057315a51b27c28bca46d8bfd93e..a0ffc77da8091a3ab962b8570a7592e9d254bfb5 100644 (file)
@@ -302,6 +302,7 @@ comment "Power management"
 config SAMSUNG_PM_DEBUG
        bool "S3C2410 PM Suspend debug"
        depends on PM
+       select DEBUG_LL
        help
          Say Y here if you want verbose debugging from the PM Suspend and
          Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
index f13b78d5e1ca2c8f170357dd39c35d124f445daf..ab4577f93d96c97f347936a33a75dce2825df0c4 100644 (file)
 /* This number is used when no interrupt has been assigned */
 #define NO_IRQ         0
 
-struct irq_data;
-extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
-extern irq_hw_number_t virq_to_hw(unsigned int virq);
-
 extern void __init init_pic_c64xplus(void);
 
 extern void init_IRQ(void);
index 65b8ddf54b446ca904780dbc02a2e181fde037b1..c90fb5e82ad7b829fb9be3a9d562118374eff901 100644 (file)
@@ -130,16 +130,3 @@ int arch_show_interrupts(struct seq_file *p, int prec)
        seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
        return 0;
 }
-
-irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
-{
-       return d->hwirq;
-}
-EXPORT_SYMBOL_GPL(irqd_to_hwirq);
-
-irq_hw_number_t virq_to_hw(unsigned int virq)
-{
-       struct irq_data *irq_data = irq_get_irq_data(virq);
-       return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
-}
-EXPORT_SYMBOL_GPL(virq_to_hw);
index 4c96187e204908bb3a9ba7e37a198df61159ff28..4f37dbbb864081cac07e473270f8dd5ec42cf083 100644 (file)
@@ -1 +1,147 @@
-#include <asm/intrinsics.h>
+#ifndef _ASM_IA64_CMPXCHG_H
+#define _ASM_IA64_CMPXCHG_H
+
+/*
+ * Compare/Exchange, forked from asm/intrinsics.h
+ * which was:
+ *
+ *     Copyright (C) 2002-2003 Hewlett-Packard Co
+ *     David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+/* include compiler specific intrinsics */
+#include <asm/ia64regs.h>
+#ifdef __INTEL_COMPILER
+# include <asm/intel_intrin.h>
+#else
+# include <asm/gcc_intrin.h>
+#endif
+
+/*
+ * This function doesn't exist, so you'll get a linker error if
+ * something tries to do an invalid xchg().
+ */
+extern void ia64_xchg_called_with_bad_pointer(void);
+
+#define __xchg(x, ptr, size)                                           \
+({                                                                     \
+       unsigned long __xchg_result;                                    \
+                                                                       \
+       switch (size) {                                                 \
+       case 1:                                                         \
+               __xchg_result = ia64_xchg1((__u8 *)ptr, x);             \
+               break;                                                  \
+                                                                       \
+       case 2:                                                         \
+               __xchg_result = ia64_xchg2((__u16 *)ptr, x);            \
+               break;                                                  \
+                                                                       \
+       case 4:                                                         \
+               __xchg_result = ia64_xchg4((__u32 *)ptr, x);            \
+               break;                                                  \
+                                                                       \
+       case 8:                                                         \
+               __xchg_result = ia64_xchg8((__u64 *)ptr, x);            \
+               break;                                                  \
+       default:                                                        \
+               ia64_xchg_called_with_bad_pointer();                    \
+       }                                                               \
+       __xchg_result;                                                  \
+})
+
+#define xchg(ptr, x)                                                   \
+((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr))))
+
+/*
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg().
+ */
+extern long ia64_cmpxchg_called_with_bad_pointer(void);
+
+#define ia64_cmpxchg(sem, ptr, old, new, size)                         \
+({                                                                     \
+       __u64 _o_, _r_;                                                 \
+                                                                       \
+       switch (size) {                                                 \
+       case 1:                                                         \
+               _o_ = (__u8) (long) (old);                              \
+               break;                                                  \
+       case 2:                                                         \
+               _o_ = (__u16) (long) (old);                             \
+               break;                                                  \
+       case 4:                                                         \
+               _o_ = (__u32) (long) (old);                             \
+               break;                                                  \
+       case 8:                                                         \
+               _o_ = (__u64) (long) (old);                             \
+               break;                                                  \
+       default:                                                        \
+               break;                                                  \
+       }                                                               \
+       switch (size) {                                                 \
+       case 1:                                                         \
+               _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_);      \
+               break;                                                  \
+                                                                       \
+       case 2:                                                         \
+               _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_);     \
+               break;                                                  \
+                                                                       \
+       case 4:                                                         \
+               _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_);     \
+               break;                                                  \
+                                                                       \
+       case 8:                                                         \
+               _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_);     \
+               break;                                                  \
+                                                                       \
+       default:                                                        \
+               _r_ = ia64_cmpxchg_called_with_bad_pointer();           \
+               break;                                                  \
+       }                                                               \
+       (__typeof__(old)) _r_;                                          \
+})
+
+#define cmpxchg_acq(ptr, o, n) \
+       ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr)))
+#define cmpxchg_rel(ptr, o, n) \
+       ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr)))
+
+/* for compatibility with other platforms: */
+#define cmpxchg(ptr, o, n)     cmpxchg_acq((ptr), (o), (n))
+#define cmpxchg64(ptr, o, n)   cmpxchg_acq((ptr), (o), (n))
+
+#define cmpxchg_local          cmpxchg
+#define cmpxchg64_local                cmpxchg64
+
+#ifdef CONFIG_IA64_DEBUG_CMPXCHG
+# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128;
+# define CMPXCHG_BUGCHECK(v)                                           \
+do {                                                                   \
+       if (_cmpxchg_bugcheck_count-- <= 0) {                           \
+               void *ip;                                               \
+               extern int printk(const char *fmt, ...);                \
+               ip = (void *) ia64_getreg(_IA64_REG_IP);                \
+               printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));\
+               break;                                                  \
+       }                                                               \
+} while (0)
+#else /* !CONFIG_IA64_DEBUG_CMPXCHG */
+# define CMPXCHG_BUGCHECK_DECL
+# define CMPXCHG_BUGCHECK(v)
+#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_IA64_CMPXCHG_H */
index 0ab82cc2dc8fe990f79d7db76f166b94e75b11d9..d2bf1fd5e44f5970caf455acdddc671fc0dee192 100644 (file)
@@ -106,15 +106,16 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
                return -EFAULT;
 
        {
-               register unsigned long r8 __asm ("r8") = 0;
+               register unsigned long r8 __asm ("r8");
                unsigned long prev;
                __asm__ __volatile__(
                        "       mf;;                                    \n"
-                       "       mov ar.ccv=%3;;                         \n"
-                       "[1:]   cmpxchg4.acq %0=[%1],%2,ar.ccv          \n"
+                       "       mov %0=r0                               \n"
+                       "       mov ar.ccv=%4;;                         \n"
+                       "[1:]   cmpxchg4.acq %1=[%2],%3,ar.ccv          \n"
                        "       .xdata4 \"__ex_table\", 1b-., 2f-.      \n"
                        "[2:]"
-                       : "=r" (prev)
+                       : "=r" (r8), "=r" (prev)
                        : "r" (uaddr), "r" (newval),
                          "rO" ((long) (unsigned) oldval)
                        : "memory");
index e4076b511829572ad590d36e362f463f93e813d6..d129e367e76448036c4dad8c347cc6a33977f710 100644 (file)
@@ -18,6 +18,7 @@
 #else
 # include <asm/gcc_intrin.h>
 #endif
+#include <asm/cmpxchg.h>
 
 #define ia64_native_get_psr_i()        (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
 
@@ -81,119 +82,6 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
 
 #define ia64_fetch_and_add(i,v)        (ia64_fetchadd(i, v, rel) + (i)) /* return new value */
 
-/*
- * This function doesn't exist, so you'll get a linker error if
- * something tries to do an invalid xchg().
- */
-extern void ia64_xchg_called_with_bad_pointer (void);
-
-#define __xchg(x,ptr,size)                                             \
-({                                                                     \
-       unsigned long __xchg_result;                                    \
-                                                                       \
-       switch (size) {                                                 \
-             case 1:                                                   \
-               __xchg_result = ia64_xchg1((__u8 *)ptr, x);             \
-               break;                                                  \
-                                                                       \
-             case 2:                                                   \
-               __xchg_result = ia64_xchg2((__u16 *)ptr, x);            \
-               break;                                                  \
-                                                                       \
-             case 4:                                                   \
-               __xchg_result = ia64_xchg4((__u32 *)ptr, x);            \
-               break;                                                  \
-                                                                       \
-             case 8:                                                   \
-               __xchg_result = ia64_xchg8((__u64 *)ptr, x);            \
-               break;                                                  \
-             default:                                                  \
-               ia64_xchg_called_with_bad_pointer();                    \
-       }                                                               \
-       __xchg_result;                                                  \
-})
-
-#define xchg(ptr,x)                                                         \
-  ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr))))
-
-/*
- * Atomic compare and exchange.  Compare OLD with MEM, if identical,
- * store NEW in MEM.  Return the initial value in MEM.  Success is
- * indicated by comparing RETURN with OLD.
- */
-
-#define __HAVE_ARCH_CMPXCHG 1
-
-/*
- * This function doesn't exist, so you'll get a linker error
- * if something tries to do an invalid cmpxchg().
- */
-extern long ia64_cmpxchg_called_with_bad_pointer (void);
-
-#define ia64_cmpxchg(sem,ptr,old,new,size)                                             \
-({                                                                                     \
-       __u64 _o_, _r_;                                                                 \
-                                                                                       \
-       switch (size) {                                                                 \
-             case 1: _o_ = (__u8 ) (long) (old); break;                                \
-             case 2: _o_ = (__u16) (long) (old); break;                                \
-             case 4: _o_ = (__u32) (long) (old); break;                                \
-             case 8: _o_ = (__u64) (long) (old); break;                                \
-             default: break;                                                           \
-       }                                                                               \
-       switch (size) {                                                                 \
-             case 1:                                                                   \
-               _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_);                      \
-               break;                                                                  \
-                                                                                       \
-             case 2:                                                                   \
-              _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_);                      \
-               break;                                                                  \
-                                                                                       \
-             case 4:                                                                   \
-               _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_);                     \
-               break;                                                                  \
-                                                                                       \
-             case 8:                                                                   \
-               _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_);                     \
-               break;                                                                  \
-                                                                                       \
-             default:                                                                  \
-               _r_ = ia64_cmpxchg_called_with_bad_pointer();                           \
-               break;                                                                  \
-       }                                                                               \
-       (__typeof__(old)) _r_;                                                          \
-})
-
-#define cmpxchg_acq(ptr, o, n) \
-       ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr)))
-#define cmpxchg_rel(ptr, o, n) \
-       ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr)))
-
-/* for compatibility with other platforms: */
-#define cmpxchg(ptr, o, n)     cmpxchg_acq((ptr), (o), (n))
-#define cmpxchg64(ptr, o, n)   cmpxchg_acq((ptr), (o), (n))
-
-#define cmpxchg_local          cmpxchg
-#define cmpxchg64_local                cmpxchg64
-
-#ifdef CONFIG_IA64_DEBUG_CMPXCHG
-# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128;
-# define CMPXCHG_BUGCHECK(v)                                                   \
-  do {                                                                         \
-       if (_cmpxchg_bugcheck_count-- <= 0) {                                   \
-               void *ip;                                                       \
-               extern int printk(const char *fmt, ...);                        \
-               ip = (void *) ia64_getreg(_IA64_REG_IP);                        \
-               printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));  \
-               break;                                                          \
-       }                                                                       \
-  } while (0)
-#else /* !CONFIG_IA64_DEBUG_CMPXCHG */
-# define CMPXCHG_BUGCHECK_DECL
-# define CMPXCHG_BUGCHECK(v)
-#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
-
 #endif
 
 #ifdef __KERNEL__
index 9d0fd7d5bb82c03d65820a01b1af673c7b0c7c7e..f00ba025375d5696d0070bfe640b6f26f554eebd 100644 (file)
@@ -604,12 +604,6 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f)
        spin_unlock(&(x)->ctx_lock);
 }
 
-static inline unsigned int
-pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct)
-{
-       return do_munmap(mm, addr, len);
-}
-
 static inline unsigned long 
 pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
 {
@@ -1458,8 +1452,9 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
  * a PROTECT_CTX() section.
  */
 static int
-pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size)
+pfm_remove_smpl_mapping(void *vaddr, unsigned long size)
 {
+       struct task_struct *task = current;
        int r;
 
        /* sanity checks */
@@ -1473,13 +1468,8 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz
        /*
         * does the actual unmapping
         */
-       down_write(&task->mm->mmap_sem);
+       r = vm_munmap((unsigned long)vaddr, size);
 
-       DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size));
-
-       r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0);
-
-       up_write(&task->mm->mmap_sem);
        if (r !=0) {
                printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);
        }
@@ -1945,7 +1935,7 @@ pfm_flush(struct file *filp, fl_owner_t id)
         * because some VM function reenables interrupts.
         *
         */
-       if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size);
+       if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size);
 
        return 0;
 }
index 33c32aeca12beb418955260a4f83a127ef900960..a1230e82bb1e5226c3d61968b1c625bbf40c6a17 100644 (file)
@@ -49,7 +49,6 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_FEC=y
-CONFIG_FEC2=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_PPP=y
index 7ed848c3b848784cf4d0067e35889ce4c857a0fd..f91a53294c357eebe80364a9a696a5993ab782f7 100644 (file)
@@ -74,9 +74,7 @@ static void __init m527x_fec_init(void)
        writew(par | 0xf00, MCF_IPSBAR + 0x100082);
        v = readb(MCF_IPSBAR + 0x100078);
        writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
-#endif
 
-#ifdef CONFIG_FEC2
        /* Set multi-function pins to ethernet mode for fec1 */
        par = readw(MCF_IPSBAR + 0x100082);
        writew(par | 0xa0, MCF_IPSBAR + 0x100082);
index ee97735a242c5575c208c8391559b2e2fab98dce..b44d799b111500d9e4406227fd50ff85ac812830 100644 (file)
@@ -3,9 +3,3 @@
 #
 
 obj-y := config.o
-
-extra-y := bootlogo.rh
-
-$(obj)/bootlogo.rh: $(src)/bootlogo.h
-       perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \
-               > $(obj)/bootlogo.rh
index 447ffa0fd7c7a15759e06403a4c7eafe9fabbfb6..a49d75e654899a1adb229fb275290943ad0b3b94 100644 (file)
@@ -3,14 +3,9 @@
 #
 
 obj-y          := config.o
-logo-$(UCDIMM) := bootlogo.rh
-logo-$(DRAGEN2)        := screen.h
-extra-y                := $(logo-y)
-
-$(obj)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h
-       perl $(src)/bootlogo.pl < $(src)/../68328/bootlogo.h > $(obj)/bootlogo.rh
+extra-$(DRAGEN2):= screen.h
 
 $(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl
        perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h
 
-clean-files := $(obj)/screen.h $(obj)/bootlogo.rh
+clean-files := $(obj)/screen.h
similarity index 99%
rename from arch/m68k/platform/68EZ328/bootlogo.h
rename to arch/m68k/platform/68VZ328/bootlogo.h
index e842bdae583935abdf4110875b60a97cdb552f96..b38e2b255142ef1cf6132f7293d7bb393a566864 100644 (file)
@@ -1,6 +1,6 @@
 #define splash_width 640
 #define splash_height 480
-static unsigned char splash_bits[] = {
+unsigned char __attribute__ ((aligned(16))) bootlogo_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
index fa50c48292ffafc7597afb073079dd79c3b6bb98..7af97362b95c3bb067ee939f35d50bcd0991ac4f 100644 (file)
@@ -114,7 +114,7 @@ static struct resource mcf_fec1_resources[] = {
 
 static struct platform_device mcf_fec1 = {
        .name                   = "fec",
-       .id                     = 0,
+       .id                     = 1,
        .num_resources          = ARRAY_SIZE(mcf_fec1_resources),
        .resource               = mcf_fec1_resources,
 };
diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi b/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi
new file mode 100644 (file)
index 0000000..1cf0b77
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * PQ3 MPIC Message (Group B) device tree stub [ controller @ offset 0x42400 ]
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+message@42400 {
+       compatible = "fsl,mpic-v3.1-msgr";
+       reg = <0x42400 0x200>;
+       interrupts = <
+               0xb4 2 0 0
+               0xb5 2 0 0
+               0xb6 2 0 0
+               0xb7 2 0 0>;
+};
index fdedf7b1fe0f2e25d47729470e1665be9615a3d8..71c30eb10056962c439d6e7900415d9c27c829fc 100644 (file)
@@ -53,6 +53,16 @@ timer@41100 {
                      3 0 3 0>;
 };
 
+message@41400 {
+       compatible = "fsl,mpic-v3.1-msgr";
+       reg = <0x41400 0x200>;
+       interrupts = <
+               0xb0 2 0 0
+               0xb1 2 0 0
+               0xb2 2 0 0
+               0xb3 2 0 0>;
+};
+
 msi@41600 {
        compatible = "fsl,mpic-msi";
        reg = <0x41600 0x80>;
index cf417e51073627ff6184f15ddd3a78f7948419c7..e648af92ced18b20384102912fbaeafc903ddfb0 100644 (file)
@@ -33,8 +33,6 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Same thing, used by the generic IRQ code */
 #define NR_IRQS_LEGACY         NUM_ISA_INTERRUPTS
 
-struct irq_data;
-extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
 
 /**
index c65b9294376ee8e2e1745cf73b014dc1f49d372e..c9f698a994be246860ee6cfdd6895d27d68cea7b 100644 (file)
@@ -275,9 +275,6 @@ struct mpic
        unsigned int            isu_mask;
        /* Number of sources */
        unsigned int            num_sources;
-       /* default senses array */
-       unsigned char           *senses;
-       unsigned int            senses_count;
 
        /* vector numbers used for internal sources (ipi/timers) */
        unsigned int            ipi_vecs[4];
@@ -415,21 +412,6 @@ extern struct mpic *mpic_alloc(struct device_node *node,
 extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
                            phys_addr_t phys_addr);
 
-/* Set default sense codes
- *
- * @mpic:      controller
- * @senses:    array of sense codes
- * @count:     size of above array
- *
- * Optionally provide an array (indexed on hardware interrupt numbers
- * for this MPIC) of default sense codes for the chip. Those are linux
- * sense codes IRQ_TYPE_*
- *
- * The driver gets ownership of the pointer, don't dispose of it or
- * anything like that. __init only.
- */
-extern void mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count);
-
 
 /* Initialize the controller. After this has been called, none of the above
  * should be called again for this mpic
index 3ec37dc9003e2575ee7170c4786904ab0ac6ee95..326d33ca55cdc33e8b3cb112f0fefb8117bab3af 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/types.h>
 #include <linux/spinlock.h>
+#include <asm/smp.h>
 
 struct mpic_msgr {
        u32 __iomem *base;
index b86faa9107da24338d661d7acf7ba455da413974..8a97aa7289d36b155a1e01df4211a261a7a110e8 100644 (file)
 #ifndef __ASM_POWERPC_REG_BOOKE_H__
 #define __ASM_POWERPC_REG_BOOKE_H__
 
-#ifdef CONFIG_BOOKE_WDT
-extern u32 booke_wdt_enabled;
-extern u32 booke_wdt_period;
-#endif /* CONFIG_BOOKE_WDT */
-
 /* Machine State Register (MSR) Fields */
 #define MSR_GS         (1<<28) /* Guest state */
 #define MSR_UCLE       (1<<26) /* User-mode cache lock enable */
index 3e57a00b8cba784633d1b0465fd3b47f1b85baf0..ba3aeb4bc06a81453105c6294bd74b81b340ed77 100644 (file)
@@ -206,40 +206,43 @@ reenable_mmu:                             /* re-enable mmu so we can */
        andi.   r10,r10,MSR_EE          /* Did EE change? */
        beq     1f
 
-       /* Save handler and return address into the 2 unused words
-        * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything
-        * else can be recovered from the pt_regs except r3 which for
-        * normal interrupts has been set to pt_regs and for syscalls
-        * is an argument, so we temporarily use ORIG_GPR3 to save it
-        */
-       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.
+        *
+        * This is handy because we also need to save a bunch of GPRs,
+        * r3 can be different from GPR3(r1) at this point, r9 and r11
+        * contains the old MSR and handler address respectively,
+        * r4 & r5 can contain page fault arguments that need to be passed
+        * along as well. r12, CCR, CTR, XER etc... are left clobbered as
+        * they aren't useful past this point (aren't syscall arguments),
+        * the rest is restored from the exception frame.
         */
+       stwu    r1,-32(r1)
+       stw     r9,8(r1)
+       stw     r11,12(r1)
+       stw     r3,16(r1)
+       stw     r4,20(r1)
+       stw     r5,24(r1)
        andi.   r12,r12,MSR_PR
-       beq     11f
-       stwu    r1,-16(r1)
+       b       11f
        bl      trace_hardirqs_off
-       addi    r1,r1,16
        b       12f
-
 11:
        bl      trace_hardirqs_off
 12:
+       lwz     r5,24(r1)
+       lwz     r4,20(r1)
+       lwz     r3,16(r1)
+       lwz     r11,12(r1)
+       lwz     r9,8(r1)
+       addi    r1,r1,32
        lwz     r0,GPR0(r1)
-       lwz     r3,ORIG_GPR3(r1)
-       lwz     r4,GPR4(r1)
-       lwz     r5,GPR5(r1)
        lwz     r6,GPR6(r1)
        lwz     r7,GPR7(r1)
        lwz     r8,GPR8(r1)
-       lwz     r9,8(r1)
-       lwz     r11,12(r1)
 1:     mtctr   r11
        mtlr    r9
        bctr                            /* jump to handler */
index 243dbabfe74dff0ebbe55fab216a335574c1dc12..5ec1b2354ca62301b83019db2f342bd92c085b80 100644 (file)
@@ -560,12 +560,6 @@ void do_softirq(void)
        local_irq_restore(flags);
 }
 
-irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
-{
-       return d->hwirq;
-}
-EXPORT_SYMBOL_GPL(irqd_to_hwirq);
-
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
        struct irq_data *irq_data = irq_get_irq_data(virq);
index f88698c0f332d2a0c87957d10f1ca32ddd3d5eb0..4937c9690090d0e9bf3809b7ae923ae24d181d93 100644 (file)
@@ -1235,7 +1235,7 @@ void __ppc64_runlatch_on(void)
        ctrl |= CTRL_RUNLATCH;
        mtspr(SPRN_CTRLT, ctrl);
 
-       ti->local_flags |= TLF_RUNLATCH;
+       ti->local_flags |= _TLF_RUNLATCH;
 }
 
 /* Called with hard IRQs off */
@@ -1244,7 +1244,7 @@ void __ppc64_runlatch_off(void)
        struct thread_info *ti = current_thread_info();
        unsigned long ctrl;
 
-       ti->local_flags &= ~TLF_RUNLATCH;
+       ti->local_flags &= ~_TLF_RUNLATCH;
 
        ctrl = mfspr(SPRN_CTRLF);
        ctrl &= ~CTRL_RUNLATCH;
index 9825f29d1fafbcfd381aec51286137efa51830e9..ec8a53fa9e8f6a07f82b640426ef50f38e224d53 100644 (file)
@@ -150,6 +150,9 @@ notrace void __init machine_init(u64 dt_ptr)
 }
 
 #ifdef CONFIG_BOOKE_WDT
+extern u32 booke_wdt_enabled;
+extern u32 booke_wdt_period;
+
 /* Checks wdt=x and wdt_period=xx command-line option */
 notrace int __init early_parse_wdt(char *p)
 {
index bed1279aa6a8788a8308b8966ef4c970f8aafd36..e1b60f56f2a1eb73bdd00ebc36faa44e5e3a0aa2 100644 (file)
@@ -173,9 +173,9 @@ static void __init kvm_linear_init_one(ulong size, int count, int type)
 
 static struct kvmppc_linear_info *kvm_alloc_linear(int type)
 {
-       struct kvmppc_linear_info *ri;
+       struct kvmppc_linear_info *ri, *ret;
 
-       ri = NULL;
+       ret = NULL;
        spin_lock(&linear_lock);
        list_for_each_entry(ri, &free_linears, list) {
                if (ri->type != type)
@@ -183,11 +183,12 @@ static struct kvmppc_linear_info *kvm_alloc_linear(int type)
 
                list_del(&ri->list);
                atomic_inc(&ri->use_count);
+               memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT);
+               ret = ri;
                break;
        }
        spin_unlock(&linear_lock);
-       memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT);
-       return ri;
+       return ret;
 }
 
 static void kvm_release_linear(struct kvmppc_linear_info *ri)
index 3f7b674dd4bf4843ab37e649527149fd6143cf23..d3fb4df02c419f48dfd8d3205c042cc04ff94426 100644 (file)
@@ -46,8 +46,10 @@ _GLOBAL(__kvmppc_vcore_entry)
        /* Save host state to the stack */
        stdu    r1, -SWITCH_FRAME_SIZE(r1)
 
-       /* Save non-volatile registers (r14 - r31) */
+       /* Save non-volatile registers (r14 - r31) and CR */
        SAVE_NVGPRS(r1)
+       mfcr    r3
+       std     r3, _CCR(r1)
 
        /* Save host DSCR */
 BEGIN_FTR_SECTION
@@ -157,8 +159,10 @@ kvmppc_handler_highmem:
         * R13      = PACA
         */
 
-       /* Restore non-volatile host registers (r14 - r31) */
+       /* Restore non-volatile host registers (r14 - r31) and CR */
        REST_NVGPRS(r1)
+       ld      r4, _CCR(r1)
+       mtcr    r4
 
        addi    r1, r1, SWITCH_FRAME_SIZE
        ld      r0, PPC_LR_STKOFF(r1)
index 0a8515a5c0422db7dc27890d4651267a62a6531c..3e35383bdb2186e81bb78dfbae2ebe8818c223ac 100644 (file)
@@ -84,6 +84,10 @@ kvm_start_entry:
        /* Save non-volatile registers (r14 - r31) */
        SAVE_NVGPRS(r1)
 
+       /* Save CR */
+       mfcr    r14
+       stw     r14, _CCR(r1)
+
        /* Save LR */
        PPC_STL r0, _LINK(r1)
 
@@ -165,6 +169,9 @@ kvm_exit_loop:
        PPC_LL  r4, _LINK(r1)
        mtlr    r4
 
+       lwz     r14, _CCR(r1)
+       mtcr    r14
+
        /* Restore non-volatile host registers (r14 - r31) */
        REST_NVGPRS(r1)
 
index 642d88574b07a683c58e197a8a5b60d81ec92d85..7759053d391b87298a4888c1cbbb7463ee6e8431 100644 (file)
@@ -777,6 +777,7 @@ program_interrupt:
        }
        }
 
+       preempt_disable();
        if (!(r & RESUME_HOST)) {
                /* To avoid clobbering exit_reason, only check for signals if
                 * we aren't already exiting to userspace for some other
@@ -798,8 +799,6 @@ program_interrupt:
                        run->exit_reason = KVM_EXIT_INTR;
                        r = -EINTR;
                } else {
-                       preempt_disable();
-
                        /* In case an interrupt came in that was triggered
                         * from userspace (like DEC), we need to check what
                         * to inject now! */
@@ -881,7 +880,8 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 
        switch (reg->id) {
        case KVM_REG_PPC_HIOR:
-               r = put_user(to_book3s(vcpu)->hior, (u64 __user *)reg->addr);
+               r = copy_to_user((u64 __user *)(long)reg->addr,
+                               &to_book3s(vcpu)->hior, sizeof(u64));
                break;
        default:
                break;
@@ -896,7 +896,8 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 
        switch (reg->id) {
        case KVM_REG_PPC_HIOR:
-               r = get_user(to_book3s(vcpu)->hior, (u64 __user *)reg->addr);
+               r = copy_from_user(&to_book3s(vcpu)->hior,
+                                  (u64 __user *)(long)reg->addr, sizeof(u64));
                if (!r)
                        to_book3s(vcpu)->hior_explicit = true;
                break;
index 10d8ef602e5c9303795c7b78268d5691be79eeec..c8c4b878795a71542876308d68e34d7ff6e26163 100644 (file)
@@ -34,7 +34,8 @@
 /* r2 is special: it holds 'current', and it made nonvolatile in the
  * kernel with the -ffixed-r2 gcc option. */
 #define HOST_R2         12
-#define HOST_NV_GPRS    16
+#define HOST_CR         16
+#define HOST_NV_GPRS    20
 #define HOST_NV_GPR(n)  (HOST_NV_GPRS + ((n - 14) * 4))
 #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(31) + 4)
 #define HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */
@@ -296,8 +297,10 @@ heavyweight_exit:
 
        /* Return to kvm_vcpu_run(). */
        lwz     r4, HOST_STACK_LR(r1)
+       lwz     r5, HOST_CR(r1)
        addi    r1, r1, HOST_STACK_SIZE
        mtlr    r4
+       mtcr    r5
        /* r3 still contains the return code from kvmppc_handle_exit(). */
        blr
 
@@ -314,6 +317,8 @@ _GLOBAL(__kvmppc_vcpu_run)
        stw     r3, HOST_RUN(r1)
        mflr    r3
        stw     r3, HOST_STACK_LR(r1)
+       mfcr    r5
+       stw     r5, HOST_CR(r1)
 
        /* Save host non-volatile register state to stack. */
        stw     r14, HOST_NV_GPR(r14)(r1)
index af1ab5e9a691e6b3c70b8d08415992f8c2205049..5c3cf2d04e41ccaa6e8b7aa94eb7ca27ba4baad9 100644 (file)
 /*
  * Assembly helpers from arch/powerpc/net/bpf_jit.S:
  */
-extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
+#define DECLARE_LOAD_FUNC(func)        \
+       extern u8 func[], func##_negative_offset[], func##_positive_offset[]
+
+DECLARE_LOAD_FUNC(sk_load_word);
+DECLARE_LOAD_FUNC(sk_load_half);
+DECLARE_LOAD_FUNC(sk_load_byte);
+DECLARE_LOAD_FUNC(sk_load_byte_msh);
 
 #define FUNCTION_DESCR_SIZE    24
 
index ff4506e85cce80bc2fdb7003078cec3f5c0d9962..55ba3855a97f58093ec06f343cde1df2dffbb17b 100644 (file)
  * then branch directly to slow_path_XXX if required.  (In fact, could
  * load a spare GPR with the address of slow_path_generic and pass size
  * as an argument, making the call site a mtlr, li and bllr.)
- *
- * Technically, the "is addr < 0" check is unnecessary & slowing down
- * the ABS path, as it's statically checked on generation.
  */
        .globl  sk_load_word
 sk_load_word:
        cmpdi   r_addr, 0
-       blt     bpf_error
+       blt     bpf_slow_path_word_neg
+       .globl  sk_load_word_positive_offset
+sk_load_word_positive_offset:
        /* Are we accessing past headlen? */
        subi    r_scratch1, r_HL, 4
        cmpd    r_scratch1, r_addr
@@ -51,7 +50,9 @@ sk_load_word:
        .globl  sk_load_half
 sk_load_half:
        cmpdi   r_addr, 0
-       blt     bpf_error
+       blt     bpf_slow_path_half_neg
+       .globl  sk_load_half_positive_offset
+sk_load_half_positive_offset:
        subi    r_scratch1, r_HL, 2
        cmpd    r_scratch1, r_addr
        blt     bpf_slow_path_half
@@ -61,7 +62,9 @@ sk_load_half:
        .globl  sk_load_byte
 sk_load_byte:
        cmpdi   r_addr, 0
-       blt     bpf_error
+       blt     bpf_slow_path_byte_neg
+       .globl  sk_load_byte_positive_offset
+sk_load_byte_positive_offset:
        cmpd    r_HL, r_addr
        ble     bpf_slow_path_byte
        lbzx    r_A, r_D, r_addr
@@ -69,22 +72,20 @@ sk_load_byte:
 
 /*
  * BPF_S_LDX_B_MSH: ldxb  4*([offset]&0xf)
- * r_addr is the offset value, already known positive
+ * r_addr is the offset value
  */
        .globl sk_load_byte_msh
 sk_load_byte_msh:
+       cmpdi   r_addr, 0
+       blt     bpf_slow_path_byte_msh_neg
+       .globl sk_load_byte_msh_positive_offset
+sk_load_byte_msh_positive_offset:
        cmpd    r_HL, r_addr
        ble     bpf_slow_path_byte_msh
        lbzx    r_X, r_D, r_addr
        rlwinm  r_X, r_X, 2, 32-4-2, 31-2
        blr
 
-bpf_error:
-       /* Entered with cr0 = lt */
-       li      r3, 0
-       /* Generated code will 'blt epilogue', returning 0. */
-       blr
-
 /* Call out to skb_copy_bits:
  * We'll need to back up our volatile regs first; we have
  * local variable space at r1+(BPF_PPC_STACK_BASIC).
@@ -136,3 +137,84 @@ bpf_slow_path_byte_msh:
        lbz     r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
        rlwinm  r_X, r_X, 2, 32-4-2, 31-2
        blr
+
+/* Call out to bpf_internal_load_pointer_neg_helper:
+ * We'll need to back up our volatile regs first; we have
+ * local variable space at r1+(BPF_PPC_STACK_BASIC).
+ * Allocate a new stack frame here to remain ABI-compliant in
+ * stashing LR.
+ */
+#define sk_negative_common(SIZE)                               \
+       mflr    r0;                                             \
+       std     r0, 16(r1);                                     \
+       /* R3 goes in parameter space of caller's frame */      \
+       std     r_skb, (BPF_PPC_STACKFRAME+48)(r1);             \
+       std     r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);           \
+       std     r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);           \
+       stdu    r1, -BPF_PPC_SLOWPATH_FRAME(r1);                \
+       /* R3 = r_skb, as passed */                             \
+       mr      r4, r_addr;                                     \
+       li      r5, SIZE;                                       \
+       bl      bpf_internal_load_pointer_neg_helper;           \
+       /* R3 != 0 on success */                                \
+       addi    r1, r1, BPF_PPC_SLOWPATH_FRAME;                 \
+       ld      r0, 16(r1);                                     \
+       ld      r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);           \
+       ld      r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);           \
+       mtlr    r0;                                             \
+       cmpldi  r3, 0;                                          \
+       beq     bpf_error_slow; /* cr0 = EQ */                  \
+       mr      r_addr, r3;                                     \
+       ld      r_skb, (BPF_PPC_STACKFRAME+48)(r1);             \
+       /* Great success! */
+
+bpf_slow_path_word_neg:
+       lis     r_scratch1,-32  /* SKF_LL_OFF */
+       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       blt     bpf_error       /* cr0 = LT */
+       .globl  sk_load_word_negative_offset
+sk_load_word_negative_offset:
+       sk_negative_common(4)
+       lwz     r_A, 0(r_addr)
+       blr
+
+bpf_slow_path_half_neg:
+       lis     r_scratch1,-32  /* SKF_LL_OFF */
+       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       blt     bpf_error       /* cr0 = LT */
+       .globl  sk_load_half_negative_offset
+sk_load_half_negative_offset:
+       sk_negative_common(2)
+       lhz     r_A, 0(r_addr)
+       blr
+
+bpf_slow_path_byte_neg:
+       lis     r_scratch1,-32  /* SKF_LL_OFF */
+       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       blt     bpf_error       /* cr0 = LT */
+       .globl  sk_load_byte_negative_offset
+sk_load_byte_negative_offset:
+       sk_negative_common(1)
+       lbz     r_A, 0(r_addr)
+       blr
+
+bpf_slow_path_byte_msh_neg:
+       lis     r_scratch1,-32  /* SKF_LL_OFF */
+       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       blt     bpf_error       /* cr0 = LT */
+       .globl  sk_load_byte_msh_negative_offset
+sk_load_byte_msh_negative_offset:
+       sk_negative_common(1)
+       lbz     r_X, 0(r_addr)
+       rlwinm  r_X, r_X, 2, 32-4-2, 31-2
+       blr
+
+bpf_error_slow:
+       /* fabricate a cr0 = lt */
+       li      r_scratch1, -1
+       cmpdi   r_scratch1, 0
+bpf_error:
+       /* Entered with cr0 = lt */
+       li      r3, 0
+       /* Generated code will 'blt epilogue', returning 0. */
+       blr
index 73619d3aeb6ceebaa9d54e652b5025234f31660c..2dc8b14848455122918d13cf1d2985984f8a248b 100644 (file)
@@ -127,6 +127,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
        PPC_BLR();
 }
 
+#define CHOOSE_LOAD_FUNC(K, func) \
+       ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
+
 /* Assemble the body code between the prologue & epilogue. */
 static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
                              struct codegen_context *ctx,
@@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 
                        /*** Absolute loads from packet header/data ***/
                case BPF_S_LD_W_ABS:
-                       func = sk_load_word;
+                       func = CHOOSE_LOAD_FUNC(K, sk_load_word);
                        goto common_load;
                case BPF_S_LD_H_ABS:
-                       func = sk_load_half;
+                       func = CHOOSE_LOAD_FUNC(K, sk_load_half);
                        goto common_load;
                case BPF_S_LD_B_ABS:
-                       func = sk_load_byte;
+                       func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
                common_load:
-                       /*
-                        * Load from [K].  Reference with the (negative)
-                        * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
-                        */
+                       /* Load from [K]. */
                        ctx->seen |= SEEN_DATAREF;
-                       if ((int)K < 0)
-                               return -ENOTSUPP;
                        PPC_LI64(r_scratch1, func);
                        PPC_MTLR(r_scratch1);
                        PPC_LI32(r_addr, K);
@@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
                common_load_ind:
                        /*
                         * Load from [X + K].  Negative offsets are tested for
-                        * in the helper functions, and result in a 'ret 0'.
+                        * in the helper functions.
                         */
                        ctx->seen |= SEEN_DATAREF | SEEN_XREG;
                        PPC_LI64(r_scratch1, func);
@@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
                        break;
 
                case BPF_S_LDX_B_MSH:
-                       /*
-                        * x86 version drops packet (RET 0) when K<0, whereas
-                        * interpreter does allow K<0 (__load_pointer, special
-                        * ancillary data).  common_load returns ENOTSUPP if K<0,
-                        * so we fall back to interpreter & filter works.
-                        */
-                       func = sk_load_byte_msh;
+                       func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
                        goto common_load;
                        break;
 
index 9fef5302adc127468d821f8335c0ef007e416270..67dac22b4363c07f5add4b0c56c06af0d3225ba9 100644 (file)
@@ -21,6 +21,12 @@ static struct of_device_id __initdata mpc85xx_common_ids[] = {
        { .compatible = "fsl,qe", },
        { .compatible = "fsl,cpm2", },
        { .compatible = "fsl,srio", },
+       /* So that the DMA channel nodes can be probed individually: */
+       { .compatible = "fsl,eloplus-dma", },
+       /* For the PMC driver */
+       { .compatible = "fsl,mpc8548-guts", },
+       /* Probably unnecessary? */
+       { .compatible = "gpio-leds", },
        {},
 };
 
index 9a6f04406e0d63ebee34841a15ebd665a50ad3cd..d208ebccb91cc5f5db92bee1cf47e82e0e0c4b31 100644 (file)
@@ -399,12 +399,6 @@ static int __init board_fixups(void)
 machine_arch_initcall(mpc8568_mds, board_fixups);
 machine_arch_initcall(mpc8569_mds, board_fixups);
 
-static struct of_device_id mpc85xx_ids[] = {
-       { .compatible = "fsl,mpc8548-guts", },
-       { .compatible = "gpio-leds", },
-       {},
-};
-
 static int __init mpc85xx_publish_devices(void)
 {
        if (machine_is(mpc8568_mds))
@@ -412,10 +406,7 @@ static int __init mpc85xx_publish_devices(void)
        if (machine_is(mpc8569_mds))
                simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");
 
-       mpc85xx_common_publish_devices();
-       of_platform_bus_probe(NULL, mpc85xx_ids, NULL);
-
-       return 0;
+       return mpc85xx_common_publish_devices();
 }
 
 machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
index e74b7cde9aee77482f27c739af6dad8cf024d725..f700c81a1321ca2de222b6f1561408e454094204 100644 (file)
@@ -460,18 +460,7 @@ static void __init p1022_ds_setup_arch(void)
        pr_info("Freescale P1022 DS reference board\n");
 }
 
-static struct of_device_id __initdata p1022_ds_ids[] = {
-       /* So that the DMA channel nodes can be probed individually: */
-       { .compatible = "fsl,eloplus-dma", },
-       {},
-};
-
-static int __init p1022_ds_publish_devices(void)
-{
-       mpc85xx_common_publish_devices();
-       return of_platform_bus_probe(NULL, p1022_ds_ids, NULL);
-}
-machine_device_initcall(p1022_ds, p1022_ds_publish_devices);
+machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices);
 
 machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier);
 
index db360fc4cf0e616a9f463c37f197ee04ba4d657d..d09f3e8e68670585230e52d33c28109d9ce6cf8e 100644 (file)
@@ -392,7 +392,7 @@ static int axon_msi_probe(struct platform_device *device)
        }
        memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
-       msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
+       msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic);
        if (!msic->irq_domain) {
                printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
                       dn->full_name);
index e5c3a2c6090d186b5ddeb5941514bda73d165065..f9a48af335cb8d17b52cb1ed34503175d0772fef 100644 (file)
@@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void)
        ppc_md.get_irq = beatic_get_irq;
 
        /* Allocate an irq host */
-       beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
+       beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL);
        BUG_ON(beatic_host == NULL);
        irq_set_default_host(beatic_host);
 }
index 996c5ff7824b7b3342e1bce1ce46d44db06e8491..03685a329d7dadde0c52643ddd85a4ee23211747 100644 (file)
@@ -366,11 +366,20 @@ static void kw_i2c_timeout(unsigned long data)
        unsigned long flags;
 
        spin_lock_irqsave(&host->lock, flags);
+
+       /*
+        * If the timer is pending, that means we raced with the
+        * irq, in which case we just return
+        */
+       if (timer_pending(&host->timeout_timer))
+               goto skip;
+
        kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr));
        if (host->state != state_idle) {
                host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;
                add_timer(&host->timeout_timer);
        }
+ skip:
        spin_unlock_irqrestore(&host->lock, flags);
 }
 
index a81e5a88fbdf1c49c70cba6ef2699b86ed95d7b5..b4ddaa3fbb298eccc37044f61222d38a688c9f8c 100644 (file)
@@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void)
 {
        int rc = -ENOMEM;
 
-       psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
+       psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL);
 
        if (psurge_host)
                psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
index 2a4ff86cc21f72c5c0af0082e4c12c64de5db6cd..5f3b23220b8ee395e0d9e05821a43b98fd8592f1 100644 (file)
@@ -753,9 +753,8 @@ void __init ps3_init_IRQ(void)
        unsigned cpu;
        struct irq_domain *host;
 
-       host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
+       host = irq_domain_add_nomap(NULL, PS3_PLUG_MAX + 1, &ps3_host_ops, NULL);
        irq_set_default_host(host);
-       irq_set_virq_count(PS3_PLUG_MAX + 1);
 
        for_each_possible_cpu(cpu) {
                struct ps3_private *pd = &per_cpu(ps3_private, cpu);
index 309d38ef732209ce68ec99380ef09b97d5bfc41f..a75e37dc41aa7d94dc762c9f9c7afb23acab1841 100644 (file)
@@ -1076,7 +1076,7 @@ static void eeh_add_device_late(struct pci_dev *dev)
        pr_debug("EEH: Adding device %s\n", pci_name(dev));
 
        dn = pci_device_to_OF_node(dev);
-       edev = pci_dev_to_eeh_dev(dev);
+       edev = of_node_to_eeh_dev(dn);
        if (edev->pdev == dev) {
                pr_debug("EEH: Already referenced !\n");
                return;
index 9ac71ebd2c408b47869f5f152ff577e84c958064..395af1347749104aeef3c832fb48dd26e6385ace 100644 (file)
@@ -604,18 +604,14 @@ static struct mpic *mpic_find(unsigned int irq)
 }
 
 /* Determine if the linux irq is an IPI */
-static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq)
+static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src)
 {
-       unsigned int src = virq_to_hw(irq);
-
        return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);
 }
 
 /* Determine if the linux irq is a timer */
-static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq)
+static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src)
 {
-       unsigned int src = virq_to_hw(irq);
-
        return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]);
 }
 
@@ -876,21 +872,45 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
        if (src >= mpic->num_sources)
                return -EINVAL;
 
+       vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
+
+       /* We don't support "none" type */
        if (flow_type == IRQ_TYPE_NONE)
-               if (mpic->senses && src < mpic->senses_count)
-                       flow_type = mpic->senses[src];
-       if (flow_type == IRQ_TYPE_NONE)
-               flow_type = IRQ_TYPE_LEVEL_LOW;
+               flow_type = IRQ_TYPE_DEFAULT;
+
+       /* Default: read HW settings */
+       if (flow_type == IRQ_TYPE_DEFAULT) {
+               switch(vold & (MPIC_INFO(VECPRI_POLARITY_MASK) |
+                              MPIC_INFO(VECPRI_SENSE_MASK))) {
+                       case MPIC_INFO(VECPRI_SENSE_EDGE) |
+                            MPIC_INFO(VECPRI_POLARITY_POSITIVE):
+                               flow_type = IRQ_TYPE_EDGE_RISING;
+                               break;
+                       case MPIC_INFO(VECPRI_SENSE_EDGE) |
+                            MPIC_INFO(VECPRI_POLARITY_NEGATIVE):
+                               flow_type = IRQ_TYPE_EDGE_FALLING;
+                               break;
+                       case MPIC_INFO(VECPRI_SENSE_LEVEL) |
+                            MPIC_INFO(VECPRI_POLARITY_POSITIVE):
+                               flow_type = IRQ_TYPE_LEVEL_HIGH;
+                               break;
+                       case MPIC_INFO(VECPRI_SENSE_LEVEL) |
+                            MPIC_INFO(VECPRI_POLARITY_NEGATIVE):
+                               flow_type = IRQ_TYPE_LEVEL_LOW;
+                               break;
+               }
+       }
 
+       /* Apply to irq desc */
        irqd_set_trigger_type(d, flow_type);
 
+       /* Apply to HW */
        if (mpic_is_ht_interrupt(mpic, src))
                vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
                        MPIC_VECPRI_SENSE_EDGE;
        else
                vecpri = mpic_type_to_vecpri(mpic, flow_type);
 
-       vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
        vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |
                        MPIC_INFO(VECPRI_SENSE_MASK));
        vnew |= vecpri;
@@ -1026,7 +1046,7 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,
        irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);
 
        /* Set default irq type */
-       irq_set_irq_type(virq, IRQ_TYPE_NONE);
+       irq_set_irq_type(virq, IRQ_TYPE_DEFAULT);
 
        /* If the MPIC was reset, then all vectors have already been
         * initialized.  Otherwise, a per source lazy initialization
@@ -1417,12 +1437,6 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
                mpic->num_sources = isu_first + mpic->isu_size;
 }
 
-void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count)
-{
-       mpic->senses = senses;
-       mpic->senses_count = count;
-}
-
 void __init mpic_init(struct mpic *mpic)
 {
        int i, cpu;
@@ -1555,12 +1569,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
                return;
 
        raw_spin_lock_irqsave(&mpic_lock, flags);
-       if (mpic_is_ipi(mpic, irq)) {
+       if (mpic_is_ipi(mpic, src)) {
                reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
                        ~MPIC_VECPRI_PRIORITY_MASK;
                mpic_ipi_write(src - mpic->ipi_vecs[0],
                               reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
-       } else if (mpic_is_tm(mpic, irq)) {
+       } else if (mpic_is_tm(mpic, src)) {
                reg = mpic_tm_read(src - mpic->timer_vecs[0]) &
                        ~MPIC_VECPRI_PRIORITY_MASK;
                mpic_tm_write(src - mpic->timer_vecs[0],
index 6e7fa386e76a75c36de9f38cf376d178ef6ea83f..483d8fa72e8ba3bc6bca736faf2f007399282e13 100644 (file)
@@ -27,6 +27,7 @@
 
 static struct mpic_msgr **mpic_msgrs;
 static unsigned int mpic_msgr_count;
+static DEFINE_RAW_SPINLOCK(msgrs_lock);
 
 static inline void _mpic_msgr_mer_write(struct mpic_msgr *msgr, u32 value)
 {
@@ -56,12 +57,11 @@ struct mpic_msgr *mpic_msgr_get(unsigned int reg_num)
        if (reg_num >= mpic_msgr_count)
                return ERR_PTR(-ENODEV);
 
-       raw_spin_lock_irqsave(&msgr->lock, flags);
-       if (mpic_msgrs[reg_num]->in_use == MSGR_FREE) {
-               msgr = mpic_msgrs[reg_num];
+       raw_spin_lock_irqsave(&msgrs_lock, flags);
+       msgr = mpic_msgrs[reg_num];
+       if (msgr->in_use == MSGR_FREE)
                msgr->in_use = MSGR_INUSE;
-       }
-       raw_spin_unlock_irqrestore(&msgr->lock, flags);
+       raw_spin_unlock_irqrestore(&msgrs_lock, flags);
 
        return msgr;
 }
@@ -228,7 +228,7 @@ static __devinit int mpic_msgr_probe(struct platform_device *dev)
 
                reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i;
                msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE;
-               msgr->mer = msgr->base + MPIC_MSGR_MER_OFFSET;
+               msgr->mer = (u32 *)((u8 *)msgr->base + MPIC_MSGR_MER_OFFSET);
                msgr->in_use = MSGR_FREE;
                msgr->num = i;
                raw_spin_lock_init(&msgr->lock);
index 2b7c0fbe578e3341a8d52e98f9cfced0a82023df..9015060919a0430cd5b8233081f2e12f4c3e2547 100644 (file)
@@ -90,7 +90,6 @@ config S390
        select HAVE_KERNEL_XZ
        select HAVE_ARCH_MUTEX_CPU_RELAX
        select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
-       select HAVE_RCU_TABLE_FREE if SMP
        select ARCH_SAVE_PAGE_KEYS if HIBERNATION
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
index 6cf8e26b313780a4addc668018f3a658880be257..1957a9dd256d655400deca01f69e7530de33869d 100644 (file)
@@ -1,8 +1,12 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
-CONFIG_RCU_TRACE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -14,16 +18,22 @@ CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
 CONFIG_CGROUP_SCHED=y
 CONFIG_RT_GROUP_SCHED=y
 CONFIG_BLK_CGROUP=y
+CONFIG_NAMESPACES=y
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+CONFIG_EXPERT=y
 # CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
 CONFIG_DEFAULT_DEADLINE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -34,18 +44,15 @@ CONFIG_KSM=y
 CONFIG_BINFMT_MISC=m
 CONFIG_CMM=m
 CONFIG_HZ_100=y
-CONFIG_KEXEC=y
-CONFIG_PM=y
+CONFIG_CRASH_DUMP=y
 CONFIG_HIBERNATION=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
-CONFIG_AFIUCV=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_INET_LRO is not set
 CONFIG_IPV6=y
-CONFIG_NET_SCTPPROBE=m
 CONFIG_L2TP=m
 CONFIG_L2TP_DEBUGFS=m
 CONFIG_VLAN_8021Q=y
@@ -84,15 +91,14 @@ CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
 CONFIG_ZFCP=y
-CONFIG_ZFCP_DIF=y
 CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
 CONFIG_BONDING=m
+CONFIG_DUMMY=m
 CONFIG_EQUALIZER=m
 CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
 CONFIG_VIRTIO_NET=y
 CONFIG_RAW_DRIVER=m
+CONFIG_VIRTIO_BALLOON=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@ -103,27 +109,21 @@ CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_IBM_PARTITION=y
-CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_TIMER_STATS=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_PROVE_RCU=y
 CONFIG_LOCK_STAT=y
 CONFIG_DEBUG_LOCKDEP=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_LIST=y
 CONFIG_DEBUG_NOTIFIERS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_TRACE=y
 CONFIG_KPROBES_SANITY_TEST=y
 CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
 CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
 CONFIG_LATENCYTOP=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_DEBUG_PAGEALLOC=y
-# CONFIG_FTRACE is not set
+CONFIG_BLK_DEV_IO_TRACE=y
 # CONFIG_STRICT_DEVMEM is not set
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
@@ -173,4 +173,3 @@ CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_DES_S390=m
 CONFIG_CRYPTO_AES_S390=m
 CONFIG_CRC7=m
-CONFIG_VIRTIO_BALLOON=y
index 1e5b27edc0c92e72e656485539391b579db8086a..2ee66a65f2d4740572791c46b9cf42a9c4e65d51 100644 (file)
@@ -38,12 +38,11 @@ static inline void stfle(u64 *stfle_fac_list, int size)
        unsigned long nr;
 
        preempt_disable();
-       S390_lowcore.stfl_fac_list = 0;
        asm volatile(
                "       .insn s,0xb2b10000,0(0)\n" /* stfl */
                "0:\n"
                EX_TABLE(0b, 0b)
-               : "=m" (S390_lowcore.stfl_fac_list));
+               : "+m" (S390_lowcore.stfl_fac_list));
        nr = 4; /* bytes stored by stfl */
        memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
        if (S390_lowcore.stfl_fac_list & 0x01000000) {
index 8eef9b5b3cf440c35744ed5338240e39f777067a..78e3041919dedd11556ed359c40c1b2d875a197c 100644 (file)
@@ -22,10 +22,7 @@ void crst_table_free(struct mm_struct *, unsigned long *);
 
 unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
 void page_table_free(struct mm_struct *, unsigned long *);
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 void page_table_free_rcu(struct mmu_gather *, unsigned long *);
-void __tlb_remove_table(void *_table);
-#endif
 
 static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
 {
index 6bdee21c077e0755ab0e0bc2084e118bdcb5e83f..a3e4ebb32090dc10ab0692f320c3ae3137f0f7dc 100644 (file)
@@ -77,7 +77,7 @@ static inline __u16 __arch_swab16p(const __u16 *x)
        
        asm volatile(
 #ifndef __s390x__
-               "       icm     %0,2,%O+1(%R1)\n"
+               "       icm     %0,2,%O1+1(%R1)\n"
                "       ic      %0,%1\n"
                : "=&d" (result) : "Q" (*x) : "cc");
 #else /* __s390x__ */
index c687a2c834626adb1f01cc24ae4f62713d83adaa..775a5eea8f9eb9896e9d38e809dc74d51823d99f 100644 (file)
 
 struct mmu_gather {
        struct mm_struct *mm;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        struct mmu_table_batch *batch;
-#endif
        unsigned int fullmm;
-       unsigned int need_flush;
 };
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 struct mmu_table_batch {
        struct rcu_head         rcu;
        unsigned int            nr;
@@ -49,7 +45,6 @@ struct mmu_table_batch {
 
 extern void tlb_table_flush(struct mmu_gather *tlb);
 extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
-#endif
 
 static inline void tlb_gather_mmu(struct mmu_gather *tlb,
                                  struct mm_struct *mm,
@@ -57,29 +52,20 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb,
 {
        tlb->mm = mm;
        tlb->fullmm = full_mm_flush;
-       tlb->need_flush = 0;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        tlb->batch = NULL;
-#endif
        if (tlb->fullmm)
                __tlb_flush_mm(mm);
 }
 
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
-       if (!tlb->need_flush)
-               return;
-       tlb->need_flush = 0;
-       __tlb_flush_mm(tlb->mm);
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        tlb_table_flush(tlb);
-#endif
 }
 
 static inline void tlb_finish_mmu(struct mmu_gather *tlb,
                                  unsigned long start, unsigned long end)
 {
-       tlb_flush_mmu(tlb);
+       tlb_table_flush(tlb);
 }
 
 /*
@@ -105,10 +91,8 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
                                unsigned long address)
 {
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        if (!tlb->fullmm)
                return page_table_free_rcu(tlb, (unsigned long *) pte);
-#endif
        page_table_free(tlb->mm, (unsigned long *) pte);
 }
 
@@ -125,10 +109,8 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
 #ifdef __s390x__
        if (tlb->mm->context.asce_limit <= (1UL << 31))
                return;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        if (!tlb->fullmm)
                return tlb_remove_table(tlb, pmd);
-#endif
        crst_table_free(tlb->mm, (unsigned long *) pmd);
 #endif
 }
@@ -146,10 +128,8 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
 #ifdef __s390x__
        if (tlb->mm->context.asce_limit <= (1UL << 42))
                return;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        if (!tlb->fullmm)
                return tlb_remove_table(tlb, pud);
-#endif
        crst_table_free(tlb->mm, (unsigned long *) pud);
 #endif
 }
index c27a0727f9304cecf518aa310c70c33260fc3245..adccd908ebc773d51c8850897098c04af91b601d 100644 (file)
@@ -474,9 +474,9 @@ ENTRY(startup_kdump)
        stck    __LC_LAST_UPDATE_CLOCK
        spt     5f-.LPG0(%r13)
        mvc     __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
+       xc      __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
 #ifndef CONFIG_MARCH_G5
        # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
-       xc      __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
        .insn   s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list
        tm      __LC_STFL_FAC_LIST,0x01 # stfle available ?
        jz      0f
index 1c2cdd59ccd0504469a1d31a45ba2aaf6442368b..8a22c27219dd0748f380a0aef0d63128b01ec21a 100644 (file)
@@ -118,9 +118,10 @@ asmlinkage void do_softirq(void)
                                         "a" (__do_softirq)
                                     : "0", "1", "2", "3", "4", "5", "14",
                                       "cc", "memory" );
-               } else
+               } else {
                        /* We are already on the async stack. */
                        __do_softirq();
+               }
        }
 
        local_irq_restore(flags);
@@ -192,11 +193,12 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
        int index = ext_hash(code);
 
        spin_lock_irqsave(&ext_int_hash_lock, flags);
-       list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
+       list_for_each_entry_rcu(p, &ext_int_hash[index], entry) {
                if (p->code == code && p->handler == handler) {
                        list_del_rcu(&p->entry);
                        kfree_rcu(p, rcu);
                }
+       }
        spin_unlock_irqrestore(&ext_int_hash_lock, flags);
        return 0;
 }
@@ -211,9 +213,10 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
 
        old_regs = set_irq_regs(regs);
        irq_enter();
-       if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
+       if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) {
                /* Serve timer interrupts first. */
                clock_comparator_work();
+       }
        kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
        if (ext_code.code != 0x1004)
                __get_cpu_var(s390_idle).nohz_delay = 1;
index 46405086479c246f6439151c879ab7430d59e5f2..cb019f429e88ba22745a14bf38c714743c2383ad 100644 (file)
@@ -178,7 +178,7 @@ static void cpumf_pmu_enable(struct pmu *pmu)
        err = lcctl(cpuhw->state);
        if (err) {
                pr_err("Enabling the performance measuring unit "
-                      "failed with rc=%lx\n", err);
+                      "failed with rc=%x\n", err);
                return;
        }
 
@@ -203,7 +203,7 @@ static void cpumf_pmu_disable(struct pmu *pmu)
        err = lcctl(inactive);
        if (err) {
                pr_err("Disabling the performance measuring unit "
-                      "failed with rc=%lx\n", err);
+                      "failed with rc=%x\n", err);
                return;
        }
 
index 7bb15fcca75ea572362d02a6b2626836868be9ed..e1335dc2b1b76fffea016ef83e7d1b229086bf20 100644 (file)
@@ -61,21 +61,14 @@ long probe_kernel_write(void *dst, const void *src, size_t size)
        return copied < 0 ? -EFAULT : 0;
 }
 
-/*
- * Copy memory in real mode (kernel to kernel)
- */
-int memcpy_real(void *dest, void *src, size_t count)
+static int __memcpy_real(void *dest, void *src, size_t count)
 {
        register unsigned long _dest asm("2") = (unsigned long) dest;
        register unsigned long _len1 asm("3") = (unsigned long) count;
        register unsigned long _src  asm("4") = (unsigned long) src;
        register unsigned long _len2 asm("5") = (unsigned long) count;
-       unsigned long flags;
        int rc = -EFAULT;
 
-       if (!count)
-               return 0;
-       flags = __arch_local_irq_stnsm(0xf8UL);
        asm volatile (
                "0:     mvcle   %1,%2,0x0\n"
                "1:     jo      0b\n"
@@ -86,7 +79,23 @@ int memcpy_real(void *dest, void *src, size_t count)
                  "+d" (_len2), "=m" (*((long *) dest))
                : "m" (*((long *) src))
                : "cc", "memory");
-       arch_local_irq_restore(flags);
+       return rc;
+}
+
+/*
+ * Copy memory in real mode (kernel to kernel)
+ */
+int memcpy_real(void *dest, void *src, size_t count)
+{
+       unsigned long flags;
+       int rc;
+
+       if (!count)
+               return 0;
+       local_irq_save(flags);
+       __arch_local_irq_stnsm(0xfbUL);
+       rc = __memcpy_real(dest, src, count);
+       local_irq_restore(flags);
        return rc;
 }
 
index 373adf69b01c48ceebfa2808131326ba5c7188dc..6e765bf00670c2d062632baa317c2b8ef0ea7235 100644 (file)
@@ -678,8 +678,6 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
        }
 }
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-
 static void __page_table_free_rcu(void *table, unsigned bit)
 {
        struct page *page;
@@ -733,7 +731,66 @@ void __tlb_remove_table(void *_table)
                free_pages((unsigned long) table, ALLOC_ORDER);
 }
 
-#endif
+static void tlb_remove_table_smp_sync(void *arg)
+{
+       /* Simply deliver the interrupt */
+}
+
+static void tlb_remove_table_one(void *table)
+{
+       /*
+        * This isn't an RCU grace period and hence the page-tables cannot be
+        * assumed to be actually RCU-freed.
+        *
+        * It is however sufficient for software page-table walkers that rely
+        * on IRQ disabling. See the comment near struct mmu_table_batch.
+        */
+       smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
+       __tlb_remove_table(table);
+}
+
+static void tlb_remove_table_rcu(struct rcu_head *head)
+{
+       struct mmu_table_batch *batch;
+       int i;
+
+       batch = container_of(head, struct mmu_table_batch, rcu);
+
+       for (i = 0; i < batch->nr; i++)
+               __tlb_remove_table(batch->tables[i]);
+
+       free_page((unsigned long)batch);
+}
+
+void tlb_table_flush(struct mmu_gather *tlb)
+{
+       struct mmu_table_batch **batch = &tlb->batch;
+
+       if (*batch) {
+               __tlb_flush_mm(tlb->mm);
+               call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
+               *batch = NULL;
+       }
+}
+
+void tlb_remove_table(struct mmu_gather *tlb, void *table)
+{
+       struct mmu_table_batch **batch = &tlb->batch;
+
+       if (*batch == NULL) {
+               *batch = (struct mmu_table_batch *)
+                       __get_free_page(GFP_NOWAIT | __GFP_NOWARN);
+               if (*batch == NULL) {
+                       __tlb_flush_mm(tlb->mm);
+                       tlb_remove_table_one(table);
+                       return;
+               }
+               (*batch)->nr = 0;
+       }
+       (*batch)->tables[(*batch)->nr++] = table;
+       if ((*batch)->nr == MAX_TABLE_BATCH)
+               tlb_table_flush(tlb);
+}
 
 /*
  * switch on pgstes for its userspace process (for kvm)
index c1d5a820b1aa3f64e72475203515b6a4303c1c0f..5f2bb4242c0f78465cbaea70cbb43d5c7f66d91c 100644 (file)
@@ -61,6 +61,7 @@ config DUMP_CODE
 config DWARF_UNWINDER
        bool "Enable the DWARF unwinder for stacktraces"
        select FRAME_POINTER
+       depends on SUPERH32
        default n
        help
          Enabling this option will make stacktraces more accurate, at
index d879848f3cdd49ac533502064b7025c39cf53ecb..d0d6221d7c2eaef908b4804848c442923c970b21 100644 (file)
@@ -28,6 +28,7 @@
 #include <cpu/sh7785.h>
 #include <asm/heartbeat.h>
 #include <asm/clock.h>
+#include <asm/bl_bit.h>
 
 /*
  * NOTE: This board has 2 physical memory maps.
index adc9b4bba8281fd1875332d2672222a7c2294115..8b50cf763c065010666d9598bed8c1a3f59043f0 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/hd64461.h>
+#include <asm/bl_bit.h>
 #include <mach/hp6xx.h>
 #include <cpu/dac.h>
 #include <asm/freq.h>
index b1cb2715ad6e8de77c9d7ee555c6e078e17834da..67ee956038138b2ca039512a48995085271e36dd 100644 (file)
@@ -54,7 +54,7 @@ static int __init dma_subsys_init(void)
        if (unlikely(ret))
                return ret;
 
-       return device_create_file(dma_subsys.dev_root, &dev_attr_devices.attr);
+       return device_create_file(dma_subsys.dev_root, &dev_attr_devices);
 }
 postcore_initcall(dma_subsys_init);
 
index 7f1b70cace35d74be094e5078df32fe63c7eb680..f8f7af51c12892e6fc513a5a38aa8786789c163b 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/slab.h>
 #include <asm/processor.h>
 #include <asm/fpu.h>
+#include <asm/traps.h>
 
 int init_fpu(struct task_struct *tsk)
 {
index 488d24e0cdf0b1aa59988a17afc7a9edd9a7e898..98bbaa447c93400363b9ed1e5b3739473598bfec 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <asm/fpu.h>
+#include <asm/traps.h>
 
 /* The PR (precision) bit in the FP Status Register must be clear when
  * an frchg instruction is executed, otherwise the instruction is undefined.
index e74cd6c0f10de9c5b94078de2ada8ddd5afa47d9..69ab4d3c8d4149be3bfd90dbb6d97090c12aceed 100644 (file)
@@ -16,6 +16,7 @@
 #include <cpu/fpu.h>
 #include <asm/processor.h>
 #include <asm/fpu.h>
+#include <asm/traps.h>
 
 /* The PR (precision) bit in the FP Status Register must be clear when
  * an frchg instruction is executed, otherwise the instruction is undefined.
index 5853989586ed6a2d4687937d38c80381106eea0e..04ab5aeaf9206527d0eae807a317ecd342a233fd 100644 (file)
@@ -113,7 +113,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
 
        /* MSTP32 clocks */
-       CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]),
+       CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP004]),
        CLKDEV_CON_ID("riic0", &mstp_clks[MSTP000]),
        CLKDEV_CON_ID("riic1", &mstp_clks[MSTP000]),
        CLKDEV_CON_ID("riic2", &mstp_clks[MSTP000]),
index a6f95ae4aae705269db86f8e133f3114d93646a1..08d27fac8d080736110008282b03188d8917cae8 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/suspend.h>
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
+#include <asm/bl_bit.h>
 
 /*
  * Notifier lists for pre/post sleep notification
index 64852ecc6881ecab8646ad6ff59a1e2643941e69..ee226e20c20cf49e874efb87fd11bba4681e73fd 100644 (file)
@@ -17,8 +17,8 @@
 #include <linux/irqflags.h>
 #include <linux/smp.h>
 #include <linux/cpuidle.h>
-#include <asm/pgalloc.h>
 #include <linux/atomic.h>
+#include <asm/pgalloc.h>
 #include <asm/smp.h>
 #include <asm/bl_bit.h>
 
index efb6d398dec3b9f2a1beacc8c279b8bfd1c5c6d6..b117781bfea2914efef3579cbe696cd29f399f00 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <asm/cacheflush.h>
+#include <asm/traps.h>
 
 /* Macros for single step instruction identification */
 #define OPCODE_BT(op)          (((op) & 0xff00) == 0x8900)
index f72e3a951588297fe59ed0f310574f75cd2be17b..94273aaf78c1605da62d82ea61dc14a746ec5dff 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/mmu_context.h>
 #include <asm/fpu.h>
 #include <asm/syscalls.h>
+#include <asm/switch_to.h>
 
 void show_regs(struct pt_regs * regs)
 {
index a17a14d32340fb1c537955b3b1266d20cfe3576d..eaebdf6a5c77506f5b80bb2af9f9693d17894838 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/smp.h>
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
+#include <asm/setup.h>
 
 int __cpu_number_map[NR_CPUS];         /* Map physical to logical */
 int __cpu_logical_map[NR_CPUS];                /* Map logical to physical */
index 555a64f124ca0cf9200e10c615662bb492c54db2..23af17584054e4601ae6277046eafd1145841a99 100644 (file)
@@ -34,6 +34,41 @@ __kernel_rt_sigreturn:
 1:     .short  __NR_rt_sigreturn
 .LEND_rt_sigreturn:
        .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
+       .previous
 
        .section .eh_frame,"a",@progbits
+.LCIE1:
+       .ualong .LCIE1_end - .LCIE1_start
+.LCIE1_start:
+       .ualong 0               /* CIE ID */
+       .byte   0x1             /* Version number */
+       .string "zRS"           /* NUL-terminated augmentation string */
+       .uleb128 0x1            /* Code alignment factor */
+       .sleb128 -4             /* Data alignment factor */
+       .byte   0x11            /* Return address register column */
+       .uleb128 0x1            /* Augmentation length and data */
+       .byte 0x1b              /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */
+       .byte   0xc, 0xf, 0x0   /* DW_CFA_def_cfa: r15 ofs 0 */
+
+       .align 2
+.LCIE1_end:
+
+       .ualong .LFDE0_end-.LFDE0_start /* Length FDE0 */
+.LFDE0_start:
+       .ualong .LFDE0_start-.LCIE1     /* CIE pointer */
+       .ualong .LSTART_sigreturn-.     /* PC-relative start address */
+       .ualong .LEND_sigreturn-.LSTART_sigreturn
+       .uleb128 0                      /* Augmentation */
+       .align 2
+.LFDE0_end:
+
+       .ualong .LFDE1_end-.LFDE1_start /* Length FDE1 */
+.LFDE1_start:
+       .ualong .LFDE1_start-.LCIE1     /* CIE pointer */
+       .ualong .LSTART_rt_sigreturn-.  /* PC-relative start address */
+       .ualong .LEND_rt_sigreturn-.LSTART_rt_sigreturn
+       .uleb128 0                      /* Augmentation */
+       .align 2
+.LFDE1_end:
+
        .previous
index 3e70f851cdc6c1b674af7dec81bb8f19e290d4ad..0eb74d00690a18d4c725fb95c9bd697c7a04e7f6 100644 (file)
@@ -3,37 +3,34 @@
        .type __kernel_vsyscall,@function
 __kernel_vsyscall:
 .LSTART_vsyscall:
-       /* XXX: We'll have to do something here once we opt to use the vDSO
-        * page for something other than the signal trampoline.. as well as
-        * fill out .eh_frame -- PFM. */
+       trapa   #0x10
+        nop
 .LEND_vsyscall:
        .size __kernel_vsyscall,.-.LSTART_vsyscall
+       .previous
 
        .section .eh_frame,"a",@progbits
-       .previous
 .LCIE:
        .ualong .LCIE_end - .LCIE_start
 .LCIE_start:
        .ualong 0               /* CIE ID */
        .byte   0x1             /* Version number */
-       .string "zRS"           /* NUL-terminated augmentation string */
+       .string "zR           /* NUL-terminated augmentation string */
        .uleb128 0x1            /* Code alignment factor */
        .sleb128 -4             /* Data alignment factor */
        .byte   0x11            /* Return address register column */
-                               /* Augmentation length and data (none) */
-       .byte   0xc             /* DW_CFA_def_cfa */
-       .uleb128 0xf            /* r15 */
-       .uleb128 0x0            /* offset 0 */
-
+       .uleb128 0x1            /* Augmentation length and data */
+       .byte 0x1b              /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */
+       .byte   0xc,0xf,0x0     /* DW_CFA_def_cfa: r15 ofs 0 */
        .align 2
 .LCIE_end:
 
        .ualong .LFDE_end-.LFDE_start   /* Length FDE */
 .LFDE_start:
-       .ualong .LCIE                   /* CIE pointer */
-       .ualong .LSTART_vsyscall-.      /* start address */
+       .ualong .LFDE_start-.LCIE       /* CIE pointer */
+       .ualong .LSTART_vsyscall-.      /* PC-relative start address */
        .ualong .LEND_vsyscall-.LSTART_vsyscall
-       .uleb128 0
+       .uleb128 0                      /* Augmentation */
        .align 2
 .LFDE_end:
        .previous
index 112fea12522afab24166a879bc496e5fbda8e893..0e529285b28d42c688fb0901349ba70218385d51 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/highmem.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
+#include <asm/cache_insns.h>
 #include <asm/cacheflush.h>
 
 /*
index 75a17f5bfa1478f906d1b4c9dbcffc5b82b7badf..0b85dd9dd3a7df0ae97e37da5228328bf0c4a5ac 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/mm.h>
 #include <asm/mmu_context.h>
+#include <asm/cache_insns.h>
 #include <asm/cacheflush.h>
 #include <asm/traps.h>
 
index bc156ec4545e07941bce9f5a1cb4fcafd35b449d..2d8fa718d55e7416eeffc12e932717953c951d2e 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/errno.h>
 #include <asm/sram.h>
 
 /*
index fea13c7b1aeeddcf206217c935a1b044ae96e215..b93c2c9ccb1d17c250d4a945e0fea06fff38baf6 100644 (file)
@@ -1264,4 +1264,4 @@ static int __init ds_init(void)
        return vio_register_driver(&ds_driver);
 }
 
-subsys_initcall(ds_init);
+fs_initcall(ds_init);
index aba6b958b2a5da25a49adbe76783eca1e5570dc9..19f56058742be945d1a29be0137a683523aa49cd 100644 (file)
@@ -45,7 +45,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
 
 void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
 {
-       struct leon_pci_info *info = pbus->sysdata;
        struct pci_dev *dev;
        int i, has_io, has_mem;
        u16 cmd;
@@ -111,18 +110,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
        return pci_enable_resources(dev, mask);
 }
 
-struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
-{
-       /*
-        * Currently the OpenBoot nodes are not connected with the PCI device,
-        * this is because the LEON PROM does not create PCI nodes. Eventually
-        * this will change and the same approach as pcic.c can be used to
-        * match PROM nodes with pci devices.
-        */
-       return NULL;
-}
-EXPORT_SYMBOL(pci_device_to_OF_node);
-
 void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
 {
 #ifdef CONFIG_PCI_DEBUG
index 1210fde187406c2a5c149151ab46205c00c3358d..160cac9c403654043269e0a63123ecf3ee3bd0a6 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pm.h>
 #include <linux/delay.h>
 #include <linux/gfp.h>
+#include <linux/cpu.h>
 
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
@@ -78,6 +79,8 @@ void __cpuinit leon_callin(void)
        local_flush_tlb_all();
        leon_configure_cache_smp();
 
+       notify_cpu_starting(cpuid);
+
        /* Get our local ticker going. */
        smp_setup_percpu_timer();
 
index 77f1b95e0806bb92dc19fd421acd6f159e7dfab0..9171fc238def230e6e14e92852f2ee2d9b33a8f2 100644 (file)
 
                .text
                .align                  32
-__handle_softirq:
-               call                    do_softirq
-                nop
-               ba,a,pt                 %xcc, __handle_softirq_continue
-                nop
 __handle_preemption:
                call                    schedule
                 wrpr                   %g0, RTRAP_PSTATE, %pstate
@@ -89,9 +84,7 @@ rtrap:
                cmp                     %l1, 0
 
                /* mm/ultra.S:xcall_report_regs KNOWS about this load. */
-               bne,pn                  %icc, __handle_softirq
                 ldx                    [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
-__handle_softirq_continue:
 rtrap_xcall:
                sethi                   %hi(0xf << 20), %l4
                and                     %l1, %l4, %l4
index 232df9949530f3d95c3c95385a62d45402c6d042..3ee51f189a55297b0babeb1f54d0b40af97de6f8 100644 (file)
@@ -566,15 +566,10 @@ out:
 
 SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len)
 {
-       long ret;
-
        if (invalid_64bit_range(addr, len))
                return -EINVAL;
 
-       down_write(&current->mm->mmap_sem);
-       ret = do_munmap(current->mm, addr, len);
-       up_write(&current->mm->mmap_sem);
-       return ret;
+       return vm_munmap(addr, len);
 }
 
 extern unsigned long do_mremap(unsigned long addr,
index 7705c6731e2843697286e3d045279811d5691ed1..df3155a179918e0ad5e9741eceab601ae93d8abb 100644 (file)
@@ -225,6 +225,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
        unsigned long g2;
        int from_user = !(regs->psr & PSR_PS);
        int fault, code;
+       unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+                             (write ? FAULT_FLAG_WRITE : 0));
 
        if(text_fault)
                address = regs->pc;
@@ -251,6 +253,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
 
        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 
+retry:
        down_read(&mm->mmap_sem);
 
        /*
@@ -289,7 +292,11 @@ good_area:
         * make sure we exit gracefully rather than endlessly redo
         * the fault.
         */
-       fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
+       fault = handle_mm_fault(mm, vma, address, flags);
+
+       if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+               return;
+
        if (unlikely(fault & VM_FAULT_ERROR)) {
                if (fault & VM_FAULT_OOM)
                        goto out_of_memory;
@@ -297,13 +304,29 @@ good_area:
                        goto do_sigbus;
                BUG();
        }
-       if (fault & VM_FAULT_MAJOR) {
-               current->maj_flt++;
-               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
-       } else {
-               current->min_flt++;
-               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
+
+       if (flags & FAULT_FLAG_ALLOW_RETRY) {
+               if (fault & VM_FAULT_MAJOR) {
+                       current->maj_flt++;
+                       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
+                                     1, regs, address);
+               } else {
+                       current->min_flt++;
+                       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+                                     1, regs, address);
+               }
+               if (fault & VM_FAULT_RETRY) {
+                       flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+                       /* No need to up_read(&mm->mmap_sem) as we would
+                        * have already released it in __lock_page_or_retry
+                        * in mm/filemap.c.
+                        */
+
+                       goto retry;
+               }
        }
+
        up_read(&mm->mmap_sem);
        return;
 
index 504c0622f7296c42bb09cae18bc487630e6344a4..1fe0429b6314257faa40d80b07f7d4e3b77538c6 100644 (file)
@@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
        unsigned int insn = 0;
        int si_code, fault_code, fault;
        unsigned long address, mm_rss;
+       unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
        fault_code = get_thread_fault_code();
 
@@ -333,6 +334,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
                        insn = get_fault_insn(regs, insn);
                        goto handle_kernel_fault;
                }
+
+retry:
                down_read(&mm->mmap_sem);
        }
 
@@ -423,7 +426,12 @@ good_area:
                        goto bad_area;
        }
 
-       fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
+       flags |= ((fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
+       fault = handle_mm_fault(mm, vma, address, flags);
+
+       if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+               return;
+
        if (unlikely(fault & VM_FAULT_ERROR)) {
                if (fault & VM_FAULT_OOM)
                        goto out_of_memory;
@@ -431,12 +439,27 @@ good_area:
                        goto do_sigbus;
                BUG();
        }
-       if (fault & VM_FAULT_MAJOR) {
-               current->maj_flt++;
-               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
-       } else {
-               current->min_flt++;
-               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
+
+       if (flags & FAULT_FLAG_ALLOW_RETRY) {
+               if (fault & VM_FAULT_MAJOR) {
+                       current->maj_flt++;
+                       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
+                                     1, regs, address);
+               } else {
+                       current->min_flt++;
+                       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+                                     1, regs, address);
+               }
+               if (fault & VM_FAULT_RETRY) {
+                       flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+                       /* No need to up_read(&mm->mmap_sem) as we would
+                        * have already released it in __lock_page_or_retry
+                        * in mm/filemap.c.
+                        */
+
+                       goto retry;
+               }
        }
        up_read(&mm->mmap_sem);
 
index 11270ca22c0a7b880718cd832a3e890f0b69c28f..96033e2d6845cc84a442541fb73f095f8d272f91 100644 (file)
@@ -12,7 +12,7 @@ config TILE
        select GENERIC_PENDING_IRQ if SMP
        select GENERIC_IRQ_SHOW
        select SYS_HYPERVISOR
-       select ARCH_HAVE_NMI_SAFE_CMPXCHG if !M386
+       select ARCH_HAVE_NMI_SAFE_CMPXCHG
 
 # FIXME: investigate whether we need/want these options.
 #      select HAVE_IOREMAP_PROT
@@ -69,6 +69,9 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
        def_bool y
 
+config NEED_DMA_MAP_STATE
+       def_bool y
+
 config LOCKDEP_SUPPORT
        def_bool y
 
@@ -118,7 +121,7 @@ config 64BIT
 
 config ARCH_DEFCONFIG
        string
-       default "arch/tile/configs/tile_defconfig" if !TILEGX
+       default "arch/tile/configs/tilepro_defconfig" if !TILEGX
        default "arch/tile/configs/tilegx_defconfig" if TILEGX
 
 source "init/Kconfig"
@@ -240,6 +243,7 @@ endchoice
 
 config PAGE_OFFSET
        hex
+       depends on !64BIT
        default 0xF0000000 if VMSPLIT_3_75G
        default 0xE0000000 if VMSPLIT_3_5G
        default 0xB0000000 if VMSPLIT_2_75G
index 17acce70569b01aaf7de554a66c0f7e6e8a47157..9520bc5a4b7f65f9904882185267d797885ab7f5 100644 (file)
@@ -30,7 +30,8 @@ ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"")
 KBUILD_CFLAGS   += $(CONFIG_DEBUG_EXTRA_FLAGS)
 endif
 
-LIBGCC_PATH     := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
+LIBGCC_PATH     := \
+  $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name)
 
 # Provide the path to use for "make defconfig".
 KBUILD_DEFCONFIG := $(ARCH)_defconfig
@@ -53,8 +54,6 @@ libs-y                += $(LIBGCC_PATH)
 # See arch/tile/Kbuild for content of core part of the kernel
 core-y         += arch/tile/
 
-core-$(CONFIG_KVM) += arch/tile/kvm/
-
 ifdef TILERA_ROOT
 INSTALL_PATH ?= $(TILERA_ROOT)/tile/boot
 endif
index f548efeb2de3f7fc005f90854a80d1b4941e3a98..d6ba449b5363f3318d094ece0f1bf455853da755 100644 (file)
@@ -60,8 +60,8 @@
        _concat4(SPR_IPI_EVENT_, CONFIG_KERNEL_PL,,)
 #define SPR_IPI_EVENT_RESET_K \
        _concat4(SPR_IPI_EVENT_RESET_, CONFIG_KERNEL_PL,,)
-#define SPR_IPI_MASK_SET_K \
-       _concat4(SPR_IPI_MASK_SET_, CONFIG_KERNEL_PL,,)
+#define SPR_IPI_EVENT_SET_K \
+       _concat4(SPR_IPI_EVENT_SET_, CONFIG_KERNEL_PL,,)
 #define INT_IPI_K \
        _concat4(INT_IPI_, CONFIG_KERNEL_PL,,)
 
index bb696da5d7cdbdbd4b20d98dedc9d12d53ced994..f2461429a4a4004b474e5024447b4a11200d4fa3 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef _ASM_TILE_ATOMIC_H
 #define _ASM_TILE_ATOMIC_H
 
+#include <asm/cmpxchg.h>
+
 #ifndef __ASSEMBLY__
 
 #include <linux/compiler.h>
@@ -121,54 +123,6 @@ static inline int atomic_read(const atomic_t *v)
  */
 #define atomic_add_negative(i, v)      (atomic_add_return((i), (v)) < 0)
 
-/* Nonexistent functions intended to cause link errors. */
-extern unsigned long __xchg_called_with_bad_pointer(void);
-extern unsigned long __cmpxchg_called_with_bad_pointer(void);
-
-#define xchg(ptr, x)                                                   \
-       ({                                                              \
-               typeof(*(ptr)) __x;                                     \
-               switch (sizeof(*(ptr))) {                               \
-               case 4:                                                 \
-                       __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \
-                               (atomic_t *)(ptr),                      \
-                               (u32)(typeof((x)-(x)))(x));             \
-                       break;                                          \
-               case 8:                                                 \
-                       __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \
-                               (atomic64_t *)(ptr),                    \
-                               (u64)(typeof((x)-(x)))(x));             \
-                       break;                                          \
-               default:                                                \
-                       __xchg_called_with_bad_pointer();               \
-               }                                                       \
-               __x;                                                    \
-       })
-
-#define cmpxchg(ptr, o, n)                                             \
-       ({                                                              \
-               typeof(*(ptr)) __x;                                     \
-               switch (sizeof(*(ptr))) {                               \
-               case 4:                                                 \
-                       __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \
-                               (atomic_t *)(ptr),                      \
-                               (u32)(typeof((o)-(o)))(o),              \
-                               (u32)(typeof((n)-(n)))(n));             \
-                       break;                                          \
-               case 8:                                                 \
-                       __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \
-                               (atomic64_t *)(ptr),                    \
-                               (u64)(typeof((o)-(o)))(o),              \
-                               (u64)(typeof((n)-(n)))(n));             \
-                       break;                                          \
-               default:                                                \
-                       __cmpxchg_called_with_bad_pointer();            \
-               }                                                       \
-               __x;                                                    \
-       })
-
-#define tas(ptr) (xchg((ptr), 1))
-
 #endif /* __ASSEMBLY__ */
 
 #ifndef __tilegx__
index 466dc4a39a4faf004d7d7dcabd683d6d41044f40..54d1da826f93dfbf167aaa3c219f143783d91902 100644 (file)
@@ -200,7 +200,7 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
  * @u: ...unless v is equal to u.
  *
  * Atomically adds @a to @v, so long as @v was not already @u.
- * Returns the old value of @v.
+ * Returns non-zero if @v was not @u, and zero otherwise.
  */
 static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
 {
index 58d021a9834f0b12d2b8bc2f091d32a22ca17baf..60b87ee54fb8863eb2387467b76d95117405fb6c 100644 (file)
@@ -38,10 +38,10 @@ static inline void clear_bit(unsigned nr, volatile unsigned long *addr)
 
 static inline void change_bit(unsigned nr, volatile unsigned long *addr)
 {
-       unsigned long old, mask = (1UL << (nr % BITS_PER_LONG));
-       long guess, oldval;
+       unsigned long mask = (1UL << (nr % BITS_PER_LONG));
+       unsigned long guess, oldval;
        addr += nr / BITS_PER_LONG;
-       old = *addr;
+       oldval = *addr;
        do {
                guess = oldval;
                oldval = atomic64_cmpxchg((atomic64_t *)addr,
@@ -85,7 +85,7 @@ static inline int test_and_change_bit(unsigned nr,
                                      volatile unsigned long *addr)
 {
        unsigned long mask = (1UL << (nr % BITS_PER_LONG));
-       long guess, oldval = *addr;
+       unsigned long guess, oldval;
        addr += nr / BITS_PER_LONG;
        oldval = *addr;
        do {
diff --git a/arch/tile/include/asm/cmpxchg.h b/arch/tile/include/asm/cmpxchg.h
new file mode 100644 (file)
index 0000000..276f067
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * cmpxchg.h -- forked from asm/atomic.h with this copyright:
+ *
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   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, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ */
+
+#ifndef _ASM_TILE_CMPXCHG_H
+#define _ASM_TILE_CMPXCHG_H
+
+#ifndef __ASSEMBLY__
+
+/* Nonexistent functions intended to cause link errors. */
+extern unsigned long __xchg_called_with_bad_pointer(void);
+extern unsigned long __cmpxchg_called_with_bad_pointer(void);
+
+#define xchg(ptr, x)                                                   \
+       ({                                                              \
+               typeof(*(ptr)) __x;                                     \
+               switch (sizeof(*(ptr))) {                               \
+               case 4:                                                 \
+                       __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \
+                               (atomic_t *)(ptr),                      \
+                               (u32)(typeof((x)-(x)))(x));             \
+                       break;                                          \
+               case 8:                                                 \
+                       __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \
+                               (atomic64_t *)(ptr),                    \
+                               (u64)(typeof((x)-(x)))(x));             \
+                       break;                                          \
+               default:                                                \
+                       __xchg_called_with_bad_pointer();               \
+               }                                                       \
+               __x;                                                    \
+       })
+
+#define cmpxchg(ptr, o, n)                                             \
+       ({                                                              \
+               typeof(*(ptr)) __x;                                     \
+               switch (sizeof(*(ptr))) {                               \
+               case 4:                                                 \
+                       __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \
+                               (atomic_t *)(ptr),                      \
+                               (u32)(typeof((o)-(o)))(o),              \
+                               (u32)(typeof((n)-(n)))(n));             \
+                       break;                                          \
+               case 8:                                                 \
+                       __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \
+                               (atomic64_t *)(ptr),                    \
+                               (u64)(typeof((o)-(o)))(o),              \
+                               (u64)(typeof((n)-(n)))(n));             \
+                       break;                                          \
+               default:                                                \
+                       __cmpxchg_called_with_bad_pointer();            \
+               }                                                       \
+               __x;                                                    \
+       })
+
+#define tas(ptr) (xchg((ptr), 1))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_TILE_CMPXCHG_H */
index f80f8ceabc67abd6ef57fce76cb1a224f53204c8..33cff9a3058b02ebb2104ab04bcc85741ec83e0d 100644 (file)
@@ -21,7 +21,7 @@
 #define NR_IRQS 32
 
 /* IRQ numbers used for linux IPIs. */
-#define IRQ_RESCHEDULE 1
+#define IRQ_RESCHEDULE 0
 
 #define irq_canonicalize(irq)   (irq)
 
index 72be5904e020e7df9b4923edb92bf25fbf8670a5..5f8b6a095fd84a0748ea645c96a4b3908ba6d6fb 100644 (file)
@@ -137,7 +137,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
        __insn_mf();
-       rw->lock = 0;
+       __insn_exch4(&rw->lock, 0);  /* Avoid waiting in the write buffer. */
 }
 
 static inline int arch_read_trylock(arch_rwlock_t *rw)
index 4d97a2db932e90784d37eb4f53ff7da3f80eb4e2..0e9d382a2d451482ff2d5f686cdecaa8b7f56a05 100644 (file)
@@ -25,7 +25,6 @@
 struct KBacktraceIterator {
        BacktraceIterator it;
        struct task_struct *task;     /* task we are backtracing */
-       pte_t *pgtable;               /* page table for user space access */
        int end;                      /* iteration complete. */
        int new_context;              /* new context is starting */
        int profile;                  /* profiling, so stop on async intrpt */
index 5f20f920f932b6c38e0a8971d1cedfb012dd729c..e28c3df4176a918c09fc56dfa702c17e0f48e401 100644 (file)
@@ -64,7 +64,11 @@ void do_breakpoint(struct pt_regs *, int fault_num);
 
 
 #ifdef __tilegx__
+/* kernel/single_step.c */
 void gx_singlestep_handle(struct pt_regs *, int fault_num);
+
+/* kernel/intvec_64.S */
+void fill_ra_stack(void);
 #endif
 
-#endif /* _ASM_TILE_SYSCALLS_H */
+#endif /* _ASM_TILE_TRAPS_H */
index 431e9ae60488c73f29c35761170150e7f65a7a92..ec91568df880ef0d41f99f7ab86cc0fdb2330551 100644 (file)
@@ -85,6 +85,7 @@ STD_ENTRY(cpu_idle_on_new_stack)
 /* Loop forever on a nap during SMP boot. */
 STD_ENTRY(smp_nap)
        nap
+       nop       /* avoid provoking the icache prefetch with a jump */
        j smp_nap /* we are not architecturally guaranteed not to exit nap */
        jrp lr    /* clue in the backtracer */
        STD_ENDPROC(smp_nap)
@@ -105,5 +106,6 @@ STD_ENTRY(_cpu_idle)
        .global _cpu_idle_nap
 _cpu_idle_nap:
        nap
+       nop       /* avoid provoking the icache prefetch with a jump */
        jrp lr
        STD_ENDPROC(_cpu_idle)
index aecc8ed5f39bd71d48cb150fe30301425b2179b7..5d56a1ef5ba5212e6cffe97e0fe14223bc0d116b 100644 (file)
@@ -799,6 +799,10 @@ handle_interrupt:
  * This routine takes a boolean in r30 indicating if this is an NMI.
  * If so, we also expect a boolean in r31 indicating whether to
  * re-enable the oprofile interrupts.
+ *
+ * Note that .Lresume_userspace is jumped to directly in several
+ * places, and we need to make sure r30 is set correctly in those
+ * callers as well.
  */
 STD_ENTRY(interrupt_return)
        /* If we're resuming to kernel space, don't check thread flags. */
@@ -1237,7 +1241,10 @@ handle_syscall:
        bzt     r30, 1f
        jal     do_syscall_trace
        FEEDBACK_REENTER(handle_syscall)
-1:     j       .Lresume_userspace   /* jump into middle of interrupt_return */
+1:     {
+        movei  r30, 0               /* not an NMI */
+        j      .Lresume_userspace   /* jump into middle of interrupt_return */
+       }
 
 .Linvalid_syscall:
        /* Report an invalid syscall back to the user program */
@@ -1246,7 +1253,10 @@ handle_syscall:
         movei  r28, -ENOSYS
        }
        sw      r29, r28
-       j       .Lresume_userspace   /* jump into middle of interrupt_return */
+       {
+        movei  r30, 0               /* not an NMI */
+        j      .Lresume_userspace   /* jump into middle of interrupt_return */
+       }
        STD_ENDPROC(handle_syscall)
 
        /* Return the address for oprofile to suppress in backtraces. */
@@ -1262,7 +1272,10 @@ STD_ENTRY(ret_from_fork)
        jal     sim_notify_fork
        jal     schedule_tail
        FEEDBACK_REENTER(ret_from_fork)
-       j       .Lresume_userspace   /* jump into middle of interrupt_return */
+       {
+        movei  r30, 0               /* not an NMI */
+        j      .Lresume_userspace   /* jump into middle of interrupt_return */
+       }
        STD_ENDPROC(ret_from_fork)
 
        /*
@@ -1376,7 +1389,10 @@ handle_ill:
 
        jal     send_sigtrap    /* issue a SIGTRAP */
        FEEDBACK_REENTER(handle_ill)
-       j       .Lresume_userspace   /* jump into middle of interrupt_return */
+       {
+        movei  r30, 0               /* not an NMI */
+        j      .Lresume_userspace   /* jump into middle of interrupt_return */
+       }
 
 .Ldispatch_normal_ill:
        {
index 79c93e10ba27b1a11c939e216233ec5956b6b11a..49d9d66216822a463a4e905f3425e8eb2a4f77e8 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/irqflags.h>
 #include <asm/asm-offsets.h>
 #include <asm/types.h>
+#include <asm/signal.h>
 #include <hv/hypervisor.h>
 #include <arch/abi.h>
 #include <arch/interrupts.h>
@@ -605,6 +606,10 @@ handle_interrupt:
  * This routine takes a boolean in r30 indicating if this is an NMI.
  * If so, we also expect a boolean in r31 indicating whether to
  * re-enable the oprofile interrupts.
+ *
+ * Note that .Lresume_userspace is jumped to directly in several
+ * places, and we need to make sure r30 is set correctly in those
+ * callers as well.
  */
 STD_ENTRY(interrupt_return)
        /* If we're resuming to kernel space, don't check thread flags. */
@@ -1039,11 +1044,28 @@ handle_syscall:
 
        /* Do syscall trace again, if requested. */
        ld      r30, r31
-       andi    r30, r30, _TIF_SYSCALL_TRACE
-       beqzt   r30, 1f
+       andi    r0, r30, _TIF_SYSCALL_TRACE
+       {
+        andi    r0, r30, _TIF_SINGLESTEP
+        beqzt   r0, 1f
+       }
        jal     do_syscall_trace
        FEEDBACK_REENTER(handle_syscall)
-1:     j       .Lresume_userspace   /* jump into middle of interrupt_return */
+       andi    r0, r30, _TIF_SINGLESTEP
+
+1:     beqzt   r0, 2f
+
+       /* Single stepping -- notify ptrace. */
+       {
+        movei   r0, SIGTRAP
+        jal     ptrace_notify
+       }
+       FEEDBACK_REENTER(handle_syscall)
+
+2:     {
+        movei  r30, 0               /* not an NMI */
+        j      .Lresume_userspace   /* jump into middle of interrupt_return */
+       }
 
 .Lcompat_syscall:
        /*
@@ -1077,7 +1099,10 @@ handle_syscall:
         movei  r28, -ENOSYS
        }
        st      r29, r28
-       j       .Lresume_userspace   /* jump into middle of interrupt_return */
+       {
+        movei  r30, 0               /* not an NMI */
+        j      .Lresume_userspace   /* jump into middle of interrupt_return */
+       }
        STD_ENDPROC(handle_syscall)
 
        /* Return the address for oprofile to suppress in backtraces. */
@@ -1093,7 +1118,10 @@ STD_ENTRY(ret_from_fork)
        jal     sim_notify_fork
        jal     schedule_tail
        FEEDBACK_REENTER(ret_from_fork)
-       j       .Lresume_userspace
+       {
+        movei  r30, 0               /* not an NMI */
+        j      .Lresume_userspace   /* jump into middle of interrupt_return */
+       }
        STD_ENDPROC(ret_from_fork)
 
 /* Various stub interrupt handlers and syscall handlers */
@@ -1156,6 +1184,18 @@ int_unalign:
        push_extra_callee_saves r0
        j       do_trap
 
+/* Fill the return address stack with nonzero entries. */
+STD_ENTRY(fill_ra_stack)
+       {
+        move   r0, lr
+        jal    1f
+       }
+1:     jal     2f
+2:     jal     3f
+3:     jal     4f
+4:     jrp     r0
+       STD_ENDPROC(fill_ra_stack)
+
 /* Include .intrpt1 array of interrupt vectors */
        .section ".intrpt1", "ax"
 
@@ -1166,7 +1206,7 @@ int_unalign:
 #define do_hardwall_trap bad_intr
 #endif
 
-       int_hand     INT_MEM_ERROR, MEM_ERROR, bad_intr
+       int_hand     INT_MEM_ERROR, MEM_ERROR, do_trap
        int_hand     INT_SINGLE_STEP_3, SINGLE_STEP_3, bad_intr
 #if CONFIG_KERNEL_PL == 2
        int_hand     INT_SINGLE_STEP_2, SINGLE_STEP_2, gx_singlestep_handle
index b90ab9925674339f1389abd511fc56d7c6881330..98d476920106084d847b54fd9bf9cc19c9e21983 100644 (file)
@@ -67,6 +67,8 @@ void *module_alloc(unsigned long size)
        area = __get_vm_area(size, VM_ALLOC, MEM_MODULE_START, MEM_MODULE_END);
        if (!area)
                goto error;
+       area->nr_pages = npages;
+       area->pages = pages;
 
        if (map_vm_area(area, prot_rwx, &pages)) {
                vunmap(area->addr);
index 7a93270464045753c76caa4032716ea6981c082c..446a7f52cc11f3a6380b7e6cfbf2181abca046a0 100644 (file)
@@ -146,7 +146,6 @@ static ctl_table unaligned_table[] = {
        },
        {}
 };
-#endif
 
 static struct ctl_path tile_path[] = {
        { .procname = "tile" },
@@ -155,10 +154,9 @@ static struct ctl_path tile_path[] = {
 
 static int __init proc_sys_tile_init(void)
 {
-#ifndef __tilegx__  /* FIXME: GX: no support for unaligned access yet */
        register_sysctl_paths(tile_path, unaligned_table);
-#endif
        return 0;
 }
 
 arch_initcall(proc_sys_tile_init);
+#endif
index 30caecac94dcae955928900c4d6841c154263810..2d5ef617bb3906cfcf1f9846af10b9d87e8d53e0 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/tracehook.h>
 #include <linux/signal.h>
 #include <asm/stack.h>
+#include <asm/switch_to.h>
 #include <asm/homecache.h>
 #include <asm/syscalls.h>
 #include <asm/traps.h>
@@ -285,7 +286,7 @@ struct task_struct *validate_current(void)
        static struct task_struct corrupt = { .comm = "<corrupt>" };
        struct task_struct *tsk = current;
        if (unlikely((unsigned long)tsk < PAGE_OFFSET ||
-                    (void *)tsk > high_memory ||
+                    (high_memory && (void *)tsk > high_memory) ||
                     ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) {
                pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer);
                tsk = &corrupt;
index 92a94f4920ad6e2e5422ec7775f1891d70ed9d04..bff23f4761103713ee00be2294a726fac6eeb06c 100644 (file)
@@ -103,13 +103,11 @@ unsigned long __initdata pci_reserve_end_pfn = -1U;
 
 static int __init setup_maxmem(char *str)
 {
-       long maxmem_mb;
-       if (str == NULL || strict_strtol(str, 0, &maxmem_mb) != 0 ||
-           maxmem_mb == 0)
+       unsigned long long maxmem;
+       if (str == NULL || (maxmem = memparse(str, NULL)) == 0)
                return -EINVAL;
 
-       maxmem_pfn = (maxmem_mb >> (HPAGE_SHIFT - 20)) <<
-               (HPAGE_SHIFT - PAGE_SHIFT);
+       maxmem_pfn = (maxmem >> HPAGE_SHIFT) << (HPAGE_SHIFT - PAGE_SHIFT);
        pr_info("Forcing RAM used to no more than %dMB\n",
               maxmem_pfn >> (20 - PAGE_SHIFT));
        return 0;
@@ -119,14 +117,15 @@ early_param("maxmem", setup_maxmem);
 static int __init setup_maxnodemem(char *str)
 {
        char *endp;
-       long maxnodemem_mb, node;
+       unsigned long long maxnodemem;
+       long node;
 
        node = str ? simple_strtoul(str, &endp, 0) : INT_MAX;
-       if (node >= MAX_NUMNODES || *endp != ':' ||
-           strict_strtol(endp+1, 0, &maxnodemem_mb) != 0)
+       if (node >= MAX_NUMNODES || *endp != ':')
                return -EINVAL;
 
-       maxnodemem_pfn[node] = (maxnodemem_mb >> (HPAGE_SHIFT - 20)) <<
+       maxnodemem = memparse(endp+1, NULL);
+       maxnodemem_pfn[node] = (maxnodemem >> HPAGE_SHIFT) <<
                (HPAGE_SHIFT - PAGE_SHIFT);
        pr_info("Forcing RAM used on node %ld to no more than %dMB\n",
               node, maxnodemem_pfn[node] >> (20 - PAGE_SHIFT));
@@ -913,6 +912,13 @@ void __cpuinit setup_cpu(int boot)
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
+/*
+ * Note that the kernel can potentially support other compression
+ * techniques than gz, though we don't do so by default.  If we ever
+ * decide to do so we can either look for other filename extensions,
+ * or just allow a file with this name to be compressed with an
+ * arbitrary compressor (somewhat counterintuitively).
+ */
 static int __initdata set_initramfs_file;
 static char __initdata initramfs_file[128] = "initramfs.cpio.gz";
 
@@ -928,9 +934,9 @@ static int __init setup_initramfs_file(char *str)
 early_param("initramfs_file", setup_initramfs_file);
 
 /*
- * We look for an additional "initramfs.cpio.gz" file in the hvfs.
+ * We look for an "initramfs.cpio.gz" file in the hvfs.
  * If there is one, we allocate some memory for it and it will be
- * unpacked to the initramfs after any built-in initramfs_data.
+ * unpacked to the initramfs.
  */
 static void __init load_hv_initrd(void)
 {
index bc1eb586e24db24bf924644fe5e68b3424e7a308..89529c9f060535013bfd0505cfa3a13cfd728cd6 100644 (file)
@@ -153,6 +153,25 @@ static tile_bundle_bits rewrite_load_store_unaligned(
        if (((unsigned long)addr % size) == 0)
                return bundle;
 
+       /*
+        * Return SIGBUS with the unaligned address, if requested.
+        * Note that we return SIGBUS even for completely invalid addresses
+        * as long as they are in fact unaligned; this matches what the
+        * tilepro hardware would be doing, if it could provide us with the
+        * actual bad address in an SPR, which it doesn't.
+        */
+       if (unaligned_fixup == 0) {
+               siginfo_t info = {
+                       .si_signo = SIGBUS,
+                       .si_code = BUS_ADRALN,
+                       .si_addr = addr
+               };
+               trace_unhandled_signal("unaligned trap", regs,
+                                      (unsigned long)addr, SIGBUS);
+               force_sig_info(info.si_signo, &info, current);
+               return (tilepro_bundle_bits) 0;
+       }
+
 #ifndef __LITTLE_ENDIAN
 # error We assume little-endian representation with copy_xx_user size 2 here
 #endif
@@ -192,18 +211,6 @@ static tile_bundle_bits rewrite_load_store_unaligned(
                return (tile_bundle_bits) 0;
        }
 
-       if (unaligned_fixup == 0) {
-               siginfo_t info = {
-                       .si_signo = SIGBUS,
-                       .si_code = BUS_ADRALN,
-                       .si_addr = addr
-               };
-               trace_unhandled_signal("unaligned trap", regs,
-                                      (unsigned long)addr, SIGBUS);
-               force_sig_info(info.si_signo, &info, current);
-               return (tile_bundle_bits) 0;
-       }
-
        if (unaligned_printk || unaligned_fixup_count == 0) {
                pr_info("Process %d/%s: PC %#lx: Fixup of"
                        " unaligned %s at %#lx.\n",
@@ -339,12 +346,10 @@ void single_step_once(struct pt_regs *regs)
                }
 
                /* allocate a cache line of writable, executable memory */
-               down_write(&current->mm->mmap_sem);
-               buffer = (void __user *) do_mmap(NULL, 0, 64,
+               buffer = (void __user *) vm_mmap(NULL, 0, 64,
                                          PROT_EXEC | PROT_READ | PROT_WRITE,
                                          MAP_PRIVATE | MAP_ANONYMOUS,
                                          0);
-               up_write(&current->mm->mmap_sem);
 
                if (IS_ERR((void __force *)buffer)) {
                        kfree(state);
index a44e103c5a636670bdbd358f5143419c24d19d7a..91da0f721958da44d91ea08c526228c6c9a015e6 100644 (file)
@@ -103,7 +103,7 @@ static void smp_stop_cpu_interrupt(void)
        set_cpu_online(smp_processor_id(), 0);
        arch_local_irq_disable_all();
        for (;;)
-               asm("nap");
+               asm("nap; nop");
 }
 
 /* This function calls the 'stop' function on all other CPUs in the system. */
@@ -113,6 +113,12 @@ void smp_send_stop(void)
        send_IPI_allbutself(MSG_TAG_STOP_CPU);
 }
 
+/* On panic, just wait; we may get an smp_send_stop() later on. */
+void panic_smp_self_stop(void)
+{
+       while (1)
+               asm("nap; nop");
+}
 
 /*
  * Dispatch code called from hv_message_intr() for HV_MSG_TILE hv messages.
index b949edcec200b60018c7ecf6a9aef049771e0260..172aef7d3159b254e428ccede2a86dca05115716 100644 (file)
@@ -196,6 +196,8 @@ void __cpuinit online_secondary(void)
        /* This must be done before setting cpu_online_mask */
        wmb();
 
+       notify_cpu_starting(smp_processor_id());
+
        /*
         * We need to hold call_lock, so there is no inconsistency
         * between the time smp_call_function() determines number of
index 37ee4d037e0bae6788762e23e28fd3f518f38175..b2f44c28dda6f29c1867c59464462c63ac427e6a 100644 (file)
 #include <linux/stacktrace.h>
 #include <linux/uaccess.h>
 #include <linux/mmzone.h>
+#include <linux/dcache.h>
+#include <linux/fs.h>
 #include <asm/backtrace.h>
 #include <asm/page.h>
-#include <asm/tlbflush.h>
 #include <asm/ucontext.h>
+#include <asm/switch_to.h>
 #include <asm/sigframe.h>
 #include <asm/stack.h>
 #include <arch/abi.h>
@@ -44,72 +46,23 @@ static int in_kernel_stack(struct KBacktraceIterator *kbt, unsigned long sp)
        return sp >= kstack_base && sp < kstack_base + THREAD_SIZE;
 }
 
-/* Is address valid for reading? */
-static int valid_address(struct KBacktraceIterator *kbt, unsigned long address)
-{
-       HV_PTE *l1_pgtable = kbt->pgtable;
-       HV_PTE *l2_pgtable;
-       unsigned long pfn;
-       HV_PTE pte;
-       struct page *page;
-
-       if (l1_pgtable == NULL)
-               return 0;       /* can't read user space in other tasks */
-
-#ifdef CONFIG_64BIT
-       /* Find the real l1_pgtable by looking in the l0_pgtable. */
-       pte = l1_pgtable[HV_L0_INDEX(address)];
-       if (!hv_pte_get_present(pte))
-               return 0;
-       pfn = hv_pte_get_pfn(pte);
-       if (pte_huge(pte)) {
-               if (!pfn_valid(pfn)) {
-                       pr_err("L0 huge page has bad pfn %#lx\n", pfn);
-                       return 0;
-               }
-               return hv_pte_get_present(pte) && hv_pte_get_readable(pte);
-       }
-       page = pfn_to_page(pfn);
-       BUG_ON(PageHighMem(page));  /* No HIGHMEM on 64-bit. */
-       l1_pgtable = (HV_PTE *)pfn_to_kaddr(pfn);
-#endif
-       pte = l1_pgtable[HV_L1_INDEX(address)];
-       if (!hv_pte_get_present(pte))
-               return 0;
-       pfn = hv_pte_get_pfn(pte);
-       if (pte_huge(pte)) {
-               if (!pfn_valid(pfn)) {
-                       pr_err("huge page has bad pfn %#lx\n", pfn);
-                       return 0;
-               }
-               return hv_pte_get_present(pte) && hv_pte_get_readable(pte);
-       }
-
-       page = pfn_to_page(pfn);
-       if (PageHighMem(page)) {
-               pr_err("L2 page table not in LOWMEM (%#llx)\n",
-                      HV_PFN_TO_CPA(pfn));
-               return 0;
-       }
-       l2_pgtable = (HV_PTE *)pfn_to_kaddr(pfn);
-       pte = l2_pgtable[HV_L2_INDEX(address)];
-       return hv_pte_get_present(pte) && hv_pte_get_readable(pte);
-}
-
 /* Callback for backtracer; basically a glorified memcpy */
 static bool read_memory_func(void *result, unsigned long address,
                             unsigned int size, void *vkbt)
 {
        int retval;
        struct KBacktraceIterator *kbt = (struct KBacktraceIterator *)vkbt;
+
+       if (address == 0)
+               return 0;
        if (__kernel_text_address(address)) {
                /* OK to read kernel code. */
        } else if (address >= PAGE_OFFSET) {
                /* We only tolerate kernel-space reads of this task's stack */
                if (!in_kernel_stack(kbt, address))
                        return 0;
-       } else if (!valid_address(kbt, address)) {
-               return 0;       /* invalid user-space address */
+       } else if (!kbt->is_current) {
+               return 0;       /* can't read from other user address spaces */
        }
        pagefault_disable();
        retval = __copy_from_user_inatomic(result,
@@ -127,6 +80,8 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
        unsigned long sp = kbt->it.sp;
        struct pt_regs *p;
 
+       if (sp % sizeof(long) != 0)
+               return NULL;
        if (!in_kernel_stack(kbt, sp))
                return NULL;
        if (!in_kernel_stack(kbt, sp + C_ABI_SAVE_AREA_SIZE + PTREGS_SIZE-1))
@@ -169,27 +124,27 @@ static int is_sigreturn(unsigned long pc)
 }
 
 /* Return a pt_regs pointer for a valid signal handler frame */
-static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt)
+static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt,
+                                     struct rt_sigframe* kframe)
 {
        BacktraceIterator *b = &kbt->it;
 
-       if (b->pc == VDSO_BASE) {
-               struct rt_sigframe *frame;
-               unsigned long sigframe_top =
-                       b->sp + sizeof(struct rt_sigframe) - 1;
-               if (!valid_address(kbt, b->sp) ||
-                   !valid_address(kbt, sigframe_top)) {
-                       if (kbt->verbose)
-                               pr_err("  (odd signal: sp %#lx?)\n",
-                                      (unsigned long)(b->sp));
+       if (b->pc == VDSO_BASE && b->sp < PAGE_OFFSET &&
+           b->sp % sizeof(long) == 0) {
+               int retval;
+               pagefault_disable();
+               retval = __copy_from_user_inatomic(
+                       kframe, (void __user __force *)b->sp,
+                       sizeof(*kframe));
+               pagefault_enable();
+               if (retval != 0 ||
+                   (unsigned int)(kframe->info.si_signo) >= _NSIG)
                        return NULL;
-               }
-               frame = (struct rt_sigframe *)b->sp;
                if (kbt->verbose) {
                        pr_err("  <received signal %d>\n",
-                              frame->info.si_signo);
+                              kframe->info.si_signo);
                }
-               return (struct pt_regs *)&frame->uc.uc_mcontext;
+               return (struct pt_regs *)&kframe->uc.uc_mcontext;
        }
        return NULL;
 }
@@ -202,10 +157,11 @@ static int KBacktraceIterator_is_sigreturn(struct KBacktraceIterator *kbt)
 static int KBacktraceIterator_restart(struct KBacktraceIterator *kbt)
 {
        struct pt_regs *p;
+       struct rt_sigframe kframe;
 
        p = valid_fault_handler(kbt);
        if (p == NULL)
-               p = valid_sigframe(kbt);
+               p = valid_sigframe(kbt, &kframe);
        if (p == NULL)
                return 0;
        backtrace_init(&kbt->it, read_memory_func, kbt,
@@ -265,41 +221,19 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
 
        /*
         * Set up callback information.  We grab the kernel stack base
-        * so we will allow reads of that address range, and if we're
-        * asking about the current process we grab the page table
-        * so we can check user accesses before trying to read them.
-        * We flush the TLB to avoid any weird skew issues.
+        * so we will allow reads of that address range.
         */
-       is_current = (t == NULL);
+       is_current = (t == NULL || t == current);
        kbt->is_current = is_current;
        if (is_current)
                t = validate_current();
        kbt->task = t;
-       kbt->pgtable = NULL;
        kbt->verbose = 0;   /* override in caller if desired */
        kbt->profile = 0;   /* override in caller if desired */
        kbt->end = KBT_ONGOING;
-       kbt->new_context = 0;
-       if (is_current) {
-               HV_PhysAddr pgdir_pa = hv_inquire_context().page_table;
-               if (pgdir_pa == (unsigned long)swapper_pg_dir - PAGE_OFFSET) {
-                       /*
-                        * Not just an optimization: this also allows
-                        * this to work at all before va/pa mappings
-                        * are set up.
-                        */
-                       kbt->pgtable = swapper_pg_dir;
-               } else {
-                       struct page *page = pfn_to_page(PFN_DOWN(pgdir_pa));
-                       if (!PageHighMem(page))
-                               kbt->pgtable = __va(pgdir_pa);
-                       else
-                               pr_err("page table not in LOWMEM"
-                                      " (%#llx)\n", pgdir_pa);
-               }
-               local_flush_tlb_all();
+       kbt->new_context = 1;
+       if (is_current)
                validate_stack(regs);
-       }
 
        if (regs == NULL) {
                if (is_current || t->state == TASK_RUNNING) {
@@ -345,6 +279,78 @@ void KBacktraceIterator_next(struct KBacktraceIterator *kbt)
 }
 EXPORT_SYMBOL(KBacktraceIterator_next);
 
+static void describe_addr(struct KBacktraceIterator *kbt,
+                         unsigned long address,
+                         int have_mmap_sem, char *buf, size_t bufsize)
+{
+       struct vm_area_struct *vma;
+       size_t namelen, remaining;
+       unsigned long size, offset, adjust;
+       char *p, *modname;
+       const char *name;
+       int rc;
+
+       /*
+        * Look one byte back for every caller frame (i.e. those that
+        * aren't a new context) so we look up symbol data for the
+        * call itself, not the following instruction, which may be on
+        * a different line (or in a different function).
+        */
+       adjust = !kbt->new_context;
+       address -= adjust;
+
+       if (address >= PAGE_OFFSET) {
+               /* Handle kernel symbols. */
+               BUG_ON(bufsize < KSYM_NAME_LEN);
+               name = kallsyms_lookup(address, &size, &offset,
+                                      &modname, buf);
+               if (name == NULL) {
+                       buf[0] = '\0';
+                       return;
+               }
+               namelen = strlen(buf);
+               remaining = (bufsize - 1) - namelen;
+               p = buf + namelen;
+               rc = snprintf(p, remaining, "+%#lx/%#lx ",
+                             offset + adjust, size);
+               if (modname && rc < remaining)
+                       snprintf(p + rc, remaining - rc, "[%s] ", modname);
+               buf[bufsize-1] = '\0';
+               return;
+       }
+
+       /* If we don't have the mmap_sem, we can't show any more info. */
+       buf[0] = '\0';
+       if (!have_mmap_sem)
+               return;
+
+       /* Find vma info. */
+       vma = find_vma(kbt->task->mm, address);
+       if (vma == NULL || address < vma->vm_start) {
+               snprintf(buf, bufsize, "[unmapped address] ");
+               return;
+       }
+
+       if (vma->vm_file) {
+               char *s;
+               p = d_path(&vma->vm_file->f_path, buf, bufsize);
+               if (IS_ERR(p))
+                       p = "?";
+               s = strrchr(p, '/');
+               if (s)
+                       p = s+1;
+       } else {
+               p = "anon";
+       }
+
+       /* Generate a string description of the vma info. */
+       namelen = strlen(p);
+       remaining = (bufsize - 1) - namelen;
+       memmove(buf, p, namelen);
+       snprintf(buf + namelen, remaining, "[%lx+%lx] ",
+                vma->vm_start, vma->vm_end - vma->vm_start);
+}
+
 /*
  * This method wraps the backtracer's more generic support.
  * It is only invoked from the architecture-specific code; show_stack()
@@ -353,6 +359,7 @@ EXPORT_SYMBOL(KBacktraceIterator_next);
 void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
 {
        int i;
+       int have_mmap_sem = 0;
 
        if (headers) {
                /*
@@ -369,31 +376,16 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
        kbt->verbose = 1;
        i = 0;
        for (; !KBacktraceIterator_end(kbt); KBacktraceIterator_next(kbt)) {
-               char *modname;
-               const char *name;
-               unsigned long address = kbt->it.pc;
-               unsigned long offset, size;
                char namebuf[KSYM_NAME_LEN+100];
+               unsigned long address = kbt->it.pc;
 
-               if (address >= PAGE_OFFSET)
-                       name = kallsyms_lookup(address, &size, &offset,
-                                              &modname, namebuf);
-               else
-                       name = NULL;
-
-               if (!name)
-                       namebuf[0] = '\0';
-               else {
-                       size_t namelen = strlen(namebuf);
-                       size_t remaining = (sizeof(namebuf) - 1) - namelen;
-                       char *p = namebuf + namelen;
-                       int rc = snprintf(p, remaining, "+%#lx/%#lx ",
-                                         offset, size);
-                       if (modname && rc < remaining)
-                               snprintf(p + rc, remaining - rc,
-                                        "[%s] ", modname);
-                       namebuf[sizeof(namebuf)-1] = '\0';
-               }
+               /* Try to acquire the mmap_sem as we pass into userspace. */
+               if (address < PAGE_OFFSET && !have_mmap_sem && kbt->task->mm)
+                       have_mmap_sem =
+                               down_read_trylock(&kbt->task->mm->mmap_sem);
+
+               describe_addr(kbt, address, have_mmap_sem,
+                             namebuf, sizeof(namebuf));
 
                pr_err("  frame %d: 0x%lx %s(sp 0x%lx)\n",
                       i++, address, namebuf, (unsigned long)(kbt->it.sp));
@@ -408,6 +400,8 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
                pr_err("Stack dump stopped; next frame identical to this one\n");
        if (headers)
                pr_err("Stack dump complete\n");
+       if (have_mmap_sem)
+               up_read(&kbt->task->mm->mmap_sem);
 }
 EXPORT_SYMBOL(tile_show_stack);
 
index 2bb6602a1ee711c64146319a39c657de79f5a7b5..73cff814ac57252065ca8086185f2fc7bb87c012 100644 (file)
@@ -200,7 +200,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
 {
        siginfo_t info = { 0 };
        int signo, code;
-       unsigned long address;
+       unsigned long address = 0;
        bundle_bits instr;
 
        /* Re-enable interrupts. */
@@ -223,6 +223,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
        }
 
        switch (fault_num) {
+       case INT_MEM_ERROR:
+               signo = SIGBUS;
+               code = BUS_OBJERR;
+               break;
        case INT_ILL:
                if (copy_from_user(&instr, (void __user *)regs->pc,
                                   sizeof(instr))) {
@@ -289,7 +293,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
                address = regs->pc;
                break;
 #ifdef __tilegx__
-       case INT_ILL_TRANS:
+       case INT_ILL_TRANS: {
+               /* Avoid a hardware erratum with the return address stack. */
+               fill_ra_stack();
+
                signo = SIGSEGV;
                code = SEGV_MAPERR;
                if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK)
@@ -297,6 +304,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
                else
                        address = 0;  /* FIXME: GX: single-step for address */
                break;
+       }
 #endif
        default:
                panic("Unexpected do_trap interrupt number %d", fault_num);
@@ -308,7 +316,8 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
        info.si_addr = (void __user *)address;
        if (signo == SIGILL)
                info.si_trapno = fault_num;
-       trace_unhandled_signal("trap", regs, address, signo);
+       if (signo != SIGTRAP)
+               trace_unhandled_signal("trap", regs, address, signo);
        force_sig_info(signo, &info, current);
 }
 
index 0c26086ecbef01523c440b3636f8bf049bdfc8f0..985f59858234d98cf7a29df45d91edc0e6deb973 100644 (file)
@@ -7,6 +7,7 @@ lib-y = cacheflush.o checksum.o cpumask.o delay.o uaccess.o \
        strchr_$(BITS).o strlen_$(BITS).o
 
 ifeq ($(CONFIG_TILEGX),y)
+CFLAGS_REMOVE_memcpy_user_64.o = -fno-omit-frame-pointer
 lib-y += memcpy_user_64.o
 else
 lib-y += atomic_32.o atomic_asm_32.o memcpy_tile64.o
index 8928aace7a641d8a2b7be866f88deefb4f5f9a1e..db4fb89e12d89a4461b8cc19c99885469fcaf22c 100644 (file)
@@ -39,7 +39,21 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
 {
        char *p, *base;
        size_t step_size, load_count;
+
+       /*
+        * On TILEPro the striping granularity is a fixed 8KB; on
+        * TILE-Gx it is configurable, and we rely on the fact that
+        * the hypervisor always configures maximum striping, so that
+        * bits 9 and 10 of the PA are part of the stripe function, so
+        * every 512 bytes we hit a striping boundary.
+        *
+        */
+#ifdef __tilegx__
+       const unsigned long STRIPE_WIDTH = 512;
+#else
        const unsigned long STRIPE_WIDTH = 8192;
+#endif
+
 #ifdef __tilegx__
        /*
         * On TILE-Gx, we must disable the dstream prefetcher before doing
@@ -74,7 +88,7 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
         * memory, that one load would be sufficient, but since we may
         * be, we also need to back up to the last load issued to
         * another memory controller, which would be the point where
-        * we crossed an 8KB boundary (the granularity of striping
+        * we crossed a "striping" boundary (the granularity of striping
         * across memory controllers).  Keep backing up and doing this
         * until we are before the beginning of the buffer, or have
         * hit all the controllers.
@@ -88,12 +102,22 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
         * every cache line on a full memory stripe on each
         * controller" that we simply do that, to simplify the logic.
         *
-        * FIXME: See bug 9535 for some issues with this code.
+        * On TILE-Gx the hash-for-home function is much more complex,
+        * with the upshot being we can't readily guarantee we have
+        * hit both entries in the 128-entry AMT that were hit by any
+        * load in the entire range, so we just re-load them all.
+        * With larger buffers, we may want to consider using a hypervisor
+        * trap to issue loads directly to each hash-for-home tile for
+        * each controller (doing it from Linux would trash the TLB).
         */
        if (hfh) {
                step_size = L2_CACHE_BYTES;
+#ifdef __tilegx__
+               load_count = (size + L2_CACHE_BYTES - 1) / L2_CACHE_BYTES;
+#else
                load_count = (STRIPE_WIDTH / L2_CACHE_BYTES) *
                              (1 << CHIP_LOG_NUM_MSHIMS());
+#endif
        } else {
                step_size = STRIPE_WIDTH;
                load_count = (1 << CHIP_LOG_NUM_MSHIMS());
@@ -109,7 +133,7 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
 
        /* Figure out how far back we need to go. */
        base = p - (step_size * (load_count - 2));
-       if ((long)base < (long)buffer)
+       if ((unsigned long)base < (unsigned long)buffer)
                base = buffer;
 
        /*
index 4763b3aff1cc7695f340aae288e913a79a02f6ea..37440caa7370fe3d4c052086c6143bb6ab8e583c 100644 (file)
  * Do memcpy(), but trap and return "n" when a load or store faults.
  *
  * Note: this idiom only works when memcpy() compiles to a leaf function.
- * If "sp" is updated during memcpy, the "jrp lr" will be incorrect.
+ * Here leaf function not only means it does not have calls, but also
+ * requires no stack operations (sp, stack frame pointer) and no
+ * use of callee-saved registers, else "jrp lr" will be incorrect since
+ * unwinding stack frame is bypassed. Since memcpy() is not complex so
+ * these conditions are satisfied here, but we need to be careful when
+ * modifying this file. This is not a clean solution but is the best
+ * one so far.
  *
  * Also note that we are capturing "n" from the containing scope here.
  */
index c101098091327e5b52a104d2b2d4769212f80043..6ac37509faca56ab614eae690123bf9be9be9313 100644 (file)
@@ -60,5 +60,5 @@ static void delay_backoff(int iterations)
        loops += __insn_crc32_32(stack_pointer, get_cycles_low()) &
                (loops - 1);
 
-       relax(1 << exponent);
+       relax(loops);
 }
index cba30e9547b41682c8cfca0f3577637f1ff8cbbf..22e58f51ed23eedd405e9dc0b719eddb9550f502 100644 (file)
@@ -130,7 +130,7 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
 }
 
 /*
- * Handle a fault on the vmalloc or module mapping area
+ * Handle a fault on the vmalloc area.
  */
 static inline int vmalloc_fault(pgd_t *pgd, unsigned long address)
 {
@@ -203,9 +203,14 @@ static pgd_t *get_current_pgd(void)
  * interrupt or a critical region, and must do as little as possible.
  * Similarly, we can't use atomic ops here, since we may be handling a
  * fault caused by an atomic op access.
+ *
+ * If we find a migrating PTE while we're in an NMI context, and we're
+ * at a PC that has a registered exception handler, we don't wait,
+ * since this thread may (e.g.) have been interrupted while migrating
+ * its own stack, which would then cause us to self-deadlock.
  */
 static int handle_migrating_pte(pgd_t *pgd, int fault_num,
-                               unsigned long address,
+                               unsigned long address, unsigned long pc,
                                int is_kernel_mode, int write)
 {
        pud_t *pud;
@@ -227,6 +232,8 @@ static int handle_migrating_pte(pgd_t *pgd, int fault_num,
                pte_offset_kernel(pmd, address);
        pteval = *pte;
        if (pte_migrating(pteval)) {
+               if (in_nmi() && search_exception_tables(pc))
+                       return 0;
                wait_for_migration(pte);
                return 1;
        }
@@ -300,7 +307,7 @@ static int handle_page_fault(struct pt_regs *regs,
         * rather than trying to patch up the existing PTE.
         */
        pgd = get_current_pgd();
-       if (handle_migrating_pte(pgd, fault_num, address,
+       if (handle_migrating_pte(pgd, fault_num, address, regs->pc,
                                 is_kernel_mode, write))
                return 1;
 
@@ -335,9 +342,12 @@ static int handle_page_fault(struct pt_regs *regs,
        /*
         * If we're trying to touch user-space addresses, we must
         * be either at PL0, or else with interrupts enabled in the
-        * kernel, so either way we can re-enable interrupts here.
+        * kernel, so either way we can re-enable interrupts here
+        * unless we are doing atomic access to user space with
+        * interrupts disabled.
         */
-       local_irq_enable();
+       if (!(regs->flags & PT_FLAGS_DISABLE_IRQ))
+               local_irq_enable();
 
        mm = tsk->mm;
 
@@ -665,7 +675,7 @@ struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
         */
        if (fault_num == INT_DTLB_ACCESS)
                write = 1;
-       if (handle_migrating_pte(pgd, fault_num, address, 1, write))
+       if (handle_migrating_pte(pgd, fault_num, address, pc, 1, write))
                return state;
 
        /* Return zero so that we continue on with normal fault handling. */
index 1cc6ae477c98b59711c29deb5674e50c63c96be3..499f73770b05d09e1616e1d9a2293a20c7ae1bac 100644 (file)
@@ -394,6 +394,7 @@ int page_home(struct page *page)
                return pte_to_home(*virt_to_pte(NULL, kva));
        }
 }
+EXPORT_SYMBOL(page_home);
 
 void homecache_change_page_home(struct page *page, int order, int home)
 {
index 830c4908ea76cf4c7156777db8a8cced9fb887f9..6a9d20ddc34f416438a7d9717cf75919ea7fa34b 100644 (file)
@@ -254,11 +254,6 @@ static pgprot_t __init init_pgprot(ulong address)
                return construct_pgprot(PAGE_KERNEL_RO, PAGE_HOME_IMMUTABLE);
        }
 
-       /* As a performance optimization, keep the boot init stack here. */
-       if (address >= (ulong)&init_thread_union &&
-           address < (ulong)&init_thread_union + THREAD_SIZE)
-               return construct_pgprot(PAGE_KERNEL, smp_processor_id());
-
 #ifndef __tilegx__
 #if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
        /* Force the atomic_locks[] array page to be hash-for-home. */
@@ -557,6 +552,7 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
 
        address = MEM_SV_INTRPT;
        pmd = get_pmd(pgtables, address);
+       pfn = 0;  /* code starts at PA 0 */
        if (ktext_small) {
                /* Allocate an L2 PTE for the kernel text */
                int cpu = 0;
@@ -579,10 +575,15 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
                }
 
                BUG_ON(address != (unsigned long)_stext);
-               pfn = 0;  /* code starts at PA 0 */
-               pte = alloc_pte();
-               for (pte_ofs = 0; address < (unsigned long)_einittext;
-                    pfn++, pte_ofs++, address += PAGE_SIZE) {
+               pte = NULL;
+               for (; address < (unsigned long)_einittext;
+                    pfn++, address += PAGE_SIZE) {
+                       pte_ofs = pte_index(address);
+                       if (pte_ofs == 0) {
+                               if (pte)
+                                       assign_pte(pmd++, pte);
+                               pte = alloc_pte();
+                       }
                        if (!ktext_local) {
                                prot = set_remote_cache_cpu(prot, cpu);
                                cpu = cpumask_next(cpu, &ktext_mask);
@@ -591,7 +592,8 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
                        }
                        pte[pte_ofs] = pfn_pte(pfn, prot);
                }
-               assign_pte(pmd, pte);
+               if (pte)
+                       assign_pte(pmd, pte);
        } else {
                pte_t pteval = pfn_pte(0, PAGE_KERNEL_EXEC);
                pteval = pte_mkhuge(pteval);
@@ -614,7 +616,9 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
                else
                        pteval = hv_pte_set_mode(pteval,
                                                 HV_PTE_MODE_CACHE_NO_L3);
-               *(pte_t *)pmd = pteval;
+               for (; address < (unsigned long)_einittext;
+                    pfn += PFN_DOWN(HPAGE_SIZE), address += HPAGE_SIZE)
+                       *(pte_t *)(pmd++) = pfn_pte(pfn, pteval);
        }
 
        /* Set swapper_pgprot here so it is flushed to memory right away. */
index 87303693a0727faa96d844d58dc9115a4dd85b10..2410aa899b3e7c9c17079d2bf78d2d4eaf1eb8b1 100644 (file)
@@ -177,14 +177,10 @@ void shatter_huge_page(unsigned long addr)
        if (!pmd_huge_page(*pmd))
                return;
 
-       /*
-        * Grab the pgd_lock, since we may need it to walk the pgd_list,
-        * and since we need some kind of lock here to avoid races.
-        */
-       spin_lock_irqsave(&pgd_lock, flags);
+       spin_lock_irqsave(&init_mm.page_table_lock, flags);
        if (!pmd_huge_page(*pmd)) {
                /* Lost the race to convert the huge page. */
-               spin_unlock_irqrestore(&pgd_lock, flags);
+               spin_unlock_irqrestore(&init_mm.page_table_lock, flags);
                return;
        }
 
@@ -194,6 +190,7 @@ void shatter_huge_page(unsigned long addr)
 
 #ifdef __PAGETABLE_PMD_FOLDED
        /* Walk every pgd on the system and update the pmd there. */
+       spin_lock(&pgd_lock);
        list_for_each(pos, &pgd_list) {
                pmd_t *copy_pmd;
                pgd = list_to_pgd(pos) + pgd_index(addr);
@@ -201,6 +198,7 @@ void shatter_huge_page(unsigned long addr)
                copy_pmd = pmd_offset(pud, addr);
                __set_pmd(copy_pmd, *pmd);
        }
+       spin_unlock(&pgd_lock);
 #endif
 
        /* Tell every cpu to notice the change. */
@@ -208,7 +206,7 @@ void shatter_huge_page(unsigned long addr)
                     cpu_possible_mask, NULL, 0);
 
        /* Hold the lock until the TLB flush is finished to avoid races. */
-       spin_unlock_irqrestore(&pgd_lock, flags);
+       spin_unlock_irqrestore(&init_mm.page_table_lock, flags);
 }
 
 /*
@@ -217,9 +215,13 @@ void shatter_huge_page(unsigned long addr)
  * against pageattr.c; it is the unique case in which a valid change
  * of kernel pagetables can't be lazily synchronized by vmalloc faults.
  * vmalloc faults work because attached pagetables are never freed.
- * The locking scheme was chosen on the basis of manfred's
- * recommendations and having no core impact whatsoever.
- * -- wli
+ *
+ * The lock is always taken with interrupts disabled, unlike on x86
+ * and other platforms, because we need to take the lock in
+ * shatter_huge_page(), which may be called from an interrupt context.
+ * We are not at risk from the tlbflush IPI deadlock that was seen on
+ * x86, since we use the flush_remote() API to have the hypervisor do
+ * the TLB flushes regardless of irq disabling.
  */
 DEFINE_SPINLOCK(pgd_lock);
 LIST_HEAD(pgd_list);
@@ -469,10 +471,18 @@ void __set_pte(pte_t *ptep, pte_t pte)
 
 void set_pte(pte_t *ptep, pte_t pte)
 {
-       struct page *page = pfn_to_page(pte_pfn(pte));
-
-       /* Update the home of a PTE if necessary */
-       pte = pte_set_home(pte, page_home(page));
+       if (pte_present(pte) &&
+           (!CHIP_HAS_MMIO() || hv_pte_get_mode(pte) != HV_PTE_MODE_MMIO)) {
+               /* The PTE actually references physical memory. */
+               unsigned long pfn = pte_pfn(pte);
+               if (pfn_valid(pfn)) {
+                       /* Update the home of the PTE from the struct page. */
+                       pte = pte_set_home(pte, page_home(pfn_to_page(pfn)));
+               } else if (hv_pte_get_mode(pte) == 0) {
+                       /* remap_pfn_range(), etc, must supply PTE mode. */
+                       panic("set_pte(): out-of-range PFN and mode 0\n");
+               }
+       }
 
        __set_pte(ptep, pte);
 }
index dc36b222100b9abde780f996407a758f336afce4..6673508f342603554c4fbe874511ab6df14af45f 100644 (file)
@@ -3,41 +3,6 @@
 
 #include <asm/types.h>
 
-#if defined(__KERNEL__)
-
-# include <asm/byteorder.h>
-
-# if defined(__BIG_ENDIAN)
-#      define ntohll(x) (x)
-#      define htonll(x) (x)
-# elif defined(__LITTLE_ENDIAN)
-#      define ntohll(x)  be64_to_cpu(x)
-#      define htonll(x)  cpu_to_be64(x)
-# else
-#      error "Could not determine byte order"
-# endif
-
-#else
-/* For the definition of ntohl, htonl and __BYTE_ORDER */
-#include <endian.h>
-#include <netinet/in.h>
-#if defined(__BYTE_ORDER)
-
-#  if __BYTE_ORDER == __BIG_ENDIAN
-#      define ntohll(x) (x)
-#      define htonll(x) (x)
-#  elif __BYTE_ORDER == __LITTLE_ENDIAN
-#      define ntohll(x)  bswap_64(x)
-#      define htonll(x)  bswap_64(x)
-#  else
-#      error "Could not determine byte order: __BYTE_ORDER uncorrectly defined"
-#  endif
-
-#else  /* ! defined(__BYTE_ORDER) */
-#      error "Could not determine byte order: __BYTE_ORDER not defined"
-#endif
-#endif /* ! defined(__KERNEL__) */
-
 extern int init_cow_file(int fd, char *cow_file, char *backing_file,
                         int sectorsize, int alignment, int *bitmap_offset_out,
                         unsigned long *bitmap_len_out, int *data_offset_out);
index 9cbb426c0b9183e8a5c65afe47483f47e00da0ec..0ee9cc6cc4c79dfb4d78fd8fa15072294c62568f 100644 (file)
@@ -8,11 +8,10 @@
  * that.
  */
 #include <unistd.h>
-#include <byteswap.h>
 #include <errno.h>
 #include <string.h>
 #include <arpa/inet.h>
-#include <asm/types.h>
+#include <endian.h>
 #include "cow.h"
 #include "cow_sys.h"
 
@@ -214,8 +213,8 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
                           "header\n");
                goto out;
        }
-       header->magic = htonl(COW_MAGIC);
-       header->version = htonl(COW_VERSION);
+       header->magic = htobe32(COW_MAGIC);
+       header->version = htobe32(COW_VERSION);
 
        err = -EINVAL;
        if (strlen(backing_file) > sizeof(header->backing_file) - 1) {
@@ -246,10 +245,10 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
                goto out_free;
        }
 
-       header->mtime = htonl(modtime);
-       header->size = htonll(*size);
-       header->sectorsize = htonl(sectorsize);
-       header->alignment = htonl(alignment);
+       header->mtime = htobe32(modtime);
+       header->size = htobe64(*size);
+       header->sectorsize = htobe32(sectorsize);
+       header->alignment = htobe32(alignment);
        header->cow_format = COW_BITMAP;
 
        err = cow_write_file(fd, header, sizeof(*header));
@@ -301,8 +300,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
        magic = header->v1.magic;
        if (magic == COW_MAGIC)
                version = header->v1.version;
-       else if (magic == ntohl(COW_MAGIC))
-               version = ntohl(header->v1.version);
+       else if (magic == be32toh(COW_MAGIC))
+               version = be32toh(header->v1.version);
        /* No error printed because the non-COW case comes through here */
        else goto out;
 
@@ -327,9 +326,9 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
                                   "header\n");
                        goto out;
                }
-               *mtime_out = ntohl(header->v2.mtime);
-               *size_out = ntohll(header->v2.size);
-               *sectorsize_out = ntohl(header->v2.sectorsize);
+               *mtime_out = be32toh(header->v2.mtime);
+               *size_out = be64toh(header->v2.size);
+               *sectorsize_out = be32toh(header->v2.sectorsize);
                *bitmap_offset_out = sizeof(header->v2);
                *align_out = *sectorsize_out;
                file = header->v2.backing_file;
@@ -341,10 +340,10 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
                                   "header\n");
                        goto out;
                }
-               *mtime_out = ntohl(header->v3.mtime);
-               *size_out = ntohll(header->v3.size);
-               *sectorsize_out = ntohl(header->v3.sectorsize);
-               *align_out = ntohl(header->v3.alignment);
+               *mtime_out = be32toh(header->v3.mtime);
+               *size_out = be64toh(header->v3.size);
+               *sectorsize_out = be32toh(header->v3.sectorsize);
+               *align_out = be32toh(header->v3.alignment);
                if (*align_out == 0) {
                        cow_printf("read_cow_header - invalid COW header, "
                                   "align == 0\n");
@@ -366,16 +365,16 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
                 * this was used until Dec2005 - 64bits are needed to represent
                 * 2038+. I.e. we can safely do this truncating cast.
                 *
-                * Additionally, we must use ntohl() instead of ntohll(), since
+                * Additionally, we must use be32toh() instead of be64toh(), since
                 * the program used to use the former (tested - I got mtime
                 * mismatch "0 vs whatever").
                 *
                 * Ever heard about bug-to-bug-compatibility ? ;-) */
-               *mtime_out = (time32_t) ntohl(header->v3_b.mtime);
+               *mtime_out = (time32_t) be32toh(header->v3_b.mtime);
 
-               *size_out = ntohll(header->v3_b.size);
-               *sectorsize_out = ntohl(header->v3_b.sectorsize);
-               *align_out = ntohl(header->v3_b.alignment);
+               *size_out = be64toh(header->v3_b.size);
+               *sectorsize_out = be32toh(header->v3_b.sectorsize);
+               *align_out = be32toh(header->v3_b.alignment);
                if (*align_out == 0) {
                        cow_printf("read_cow_header - invalid COW header, "
                                   "align == 0\n");
index e672bd6d43e3b2aa72b4c1c51029db9510233f52..43b39d61b538698229a23f654b7fb44a335187b3 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
+#include <asm/switch_to.h>
 
 #include "init.h"
 #include "irq_kern.h"
index 8419f5cf2ac7e3586c68677198b2b28321b95221..fff24352255df0b0b448c43f11e287d5011fb836 100644 (file)
@@ -1,3 +1,4 @@
 generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h
 generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
-generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h
+generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h
+generic-y += switch_to.h
index 492bc4c1b62bf3516a996d81c24c05c494fcf8d5..65a1c3d690ea01c8af4e2d7ea2c74d95ab415ec2 100644 (file)
@@ -3,9 +3,10 @@
 # Licensed under the GPL
 #
 
-CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \
-                        -DELF_ARCH=$(LDS_ELF_ARCH)        \
-                        -DELF_FORMAT=$(LDS_ELF_FORMAT)
+CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START)           \
+                        -DELF_ARCH=$(LDS_ELF_ARCH)     \
+                        -DELF_FORMAT=$(LDS_ELF_FORMAT) \
+                       $(LDS_EXTRA)
 extra-y := vmlinux.lds
 clean-files :=
 
index f386d04a84a526df7a51a13cbc6c1636543071fe..2b73dedb44cacdda741b3e5774346c93b37b1b22 100644 (file)
@@ -88,11 +88,8 @@ static inline void set_current(struct task_struct *task)
 
 extern void arch_switch_to(struct task_struct *to);
 
-void *_switch_to(void *prev, void *next, void *last)
+void *__switch_to(struct task_struct *from, struct task_struct *to)
 {
-       struct task_struct *from = prev;
-       struct task_struct *to = next;
-
        to->thread.prev_sched = from;
        set_current(to);
 
@@ -111,7 +108,6 @@ void *_switch_to(void *prev, void *next, void *last)
        } while (current->thread.saved_task);
 
        return current->thread.prev_sched;
-
 }
 
 void interrupt_end(void)
index 4947b319f53ad7d1359631bf3ae09e0e38731b12..0a49ef0c2bf48995cb063ea425a10b91d11c8c96 100644 (file)
@@ -103,7 +103,6 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
 
 void uml_setup_stubs(struct mm_struct *mm)
 {
-       struct page **pages;
        int err, ret;
 
        if (!skas_needs_stub)
index 4be406abeefde51f1f3dd9419a799256ae1c1e1d..36b62bc52638368c750c250a529995cd8cac80cb 100644 (file)
@@ -14,6 +14,9 @@ LINK-y                        += $(call cc-option,-m32)
 
 export LDFLAGS
 
+LDS_EXTRA              := -Ui386
+export LDS_EXTRA
+
 # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
 include $(srctree)/arch/x86/Makefile_32.cpu
 
index d511d951a0527103e05abca9c1cf73b4b024b7c1..4824fb45560f7b6afe7bef4bf260f9f39f95a117 100644 (file)
@@ -119,9 +119,7 @@ static void set_brk(unsigned long start, unsigned long end)
        end = PAGE_ALIGN(end);
        if (end <= start)
                return;
-       down_write(&current->mm->mmap_sem);
-       do_brk(start, end - start);
-       up_write(&current->mm->mmap_sem);
+       vm_brk(start, end - start);
 }
 
 #ifdef CORE_DUMP
@@ -332,9 +330,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                pos = 32;
                map_size = ex.a_text+ex.a_data;
 
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(text_addr & PAGE_MASK, map_size);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(text_addr & PAGE_MASK, map_size);
 
                if (error != (text_addr & PAGE_MASK)) {
                        send_sig(SIGKILL, current, 0);
@@ -373,9 +369,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) {
                        loff_t pos = fd_offset;
 
-                       down_write(&current->mm->mmap_sem);
-                       do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
-                       up_write(&current->mm->mmap_sem);
+                       vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
                        bprm->file->f_op->read(bprm->file,
                                        (char __user *)N_TXTADDR(ex),
                                        ex.a_text+ex.a_data, &pos);
@@ -385,26 +379,22 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                        goto beyond_if;
                }
 
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
+               error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
                                PROT_READ | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
                                MAP_EXECUTABLE | MAP_32BIT,
                                fd_offset);
-               up_write(&current->mm->mmap_sem);
 
                if (error != N_TXTADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
                }
 
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
+               error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
                                PROT_READ | PROT_WRITE | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
                                MAP_EXECUTABLE | MAP_32BIT,
                                fd_offset + ex.a_text);
-               up_write(&current->mm->mmap_sem);
                if (error != N_DATADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
@@ -476,9 +466,7 @@ static int load_aout_library(struct file *file)
                        error_time = jiffies;
                }
 #endif
-               down_write(&current->mm->mmap_sem);
-               do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
-               up_write(&current->mm->mmap_sem);
+               vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
 
                file->f_op->read(file, (char __user *)start_addr,
                        ex.a_text + ex.a_data, &pos);
@@ -490,12 +478,10 @@ static int load_aout_library(struct file *file)
                goto out;
        }
        /* Now use mmap to map the library into memory. */
-       down_write(&current->mm->mmap_sem);
-       error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
+       error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT,
                        N_TXTOFF(ex));
-       up_write(&current->mm->mmap_sem);
        retval = error;
        if (error != start_addr)
                goto out;
@@ -503,9 +489,7 @@ static int load_aout_library(struct file *file)
        len = PAGE_ALIGN(ex.a_text + ex.a_data);
        bss = ex.a_text + ex.a_data + ex.a_bss;
        if (bss > len) {
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(start_addr + len, bss - len);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(start_addr + len, bss - len);
                retval = error;
                if (error != start_addr + len)
                        goto out;
index b3b7332629096849d11866c017c4444f8d156f9e..99480e55973d975a6082bf53c6f209591ec3d56c 100644 (file)
@@ -43,7 +43,7 @@ extern void __add_wrong_size(void)
                switch (sizeof(*(ptr))) {                               \
                case __X86_CASE_B:                                      \
                        asm volatile (lock #op "b %b0, %1\n"            \
-                                     : "+r" (__ret), "+m" (*(ptr))     \
+                                     : "+q" (__ret), "+m" (*(ptr))     \
                                      : : "memory", "cc");              \
                        break;                                          \
                case __X86_CASE_W:                                      \
@@ -173,7 +173,7 @@ extern void __add_wrong_size(void)
                switch (sizeof(*(ptr))) {                               \
                case __X86_CASE_B:                                      \
                        asm volatile (lock "addb %b1, %0\n"             \
-                                     : "+m" (*(ptr)) : "ri" (inc)      \
+                                     : "+m" (*(ptr)) : "qi" (inc)      \
                                      : "memory", "cc");                \
                        break;                                          \
                case __X86_CASE_W:                                      \
index 8be5f54d93606a374943cba5080dde65ff5e9e1d..e0544597cfe7b30a0e40d52c9d13cb65a6bf3d6c 100644 (file)
@@ -557,6 +557,8 @@ struct __large_struct { unsigned long buf[100]; };
 
 extern unsigned long
 copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
+extern __must_check long
+strncpy_from_user(char *dst, const char __user *src, long count);
 
 /*
  * movsl can be slow when source and dest are not both 8-byte aligned
index 566e803cc6026a11a1391fd25051717cef3f5979..8084bc73b18cbf8164f85dc86f7e78c4e1b07c78 100644 (file)
@@ -213,11 +213,6 @@ static inline unsigned long __must_check copy_from_user(void *to,
        return n;
 }
 
-long __must_check strncpy_from_user(char *dst, const char __user *src,
-                                   long count);
-long __must_check __strncpy_from_user(char *dst,
-                                     const char __user *src, long count);
-
 /**
  * strlen_user: - Get the size of a string in user space.
  * @str: The string to measure.
index 1c66d30971adedaac940770d701e141ae464e1f4..fcd4b6f3ef02ffcabec9ae5ef815ea7b7fdf80a8 100644 (file)
@@ -208,10 +208,6 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
        }
 }
 
-__must_check long
-strncpy_from_user(char *dst, const char __user *src, long count);
-__must_check long
-__strncpy_from_user(char *dst, const char __user *src, long count);
 __must_check long strnlen_user(const char __user *str, long n);
 __must_check long __strnlen_user(const char __user *str, long n);
 __must_check long strlen_user(const char __user *str);
index 694d801bf606736fb5b54a74b225fa229c7f5ac4..b8ba6e4a27e4102bd36a6445ec4b503be990d62d 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/traps.h>
 #include <asm/desc.h>
 #include <asm/tlbflush.h>
+#include <asm/idle.h>
 
 static int kvmapf = 1;
 
@@ -253,7 +254,10 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
                kvm_async_pf_task_wait((u32)read_cr2());
                break;
        case KVM_PV_REASON_PAGE_READY:
+               rcu_irq_enter();
+               exit_idle();
                kvm_async_pf_task_wake((u32)read_cr2());
+               rcu_irq_exit();
                break;
        }
 }
index f386dc49f988d753c5b9f8167c80313d5be72178..7515cf0e1805eae308e1dd0650b1dd33a8d8564d 100644 (file)
@@ -216,9 +216,9 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
        current_thread_info()->sig_on_uaccess_error = 1;
 
        /*
-        * 0 is a valid user pointer (in the access_ok sense) on 32-bit and
+        * NULL is a valid user pointer (in the access_ok sense) on 32-bit and
         * 64-bit, so we don't need to special-case it here.  For all the
-        * vsyscalls, 0 means "don't write anything" not "write it at
+        * vsyscalls, NULL means "don't write anything" not "write it at
         * address 0".
         */
        ret = -EFAULT;
@@ -247,7 +247,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 
                ret = sys_getcpu((unsigned __user *)regs->di,
                                 (unsigned __user *)regs->si,
-                                0);
+                                NULL);
                break;
        }
 
index a73f0c1048137062417b43e59785546c38b0dcd5..2e88438ffd83186c0d7a6b136cc97ae5c943ae4a 100644 (file)
@@ -369,7 +369,7 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data)
        case MSR_CORE_PERF_FIXED_CTR_CTRL:
                if (pmu->fixed_ctr_ctrl == data)
                        return 0;
-               if (!(data & 0xfffffffffffff444)) {
+               if (!(data & 0xfffffffffffff444ull)) {
                        reprogram_fixed_counters(pmu, data);
                        return 0;
                }
@@ -459,17 +459,17 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
        pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1);
 
        if (pmu->version == 1) {
-               pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1;
-               return;
+               pmu->nr_arch_fixed_counters = 0;
+       } else {
+               pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
+                               X86_PMC_MAX_FIXED);
+               pmu->counter_bitmask[KVM_PMC_FIXED] =
+                       ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
        }
 
-       pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
-                       X86_PMC_MAX_FIXED);
-       pmu->counter_bitmask[KVM_PMC_FIXED] =
-               ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
-       pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1)
-                       | (((1ull << pmu->nr_arch_fixed_counters) - 1)
-                               << X86_PMC_IDX_FIXED));
+       pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
+               (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED);
+       pmu->global_ctrl_mask = ~pmu->global_ctrl;
 }
 
 void kvm_pmu_init(struct kvm_vcpu *vcpu)
index 280751c84724a087ce5a6d9bbeb9c3dba67541bc..4ff0ab9bc3c86fd26889fa4b88b23c48c84523db 100644 (file)
@@ -2210,9 +2210,12 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
                msr = find_msr_entry(vmx, msr_index);
                if (msr) {
                        msr->data = data;
-                       if (msr - vmx->guest_msrs < vmx->save_nmsrs)
+                       if (msr - vmx->guest_msrs < vmx->save_nmsrs) {
+                               preempt_disable();
                                kvm_set_shared_msr(msr->index, msr->data,
                                                   msr->mask);
+                               preempt_enable();
+                       }
                        break;
                }
                ret = kvm_set_msr_common(vcpu, msr_index, data);
@@ -3906,7 +3909,9 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
                vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
 
        vmx->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
+       vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
        vmx_set_cr0(&vmx->vcpu, kvm_read_cr0(vcpu)); /* enter rmode */
+       srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
        vmx_set_cr4(&vmx->vcpu, 0);
        vmx_set_efer(&vmx->vcpu, 0);
        vmx_fpu_activate(&vmx->vcpu);
index 4044ce0bf7c1e7741620b8fcda9a78c9cb1bc775..91a5e989abcfe86f60df7bcb2a2919e25f87df6a 100644 (file)
@@ -6336,13 +6336,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
                if (npages && !old.rmap) {
                        unsigned long userspace_addr;
 
-                       down_write(&current->mm->mmap_sem);
-                       userspace_addr = do_mmap(NULL, 0,
+                       userspace_addr = vm_mmap(NULL, 0,
                                                 npages * PAGE_SIZE,
                                                 PROT_READ | PROT_WRITE,
                                                 map_flags,
                                                 0);
-                       up_write(&current->mm->mmap_sem);
 
                        if (IS_ERR((void *)userspace_addr))
                                return PTR_ERR((void *)userspace_addr);
@@ -6366,10 +6364,8 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
        if (!user_alloc && !old.user_alloc && old.rmap && !npages) {
                int ret;
 
-               down_write(&current->mm->mmap_sem);
-               ret = do_munmap(current->mm, old.userspace_addr,
+               ret = vm_munmap(old.userspace_addr,
                                old.npages * PAGE_SIZE);
-               up_write(&current->mm->mmap_sem);
                if (ret < 0)
                        printk(KERN_WARNING
                               "kvm_vm_ioctl_set_memory_region: "
index 25feb1ae71c5758273346057d8809232bdb1c769..b1e6c4b2e8eb228834edcbad9d9ff8ffbb9d99f9 100644 (file)
@@ -379,8 +379,8 @@ err_out:
        return;
 }
 
-/* Decode moffset16/32/64 */
-static void __get_moffset(struct insn *insn)
+/* Decode moffset16/32/64. Return 0 if failed */
+static int __get_moffset(struct insn *insn)
 {
        switch (insn->addr_bytes) {
        case 2:
@@ -397,15 +397,19 @@ static void __get_moffset(struct insn *insn)
                insn->moffset2.value = get_next(int, insn);
                insn->moffset2.nbytes = 4;
                break;
+       default:        /* opnd_bytes must be modified manually */
+               goto err_out;
        }
        insn->moffset1.got = insn->moffset2.got = 1;
 
+       return 1;
+
 err_out:
-       return;
+       return 0;
 }
 
-/* Decode imm v32(Iz) */
-static void __get_immv32(struct insn *insn)
+/* Decode imm v32(Iz). Return 0 if failed */
+static int __get_immv32(struct insn *insn)
 {
        switch (insn->opnd_bytes) {
        case 2:
@@ -417,14 +421,18 @@ static void __get_immv32(struct insn *insn)
                insn->immediate.value = get_next(int, insn);
                insn->immediate.nbytes = 4;
                break;
+       default:        /* opnd_bytes must be modified manually */
+               goto err_out;
        }
 
+       return 1;
+
 err_out:
-       return;
+       return 0;
 }
 
-/* Decode imm v64(Iv/Ov) */
-static void __get_immv(struct insn *insn)
+/* Decode imm v64(Iv/Ov), Return 0 if failed */
+static int __get_immv(struct insn *insn)
 {
        switch (insn->opnd_bytes) {
        case 2:
@@ -441,15 +449,18 @@ static void __get_immv(struct insn *insn)
                insn->immediate2.value = get_next(int, insn);
                insn->immediate2.nbytes = 4;
                break;
+       default:        /* opnd_bytes must be modified manually */
+               goto err_out;
        }
        insn->immediate1.got = insn->immediate2.got = 1;
 
+       return 1;
 err_out:
-       return;
+       return 0;
 }
 
 /* Decode ptr16:16/32(Ap) */
-static void __get_immptr(struct insn *insn)
+static int __get_immptr(struct insn *insn)
 {
        switch (insn->opnd_bytes) {
        case 2:
@@ -462,14 +473,17 @@ static void __get_immptr(struct insn *insn)
                break;
        case 8:
                /* ptr16:64 is not exist (no segment) */
-               return;
+               return 0;
+       default:        /* opnd_bytes must be modified manually */
+               goto err_out;
        }
        insn->immediate2.value = get_next(unsigned short, insn);
        insn->immediate2.nbytes = 2;
        insn->immediate1.got = insn->immediate2.got = 1;
 
+       return 1;
 err_out:
-       return;
+       return 0;
 }
 
 /**
@@ -489,7 +503,8 @@ void insn_get_immediate(struct insn *insn)
                insn_get_displacement(insn);
 
        if (inat_has_moffset(insn->attr)) {
-               __get_moffset(insn);
+               if (!__get_moffset(insn))
+                       goto err_out;
                goto done;
        }
 
@@ -517,16 +532,20 @@ void insn_get_immediate(struct insn *insn)
                insn->immediate2.nbytes = 4;
                break;
        case INAT_IMM_PTR:
-               __get_immptr(insn);
+               if (!__get_immptr(insn))
+                       goto err_out;
                break;
        case INAT_IMM_VWORD32:
-               __get_immv32(insn);
+               if (!__get_immv32(insn))
+                       goto err_out;
                break;
        case INAT_IMM_VWORD:
-               __get_immv(insn);
+               if (!__get_immv(insn))
+                       goto err_out;
                break;
        default:
-               break;
+               /* Here, insn must have an immediate, but failed */
+               goto err_out;
        }
        if (inat_has_second_immediate(insn->attr)) {
                insn->immediate2.value = get_next(char, insn);
index 97be9cb54483a05f8c5e9510d563f129ea863966..d6ae30bbd7bb833356049d89bdf8d0e5ae004b0c 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/highmem.h>
 #include <linux/module.h>
 
+#include <asm/word-at-a-time.h>
+
 /*
  * best effort, GUP based copy_from_user() that is NMI-safe
  */
@@ -41,3 +43,104 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
        return len;
 }
 EXPORT_SYMBOL_GPL(copy_from_user_nmi);
+
+static inline unsigned long count_bytes(unsigned long mask)
+{
+       mask = (mask - 1) & ~mask;
+       mask >>= 7;
+       return count_masked_bytes(mask);
+}
+
+/*
+ * Do a strncpy, return length of string without final '\0'.
+ * 'count' is the user-supplied count (return 'count' if we
+ * hit it), 'max' is the address space maximum (and we return
+ * -EFAULT if we hit it).
+ */
+static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max)
+{
+       long res = 0;
+
+       /*
+        * Truncate 'max' to the user-specified limit, so that
+        * we only have one limit we need to check in the loop
+        */
+       if (max > count)
+               max = count;
+
+       while (max >= sizeof(unsigned long)) {
+               unsigned long c;
+
+               /* Fall back to byte-at-a-time if we get a page fault */
+               if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
+                       break;
+               /* This can write a few bytes past the NUL character, but that's ok */
+               *(unsigned long *)(dst+res) = c;
+               c = has_zero(c);
+               if (c)
+                       return res + count_bytes(c);
+               res += sizeof(unsigned long);
+               max -= sizeof(unsigned long);
+       }
+
+       while (max) {
+               char c;
+
+               if (unlikely(__get_user(c,src+res)))
+                       return -EFAULT;
+               dst[res] = c;
+               if (!c)
+                       return res;
+               res++;
+               max--;
+       }
+
+       /*
+        * Uhhuh. We hit 'max'. But was that the user-specified maximum
+        * too? If so, that's ok - we got as much as the user asked for.
+        */
+       if (res >= count)
+               return res;
+
+       /*
+        * Nope: we hit the address space limit, and we still had more
+        * characters the caller would have wanted. That's an EFAULT.
+        */
+       return -EFAULT;
+}
+
+/**
+ * strncpy_from_user: - Copy a NUL terminated string from userspace.
+ * @dst:   Destination address, in kernel space.  This buffer must be at
+ *         least @count bytes long.
+ * @src:   Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ *
+ * Copies a NUL-terminated string from userspace to kernel space.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
+long
+strncpy_from_user(char *dst, const char __user *src, long count)
+{
+       unsigned long max_addr, src_addr;
+
+       if (unlikely(count <= 0))
+               return 0;
+
+       max_addr = current_thread_info()->addr_limit.seg;
+       src_addr = (unsigned long)src;
+       if (likely(src_addr < max_addr)) {
+               unsigned long max = max_addr - src_addr;
+               return do_strncpy_from_user(dst, src, count, max);
+       }
+       return -EFAULT;
+}
+EXPORT_SYMBOL(strncpy_from_user);
index d9b094ca7aaaed9305564228f6d68810d8b8afa1..ef2a6a5d78e39ddc71c2c51d90dc56f9cbcab9ef 100644 (file)
@@ -32,93 +32,6 @@ static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned lon
 #define movsl_is_ok(a1, a2, n) \
        __movsl_is_ok((unsigned long)(a1), (unsigned long)(a2), (n))
 
-/*
- * Copy a null terminated string from userspace.
- */
-
-#define __do_strncpy_from_user(dst, src, count, res)                      \
-do {                                                                      \
-       int __d0, __d1, __d2;                                              \
-       might_fault();                                                     \
-       __asm__ __volatile__(                                              \
-               "       testl %1,%1\n"                                     \
-               "       jz 2f\n"                                           \
-               "0:     lodsb\n"                                           \
-               "       stosb\n"                                           \
-               "       testb %%al,%%al\n"                                 \
-               "       jz 1f\n"                                           \
-               "       decl %1\n"                                         \
-               "       jnz 0b\n"                                          \
-               "1:     subl %1,%0\n"                                      \
-               "2:\n"                                                     \
-               ".section .fixup,\"ax\"\n"                                 \
-               "3:     movl %5,%0\n"                                      \
-               "       jmp 2b\n"                                          \
-               ".previous\n"                                              \
-               _ASM_EXTABLE(0b,3b)                                        \
-               : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),    \
-                 "=&D" (__d2)                                             \
-               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
-               : "memory");                                               \
-} while (0)
-
-/**
- * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
- * @dst:   Destination address, in kernel space.  This buffer must be at
- *         least @count bytes long.
- * @src:   Source address, in user space.
- * @count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- * Caller must check the specified block with access_ok() before calling
- * this function.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * If @count is smaller than the length of the string, copies @count bytes
- * and returns @count.
- */
-long
-__strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res;
-       __do_strncpy_from_user(dst, src, count, res);
-       return res;
-}
-EXPORT_SYMBOL(__strncpy_from_user);
-
-/**
- * strncpy_from_user: - Copy a NUL terminated string from userspace.
- * @dst:   Destination address, in kernel space.  This buffer must be at
- *         least @count bytes long.
- * @src:   Source address, in user space.
- * @count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * If @count is smaller than the length of the string, copies @count bytes
- * and returns @count.
- */
-long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res = -EFAULT;
-       if (access_ok(VERIFY_READ, src, 1))
-               __do_strncpy_from_user(dst, src, count, res);
-       return res;
-}
-EXPORT_SYMBOL(strncpy_from_user);
-
 /*
  * Zero Userspace
  */
index b7c2849ffb66015ed114a5ab2015956aecd69d7b..0d0326f388c0bdf9778ec2157c6d39cae3ff5c12 100644 (file)
@@ -8,55 +8,6 @@
 #include <linux/module.h>
 #include <asm/uaccess.h>
 
-/*
- * Copy a null terminated string from userspace.
- */
-
-#define __do_strncpy_from_user(dst,src,count,res)                         \
-do {                                                                      \
-       long __d0, __d1, __d2;                                             \
-       might_fault();                                                     \
-       __asm__ __volatile__(                                              \
-               "       testq %1,%1\n"                                     \
-               "       jz 2f\n"                                           \
-               "0:     lodsb\n"                                           \
-               "       stosb\n"                                           \
-               "       testb %%al,%%al\n"                                 \
-               "       jz 1f\n"                                           \
-               "       decq %1\n"                                         \
-               "       jnz 0b\n"                                          \
-               "1:     subq %1,%0\n"                                      \
-               "2:\n"                                                     \
-               ".section .fixup,\"ax\"\n"                                 \
-               "3:     movq %5,%0\n"                                      \
-               "       jmp 2b\n"                                          \
-               ".previous\n"                                              \
-               _ASM_EXTABLE(0b,3b)                                        \
-               : "=&r"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),    \
-                 "=&D" (__d2)                                             \
-               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
-               : "memory");                                               \
-} while (0)
-
-long
-__strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res;
-       __do_strncpy_from_user(dst, src, count, res);
-       return res;
-}
-EXPORT_SYMBOL(__strncpy_from_user);
-
-long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res = -EFAULT;
-       if (access_ok(VERIFY_READ, src, 1))
-               return __strncpy_from_user(dst, src, count);
-       return res;
-}
-EXPORT_SYMBOL(strncpy_from_user);
-
 /*
  * Zero Userspace
  */
diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h
new file mode 100644 (file)
index 0000000..7d01b8c
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef _ASM_UM_BARRIER_H_
+#define _ASM_UM_BARRIER_H_
+
+#include <asm/asm.h>
+#include <asm/segment.h>
+#include <asm/cpufeature.h>
+#include <asm/cmpxchg.h>
+#include <asm/nops.h>
+
+#include <linux/kernel.h>
+#include <linux/irqflags.h>
+
+/*
+ * Force strict CPU ordering.
+ * And yes, this is required on UP too when we're talking
+ * to devices.
+ */
+#ifdef CONFIG_X86_32
+
+#define mb()   alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
+#define rmb()  alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
+#define wmb()  alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
+
+#else /* CONFIG_X86_32 */
+
+#define mb()   asm volatile("mfence" : : : "memory")
+#define rmb()  asm volatile("lfence" : : : "memory")
+#define wmb()  asm volatile("sfence" : : : "memory")
+
+#endif /* CONFIG_X86_32 */
+
+#define read_barrier_depends() do { } while (0)
+
+#ifdef CONFIG_SMP
+
+#define smp_mb()       mb()
+#ifdef CONFIG_X86_PPRO_FENCE
+#define smp_rmb()      rmb()
+#else /* CONFIG_X86_PPRO_FENCE */
+#define smp_rmb()      barrier()
+#endif /* CONFIG_X86_PPRO_FENCE */
+
+#ifdef CONFIG_X86_OOSTORE
+#define smp_wmb()      wmb()
+#else /* CONFIG_X86_OOSTORE */
+#define smp_wmb()      barrier()
+#endif /* CONFIG_X86_OOSTORE */
+
+#define smp_read_barrier_depends()     read_barrier_depends()
+#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
+
+#else /* CONFIG_SMP */
+
+#define smp_mb()       barrier()
+#define smp_rmb()      barrier()
+#define smp_wmb()      barrier()
+#define smp_read_barrier_depends()     do { } while (0)
+#define set_mb(var, value) do { var = value; barrier(); } while (0)
+
+#endif /* CONFIG_SMP */
+
+/*
+ * Stop RDTSC speculation. This is needed when you need to use RDTSC
+ * (or get_cycles or vread that possibly accesses the TSC) in a defined
+ * code region.
+ *
+ * (Could use an alternative three way for this if there was one.)
+ */
+static inline void rdtsc_barrier(void)
+{
+       alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
+       alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
+}
+
+#endif
diff --git a/arch/x86/um/asm/system.h b/arch/x86/um/asm/system.h
deleted file mode 100644 (file)
index a459fd9..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-#ifndef _ASM_X86_SYSTEM_H_
-#define _ASM_X86_SYSTEM_H_
-
-#include <asm/asm.h>
-#include <asm/segment.h>
-#include <asm/cpufeature.h>
-#include <asm/cmpxchg.h>
-#include <asm/nops.h>
-
-#include <linux/kernel.h>
-#include <linux/irqflags.h>
-
-/* entries in ARCH_DLINFO: */
-#ifdef CONFIG_IA32_EMULATION
-# define AT_VECTOR_SIZE_ARCH 2
-#else
-# define AT_VECTOR_SIZE_ARCH 1
-#endif
-
-extern unsigned long arch_align_stack(unsigned long sp);
-
-void default_idle(void);
-
-/*
- * Force strict CPU ordering.
- * And yes, this is required on UP too when we're talking
- * to devices.
- */
-#ifdef CONFIG_X86_32
-/*
- * Some non-Intel clones support out of order store. wmb() ceases to be a
- * nop for these.
- */
-#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
-#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
-#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
-#else
-#define mb()   asm volatile("mfence":::"memory")
-#define rmb()  asm volatile("lfence":::"memory")
-#define wmb()  asm volatile("sfence" ::: "memory")
-#endif
-
-/**
- * read_barrier_depends - Flush all pending reads that subsequents reads
- * depend on.
- *
- * No data-dependent reads from memory-like regions are ever reordered
- * over this barrier.  All reads preceding this primitive are guaranteed
- * to access memory (but not necessarily other CPUs' caches) before any
- * reads following this primitive that depend on the data return by
- * any of the preceding reads.  This primitive is much lighter weight than
- * rmb() on most CPUs, and is never heavier weight than is
- * rmb().
- *
- * These ordering constraints are respected by both the local CPU
- * and the compiler.
- *
- * Ordering is not guaranteed by anything other than these primitives,
- * not even by data dependencies.  See the documentation for
- * memory_barrier() for examples and URLs to more information.
- *
- * For example, the following code would force ordering (the initial
- * value of "a" is zero, "b" is one, and "p" is "&a"):
- *
- * <programlisting>
- *     CPU 0                           CPU 1
- *
- *     b = 2;
- *     memory_barrier();
- *     p = &b;                         q = p;
- *                                     read_barrier_depends();
- *                                     d = *q;
- * </programlisting>
- *
- * because the read of "*q" depends on the read of "p" and these
- * two reads are separated by a read_barrier_depends().  However,
- * the following code, with the same initial values for "a" and "b":
- *
- * <programlisting>
- *     CPU 0                           CPU 1
- *
- *     a = 2;
- *     memory_barrier();
- *     b = 3;                          y = b;
- *                                     read_barrier_depends();
- *                                     x = a;
- * </programlisting>
- *
- * does not enforce ordering, since there is no data dependency between
- * the read of "a" and the read of "b".  Therefore, on some CPUs, such
- * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
- * in cases like this where there are no data dependencies.
- **/
-
-#define read_barrier_depends() do { } while (0)
-
-#ifdef CONFIG_SMP
-#define smp_mb()       mb()
-#ifdef CONFIG_X86_PPRO_FENCE
-# define smp_rmb()     rmb()
-#else
-# define smp_rmb()     barrier()
-#endif
-#ifdef CONFIG_X86_OOSTORE
-# define smp_wmb()     wmb()
-#else
-# define smp_wmb()     barrier()
-#endif
-#define smp_read_barrier_depends()     read_barrier_depends()
-#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
-#else
-#define smp_mb()       barrier()
-#define smp_rmb()      barrier()
-#define smp_wmb()      barrier()
-#define smp_read_barrier_depends()     do { } while (0)
-#define set_mb(var, value) do { var = value; barrier(); } while (0)
-#endif
-
-/*
- * Stop RDTSC speculation. This is needed when you need to use RDTSC
- * (or get_cycles or vread that possibly accesses the TSC) in a defined
- * code region.
- *
- * (Could use an alternative three way for this if there was one.)
- */
-static inline void rdtsc_barrier(void)
-{
-       alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
-       alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
-}
-
-extern void *_switch_to(void *prev, void *next, void *last);
-#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
-
-#endif
index 988828b479ed29660363f87adda4c6c62707441b..b8e279479a6b31984a7e715c52eec4283e38e007 100644 (file)
@@ -1859,6 +1859,7 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
 #endif /* CONFIG_X86_64 */
 
 static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss;
+static unsigned char fake_ioapic_mapping[PAGE_SIZE] __page_aligned_bss;
 
 static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
 {
@@ -1899,7 +1900,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
                 * We just don't map the IO APIC - all access is via
                 * hypercalls.  Keep the address in the pte for reference.
                 */
-               pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL);
+               pte = pfn_pte(PFN_DOWN(__pa(fake_ioapic_mapping)), PAGE_KERNEL);
                break;
 #endif
 
@@ -2064,6 +2065,7 @@ void __init xen_init_mmu_ops(void)
        pv_mmu_ops = xen_mmu_ops;
 
        memset(dummy_mapping, 0xff, PAGE_SIZE);
+       memset(fake_ioapic_mapping, 0xfd, PAGE_SIZE);
 }
 
 /* Protected by xen_reservation_lock. */
index 02900e8ce26cecba1e02bab8d4f2fdb48888d823..5fac6919b957fa88a9b9cc130007671ffbc00d13 100644 (file)
@@ -59,7 +59,7 @@ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
 
 static void __cpuinit cpu_bringup(void)
 {
-       int cpu = smp_processor_id();
+       int cpu;
 
        cpu_init();
        touch_softlockup_watchdog();
index 3a78b00edd71cfb7b667d50c9d3fe3265a5dba28..1f61b74867e41d3f74f61aeec539e8b00157dacf 100644 (file)
@@ -483,7 +483,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
        if (!q)
                return NULL;
 
-       q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL);
+       q->id = ida_simple_get(&blk_queue_ida, 0, 0, gfp_mask);
        if (q->id < 0)
                goto fail_q;
 
@@ -1277,7 +1277,8 @@ static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
        list_for_each_entry_reverse(rq, &plug->list, queuelist) {
                int el_ret;
 
-               (*request_count)++;
+               if (rq->q == q)
+                       (*request_count)++;
 
                if (rq->q != q || !blk_rq_merge_ok(rq, bio))
                        continue;
index 5eed6a76721d1d78e8105f4bbde30e41f20a66cd..f2ddb94626bd49df5e942591998d19ff8665a0eb 100644 (file)
@@ -1218,7 +1218,7 @@ void blk_throtl_drain(struct request_queue *q)
        struct bio_list bl;
        struct bio *bio;
 
-       WARN_ON_ONCE(!queue_is_locked(q));
+       queue_lockdep_assert_held(q);
 
        bio_list_init(&bl);
 
index 457295253566e97179daca0502c57c320962ed24..3c38536bd52c3e3a25f1b8152e40a6ebe5192d36 100644 (file)
@@ -295,6 +295,7 @@ struct cfq_data {
        unsigned int cfq_slice_idle;
        unsigned int cfq_group_idle;
        unsigned int cfq_latency;
+       unsigned int cfq_target_latency;
 
        /*
         * Fallback dummy cfqq for extreme OOM conditions
@@ -604,7 +605,7 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg)
 {
        struct cfq_rb_root *st = &cfqd->grp_service_tree;
 
-       return cfq_target_latency * cfqg->weight / st->total_weight;
+       return cfqd->cfq_target_latency * cfqg->weight / st->total_weight;
 }
 
 static inline unsigned
@@ -2271,7 +2272,8 @@ new_workload:
                 * to have higher weight. A more accurate thing would be to
                 * calculate system wide asnc/sync ratio.
                 */
-               tmp = cfq_target_latency * cfqg_busy_async_queues(cfqd, cfqg);
+               tmp = cfqd->cfq_target_latency *
+                       cfqg_busy_async_queues(cfqd, cfqg);
                tmp = tmp/cfqd->busy_queues;
                slice = min_t(unsigned, slice, tmp);
 
@@ -3737,6 +3739,7 @@ static void *cfq_init_queue(struct request_queue *q)
        cfqd->cfq_back_penalty = cfq_back_penalty;
        cfqd->cfq_slice[0] = cfq_slice_async;
        cfqd->cfq_slice[1] = cfq_slice_sync;
+       cfqd->cfq_target_latency = cfq_target_latency;
        cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
        cfqd->cfq_slice_idle = cfq_slice_idle;
        cfqd->cfq_group_idle = cfq_group_idle;
@@ -3788,6 +3791,7 @@ SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
 SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
 SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
 SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0);
+SHOW_FUNCTION(cfq_target_latency_show, cfqd->cfq_target_latency, 1);
 #undef SHOW_FUNCTION
 
 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)                        \
@@ -3821,6 +3825,7 @@ STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
 STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
                UINT_MAX, 0);
 STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0);
+STORE_FUNCTION(cfq_target_latency_store, &cfqd->cfq_target_latency, 1, UINT_MAX, 1);
 #undef STORE_FUNCTION
 
 #define CFQ_ATTR(name) \
@@ -3838,6 +3843,7 @@ static struct elv_fs_entry cfq_attrs[] = {
        CFQ_ATTR(slice_idle),
        CFQ_ATTR(group_idle),
        CFQ_ATTR(low_latency),
+       CFQ_ATTR(target_latency),
        __ATTR_NULL
 };
 
index 21ff9d015432e2e50737db0278ed7bea41ff601c..8e84225c096b6adfafcde59d08e066e5751af9c2 100644 (file)
@@ -627,7 +627,7 @@ config CRYPTO_BLOWFISH_COMMON
 
 config CRYPTO_BLOWFISH_X86_64
        tristate "Blowfish cipher algorithm (x86_64)"
-       depends on (X86 || UML_X86) && 64BIT
+       depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_BLOWFISH_COMMON
        help
@@ -657,7 +657,7 @@ config CRYPTO_CAMELLIA
 
 config CRYPTO_CAMELLIA_X86_64
        tristate "Camellia cipher algorithm (x86_64)"
-       depends on (X86 || UML_X86) && 64BIT
+       depends on X86 && 64BIT
        depends on CRYPTO
        select CRYPTO_ALGAPI
        select CRYPTO_LRW
@@ -893,7 +893,7 @@ config CRYPTO_TWOFISH_X86_64
 
 config CRYPTO_TWOFISH_X86_64_3WAY
        tristate "Twofish cipher algorithm (x86_64, 3-way parallel)"
-       depends on (X86 || UML_X86) && 64BIT
+       depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_TWOFISH_COMMON
        select CRYPTO_TWOFISH_X86_64
index 107f6f7be5e139129a1666f1f20aa3a6967c1ef0..dd30f40af9f505152bbc620211fa37d109eae1d7 100644 (file)
@@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len)
        index = sctx->count[0] & 0x7f;
 
        /* Update number of bytes */
-       if (!(sctx->count[0] += len))
+       if ((sctx->count[0] += len) < len)
                sctx->count[1]++;
 
         part_len = 128 - index;
index ab513a972c95b2376703ebee11cad903c7721ba6..a716fede4f25781d8e4e0633c21626ab03c83719 100644 (file)
@@ -74,7 +74,8 @@ acpi_status acpi_reset(void)
 
        /* Check if the reset register is supported */
 
-       if (!reset_reg->address) {
+       if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
+           !reset_reg->address) {
                return_ACPI_STATUS(AE_NOT_EXIST);
        }
 
index ba14fb93c92946097bafc866e316c79234ab02f3..c3881b2eb8b2c5a0ac9b353aa7d7bdd699001ba0 100644 (file)
@@ -607,8 +607,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
 
        acpi_irq_handler = handler;
        acpi_irq_context = context;
-       if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi",
-                                acpi_irq)) {
+       if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
                printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
                acpi_irq_handler = NULL;
                return AE_NOT_ACQUIRED;
index b3447f63e46b4f77a7e5edc7dc3bd5d0a7b3d33c..f3decb30223fd1b376775310ae25dec63424f920 100644 (file)
@@ -786,7 +786,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
        while (1) {
 
                if (cx->entry_method == ACPI_CSTATE_HALT)
-                       halt();
+                       safe_halt();
                else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
                        inb(cx->address);
                        /* See comment in acpi_idle_do_entry() */
index c1d612435939a5d62abb832d1f620faeeac7dc20..a6c77e8b37bde54c266cae17d620c441a896e3b9 100644 (file)
@@ -23,7 +23,8 @@ void acpi_reboot(void)
        /* Is the reset register supported? The spec says we should be
         * checking the bit width and bit offset, but Windows ignores
         * these fields */
-       /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */
+       if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
+               return;
 
        reset_value = acpi_gbl_FADT.reset_value;
 
index 01c2cf4efcdde81ba9ec012ec67a1660524c8b86..cc273226dbd014868ac68342d07225e0b095d6e1 100644 (file)
@@ -247,8 +247,7 @@ static int amba_pm_restore(struct device *dev)
 /*
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
  * enable/disable the bus clock at runtime PM suspend/resume as this
- * does not result in loss of context.  However, disabling vcore power
- * would do, so we leave that to the driver.
+ * does not result in loss of context.
  */
 static int amba_pm_runtime_suspend(struct device *dev)
 {
@@ -354,39 +353,6 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
        clk_put(pclk);
 }
 
-static int amba_get_enable_vcore(struct amba_device *pcdev)
-{
-       struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
-       int ret;
-
-       pcdev->vcore = vcore;
-
-       if (IS_ERR(vcore)) {
-               /* It is OK not to supply a vcore regulator */
-               if (PTR_ERR(vcore) == -ENODEV)
-                       return 0;
-               return PTR_ERR(vcore);
-       }
-
-       ret = regulator_enable(vcore);
-       if (ret) {
-               regulator_put(vcore);
-               pcdev->vcore = ERR_PTR(-ENODEV);
-       }
-
-       return ret;
-}
-
-static void amba_put_disable_vcore(struct amba_device *pcdev)
-{
-       struct regulator *vcore = pcdev->vcore;
-
-       if (!IS_ERR(vcore)) {
-               regulator_disable(vcore);
-               regulator_put(vcore);
-       }
-}
-
 /*
  * These are the device model conversion veneers; they convert the
  * device model structures to our more specific structures.
@@ -399,10 +365,6 @@ static int amba_probe(struct device *dev)
        int ret;
 
        do {
-               ret = amba_get_enable_vcore(pcdev);
-               if (ret)
-                       break;
-
                ret = amba_get_enable_pclk(pcdev);
                if (ret)
                        break;
@@ -420,7 +382,6 @@ static int amba_probe(struct device *dev)
                pm_runtime_put_noidle(dev);
 
                amba_put_disable_pclk(pcdev);
-               amba_put_disable_vcore(pcdev);
        } while (0);
 
        return ret;
@@ -442,7 +403,6 @@ static int amba_remove(struct device *dev)
        pm_runtime_put_noidle(dev);
 
        amba_put_disable_pclk(pcdev);
-       amba_put_disable_vcore(pcdev);
 
        return ret;
 }
index 68013f96729ffc624aad80342ec92af6768b89fa..7857e8fd0a3e56e007004492482b3e306d8ba089 100644 (file)
@@ -329,6 +329,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        /* SATA Controller IDE (Lynx Point) */
        { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (DH89xxCC) */
+       { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        { }     /* terminate list */
 };
 
index e0bda9ff89cda7a6d0271980bbd83fb1c89a9a42..28db50b57b918df812e5bb9f262243421dd97bea 100644 (file)
@@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
 static void ata_dev_xfermask(struct ata_device *dev);
 static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
-unsigned int ata_print_id = 1;
+atomic_t ata_print_id = ATOMIC_INIT(1);
 
 struct ata_force_param {
        const char      *name;
@@ -6029,7 +6029,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 
        /* give ports names and add SCSI hosts */
        for (i = 0; i < host->n_ports; i++)
-               host->ports[i]->print_id = ata_print_id++;
+               host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
 
 
        /* Create associated sysfs transport objects  */
index 1ee00c8b5b0495674c30237f2be672dee81ee928..93dabdcd2cbe3712191f4ae05c0720a1bf42549d 100644 (file)
@@ -3843,7 +3843,7 @@ int ata_sas_async_port_init(struct ata_port *ap)
        int rc = ap->ops->port_start(ap);
 
        if (!rc) {
-               ap->print_id = ata_print_id++;
+               ap->print_id = atomic_inc_return(&ata_print_id);
                __ata_port_probe(ap);
        }
 
@@ -3867,7 +3867,7 @@ int ata_sas_port_init(struct ata_port *ap)
        int rc = ap->ops->port_start(ap);
 
        if (!rc) {
-               ap->print_id = ata_print_id++;
+               ap->print_id = atomic_inc_return(&ata_print_id);
                rc = ata_port_probe(ap);
        }
 
index 74aaee30e264ce1959c3807cb6a9e4c8bad27c95..c341904853770f7dad45e5cc4e1180f76111e322 100644 (file)
@@ -294,6 +294,7 @@ int ata_tport_add(struct device *parent,
        device_enable_async_suspend(dev);
        pm_runtime_set_active(dev);
        pm_runtime_enable(dev);
+       pm_runtime_forbid(dev);
 
        transport_add_device(dev);
        transport_configure_device(dev);
index 2e26fcaf635b211192238dcfea0d7eebdad5b25b..9d0fd0b7185224239030e51d42dbe83f27ebbafb 100644 (file)
@@ -53,7 +53,7 @@ enum {
        ATA_DNXFER_QUIET        = (1 << 31),
 };
 
-extern unsigned int ata_print_id;
+extern atomic_t ata_print_id;
 extern int atapi_passthru16;
 extern int libata_fua;
 extern int libata_noacpi;
index 38950ea8398a9ebb05425a62b448578acfe172a1..7336d4a7ab317c091b7b991a1355a712f58023ab 100644 (file)
@@ -4025,7 +4025,8 @@ static int mv_platform_probe(struct platform_device *pdev)
        struct ata_host *host;
        struct mv_host_priv *hpriv;
        struct resource *res;
-       int n_ports, rc;
+       int n_ports = 0;
+       int rc;
 
        ata_print_version_once(&pdev->dev, DRV_VERSION);
 
index fb14a6343d4f52c780d186a31a3a39313dac02be..92b779ee002bba20b6af60953aa2132526380c4e 100644 (file)
@@ -138,6 +138,7 @@ static int rbtree_show(struct seq_file *s, void *ignored)
        unsigned int base, top;
        int nodes = 0;
        int registers = 0;
+       int average;
 
        mutex_lock(&map->lock);
 
@@ -152,8 +153,13 @@ static int rbtree_show(struct seq_file *s, void *ignored)
                registers += top - base + 1;
        }
 
+       if (nodes)
+               average = registers / nodes;
+       else
+               average = 0;
+
        seq_printf(s, "%d nodes, %d registers, average %d registers\n",
-                  nodes, registers, registers / nodes);
+                  nodes, registers, average);
 
        mutex_unlock(&map->lock);
 
index 87f54dbf601b90adf01e602ec200e5f967472d66..74b69095def6def7129d77a142936e7b751705d1 100644 (file)
@@ -346,6 +346,7 @@ out:
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(regcache_sync_region);
 
 /**
  * regcache_cache_only: Put a register map into cache only mode
index 05f150382da86fa70dd161067b26bdf59d33fc94..ba29b2e73d48936ab9a93a028abd0b0d9cd29691 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/sys_soc.h>
 #include <linux/err.h>
 
-static DEFINE_IDR(soc_ida);
+static DEFINE_IDA(soc_ida);
 static DEFINE_SPINLOCK(soc_lock);
 
 static ssize_t soc_info_get(struct device *dev,
@@ -168,8 +168,6 @@ void soc_device_unregister(struct soc_device *soc_dev)
 
 static int __init soc_bus_register(void)
 {
-       spin_lock_init(&soc_lock);
-
        return bus_register(&soc_bus_type);
 }
 core_initcall(soc_bus_register);
index e820b68d2f6cd4d74382b85b5e020069294f00f3..acda773b3720878495d14f5ebfbe1a82f50c0f74 100644 (file)
@@ -866,6 +866,7 @@ cciss_scsi_detect(ctlr_info_t *h)
        sh->can_queue = cciss_tape_cmds;
        sh->sg_tablesize = h->maxsgentries;
        sh->max_cmd_len = MAX_COMMAND_SIZE;
+       sh->max_sectors = h->cciss_max_sectors;
 
        ((struct cciss_scsi_adapter_data_t *) 
                h->scsi_ctlr)->scsi_host = sh;
@@ -1410,7 +1411,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c,
        /* track how many SG entries we are using */
        if (request_nsgs > h->maxSG)
                h->maxSG = request_nsgs;
-       c->Header.SGTotal = (__u8) request_nsgs + chained;
+       c->Header.SGTotal = (u16) request_nsgs + chained;
        if (request_nsgs > h->max_cmd_sgentries)
                c->Header.SGList = h->max_cmd_sgentries;
        else
index b5dd14e072f2859a1c81fc036ffafd2146cc754a..0ba837fc62a874511a910dd077feea2f26dfbd37 100644 (file)
@@ -4,6 +4,6 @@
 
 config BLK_DEV_PCIESSD_MTIP32XX
        tristate "Block Device Driver for Micron PCIe SSDs"
-       depends on HOTPLUG_PCI_PCIE
+       depends on PCI
        help
           This enables the block driver for Micron PCIe SSDs.
index 8eb81c96608fbc47aadc382015a0e44db2b4599a..00f9fc992090099e72e8f753ab9d58fe47154b46 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/idr.h>
 #include <linux/kthread.h>
 #include <../drivers/ata/ahci.h>
+#include <linux/export.h>
 #include "mtip32xx.h"
 
 #define HW_CMD_SLOT_SZ         (MTIP_MAX_COMMAND_SLOTS * 32)
@@ -44,6 +45,7 @@
 #define HW_PORT_PRIV_DMA_SZ \
                (HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ)
 
+#define HOST_CAP_NZDMA         (1 << 19)
 #define HOST_HSORG             0xFC
 #define HSORG_DISABLE_SLOTGRP_INTR (1<<24)
 #define HSORG_DISABLE_SLOTGRP_PXIS (1<<16)
@@ -139,6 +141,12 @@ static void mtip_command_cleanup(struct driver_data *dd)
        int group = 0, commandslot = 0, commandindex = 0;
        struct mtip_cmd *command;
        struct mtip_port *port = dd->port;
+       static int in_progress;
+
+       if (in_progress)
+               return;
+
+       in_progress = 1;
 
        for (group = 0; group < 4; group++) {
                for (commandslot = 0; commandslot < 32; commandslot++) {
@@ -165,7 +173,8 @@ static void mtip_command_cleanup(struct driver_data *dd)
 
        up(&port->cmd_slot);
 
-       atomic_set(&dd->drv_cleanup_done, true);
+       set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag);
+       in_progress = 0;
 }
 
 /*
@@ -262,6 +271,9 @@ static int hba_reset_nosleep(struct driver_data *dd)
                 && time_before(jiffies, timeout))
                mdelay(1);
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))
+               return -1;
+
        if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
                return -1;
 
@@ -294,6 +306,10 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag)
                        port->cmd_issue[MTIP_TAG_INDEX(tag)]);
 
        spin_unlock_irqrestore(&port->cmd_issue_lock, flags);
+
+       /* Set the command's timeout value.*/
+       port->commands[tag].comp_time = jiffies + msecs_to_jiffies(
+                                       MTIP_NCQ_COMMAND_TIMEOUT_MS);
 }
 
 /*
@@ -420,7 +436,12 @@ static void mtip_init_port(struct mtip_port *port)
                writel(0xFFFFFFFF, port->completed[i]);
 
        /* Clear any pending interrupts for this port */
-       writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT);
+       writel(readl(port->dd->mmio + PORT_IRQ_STAT),
+                                       port->dd->mmio + PORT_IRQ_STAT);
+
+       /* Clear any pending interrupts on the HBA. */
+       writel(readl(port->dd->mmio + HOST_IRQ_STAT),
+                                       port->dd->mmio + HOST_IRQ_STAT);
 
        /* Enable port interrupts */
        writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK);
@@ -447,6 +468,9 @@ static void mtip_restart_port(struct mtip_port *port)
                 && time_before(jiffies, timeout))
                ;
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+               return;
+
        /*
         * Chip quirk: escalate to hba reset if
         * PxCMD.CR not clear after 500 ms
@@ -475,6 +499,9 @@ static void mtip_restart_port(struct mtip_port *port)
        while (time_before(jiffies, timeout))
                ;
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+               return;
+
        /* Clear PxSCTL.DET */
        writel(readl(port->mmio + PORT_SCR_CTL) & ~1,
                         port->mmio + PORT_SCR_CTL);
@@ -486,15 +513,35 @@ static void mtip_restart_port(struct mtip_port *port)
                         && time_before(jiffies, timeout))
                ;
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+               return;
+
        if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0)
                dev_warn(&port->dd->pdev->dev,
                        "COM reset failed\n");
 
-       /* Clear SError, the PxSERR.DIAG.x should be set so clear it */
-       writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR);
+       mtip_init_port(port);
+       mtip_start_port(port);
 
-       /* Enable the DMA engine */
-       mtip_enable_engine(port, 1);
+}
+
+/*
+ * Helper function for tag logging
+ */
+static void print_tags(struct driver_data *dd,
+                       char *msg,
+                       unsigned long *tagbits,
+                       int cnt)
+{
+       unsigned char tagmap[128];
+       int group, tagmap_len = 0;
+
+       memset(tagmap, 0, sizeof(tagmap));
+       for (group = SLOTBITS_IN_LONGS; group > 0; group--)
+               tagmap_len = sprintf(tagmap + tagmap_len, "%016lX ",
+                                               tagbits[group-1]);
+       dev_warn(&dd->pdev->dev,
+                       "%d command(s) %s: tagmap [%s]", cnt, msg, tagmap);
 }
 
 /*
@@ -514,15 +561,18 @@ static void mtip_timeout_function(unsigned long int data)
        int tag, cmdto_cnt = 0;
        unsigned int bit, group;
        unsigned int num_command_slots = port->dd->slot_groups * 32;
+       unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
 
        if (unlikely(!port))
                return;
 
-       if (atomic_read(&port->dd->resumeflag) == true) {
+       if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) {
                mod_timer(&port->cmd_timer,
                        jiffies + msecs_to_jiffies(30000));
                return;
        }
+       /* clear the tag accumulator */
+       memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
 
        for (tag = 0; tag < num_command_slots; tag++) {
                /*
@@ -540,12 +590,10 @@ static void mtip_timeout_function(unsigned long int data)
                        command = &port->commands[tag];
                        fis = (struct host_to_dev_fis *) command->command;
 
-                       dev_warn(&port->dd->pdev->dev,
-                               "Timeout for command tag %d\n", tag);
-
+                       set_bit(tag, tagaccum);
                        cmdto_cnt++;
                        if (cmdto_cnt == 1)
-                               set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+                               set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
 
                        /*
                         * Clear the completed bit. This should prevent
@@ -578,15 +626,29 @@ static void mtip_timeout_function(unsigned long int data)
                }
        }
 
-       if (cmdto_cnt) {
-               dev_warn(&port->dd->pdev->dev,
-                       "%d commands timed out: restarting port",
-                       cmdto_cnt);
+       if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
+               print_tags(port->dd, "timed out", tagaccum, cmdto_cnt);
+
                mtip_restart_port(port);
-               clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+               clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
                wake_up_interruptible(&port->svc_wait);
        }
 
+       if (port->ic_pause_timer) {
+               to  = port->ic_pause_timer + msecs_to_jiffies(1000);
+               if (time_after(jiffies, to)) {
+                       if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
+                               port->ic_pause_timer = 0;
+                               clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+                               clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
+                               clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+                               wake_up_interruptible(&port->svc_wait);
+                       }
+
+
+               }
+       }
+
        /* Restart the timer */
        mod_timer(&port->cmd_timer,
                jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
@@ -681,23 +743,18 @@ static void mtip_completion(struct mtip_port *port,
        complete(waiting);
 }
 
-/*
- * Helper function for tag logging
- */
-static void print_tags(struct driver_data *dd,
-                       char *msg,
-                       unsigned long *tagbits)
+static void mtip_null_completion(struct mtip_port *port,
+                           int tag,
+                           void *data,
+                           int status)
 {
-       unsigned int tag, count = 0;
-
-       for (tag = 0; tag < (dd->slot_groups) * 32; tag++) {
-               if (test_bit(tag, tagbits))
-                       count++;
-       }
-       if (count)
-               dev_info(&dd->pdev->dev, "%s [%i tags]\n", msg, count);
+       return;
 }
 
+static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer,
+                               dma_addr_t buffer_dma, unsigned int sectors);
+static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id,
+                                               struct smart_attr *attrib);
 /*
  * Handle an error.
  *
@@ -708,12 +765,16 @@ static void print_tags(struct driver_data *dd,
  */
 static void mtip_handle_tfe(struct driver_data *dd)
 {
-       int group, tag, bit, reissue;
+       int group, tag, bit, reissue, rv;
        struct mtip_port *port;
-       struct mtip_cmd  *command;
+       struct mtip_cmd  *cmd;
        u32 completed;
        struct host_to_dev_fis *fis;
        unsigned long tagaccum[SLOTBITS_IN_LONGS];
+       unsigned int cmd_cnt = 0;
+       unsigned char *buf;
+       char *fail_reason = NULL;
+       int fail_all_ncq_write = 0, fail_all_ncq_cmds = 0;
 
        dev_warn(&dd->pdev->dev, "Taskfile error\n");
 
@@ -722,8 +783,11 @@ static void mtip_handle_tfe(struct driver_data *dd)
        /* Stop the timer to prevent command timeouts. */
        del_timer(&port->cmd_timer);
 
+       /* clear the tag accumulator */
+       memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+
        /* Set eh_active */
-       set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+       set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
 
        /* Loop through all the groups */
        for (group = 0; group < dd->slot_groups; group++) {
@@ -732,9 +796,6 @@ static void mtip_handle_tfe(struct driver_data *dd)
                /* clear completed status register in the hardware.*/
                writel(completed, port->completed[group]);
 
-               /* clear the tag accumulator */
-               memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
-
                /* Process successfully completed commands */
                for (bit = 0; bit < 32 && completed; bit++) {
                        if (!(completed & (1<<bit)))
@@ -745,13 +806,14 @@ static void mtip_handle_tfe(struct driver_data *dd)
                        if (tag == MTIP_TAG_INTERNAL)
                                continue;
 
-                       command = &port->commands[tag];
-                       if (likely(command->comp_func)) {
+                       cmd = &port->commands[tag];
+                       if (likely(cmd->comp_func)) {
                                set_bit(tag, tagaccum);
-                               atomic_set(&port->commands[tag].active, 0);
-                               command->comp_func(port,
+                               cmd_cnt++;
+                               atomic_set(&cmd->active, 0);
+                               cmd->comp_func(port,
                                         tag,
-                                        command->comp_data,
+                                        cmd->comp_data,
                                         0);
                        } else {
                                dev_err(&port->dd->pdev->dev,
@@ -765,12 +827,45 @@ static void mtip_handle_tfe(struct driver_data *dd)
                        }
                }
        }
-       print_tags(dd, "TFE tags completed:", tagaccum);
+
+       print_tags(dd, "completed (TFE)", tagaccum, cmd_cnt);
 
        /* Restart the port */
        mdelay(20);
        mtip_restart_port(port);
 
+       /* Trying to determine the cause of the error */
+       rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ,
+                               dd->port->log_buf,
+                               dd->port->log_buf_dma, 1);
+       if (rv) {
+               dev_warn(&dd->pdev->dev,
+                       "Error in READ LOG EXT (10h) command\n");
+               /* non-critical error, don't fail the load */
+       } else {
+               buf = (unsigned char *)dd->port->log_buf;
+               if (buf[259] & 0x1) {
+                       dev_info(&dd->pdev->dev,
+                               "Write protect bit is set.\n");
+                       set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag);
+                       fail_all_ncq_write = 1;
+                       fail_reason = "write protect";
+               }
+               if (buf[288] == 0xF7) {
+                       dev_info(&dd->pdev->dev,
+                               "Exceeded Tmax, drive in thermal shutdown.\n");
+                       set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag);
+                       fail_all_ncq_cmds = 1;
+                       fail_reason = "thermal shutdown";
+               }
+               if (buf[288] == 0xBF) {
+                       dev_info(&dd->pdev->dev,
+                               "Drive indicates rebuild has failed.\n");
+                       fail_all_ncq_cmds = 1;
+                       fail_reason = "rebuild failed";
+               }
+       }
+
        /* clear the tag accumulator */
        memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
 
@@ -779,32 +874,47 @@ static void mtip_handle_tfe(struct driver_data *dd)
                for (bit = 0; bit < 32; bit++) {
                        reissue = 1;
                        tag = (group << 5) + bit;
+                       cmd = &port->commands[tag];
 
                        /* If the active bit is set re-issue the command */
-                       if (atomic_read(&port->commands[tag].active) == 0)
+                       if (atomic_read(&cmd->active) == 0)
                                continue;
 
-                       fis = (struct host_to_dev_fis *)
-                               port->commands[tag].command;
+                       fis = (struct host_to_dev_fis *)cmd->command;
 
                        /* Should re-issue? */
                        if (tag == MTIP_TAG_INTERNAL ||
                            fis->command == ATA_CMD_SET_FEATURES)
                                reissue = 0;
+                       else {
+                               if (fail_all_ncq_cmds ||
+                                       (fail_all_ncq_write &&
+                                       fis->command == ATA_CMD_FPDMA_WRITE)) {
+                                       dev_warn(&dd->pdev->dev,
+                                       "  Fail: %s w/tag %d [%s].\n",
+                                       fis->command == ATA_CMD_FPDMA_WRITE ?
+                                               "write" : "read",
+                                       tag,
+                                       fail_reason != NULL ?
+                                               fail_reason : "unknown");
+                                       atomic_set(&cmd->active, 0);
+                                       if (cmd->comp_func) {
+                                               cmd->comp_func(port, tag,
+                                                       cmd->comp_data,
+                                                       -ENODATA);
+                                       }
+                                       continue;
+                               }
+                       }
 
                        /*
                         * First check if this command has
                         *  exceeded its retries.
                         */
-                       if (reissue &&
-                           (port->commands[tag].retries-- > 0)) {
+                       if (reissue && (cmd->retries-- > 0)) {
 
                                set_bit(tag, tagaccum);
 
-                               /* Update the timeout value. */
-                               port->commands[tag].comp_time =
-                                       jiffies + msecs_to_jiffies(
-                                       MTIP_NCQ_COMMAND_TIMEOUT_MS);
                                /* Re-issue the command. */
                                mtip_issue_ncq_command(port, tag);
 
@@ -814,13 +924,13 @@ static void mtip_handle_tfe(struct driver_data *dd)
                        /* Retire a command that will not be reissued */
                        dev_warn(&port->dd->pdev->dev,
                                "retiring tag %d\n", tag);
-                       atomic_set(&port->commands[tag].active, 0);
+                       atomic_set(&cmd->active, 0);
 
-                       if (port->commands[tag].comp_func)
-                               port->commands[tag].comp_func(
+                       if (cmd->comp_func)
+                               cmd->comp_func(
                                        port,
                                        tag,
-                                       port->commands[tag].comp_data,
+                                       cmd->comp_data,
                                        PORT_IRQ_TF_ERR);
                        else
                                dev_warn(&port->dd->pdev->dev,
@@ -828,10 +938,10 @@ static void mtip_handle_tfe(struct driver_data *dd)
                                        tag);
                }
        }
-       print_tags(dd, "TFE tags reissued:", tagaccum);
+       print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
 
        /* clear eh_active */
-       clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+       clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
        wake_up_interruptible(&port->svc_wait);
 
        mod_timer(&port->cmd_timer,
@@ -899,7 +1009,7 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat)
        struct mtip_port *port = dd->port;
        struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL];
 
-       if (test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) &&
+       if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) &&
            (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL])
                & (1 << MTIP_TAG_INTERNAL))) {
                if (cmd->comp_func) {
@@ -911,8 +1021,6 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat)
                }
        }
 
-       dev_warn(&dd->pdev->dev, "IRQ status 0x%x ignored.\n", port_stat);
-
        return;
 }
 
@@ -968,6 +1076,9 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data)
                                /* don't proceed further */
                                return IRQ_HANDLED;
                        }
+                       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                                                       &dd->dd_flag))
+                               return rv;
 
                        mtip_process_errors(dd, port_stat & PORT_IRQ_ERR);
                }
@@ -1015,6 +1126,39 @@ static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag)
                port->cmd_issue[MTIP_TAG_INDEX(tag)]);
 }
 
+static bool mtip_pause_ncq(struct mtip_port *port,
+                               struct host_to_dev_fis *fis)
+{
+       struct host_to_dev_fis *reply;
+       unsigned long task_file_data;
+
+       reply = port->rxfis + RX_FIS_D2H_REG;
+       task_file_data = readl(port->mmio+PORT_TFDATA);
+
+       if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT))
+               return false;
+
+       if (fis->command == ATA_CMD_SEC_ERASE_PREP) {
+               set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+               port->ic_pause_timer = jiffies;
+               return true;
+       } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) &&
+                                       (fis->features == 0x03)) {
+               set_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
+               port->ic_pause_timer = jiffies;
+               return true;
+       } else if ((fis->command == ATA_CMD_SEC_ERASE_UNIT) ||
+               ((fis->command == 0xFC) &&
+                       (fis->features == 0x27 || fis->features == 0x72 ||
+                        fis->features == 0x62 || fis->features == 0x26))) {
+               /* Com reset after secure erase or lowlevel format */
+               mtip_restart_port(port);
+               return false;
+       }
+
+       return false;
+}
+
 /*
  * Wait for port to quiesce
  *
@@ -1033,11 +1177,13 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
 
        to = jiffies + msecs_to_jiffies(timeout);
        do {
-               if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) &&
-                       test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
+               if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) &&
+                       test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
                        msleep(20);
                        continue; /* svc thd is actively issuing commands */
                }
+               if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+                       return -EFAULT;
                /*
                 * Ignore s_active bit 0 of array element 0.
                 * This bit will always be set
@@ -1074,7 +1220,7 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
  *     -EAGAIN  Time out waiting for command to complete.
  */
 static int mtip_exec_internal_command(struct mtip_port *port,
-                                       void *fis,
+                                       struct host_to_dev_fis *fis,
                                        int fis_len,
                                        dma_addr_t buffer,
                                        int buf_len,
@@ -1084,8 +1230,9 @@ static int mtip_exec_internal_command(struct mtip_port *port,
 {
        struct mtip_cmd_sg *command_sg;
        DECLARE_COMPLETION_ONSTACK(wait);
-       int rv = 0;
+       int rv = 0, ready2go = 1;
        struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL];
+       unsigned long to;
 
        /* Make sure the buffer is 8 byte aligned. This is asic specific. */
        if (buffer & 0x00000007) {
@@ -1094,23 +1241,38 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                return -EFAULT;
        }
 
-       /* Only one internal command should be running at a time */
-       if (test_and_set_bit(MTIP_TAG_INTERNAL, port->allocated)) {
+       to = jiffies + msecs_to_jiffies(timeout);
+       do {
+               ready2go = !test_and_set_bit(MTIP_TAG_INTERNAL,
+                                               port->allocated);
+               if (ready2go)
+                       break;
+               mdelay(100);
+       } while (time_before(jiffies, to));
+       if (!ready2go) {
                dev_warn(&port->dd->pdev->dev,
-                       "Internal command already active\n");
+                       "Internal cmd active. new cmd [%02X]\n", fis->command);
                return -EBUSY;
        }
-       set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
+       set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+       port->ic_pause_timer = 0;
+
+       if (fis->command == ATA_CMD_SEC_ERASE_UNIT)
+               clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+       else if (fis->command == ATA_CMD_DOWNLOAD_MICRO)
+               clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
 
        if (atomic == GFP_KERNEL) {
-               /* wait for io to complete if non atomic */
-               if (mtip_quiesce_io(port, 5000) < 0) {
-                       dev_warn(&port->dd->pdev->dev,
-                               "Failed to quiesce IO\n");
-                       release_slot(port, MTIP_TAG_INTERNAL);
-                       clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
-                       wake_up_interruptible(&port->svc_wait);
-                       return -EBUSY;
+               if (fis->command != ATA_CMD_STANDBYNOW1) {
+                       /* wait for io to complete if non atomic */
+                       if (mtip_quiesce_io(port, 5000) < 0) {
+                               dev_warn(&port->dd->pdev->dev,
+                                       "Failed to quiesce IO\n");
+                               release_slot(port, MTIP_TAG_INTERNAL);
+                               clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+                               wake_up_interruptible(&port->svc_wait);
+                               return -EBUSY;
+                       }
                }
 
                /* Set the completion function and data for the command. */
@@ -1120,7 +1282,7 @@ static int mtip_exec_internal_command(struct mtip_port *port,
        } else {
                /* Clear completion - we're going to poll */
                int_cmd->comp_data = NULL;
-               int_cmd->comp_func = NULL;
+               int_cmd->comp_func = mtip_null_completion;
        }
 
        /* Copy the command to the command table */
@@ -1159,6 +1321,12 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                                "Internal command did not complete [%d] "
                                "within timeout of  %lu ms\n",
                                atomic, timeout);
+                       if (mtip_check_surprise_removal(port->dd->pdev) ||
+                               test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                                               &port->dd->dd_flag)) {
+                               rv = -ENXIO;
+                               goto exec_ic_exit;
+                       }
                        rv = -EAGAIN;
                }
 
@@ -1166,31 +1334,59 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                        & (1 << MTIP_TAG_INTERNAL)) {
                        dev_warn(&port->dd->pdev->dev,
                                "Retiring internal command but CI is 1.\n");
+                       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                                               &port->dd->dd_flag)) {
+                               hba_reset_nosleep(port->dd);
+                               rv = -ENXIO;
+                       } else {
+                               mtip_restart_port(port);
+                               rv = -EAGAIN;
+                       }
+                       goto exec_ic_exit;
                }
 
        } else {
                /* Spin for <timeout> checking if command still outstanding */
                timeout = jiffies + msecs_to_jiffies(timeout);
-
-               while ((readl(
-                       port->cmd_issue[MTIP_TAG_INTERNAL])
-                       & (1 << MTIP_TAG_INTERNAL))
-                       && time_before(jiffies, timeout))
-                       ;
+               while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL])
+                               & (1 << MTIP_TAG_INTERNAL))
+                               && time_before(jiffies, timeout)) {
+                       if (mtip_check_surprise_removal(port->dd->pdev)) {
+                               rv = -ENXIO;
+                               goto exec_ic_exit;
+                       }
+                       if ((fis->command != ATA_CMD_STANDBYNOW1) &&
+                               test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                                               &port->dd->dd_flag)) {
+                               rv = -ENXIO;
+                               goto exec_ic_exit;
+                       }
+               }
 
                if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
                        & (1 << MTIP_TAG_INTERNAL)) {
                        dev_err(&port->dd->pdev->dev,
-                               "Internal command did not complete [%d]\n",
-                               atomic);
+                               "Internal command did not complete [atomic]\n");
                        rv = -EAGAIN;
+                       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                                               &port->dd->dd_flag)) {
+                               hba_reset_nosleep(port->dd);
+                               rv = -ENXIO;
+                       } else {
+                               mtip_restart_port(port);
+                               rv = -EAGAIN;
+                       }
                }
        }
-
+exec_ic_exit:
        /* Clear the allocated and active bits for the internal command. */
        atomic_set(&int_cmd->active, 0);
        release_slot(port, MTIP_TAG_INTERNAL);
-       clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
+       if (rv >= 0 && mtip_pause_ncq(port, fis)) {
+               /* NCQ paused */
+               return rv;
+       }
+       clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
        wake_up_interruptible(&port->svc_wait);
 
        return rv;
@@ -1240,6 +1436,9 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer)
        int rv = 0;
        struct host_to_dev_fis fis;
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+               return -EFAULT;
+
        /* Build the FIS. */
        memset(&fis, 0, sizeof(struct host_to_dev_fis));
        fis.type        = 0x27;
@@ -1313,6 +1512,7 @@ static int mtip_standby_immediate(struct mtip_port *port)
 {
        int rv;
        struct host_to_dev_fis  fis;
+       unsigned long start;
 
        /* Build the FIS. */
        memset(&fis, 0, sizeof(struct host_to_dev_fis));
@@ -1320,15 +1520,150 @@ static int mtip_standby_immediate(struct mtip_port *port)
        fis.opts        = 1 << 7;
        fis.command     = ATA_CMD_STANDBYNOW1;
 
-       /* Execute the command.  Use a 15-second timeout for large drives. */
+       start = jiffies;
        rv = mtip_exec_internal_command(port,
                                        &fis,
                                        5,
                                        0,
                                        0,
                                        0,
-                                       GFP_KERNEL,
+                                       GFP_ATOMIC,
                                        15000);
+       dbg_printk(MTIP_DRV_NAME "Time taken to complete standby cmd: %d ms\n",
+                       jiffies_to_msecs(jiffies - start));
+       if (rv)
+               dev_warn(&port->dd->pdev->dev,
+                       "STANDBY IMMEDIATE command failed.\n");
+
+       return rv;
+}
+
+/*
+ * Issue a READ LOG EXT command to the device.
+ *
+ * @port       pointer to the port structure.
+ * @page       page number to fetch
+ * @buffer     pointer to buffer
+ * @buffer_dma dma address corresponding to @buffer
+ * @sectors    page length to fetch, in sectors
+ *
+ * return value
+ *     @rv     return value from mtip_exec_internal_command()
+ */
+static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer,
+                               dma_addr_t buffer_dma, unsigned int sectors)
+{
+       struct host_to_dev_fis fis;
+
+       memset(&fis, 0, sizeof(struct host_to_dev_fis));
+       fis.type        = 0x27;
+       fis.opts        = 1 << 7;
+       fis.command     = ATA_CMD_READ_LOG_EXT;
+       fis.sect_count  = sectors & 0xFF;
+       fis.sect_cnt_ex = (sectors >> 8) & 0xFF;
+       fis.lba_low     = page;
+       fis.lba_mid     = 0;
+       fis.device      = ATA_DEVICE_OBS;
+
+       memset(buffer, 0, sectors * ATA_SECT_SIZE);
+
+       return mtip_exec_internal_command(port,
+                                       &fis,
+                                       5,
+                                       buffer_dma,
+                                       sectors * ATA_SECT_SIZE,
+                                       0,
+                                       GFP_ATOMIC,
+                                       MTIP_INTERNAL_COMMAND_TIMEOUT_MS);
+}
+
+/*
+ * Issue a SMART READ DATA command to the device.
+ *
+ * @port       pointer to the port structure.
+ * @buffer     pointer to buffer
+ * @buffer_dma dma address corresponding to @buffer
+ *
+ * return value
+ *     @rv     return value from mtip_exec_internal_command()
+ */
+static int mtip_get_smart_data(struct mtip_port *port, u8 *buffer,
+                                       dma_addr_t buffer_dma)
+{
+       struct host_to_dev_fis fis;
+
+       memset(&fis, 0, sizeof(struct host_to_dev_fis));
+       fis.type        = 0x27;
+       fis.opts        = 1 << 7;
+       fis.command     = ATA_CMD_SMART;
+       fis.features    = 0xD0;
+       fis.sect_count  = 1;
+       fis.lba_mid     = 0x4F;
+       fis.lba_hi      = 0xC2;
+       fis.device      = ATA_DEVICE_OBS;
+
+       return mtip_exec_internal_command(port,
+                                       &fis,
+                                       5,
+                                       buffer_dma,
+                                       ATA_SECT_SIZE,
+                                       0,
+                                       GFP_ATOMIC,
+                                       15000);
+}
+
+/*
+ * Get the value of a smart attribute
+ *
+ * @port       pointer to the port structure
+ * @id         attribute number
+ * @attrib     pointer to return attrib information corresponding to @id
+ *
+ * return value
+ *     -EINVAL NULL buffer passed or unsupported attribute @id.
+ *     -EPERM  Identify data not valid, SMART not supported or not enabled
+ */
+static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id,
+                                               struct smart_attr *attrib)
+{
+       int rv, i;
+       struct smart_attr *pattr;
+
+       if (!attrib)
+               return -EINVAL;
+
+       if (!port->identify_valid) {
+               dev_warn(&port->dd->pdev->dev, "IDENTIFY DATA not valid\n");
+               return -EPERM;
+       }
+       if (!(port->identify[82] & 0x1)) {
+               dev_warn(&port->dd->pdev->dev, "SMART not supported\n");
+               return -EPERM;
+       }
+       if (!(port->identify[85] & 0x1)) {
+               dev_warn(&port->dd->pdev->dev, "SMART not enabled\n");
+               return -EPERM;
+       }
+
+       memset(port->smart_buf, 0, ATA_SECT_SIZE);
+       rv = mtip_get_smart_data(port, port->smart_buf, port->smart_buf_dma);
+       if (rv) {
+               dev_warn(&port->dd->pdev->dev, "Failed to ge SMART data\n");
+               return rv;
+       }
+
+       pattr = (struct smart_attr *)(port->smart_buf + 2);
+       for (i = 0; i < 29; i++, pattr++)
+               if (pattr->attr_id == id) {
+                       memcpy(attrib, pattr, sizeof(struct smart_attr));
+                       break;
+               }
+
+       if (i == 29) {
+               dev_warn(&port->dd->pdev->dev,
+                       "Query for invalid SMART attribute ID\n");
+               rv = -EINVAL;
+       }
 
        return rv;
 }
@@ -1504,10 +1839,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command)
        fis.cyl_hi      = command[5];
        fis.device      = command[6] & ~0x10; /* Clear the dev bit*/
 
-
-       dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, "
-               "nsect %x, sect %x, lcyl %x, "
-               "hcyl %x, sel %x\n",
+       dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n",
                __func__,
                command[0],
                command[1],
@@ -1534,8 +1866,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command)
        command[4] = reply->cyl_low;
        command[5] = reply->cyl_hi;
 
-       dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, "
-               "err %x , cyl_lo %x cyl_hi %x\n",
+       dbg_printk(MTIP_DRV_NAME " %s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n",
                __func__,
                command[0],
                command[1],
@@ -1578,7 +1909,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
        }
 
        dbg_printk(MTIP_DRV_NAME
-               "%s: User Command: cmd %x, sect %x, "
+               " %s: User Command: cmd %x, sect %x, "
                "feat %x, sectcnt %x\n",
                __func__,
                command[0],
@@ -1607,7 +1938,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
        command[2] = command[3];
 
        dbg_printk(MTIP_DRV_NAME
-               "%s: Completion Status: stat %x, "
+               " %s: Completion Status: stat %x, "
                "err %x, cmd %x\n",
                __func__,
                command[0],
@@ -1810,9 +2141,10 @@ static int exec_drive_taskfile(struct driver_data *dd,
        }
 
        dbg_printk(MTIP_DRV_NAME
-               "taskfile: cmd %x, feat %x, nsect %x,"
+               " %s: cmd %x, feat %x, nsect %x,"
                " sect/lbal %x, lcyl/lbam %x, hcyl/lbah %x,"
                " head/dev %x\n",
+               __func__,
                fis.command,
                fis.features,
                fis.sect_count,
@@ -1823,8 +2155,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
 
        switch (fis.command) {
        case ATA_CMD_DOWNLOAD_MICRO:
-               /* Change timeout for Download Microcode to 60 seconds.*/
-               timeout = 60000;
+               /* Change timeout for Download Microcode to 2 minutes */
+               timeout = 120000;
                break;
        case ATA_CMD_SEC_ERASE_UNIT:
                /* Change timeout for Security Erase Unit to 4 minutes.*/
@@ -1840,8 +2172,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
                timeout = 10000;
                break;
        case ATA_CMD_SMART:
-               /* Change timeout for vendor unique command to 10 secs */
-               timeout = 10000;
+               /* Change timeout for vendor unique command to 15 secs */
+               timeout = 15000;
                break;
        default:
                timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS;
@@ -1903,18 +2235,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
                req_task->hob_ports[1] = reply->features_ex;
                req_task->hob_ports[2] = reply->sect_cnt_ex;
        }
-
-       /* Com rest after secure erase or lowlevel format */
-       if (((fis.command == ATA_CMD_SEC_ERASE_UNIT) ||
-               ((fis.command == 0xFC) &&
-                       (fis.features == 0x27 || fis.features == 0x72 ||
-                        fis.features == 0x62 || fis.features == 0x26))) &&
-                        !(reply->command & 1)) {
-               mtip_restart_port(dd->port);
-       }
-
        dbg_printk(MTIP_DRV_NAME
-               "%s: Completion: stat %x,"
+               " %s: Completion: stat %x,"
                "err %x, sect_cnt %x, lbalo %x,"
                "lbamid %x, lbahi %x, dev %x\n",
                __func__,
@@ -2080,14 +2402,10 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
        struct host_to_dev_fis  *fis;
        struct mtip_port *port = dd->port;
        struct mtip_cmd *command = &port->commands[tag];
+       int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 
        /* Map the scatter list for DMA access */
-       if (dir == READ)
-               nents = dma_map_sg(&dd->pdev->dev, command->sg,
-                                       nents, DMA_FROM_DEVICE);
-       else
-               nents = dma_map_sg(&dd->pdev->dev, command->sg,
-                                       nents, DMA_TO_DEVICE);
+       nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir);
 
        command->scatter_ents = nents;
 
@@ -2127,7 +2445,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
         */
        command->comp_data = dd;
        command->comp_func = mtip_async_complete;
-       command->direction = (dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+       command->direction = dma_dir;
 
        /*
         * Set the completion function and data for the command passed
@@ -2140,19 +2458,16 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
         * To prevent this command from being issued
         * if an internal command is in progress or error handling is active.
         */
-       if (unlikely(test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) ||
-                       test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags))) {
+       if (port->flags & MTIP_PF_PAUSE_IO) {
                set_bit(tag, port->cmds_to_issue);
-               set_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
+               set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags);
                return;
        }
 
        /* Issue the command to the hardware */
        mtip_issue_ncq_command(port, tag);
 
-       /* Set the command's timeout value.*/
-       port->commands[tag].comp_time = jiffies + msecs_to_jiffies(
-                                       MTIP_NCQ_COMMAND_TIMEOUT_MS);
+       return;
 }
 
 /*
@@ -2191,6 +2506,10 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
        down(&dd->port->cmd_slot);
        *tag = get_slot(dd->port);
 
+       if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) {
+               up(&dd->port->cmd_slot);
+               return NULL;
+       }
        if (unlikely(*tag < 0))
                return NULL;
 
@@ -2207,7 +2526,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
  * return value
  *     The size, in bytes, of the data copied into buf.
  */
-static ssize_t hw_show_registers(struct device *dev,
+static ssize_t mtip_hw_show_registers(struct device *dev,
                                struct device_attribute *attr,
                                char *buf)
 {
@@ -2216,7 +2535,7 @@ static ssize_t hw_show_registers(struct device *dev,
        int size = 0;
        int n;
 
-       size += sprintf(&buf[size], "%s:\ns_active:\n", __func__);
+       size += sprintf(&buf[size], "S ACTive:\n");
 
        for (n = 0; n < dd->slot_groups; n++)
                size += sprintf(&buf[size], "0x%08x\n",
@@ -2240,20 +2559,39 @@ static ssize_t hw_show_registers(struct device *dev,
                                 group_allocated);
        }
 
-       size += sprintf(&buf[size], "completed:\n");
+       size += sprintf(&buf[size], "Completed:\n");
 
        for (n = 0; n < dd->slot_groups; n++)
                size += sprintf(&buf[size], "0x%08x\n",
                                readl(dd->port->completed[n]));
 
-       size += sprintf(&buf[size], "PORT_IRQ_STAT 0x%08x\n",
+       size += sprintf(&buf[size], "PORT IRQ STAT : 0x%08x\n",
                                readl(dd->port->mmio + PORT_IRQ_STAT));
-       size += sprintf(&buf[size], "HOST_IRQ_STAT 0x%08x\n",
+       size += sprintf(&buf[size], "HOST IRQ STAT : 0x%08x\n",
                                readl(dd->mmio + HOST_IRQ_STAT));
 
        return size;
 }
-static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL);
+
+static ssize_t mtip_hw_show_status(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       struct driver_data *dd = dev_to_disk(dev)->private_data;
+       int size = 0;
+
+       if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))
+               size += sprintf(buf, "%s", "thermal_shutdown\n");
+       else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag))
+               size += sprintf(buf, "%s", "write_protect\n");
+       else
+               size += sprintf(buf, "%s", "online\n");
+
+       return size;
+}
+
+static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL);
+static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL);
 
 /*
  * Create the sysfs related attributes.
@@ -2272,7 +2610,10 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj)
 
        if (sysfs_create_file(kobj, &dev_attr_registers.attr))
                dev_warn(&dd->pdev->dev,
-                       "Error creating registers sysfs entry\n");
+                       "Error creating 'registers' sysfs entry\n");
+       if (sysfs_create_file(kobj, &dev_attr_status.attr))
+               dev_warn(&dd->pdev->dev,
+                       "Error creating 'status' sysfs entry\n");
        return 0;
 }
 
@@ -2292,6 +2633,7 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj)
                return -EINVAL;
 
        sysfs_remove_file(kobj, &dev_attr_registers.attr);
+       sysfs_remove_file(kobj, &dev_attr_status.attr);
 
        return 0;
 }
@@ -2384,10 +2726,12 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
                "FTL rebuild in progress. Polling for completion.\n");
 
        start = jiffies;
-       dd->ftlrebuildflag = 1;
        timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS);
 
        do {
+               if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                               &dd->dd_flag)))
+                       return -EFAULT;
                if (mtip_check_surprise_removal(dd->pdev))
                        return -EFAULT;
 
@@ -2408,22 +2752,17 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
                        dev_warn(&dd->pdev->dev,
                                "FTL rebuild complete (%d secs).\n",
                        jiffies_to_msecs(jiffies - start) / 1000);
-                       dd->ftlrebuildflag = 0;
                        mtip_block_initialize(dd);
-                       break;
+                       return 0;
                }
                ssleep(10);
        } while (time_before(jiffies, timeout));
 
        /* Check for timeout */
-       if (dd->ftlrebuildflag) {
-               dev_err(&dd->pdev->dev,
+       dev_err(&dd->pdev->dev,
                "Timed out waiting for FTL rebuild to complete (%d secs).\n",
                jiffies_to_msecs(jiffies - start) / 1000);
-               return -EFAULT;
-       }
-
-       return 0;
+       return -EFAULT;
 }
 
 /*
@@ -2448,14 +2787,17 @@ static int mtip_service_thread(void *data)
                 * is in progress nor error handling is active
                 */
                wait_event_interruptible(port->svc_wait, (port->flags) &&
-                       !test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) &&
-                       !test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags));
+                       !(port->flags & MTIP_PF_PAUSE_IO));
 
                if (kthread_should_stop())
                        break;
 
-               set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
-               if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
+               if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                               &dd->dd_flag)))
+                       break;
+
+               set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
+               if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
                        slot = 1;
                        /* used to restrict the loop to one iteration */
                        slot_start = num_cmd_slots;
@@ -2480,21 +2822,19 @@ static int mtip_service_thread(void *data)
                                /* Issue the command to the hardware */
                                mtip_issue_ncq_command(port, slot);
 
-                               /* Set the command's timeout value.*/
-                               port->commands[slot].comp_time = jiffies +
-                               msecs_to_jiffies(MTIP_NCQ_COMMAND_TIMEOUT_MS);
-
                                clear_bit(slot, port->cmds_to_issue);
                        }
 
-                       clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
-               } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) {
-                       mtip_ftl_rebuild_poll(dd);
-                       clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags);
+                       clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags);
+               } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) {
+                       if (!mtip_ftl_rebuild_poll(dd))
+                               set_bit(MTIP_DDF_REBUILD_FAILED_BIT,
+                                                       &dd->dd_flag);
+                       clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
                }
-               clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
+               clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
 
-               if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags))
+               if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags))
                        break;
        }
        return 0;
@@ -2513,6 +2853,9 @@ static int mtip_hw_init(struct driver_data *dd)
        int i;
        int rv;
        unsigned int num_command_slots;
+       unsigned long timeout, timetaken;
+       unsigned char *buf;
+       struct smart_attr attr242;
 
        dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR];
 
@@ -2547,7 +2890,7 @@ static int mtip_hw_init(struct driver_data *dd)
        /* Allocate memory for the command list. */
        dd->port->command_list =
                dmam_alloc_coherent(&dd->pdev->dev,
-                       HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+                       HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
                        &dd->port->command_list_dma,
                        GFP_KERNEL);
        if (!dd->port->command_list) {
@@ -2560,7 +2903,7 @@ static int mtip_hw_init(struct driver_data *dd)
        /* Clear the memory we have allocated. */
        memset(dd->port->command_list,
                0,
-               HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2));
+               HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4));
 
        /* Setup the addresse of the RX FIS. */
        dd->port->rxfis     = dd->port->command_list + HW_CMD_SLOT_SZ;
@@ -2576,10 +2919,19 @@ static int mtip_hw_init(struct driver_data *dd)
        dd->port->identify_dma = dd->port->command_tbl_dma +
                                        HW_CMD_TBL_AR_SZ;
 
-       /* Setup the address of the sector buffer. */
+       /* Setup the address of the sector buffer - for some non-ncq cmds */
        dd->port->sector_buffer = (void *) dd->port->identify + ATA_SECT_SIZE;
        dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE;
 
+       /* Setup the address of the log buf - for read log command */
+       dd->port->log_buf = (void *)dd->port->sector_buffer  + ATA_SECT_SIZE;
+       dd->port->log_buf_dma = dd->port->sector_buffer_dma + ATA_SECT_SIZE;
+
+       /* Setup the address of the smart buf - for smart read data command */
+       dd->port->smart_buf = (void *)dd->port->log_buf  + ATA_SECT_SIZE;
+       dd->port->smart_buf_dma = dd->port->log_buf_dma + ATA_SECT_SIZE;
+
+
        /* Point the command headers at the command tables. */
        for (i = 0; i < num_command_slots; i++) {
                dd->port->commands[i].command_header =
@@ -2623,14 +2975,43 @@ static int mtip_hw_init(struct driver_data *dd)
                        dd->port->mmio + i*0x80 + PORT_SDBV;
        }
 
-       /* Reset the HBA. */
-       if (mtip_hba_reset(dd) < 0) {
-               dev_err(&dd->pdev->dev,
-                       "Card did not reset within timeout\n");
-               rv = -EIO;
+       timetaken = jiffies;
+       timeout = jiffies + msecs_to_jiffies(30000);
+       while (((readl(dd->port->mmio + PORT_SCR_STAT) & 0x0F) != 0x03) &&
+                time_before(jiffies, timeout)) {
+               mdelay(100);
+       }
+       if (unlikely(mtip_check_surprise_removal(dd->pdev))) {
+               timetaken = jiffies - timetaken;
+               dev_warn(&dd->pdev->dev,
+                       "Surprise removal detected at %u ms\n",
+                       jiffies_to_msecs(timetaken));
+               rv = -ENODEV;
+               goto out2 ;
+       }
+       if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) {
+               timetaken = jiffies - timetaken;
+               dev_warn(&dd->pdev->dev,
+                       "Removal detected at %u ms\n",
+                       jiffies_to_msecs(timetaken));
+               rv = -EFAULT;
                goto out2;
        }
 
+       /* Conditionally reset the HBA. */
+       if (!(readl(dd->mmio + HOST_CAP) & HOST_CAP_NZDMA)) {
+               if (mtip_hba_reset(dd) < 0) {
+                       dev_err(&dd->pdev->dev,
+                               "Card did not reset within timeout\n");
+                       rv = -EIO;
+                       goto out2;
+               }
+       } else {
+               /* Clear any pending interrupts on the HBA */
+               writel(readl(dd->mmio + HOST_IRQ_STAT),
+                       dd->mmio + HOST_IRQ_STAT);
+       }
+
        mtip_init_port(dd->port);
        mtip_start_port(dd->port);
 
@@ -2660,6 +3041,12 @@ static int mtip_hw_init(struct driver_data *dd)
        mod_timer(&dd->port->cmd_timer,
                jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
 
+
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) {
+               rv = -EFAULT;
+               goto out3;
+       }
+
        if (mtip_get_identify(dd->port, NULL) < 0) {
                rv = -EFAULT;
                goto out3;
@@ -2667,10 +3054,47 @@ static int mtip_hw_init(struct driver_data *dd)
 
        if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) ==
                MTIP_FTL_REBUILD_MAGIC) {
-               set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags);
+               set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags);
                return MTIP_FTL_REBUILD_MAGIC;
        }
        mtip_dump_identify(dd->port);
+
+       /* check write protect, over temp and rebuild statuses */
+       rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ,
+                               dd->port->log_buf,
+                               dd->port->log_buf_dma, 1);
+       if (rv) {
+               dev_warn(&dd->pdev->dev,
+                       "Error in READ LOG EXT (10h) command\n");
+               /* non-critical error, don't fail the load */
+       } else {
+               buf = (unsigned char *)dd->port->log_buf;
+               if (buf[259] & 0x1) {
+                       dev_info(&dd->pdev->dev,
+                               "Write protect bit is set.\n");
+                       set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag);
+               }
+               if (buf[288] == 0xF7) {
+                       dev_info(&dd->pdev->dev,
+                               "Exceeded Tmax, drive in thermal shutdown.\n");
+                       set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag);
+               }
+               if (buf[288] == 0xBF) {
+                       dev_info(&dd->pdev->dev,
+                               "Drive indicates rebuild has failed.\n");
+                       /* TODO */
+               }
+       }
+
+       /* get write protect progess */
+       memset(&attr242, 0, sizeof(struct smart_attr));
+       if (mtip_get_smart_attr(dd->port, 242, &attr242))
+               dev_warn(&dd->pdev->dev,
+                               "Unable to check write protect progress\n");
+       else
+               dev_info(&dd->pdev->dev,
+                               "Write protect progress: %d%% (%d blocks)\n",
+                               attr242.cur, attr242.data);
        return rv;
 
 out3:
@@ -2688,7 +3112,7 @@ out2:
 
        /* Free the command/command header memory. */
        dmam_free_coherent(&dd->pdev->dev,
-                               HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+                               HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
                                dd->port->command_list,
                                dd->port->command_list_dma);
 out1:
@@ -2712,9 +3136,12 @@ static int mtip_hw_exit(struct driver_data *dd)
         * Send standby immediate (E0h) to the drive so that it
         * saves its state.
         */
-       if (atomic_read(&dd->drv_cleanup_done) != true) {
+       if (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
 
-               mtip_standby_immediate(dd->port);
+               if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags))
+                       if (mtip_standby_immediate(dd->port))
+                               dev_warn(&dd->pdev->dev,
+                                       "STANDBY IMMEDIATE failed\n");
 
                /* de-initialize the port. */
                mtip_deinit_port(dd->port);
@@ -2734,7 +3161,7 @@ static int mtip_hw_exit(struct driver_data *dd)
 
        /* Free the command/command header memory. */
        dmam_free_coherent(&dd->pdev->dev,
-                       HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+                       HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
                        dd->port->command_list,
                        dd->port->command_list_dma);
        /* Free the memory allocated for the for structure. */
@@ -2892,6 +3319,9 @@ static int mtip_block_ioctl(struct block_device *dev,
        if (!dd)
                return -ENOTTY;
 
+       if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)))
+               return -ENOTTY;
+
        switch (cmd) {
        case BLKFLSBUF:
                return -ENOTTY;
@@ -2927,6 +3357,9 @@ static int mtip_block_compat_ioctl(struct block_device *dev,
        if (!dd)
                return -ENOTTY;
 
+       if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)))
+               return -ENOTTY;
+
        switch (cmd) {
        case BLKFLSBUF:
                return -ENOTTY;
@@ -3049,6 +3482,24 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
        int nents = 0;
        int tag = 0;
 
+       if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) {
+               if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                                                       &dd->dd_flag))) {
+                       bio_endio(bio, -ENXIO);
+                       return;
+               }
+               if (unlikely(test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))) {
+                       bio_endio(bio, -ENODATA);
+                       return;
+               }
+               if (unlikely(test_bit(MTIP_DDF_WRITE_PROTECT_BIT,
+                                                       &dd->dd_flag) &&
+                               bio_data_dir(bio))) {
+                       bio_endio(bio, -ENODATA);
+                       return;
+               }
+       }
+
        if (unlikely(!bio_has_data(bio))) {
                blk_queue_flush(queue, 0);
                bio_endio(bio, 0);
@@ -3061,7 +3512,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
 
                if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) {
                        dev_warn(&dd->pdev->dev,
-                               "Maximum number of SGL entries exceeded");
+                               "Maximum number of SGL entries exceeded\n");
                        bio_io_error(bio);
                        mtip_hw_release_scatterlist(dd, tag);
                        return;
@@ -3210,8 +3661,10 @@ skip_create_disk:
                kobject_put(kobj);
        }
 
-       if (dd->mtip_svc_handler)
+       if (dd->mtip_svc_handler) {
+               set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
                return rv; /* service thread created for handling rebuild */
+       }
 
 start_service_thread:
        sprintf(thd_name, "mtip_svc_thd_%02d", index);
@@ -3220,12 +3673,15 @@ start_service_thread:
                                                dd, thd_name);
 
        if (IS_ERR(dd->mtip_svc_handler)) {
-               printk(KERN_ERR "mtip32xx: service thread failed to start\n");
+               dev_err(&dd->pdev->dev, "service thread failed to start\n");
                dd->mtip_svc_handler = NULL;
                rv = -EFAULT;
                goto kthread_run_error;
        }
 
+       if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC)
+               rv = wait_for_rebuild;
+
        return rv;
 
 kthread_run_error:
@@ -3266,16 +3722,18 @@ static int mtip_block_remove(struct driver_data *dd)
        struct kobject *kobj;
 
        if (dd->mtip_svc_handler) {
-               set_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags);
+               set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags);
                wake_up_interruptible(&dd->port->svc_wait);
                kthread_stop(dd->mtip_svc_handler);
        }
 
-       /* Clean up the sysfs attributes managed by the protocol layer. */
-       kobj = kobject_get(&disk_to_dev(dd->disk)->kobj);
-       if (kobj) {
-               mtip_hw_sysfs_exit(dd, kobj);
-               kobject_put(kobj);
+       /* Clean up the sysfs attributes, if created */
+       if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) {
+               kobj = kobject_get(&disk_to_dev(dd->disk)->kobj);
+               if (kobj) {
+                       mtip_hw_sysfs_exit(dd, kobj);
+                       kobject_put(kobj);
+               }
        }
 
        /*
@@ -3283,6 +3741,11 @@ static int mtip_block_remove(struct driver_data *dd)
         * from /dev
         */
        del_gendisk(dd->disk);
+
+       spin_lock(&rssd_index_lock);
+       ida_remove(&rssd_index_ida, dd->index);
+       spin_unlock(&rssd_index_lock);
+
        blk_cleanup_queue(dd->queue);
        dd->disk  = NULL;
        dd->queue = NULL;
@@ -3312,6 +3775,11 @@ static int mtip_block_shutdown(struct driver_data *dd)
 
        /* Delete our gendisk structure, and cleanup the blk queue. */
        del_gendisk(dd->disk);
+
+       spin_lock(&rssd_index_lock);
+       ida_remove(&rssd_index_ida, dd->index);
+       spin_unlock(&rssd_index_lock);
+
        blk_cleanup_queue(dd->queue);
        dd->disk  = NULL;
        dd->queue = NULL;
@@ -3359,11 +3827,6 @@ static int mtip_pci_probe(struct pci_dev *pdev,
                return -ENOMEM;
        }
 
-       /* Set the atomic variable as 1 in case of SRSI */
-       atomic_set(&dd->drv_cleanup_done, true);
-
-       atomic_set(&dd->resumeflag, false);
-
        /* Attach the private data to this PCI device.  */
        pci_set_drvdata(pdev, dd);
 
@@ -3420,7 +3883,8 @@ static int mtip_pci_probe(struct pci_dev *pdev,
         * instance number.
         */
        instance++;
-
+       if (rv != MTIP_FTL_REBUILD_MAGIC)
+               set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
        goto done;
 
 block_initialize_err:
@@ -3434,9 +3898,6 @@ iomap_err:
        pci_set_drvdata(pdev, NULL);
        return rv;
 done:
-       /* Set the atomic variable as 0 in case of SRSI */
-       atomic_set(&dd->drv_cleanup_done, true);
-
        return rv;
 }
 
@@ -3452,8 +3913,10 @@ static void mtip_pci_remove(struct pci_dev *pdev)
        struct driver_data *dd = pci_get_drvdata(pdev);
        int counter = 0;
 
+       set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
+
        if (mtip_check_surprise_removal(pdev)) {
-               while (atomic_read(&dd->drv_cleanup_done) == false) {
+               while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
                        counter++;
                        msleep(20);
                        if (counter == 10) {
@@ -3463,8 +3926,6 @@ static void mtip_pci_remove(struct pci_dev *pdev)
                        }
                }
        }
-       /* Set the atomic variable as 1 in case of SRSI */
-       atomic_set(&dd->drv_cleanup_done, true);
 
        /* Clean up the block layer. */
        mtip_block_remove(dd);
@@ -3493,7 +3954,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
                return -EFAULT;
        }
 
-       atomic_set(&dd->resumeflag, true);
+       set_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag);
 
        /* Disable ports & interrupts then send standby immediate */
        rv = mtip_block_suspend(dd);
@@ -3559,7 +4020,7 @@ static int mtip_pci_resume(struct pci_dev *pdev)
                dev_err(&pdev->dev, "Unable to resume\n");
 
 err:
-       atomic_set(&dd->resumeflag, false);
+       clear_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag);
 
        return rv;
 }
@@ -3608,18 +4069,25 @@ MODULE_DEVICE_TABLE(pci, mtip_pci_tbl);
  */
 static int __init mtip_init(void)
 {
+       int error;
+
        printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
 
        /* Allocate a major block device number to use with this driver. */
-       mtip_major = register_blkdev(0, MTIP_DRV_NAME);
-       if (mtip_major < 0) {
+       error = register_blkdev(0, MTIP_DRV_NAME);
+       if (error <= 0) {
                printk(KERN_ERR "Unable to register block device (%d)\n",
-               mtip_major);
+               error);
                return -EBUSY;
        }
+       mtip_major = error;
 
        /* Register our PCI operations. */
-       return pci_register_driver(&mtip_pci_driver);
+       error = pci_register_driver(&mtip_pci_driver);
+       if (error)
+               unregister_blkdev(mtip_major, MTIP_DRV_NAME);
+
+       return error;
 }
 
 /*
index e0554a8f2233faf85c8f98409fdf83c9cdd5cae7..4ef58336310a126af9b4d0847dc4099e4af23610 100644 (file)
@@ -34,8 +34,8 @@
 /* offset of Device Control register in PCIe extended capabilites space */
 #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET  0x48
 
-/* # of times to retry timed out IOs */
-#define MTIP_MAX_RETRIES       5
+/* # of times to retry timed out/failed IOs */
+#define MTIP_MAX_RETRIES       2
 
 /* Various timeout values in ms */
 #define MTIP_NCQ_COMMAND_TIMEOUT_MS       5000
 #define __force_bit2int (unsigned int __force)
 
 /* below are bit numbers in 'flags' defined in mtip_port */
-#define MTIP_FLAG_IC_ACTIVE_BIT                        0
-#define MTIP_FLAG_EH_ACTIVE_BIT                        1
-#define MTIP_FLAG_SVC_THD_ACTIVE_BIT           2
-#define MTIP_FLAG_ISSUE_CMDS_BIT               4
-#define MTIP_FLAG_REBUILD_BIT                  5
-#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT      8
+#define MTIP_PF_IC_ACTIVE_BIT          0 /* pio/ioctl */
+#define MTIP_PF_EH_ACTIVE_BIT          1 /* error handling */
+#define MTIP_PF_SE_ACTIVE_BIT          2 /* secure erase */
+#define MTIP_PF_DM_ACTIVE_BIT          3 /* download microcde */
+#define MTIP_PF_PAUSE_IO       ((1 << MTIP_PF_IC_ACTIVE_BIT) | \
+                               (1 << MTIP_PF_EH_ACTIVE_BIT) | \
+                               (1 << MTIP_PF_SE_ACTIVE_BIT) | \
+                               (1 << MTIP_PF_DM_ACTIVE_BIT))
+
+#define MTIP_PF_SVC_THD_ACTIVE_BIT     4
+#define MTIP_PF_ISSUE_CMDS_BIT         5
+#define MTIP_PF_REBUILD_BIT            6
+#define MTIP_PF_SVC_THD_STOP_BIT       8
+
+/* below are bit numbers in 'dd_flag' defined in driver_data */
+#define MTIP_DDF_REMOVE_PENDING_BIT    1
+#define MTIP_DDF_OVER_TEMP_BIT         2
+#define MTIP_DDF_WRITE_PROTECT_BIT     3
+#define MTIP_DDF_STOP_IO       ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
+                               (1 << MTIP_DDF_OVER_TEMP_BIT) | \
+                               (1 << MTIP_DDF_WRITE_PROTECT_BIT))
+
+#define MTIP_DDF_CLEANUP_BIT           5
+#define MTIP_DDF_RESUME_BIT            6
+#define MTIP_DDF_INIT_DONE_BIT         7
+#define MTIP_DDF_REBUILD_FAILED_BIT    8
+
+__packed struct smart_attr{
+       u8 attr_id;
+       u16 flags;
+       u8 cur;
+       u8 worst;
+       u32 data;
+       u8 res[3];
+};
 
 /* Register Frame Information Structure (FIS), host to device. */
 struct host_to_dev_fis {
@@ -345,6 +374,12 @@ struct mtip_port {
         * when the command slot and all associated data structures
         * are no longer needed.
         */
+       u16 *log_buf;
+       dma_addr_t log_buf_dma;
+
+       u8 *smart_buf;
+       dma_addr_t smart_buf_dma;
+
        unsigned long allocated[SLOTBITS_IN_LONGS];
        /*
         * used to queue commands when an internal command is in progress
@@ -368,6 +403,7 @@ struct mtip_port {
         * Timer used to complete commands that have been active for too long.
         */
        struct timer_list cmd_timer;
+       unsigned long ic_pause_timer;
        /*
         * Semaphore used to block threads if there are no
         * command slots available.
@@ -404,13 +440,9 @@ struct driver_data {
 
        unsigned slot_groups; /* number of slot groups the product supports */
 
-       atomic_t drv_cleanup_done; /* Atomic variable for SRSI */
-
        unsigned long index; /* Index to determine the disk name */
 
-       unsigned int ftlrebuildflag; /* FTL rebuild flag */
-
-       atomic_t resumeflag; /* Atomic variable to track suspend/resume */
+       unsigned long dd_flag; /* NOTE: use atomic bit operations on this */
 
        struct task_struct *mtip_svc_handler; /* task_struct of svc thd */
 };
index c4a60badf252caee7bffff38cc0cf115d0bd81a4..0d39f2f4294a3c2587e5c019e39904b3f8440fc2 100644 (file)
@@ -351,6 +351,7 @@ static void virtblk_config_changed_work(struct work_struct *work)
                  cap_str_10, cap_str_2);
 
        set_capacity(vblk->disk, capacity);
+       revalidate_disk(vblk->disk);
 done:
        mutex_unlock(&vblk->config_lock);
 }
@@ -374,6 +375,34 @@ static int init_vq(struct virtio_blk *vblk)
        return err;
 }
 
+/*
+ * Legacy naming scheme used for virtio devices.  We are stuck with it for
+ * virtio blk but don't ever use it for any new driver.
+ */
+static int virtblk_name_format(char *prefix, int index, char *buf, int buflen)
+{
+       const int base = 'z' - 'a' + 1;
+       char *begin = buf + strlen(prefix);
+       char *end = buf + buflen;
+       char *p;
+       int unit;
+
+       p = end - 1;
+       *p = '\0';
+       unit = base;
+       do {
+               if (p == begin)
+                       return -EINVAL;
+               *--p = 'a' + (index % unit);
+               index = (index / unit) - 1;
+       } while (index >= 0);
+
+       memmove(begin, p, end - p);
+       memcpy(buf, prefix, strlen(prefix));
+
+       return 0;
+}
+
 static int __devinit virtblk_probe(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk;
@@ -442,18 +471,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
 
        q->queuedata = vblk;
 
-       if (index < 26) {
-               sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
-       } else if (index < (26 + 1) * 26) {
-               sprintf(vblk->disk->disk_name, "vd%c%c",
-                       'a' + index / 26 - 1, 'a' + index % 26);
-       } else {
-               const unsigned int m1 = (index / 26 - 1) / 26 - 1;
-               const unsigned int m2 = (index / 26 - 1) % 26;
-               const unsigned int m3 =  index % 26;
-               sprintf(vblk->disk->disk_name, "vd%c%c%c",
-                       'a' + m1, 'a' + m2, 'a' + m3);
-       }
+       virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN);
 
        vblk->disk->major = major;
        vblk->disk->first_minor = index_to_minor(index);
index 0088bf60f3689db6a704c1856c4f94a682d7db44..73f196ca713f20e037e22adccba64d0e00c936b1 100644 (file)
@@ -321,6 +321,7 @@ struct seg_buf {
 static void xen_blkbk_unmap(struct pending_req *req)
 {
        struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+       struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        unsigned int i, invcount = 0;
        grant_handle_t handle;
        int ret;
@@ -332,25 +333,12 @@ static void xen_blkbk_unmap(struct pending_req *req)
                gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
                                    GNTMAP_host_map, handle);
                pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
+               pages[invcount] = virt_to_page(vaddr(req, i));
                invcount++;
        }
 
-       ret = HYPERVISOR_grant_table_op(
-               GNTTABOP_unmap_grant_ref, unmap, invcount);
+       ret = gnttab_unmap_refs(unmap, pages, invcount, false);
        BUG_ON(ret);
-       /*
-        * Note, we use invcount, so nr->pages, so we can't index
-        * using vaddr(req, i).
-        */
-       for (i = 0; i < invcount; i++) {
-               ret = m2p_remove_override(
-                       virt_to_page(unmap[i].host_addr), false);
-               if (ret) {
-                       pr_alert(DRV_PFX "Failed to remove M2P override for %lx\n",
-                                (unsigned long)unmap[i].host_addr);
-                       continue;
-               }
-       }
 }
 
 static int xen_blkbk_map(struct blkif_request *req,
@@ -378,7 +366,7 @@ static int xen_blkbk_map(struct blkif_request *req,
                                  pending_req->blkif->domid);
        }
 
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg);
+       ret = gnttab_map_refs(map, NULL, &blkbk->pending_page(pending_req, 0), nseg);
        BUG_ON(ret);
 
        /*
@@ -398,15 +386,6 @@ static int xen_blkbk_map(struct blkif_request *req,
                if (ret)
                        continue;
 
-               ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr),
-                       blkbk->pending_page(pending_req, i), NULL);
-               if (ret) {
-                       pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n",
-                                (unsigned long)map[i].dev_bus_addr, ret);
-                       /* We could switch over to GNTTABOP_copy */
-                       continue;
-               }
-
                seg[i].buf  = map[i].dev_bus_addr |
                        (req->u.rw.seg[i].first_sect << 9);
        }
@@ -419,21 +398,18 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
        int err = 0;
        int status = BLKIF_RSP_OKAY;
        struct block_device *bdev = blkif->vbd.bdev;
+       unsigned long secure;
 
        blkif->st_ds_req++;
 
        xen_blkif_get(blkif);
-       if (blkif->blk_backend_type == BLKIF_BACKEND_PHY ||
-           blkif->blk_backend_type == BLKIF_BACKEND_FILE) {
-               unsigned long secure = (blkif->vbd.discard_secure &&
-                       (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ?
-                       BLKDEV_DISCARD_SECURE : 0;
-               err = blkdev_issue_discard(bdev,
-                               req->u.discard.sector_number,
-                               req->u.discard.nr_sectors,
-                               GFP_KERNEL, secure);
-       } else
-               err = -EOPNOTSUPP;
+       secure = (blkif->vbd.discard_secure &&
+                (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ?
+                BLKDEV_DISCARD_SECURE : 0;
+
+       err = blkdev_issue_discard(bdev, req->u.discard.sector_number,
+                                  req->u.discard.nr_sectors,
+                                  GFP_KERNEL, secure);
 
        if (err == -EOPNOTSUPP) {
                pr_debug(DRV_PFX "discard op failed, not supported\n");
@@ -830,7 +806,7 @@ static int __init xen_blkif_init(void)
        int i, mmap_pages;
        int rc = 0;
 
-       if (!xen_pv_domain())
+       if (!xen_domain())
                return -ENODEV;
 
        blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);
index d0ee7edc9be8ad1819a91a491eb907f18d545fbf..773cf27dc23fc595d6fca48ea8ec6c4992438d18 100644 (file)
@@ -146,11 +146,6 @@ enum blkif_protocol {
        BLKIF_PROTOCOL_X86_64 = 3,
 };
 
-enum blkif_backend_type {
-       BLKIF_BACKEND_PHY  = 1,
-       BLKIF_BACKEND_FILE = 2,
-};
-
 struct xen_vbd {
        /* What the domain refers to this vbd as. */
        blkif_vdev_t            handle;
@@ -177,7 +172,6 @@ struct xen_blkif {
        unsigned int            irq;
        /* Comms information. */
        enum blkif_protocol     blk_protocol;
-       enum blkif_backend_type blk_backend_type;
        union blkif_back_rings  blk_rings;
        void                    *blk_ring;
        /* The VBD attached to this interface. */
index 24a2fb57e5d012d57c5d3e1fc1929f27ac3998ee..4f66171c668354b490f1284aec48278b8676bd84 100644 (file)
@@ -381,72 +381,49 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
        err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache",
                            "%d", state);
        if (err)
-               xenbus_dev_fatal(dev, err, "writing feature-flush-cache");
+               dev_warn(&dev->dev, "writing feature-flush-cache (%d)", err);
 
        return err;
 }
 
-int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be)
+static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be)
 {
        struct xenbus_device *dev = be->dev;
        struct xen_blkif *blkif = be->blkif;
-       char *type;
        int err;
        int state = 0;
+       struct block_device *bdev = be->blkif->vbd.bdev;
+       struct request_queue *q = bdev_get_queue(bdev);
 
-       type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL);
-       if (!IS_ERR(type)) {
-               if (strncmp(type, "file", 4) == 0) {
-                       state = 1;
-                       blkif->blk_backend_type = BLKIF_BACKEND_FILE;
+       if (blk_queue_discard(q)) {
+               err = xenbus_printf(xbt, dev->nodename,
+                       "discard-granularity", "%u",
+                       q->limits.discard_granularity);
+               if (err) {
+                       dev_warn(&dev->dev, "writing discard-granularity (%d)", err);
+                       return;
                }
-               if (strncmp(type, "phy", 3) == 0) {
-                       struct block_device *bdev = be->blkif->vbd.bdev;
-                       struct request_queue *q = bdev_get_queue(bdev);
-                       if (blk_queue_discard(q)) {
-                               err = xenbus_printf(xbt, dev->nodename,
-                                       "discard-granularity", "%u",
-                                       q->limits.discard_granularity);
-                               if (err) {
-                                       xenbus_dev_fatal(dev, err,
-                                               "writing discard-granularity");
-                                       goto kfree;
-                               }
-                               err = xenbus_printf(xbt, dev->nodename,
-                                       "discard-alignment", "%u",
-                                       q->limits.discard_alignment);
-                               if (err) {
-                                       xenbus_dev_fatal(dev, err,
-                                               "writing discard-alignment");
-                                       goto kfree;
-                               }
-                               state = 1;
-                               blkif->blk_backend_type = BLKIF_BACKEND_PHY;
-                       }
-                       /* Optional. */
-                       err = xenbus_printf(xbt, dev->nodename,
-                               "discard-secure", "%d",
-                               blkif->vbd.discard_secure);
-                       if (err) {
-                               xenbus_dev_fatal(dev, err,
-                                       "writting discard-secure");
-                               goto kfree;
-                       }
+               err = xenbus_printf(xbt, dev->nodename,
+                       "discard-alignment", "%u",
+                       q->limits.discard_alignment);
+               if (err) {
+                       dev_warn(&dev->dev, "writing discard-alignment (%d)", err);
+                       return;
+               }
+               state = 1;
+               /* Optional. */
+               err = xenbus_printf(xbt, dev->nodename,
+                                   "discard-secure", "%d",
+                                   blkif->vbd.discard_secure);
+               if (err) {
+                       dev_warn(&dev->dev, "writing discard-secure (%d)", err);
+                       return;
                }
-       } else {
-               err = PTR_ERR(type);
-               xenbus_dev_fatal(dev, err, "reading type");
-               goto out;
        }
-
        err = xenbus_printf(xbt, dev->nodename, "feature-discard",
                            "%d", state);
        if (err)
-               xenbus_dev_fatal(dev, err, "writing feature-discard");
-kfree:
-       kfree(type);
-out:
-       return err;
+               dev_warn(&dev->dev, "writing feature-discard (%d)", err);
 }
 int xen_blkbk_barrier(struct xenbus_transaction xbt,
                      struct backend_info *be, int state)
@@ -457,7 +434,7 @@ int xen_blkbk_barrier(struct xenbus_transaction xbt,
        err = xenbus_printf(xbt, dev->nodename, "feature-barrier",
                            "%d", state);
        if (err)
-               xenbus_dev_fatal(dev, err, "writing feature-barrier");
+               dev_warn(&dev->dev, "writing feature-barrier (%d)", err);
 
        return err;
 }
@@ -689,14 +666,12 @@ again:
                return;
        }
 
-       err = xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support);
-       if (err)
-               goto abort;
+       /* If we can't advertise it is OK. */
+       xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support);
 
-       err = xen_blkbk_discard(xbt, be);
+       xen_blkbk_discard(xbt, be);
 
-       /* If we can't advertise it is OK. */
-       err = xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
+       xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
 
        err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
                            (unsigned long long)vbd_sz(&be->blkif->vbd));
index d5e1ab95674044361920140550b0c6b34f9be9b3..4e86393a09cf5c880917fd81d3e67e507a83c0f6 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/scatterlist.h>
+#include <linux/bitmap.h>
 
 #include <xen/xen.h>
 #include <xen/xenbus.h>
@@ -81,6 +82,7 @@ static const struct block_device_operations xlvbd_block_fops;
  */
 struct blkfront_info
 {
+       spinlock_t io_lock;
        struct mutex mutex;
        struct xenbus_device *xbdev;
        struct gendisk *gd;
@@ -105,8 +107,6 @@ struct blkfront_info
        int is_ready;
 };
 
-static DEFINE_SPINLOCK(blkif_io_lock);
-
 static unsigned int nr_minors;
 static unsigned long *minors;
 static DEFINE_SPINLOCK(minor_lock);
@@ -177,8 +177,7 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr)
 
        spin_lock(&minor_lock);
        if (find_next_bit(minors, end, minor) >= end) {
-               for (; minor < end; ++minor)
-                       __set_bit(minor, minors);
+               bitmap_set(minors, minor, nr);
                rc = 0;
        } else
                rc = -EBUSY;
@@ -193,8 +192,7 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr)
 
        BUG_ON(end > nr_minors);
        spin_lock(&minor_lock);
-       for (; minor < end; ++minor)
-               __clear_bit(minor, minors);
+       bitmap_clear(minors,  minor, nr);
        spin_unlock(&minor_lock);
 }
 
@@ -419,7 +417,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
        struct request_queue *rq;
        struct blkfront_info *info = gd->private_data;
 
-       rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
+       rq = blk_init_queue(do_blkif_request, &info->io_lock);
        if (rq == NULL)
                return -1;
 
@@ -636,14 +634,14 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
        if (info->rq == NULL)
                return;
 
-       spin_lock_irqsave(&blkif_io_lock, flags);
+       spin_lock_irqsave(&info->io_lock, flags);
 
        /* No more blkif_request(). */
        blk_stop_queue(info->rq);
 
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
-       spin_unlock_irqrestore(&blkif_io_lock, flags);
+       spin_unlock_irqrestore(&info->io_lock, flags);
 
        /* Flush gnttab callback work. Must be done with no locks held. */
        flush_work_sync(&info->work);
@@ -675,16 +673,16 @@ static void blkif_restart_queue(struct work_struct *work)
 {
        struct blkfront_info *info = container_of(work, struct blkfront_info, work);
 
-       spin_lock_irq(&blkif_io_lock);
+       spin_lock_irq(&info->io_lock);
        if (info->connected == BLKIF_STATE_CONNECTED)
                kick_pending_request_queues(info);
-       spin_unlock_irq(&blkif_io_lock);
+       spin_unlock_irq(&info->io_lock);
 }
 
 static void blkif_free(struct blkfront_info *info, int suspend)
 {
        /* Prevent new requests being issued until we fix things up. */
-       spin_lock_irq(&blkif_io_lock);
+       spin_lock_irq(&info->io_lock);
        info->connected = suspend ?
                BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
        /* No more blkif_request(). */
@@ -692,7 +690,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
                blk_stop_queue(info->rq);
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
-       spin_unlock_irq(&blkif_io_lock);
+       spin_unlock_irq(&info->io_lock);
 
        /* Flush gnttab callback work. Must be done with no locks held. */
        flush_work_sync(&info->work);
@@ -728,10 +726,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
        struct blkfront_info *info = (struct blkfront_info *)dev_id;
        int error;
 
-       spin_lock_irqsave(&blkif_io_lock, flags);
+       spin_lock_irqsave(&info->io_lock, flags);
 
        if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
-               spin_unlock_irqrestore(&blkif_io_lock, flags);
+               spin_unlock_irqrestore(&info->io_lock, flags);
                return IRQ_HANDLED;
        }
 
@@ -816,7 +814,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
 
        kick_pending_request_queues(info);
 
-       spin_unlock_irqrestore(&blkif_io_lock, flags);
+       spin_unlock_irqrestore(&info->io_lock, flags);
 
        return IRQ_HANDLED;
 }
@@ -991,6 +989,7 @@ static int blkfront_probe(struct xenbus_device *dev,
        }
 
        mutex_init(&info->mutex);
+       spin_lock_init(&info->io_lock);
        info->xbdev = dev;
        info->vdevice = vdevice;
        info->connected = BLKIF_STATE_DISCONNECTED;
@@ -1068,7 +1067,7 @@ static int blkif_recover(struct blkfront_info *info)
 
        xenbus_switch_state(info->xbdev, XenbusStateConnected);
 
-       spin_lock_irq(&blkif_io_lock);
+       spin_lock_irq(&info->io_lock);
 
        /* Now safe for us to use the shared ring */
        info->connected = BLKIF_STATE_CONNECTED;
@@ -1079,7 +1078,7 @@ static int blkif_recover(struct blkfront_info *info)
        /* Kick any other new requests queued since we resumed */
        kick_pending_request_queues(info);
 
-       spin_unlock_irq(&blkif_io_lock);
+       spin_unlock_irq(&info->io_lock);
 
        return 0;
 }
@@ -1277,10 +1276,10 @@ static void blkfront_connect(struct blkfront_info *info)
        xenbus_switch_state(info->xbdev, XenbusStateConnected);
 
        /* Kick pending requests. */
-       spin_lock_irq(&blkif_io_lock);
+       spin_lock_irq(&info->io_lock);
        info->connected = BLKIF_STATE_CONNECTED;
        kick_pending_request_queues(info);
-       spin_unlock_irq(&blkif_io_lock);
+       spin_unlock_irq(&info->io_lock);
 
        add_disk(info->gd);
 
@@ -1410,7 +1409,6 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
        mutex_lock(&blkfront_mutex);
 
        bdev = bdget_disk(disk, 0);
-       bdput(bdev);
 
        if (bdev->bd_openers)
                goto out;
@@ -1441,6 +1439,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
        }
 
 out:
+       bdput(bdev);
        mutex_unlock(&blkfront_mutex);
        return 0;
 }
@@ -1475,7 +1474,7 @@ static int __init xlblk_init(void)
        if (!xen_domain())
                return -ENODEV;
 
-       if (!xen_platform_pci_unplug)
+       if (xen_hvm_domain() && !xen_platform_pci_unplug)
                return -ENODEV;
 
        if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
index 3845ab44c3304e1d2e4ce0f8bfc7455cd5ef6717..dfd7876f127c0d23c9d45bc2922ccefe85ff3181 100644 (file)
@@ -906,8 +906,8 @@ int hpet_alloc(struct hpet_data *hdp)
                hpetp->hp_which, hdp->hd_phys_address,
                hpetp->hp_ntimer > 1 ? "s" : "");
        for (i = 0; i < hpetp->hp_ntimer; i++)
-               printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
-       printk("\n");
+               printk(KERN_CONT "%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
+       printk(KERN_CONT "\n");
 
        temp = hpetp->hp_tick_freq;
        remainder = do_div(temp, 1000000);
index 54ca8b23cde3f1aa5550d2806087300227531070..4ec04a754733baed5dd8595256a9c7998965d323 100644 (file)
@@ -1260,10 +1260,15 @@ static int proc_do_uuid(ctl_table *table, int write,
        uuid = table->data;
        if (!uuid) {
                uuid = tmp_uuid;
-               uuid[8] = 0;
-       }
-       if (uuid[8] == 0)
                generate_random_uuid(uuid);
+       } else {
+               static DEFINE_SPINLOCK(bootid_spinlock);
+
+               spin_lock(&bootid_spinlock);
+               if (!uuid[8])
+                       generate_random_uuid(uuid);
+               spin_unlock(&bootid_spinlock);
+       }
 
        sprintf(buf, "%pU", uuid);
 
index 4dc019408fac7aa04b59e95f7deed8fb586ffe9e..3b22a606f79dc143abbece02b4893a71deee6e1b 100644 (file)
@@ -194,17 +194,17 @@ static ssize_t srom_read(struct file *filp, char __user *buf,
 
                hv_retval = _srom_read(srom->hv_devhdl, kernbuf,
                                       *f_pos, bytes_this_pass);
-               if (hv_retval > 0) {
-                       if (copy_to_user(buf, kernbuf, hv_retval) != 0) {
-                               retval = -EFAULT;
-                               break;
-                       }
-               } else if (hv_retval <= 0) {
+               if (hv_retval <= 0) {
                        if (retval == 0)
                                retval = hv_retval;
                        break;
                }
 
+               if (copy_to_user(buf, kernbuf, hv_retval) != 0) {
+                       retval = -EFAULT;
+                       break;
+               }
+
                retval += hv_retval;
                *f_pos += hv_retval;
                buf += hv_retval;
index 82e882028fcf2172e7a1faaf5aec0f125238a952..6b5cf02c35c88147970c69cd19048650bff7610d 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
-#include <linux/async.h>
 #include <asm/io.h>
 
 /*
@@ -180,15 +179,17 @@ static int verify_pmtmr_rate(void)
 /* Number of reads we try to get two different values */
 #define ACPI_PM_READ_CHECKS 10000
 
-static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie)
+static int __init init_acpi_pm_clocksource(void)
 {
        cycle_t value1, value2;
        unsigned int i, j = 0;
 
+       if (!pmtmr_ioport)
+               return -ENODEV;
 
        /* "verify" this timing source: */
        for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
-               usleep_range(100 * j, 100 * j + 100);
+               udelay(100 * j);
                value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
                for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
                        value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
@@ -202,34 +203,25 @@ static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie
                               " 0x%#llx, 0x%#llx - aborting.\n",
                               value1, value2);
                        pmtmr_ioport = 0;
-                       return;
+                       return -EINVAL;
                }
                if (i == ACPI_PM_READ_CHECKS) {
                        printk(KERN_INFO "PM-Timer failed consistency check "
                               " (0x%#llx) - aborting.\n", value1);
                        pmtmr_ioport = 0;
-                       return;
+                       return -ENODEV;
                }
        }
 
        if (verify_pmtmr_rate() != 0){
                pmtmr_ioport = 0;
-               return;
+               return -ENODEV;
        }
 
-       clocksource_register_hz(&clocksource_acpi_pm,
+       return clocksource_register_hz(&clocksource_acpi_pm,
                                                PMTMR_TICKS_PER_SEC);
 }
 
-static int __init init_acpi_pm_clocksource(void)
-{
-       if (!pmtmr_ioport)
-               return -ENODEV;
-
-       async_schedule(acpi_pm_clocksource_async, NULL);
-       return 0;
-}
-
 /* We use fs_initcall because we want the PCI fixups to have run
  * but we still need to load before device_initcall
  */
index ffbb446859152e232f48099c8e57b8797502ed76..5961e6415f082a54e4a29a0980d48857a724cc7c 100644 (file)
@@ -4,6 +4,7 @@
 
 config ARM_OMAP2PLUS_CPUFREQ
        bool "TI OMAP2+"
+       depends on ARCH_OMAP2PLUS
        default ARCH_OMAP2PLUS
        select CPU_FREQ_TABLE
 
index 87411cebc57725223a994eb6467ad0aa209d3515..2f0083a51a9aeb5979e145eca98b686f4dd3c196 100644 (file)
@@ -74,7 +74,7 @@ static cpuidle_enter_t cpuidle_enter_ops;
 /**
  * cpuidle_play_dead - cpu off-lining
  *
- * Only returns in case of an error
+ * Returns in case of an error or no driver
  */
 int cpuidle_play_dead(void)
 {
@@ -83,6 +83,9 @@ int cpuidle_play_dead(void)
        int i, dead_state = -1;
        int power_usage = -1;
 
+       if (!drv)
+               return -ENODEV;
+
        /* Find lowest-power state that supports long-term idle */
        for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
                struct cpuidle_state *s = &drv->states[i];
index 0053d7ebb5cae0a479eacf0d22c69606509644ea..8f3f74ce8c7fd7ac95e241c2c4504f06a52da38c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/gfp.h>
+#include <linux/module.h>
 
 #include <crypto/ctr.h>
 #include <crypto/des.h>
index dc641c79652650dbe7bc02ce5d3b0e889427e376..921039e56f87f9360156074233c9e38828bc1612 100644 (file)
@@ -124,6 +124,9 @@ struct talitos_private {
        void __iomem *reg;
        int irq[2];
 
+       /* SEC global registers lock  */
+       spinlock_t reg_lock ____cacheline_aligned;
+
        /* SEC version geometry (from device tree node) */
        unsigned int num_channels;
        unsigned int chfifo_len;
@@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data)                 \
 {                                                                      \
        struct device *dev = (struct device *)data;                     \
        struct talitos_private *priv = dev_get_drvdata(dev);            \
+       unsigned long flags;                                            \
                                                                        \
        if (ch_done_mask & 1)                                           \
                flush_channel(dev, 0, 0, 0);                            \
@@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data)                        \
 out:                                                                   \
        /* At this point, all completed channels have been processed */ \
        /* Unmask done interrupts for channels completed later on. */   \
+       spin_lock_irqsave(&priv->reg_lock, flags);                      \
        setbits32(priv->reg + TALITOS_IMR, ch_done_mask);               \
        setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);     \
+       spin_unlock_irqrestore(&priv->reg_lock, flags);                 \
 }
 DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
 DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
@@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data)         \
        struct device *dev = data;                                             \
        struct talitos_private *priv = dev_get_drvdata(dev);                   \
        u32 isr, isr_lo;                                                       \
+       unsigned long flags;                                                   \
                                                                               \
+       spin_lock_irqsave(&priv->reg_lock, flags);                             \
        isr = in_be32(priv->reg + TALITOS_ISR);                                \
        isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);                          \
        /* Acknowledge interrupt */                                            \
        out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
        out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);                          \
                                                                               \
-       if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo))    \
-               talitos_error(dev, isr, isr_lo);                               \
-       else                                                                   \
+       if (unlikely(isr & ch_err_mask || isr_lo)) {                           \
+               spin_unlock_irqrestore(&priv->reg_lock, flags);                \
+               talitos_error(dev, isr & ch_err_mask, isr_lo);                 \
+       }                                                                      \
+       else {                                                                 \
                if (likely(isr & ch_done_mask)) {                              \
                        /* mask further done interrupts. */                    \
                        clrbits32(priv->reg + TALITOS_IMR, ch_done_mask);      \
                        /* done_task will unmask done interrupts at exit */    \
                        tasklet_schedule(&priv->done_task[tlet]);              \
                }                                                              \
+               spin_unlock_irqrestore(&priv->reg_lock, flags);                \
+       }                                                                      \
                                                                               \
        return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED :  \
                                                                IRQ_NONE;      \
@@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev)
 
        priv->ofdev = ofdev;
 
+       spin_lock_init(&priv->reg_lock);
+
        err = talitos_probe_irq(ofdev);
        if (err)
                goto err_out;
index cf9da362d64f9a233512ce7a228bccad25906197..ef378b5b17e49079075f1fdf3f5834cca90f05a7 100644 (file)
@@ -91,11 +91,10 @@ config DW_DMAC
 
 config AT_HDMAC
        tristate "Atmel AHB DMA support"
-       depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+       depends on ARCH_AT91
        select DMA_ENGINE
        help
-         Support the Atmel AHB DMA controller.  This can be integrated in
-         chips such as the Atmel AT91SAM9RL.
+         Support the Atmel AHB DMA controller.
 
 config FSL_DMA
        tristate "Freescale Elo and Elo Plus DMA support"
index 767bcc31b3653b7813a9acbde71f2fcd1f3a0130..2397f6f451b15ccb274d367c9955cefa27c56013 100644 (file)
@@ -332,6 +332,20 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
 }
 EXPORT_SYMBOL(dma_find_channel);
 
+/*
+ * net_dma_find_channel - find a channel for net_dma
+ * net_dma has alignment requirements
+ */
+struct dma_chan *net_dma_find_channel(void)
+{
+       struct dma_chan *chan = dma_find_channel(DMA_MEMCPY);
+       if (chan && !is_dma_copy_aligned(chan->device, 1, 1, 1))
+               return NULL;
+
+       return chan;
+}
+EXPORT_SYMBOL(net_dma_find_channel);
+
 /**
  * dma_issue_pending_all - flush all pending operations across all channels
  */
index 31493d80e0e9dd0538546703317dbf60abe2247e..73b2b65cb1deed2ccfb16d5f3e81dbeaa47f7ec1 100644 (file)
@@ -546,9 +546,9 @@ void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
                           PCI_DMA_TODEVICE, flags, 0);
 }
 
-unsigned long ioat_get_current_completion(struct ioat_chan_common *chan)
+dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan)
 {
-       unsigned long phys_complete;
+       dma_addr_t phys_complete;
        u64 completion;
 
        completion = *chan->completion;
@@ -569,7 +569,7 @@ unsigned long ioat_get_current_completion(struct ioat_chan_common *chan)
 }
 
 bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
-                          unsigned long *phys_complete)
+                          dma_addr_t *phys_complete)
 {
        *phys_complete = ioat_get_current_completion(chan);
        if (*phys_complete == chan->last_completion)
@@ -580,14 +580,14 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
        return true;
 }
 
-static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
+static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete)
 {
        struct ioat_chan_common *chan = &ioat->base;
        struct list_head *_desc, *n;
        struct dma_async_tx_descriptor *tx;
 
-       dev_dbg(to_dev(chan), "%s: phys_complete: %lx\n",
-                __func__, phys_complete);
+       dev_dbg(to_dev(chan), "%s: phys_complete: %llx\n",
+                __func__, (unsigned long long) phys_complete);
        list_for_each_safe(_desc, n, &ioat->used_desc) {
                struct ioat_desc_sw *desc;
 
@@ -652,7 +652,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
 static void ioat1_cleanup(struct ioat_dma_chan *ioat)
 {
        struct ioat_chan_common *chan = &ioat->base;
-       unsigned long phys_complete;
+       dma_addr_t phys_complete;
 
        prefetch(chan->completion);
 
@@ -698,7 +698,7 @@ static void ioat1_timer_event(unsigned long data)
                mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
                spin_unlock_bh(&ioat->desc_lock);
        } else if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
-               unsigned long phys_complete;
+               dma_addr_t phys_complete;
 
                spin_lock_bh(&ioat->desc_lock);
                /* if we haven't made progress and we have already
index c7888bccd9740c6cefba7719c1e33cc724a7152d..5e8fe01ba69d574c3eef5cf0cb8f3ab765fb7c72 100644 (file)
@@ -88,7 +88,7 @@ struct ioatdma_device {
 struct ioat_chan_common {
        struct dma_chan common;
        void __iomem *reg_base;
-       unsigned long last_completion;
+       dma_addr_t last_completion;
        spinlock_t cleanup_lock;
        unsigned long state;
        #define IOAT_COMPLETION_PENDING 0
@@ -310,7 +310,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device);
 void __devexit ioat_dma_remove(struct ioatdma_device *device);
 struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev,
                                              void __iomem *iobase);
-unsigned long ioat_get_current_completion(struct ioat_chan_common *chan);
+dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan);
 void ioat_init_channel(struct ioatdma_device *device,
                       struct ioat_chan_common *chan, int idx);
 enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
@@ -318,7 +318,7 @@ enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
 void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
                    size_t len, struct ioat_dma_descriptor *hw);
 bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
-                          unsigned long *phys_complete);
+                          dma_addr_t *phys_complete);
 void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type);
 void ioat_kobject_del(struct ioatdma_device *device);
 extern const struct sysfs_ops ioat_sysfs_ops;
index e8e110ff3d965547b03f7bbf80cddcb58911a031..86895760b598ef61ca63ebce58f3c1f2e5093cbf 100644 (file)
@@ -128,7 +128,7 @@ static void ioat2_start_null_desc(struct ioat2_dma_chan *ioat)
        spin_unlock_bh(&ioat->prep_lock);
 }
 
-static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
+static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete)
 {
        struct ioat_chan_common *chan = &ioat->base;
        struct dma_async_tx_descriptor *tx;
@@ -179,7 +179,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 static void ioat2_cleanup(struct ioat2_dma_chan *ioat)
 {
        struct ioat_chan_common *chan = &ioat->base;
-       unsigned long phys_complete;
+       dma_addr_t phys_complete;
 
        spin_lock_bh(&chan->cleanup_lock);
        if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -260,7 +260,7 @@ int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo)
 static void ioat2_restart_channel(struct ioat2_dma_chan *ioat)
 {
        struct ioat_chan_common *chan = &ioat->base;
-       unsigned long phys_complete;
+       dma_addr_t phys_complete;
 
        ioat2_quiesce(chan, 0);
        if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -275,7 +275,7 @@ void ioat2_timer_event(unsigned long data)
        struct ioat_chan_common *chan = &ioat->base;
 
        if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
-               unsigned long phys_complete;
+               dma_addr_t phys_complete;
                u64 status;
 
                status = ioat_chansts(chan);
@@ -572,9 +572,9 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order)
         */
        struct ioat_chan_common *chan = &ioat->base;
        struct dma_chan *c = &chan->common;
-       const u16 curr_size = ioat2_ring_size(ioat);
+       const u32 curr_size = ioat2_ring_size(ioat);
        const u16 active = ioat2_ring_active(ioat);
-       const u16 new_size = 1 << order;
+       const u32 new_size = 1 << order;
        struct ioat_ring_ent **ring;
        u16 i;
 
index a2c413b2b8d8d77c8cd5b30e03956e8baed6da1c..be2a55b95c2365848a6da33de2bf91269ea97b14 100644 (file)
@@ -74,7 +74,7 @@ static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c)
        return container_of(chan, struct ioat2_dma_chan, base);
 }
 
-static inline u16 ioat2_ring_size(struct ioat2_dma_chan *ioat)
+static inline u32 ioat2_ring_size(struct ioat2_dma_chan *ioat)
 {
        return 1 << ioat->alloc_order;
 }
@@ -91,7 +91,7 @@ static inline u16 ioat2_ring_pending(struct ioat2_dma_chan *ioat)
        return CIRC_CNT(ioat->head, ioat->issued, ioat2_ring_size(ioat));
 }
 
-static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat)
+static inline u32 ioat2_ring_space(struct ioat2_dma_chan *ioat)
 {
        return ioat2_ring_size(ioat) - ioat2_ring_active(ioat);
 }
index 2c4476c0e405be9ce3b547b6a0da7cc814eecc07..f7f1dc62c15c1a0dc4d27f676f86eefaebe73e5e 100644 (file)
@@ -257,7 +257,7 @@ static bool desc_has_ext(struct ioat_ring_ent *desc)
  * The difference from the dma_v2.c __cleanup() is that this routine
  * handles extended descriptors and dma-unmapping raid operations.
  */
-static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
+static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete)
 {
        struct ioat_chan_common *chan = &ioat->base;
        struct ioat_ring_ent *desc;
@@ -314,7 +314,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 static void ioat3_cleanup(struct ioat2_dma_chan *ioat)
 {
        struct ioat_chan_common *chan = &ioat->base;
-       unsigned long phys_complete;
+       dma_addr_t phys_complete;
 
        spin_lock_bh(&chan->cleanup_lock);
        if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -333,7 +333,7 @@ static void ioat3_cleanup_event(unsigned long data)
 static void ioat3_restart_channel(struct ioat2_dma_chan *ioat)
 {
        struct ioat_chan_common *chan = &ioat->base;
-       unsigned long phys_complete;
+       dma_addr_t phys_complete;
 
        ioat2_quiesce(chan, 0);
        if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -348,7 +348,7 @@ static void ioat3_timer_event(unsigned long data)
        struct ioat_chan_common *chan = &ioat->base;
 
        if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
-               unsigned long phys_complete;
+               dma_addr_t phys_complete;
                u64 status;
 
                status = ioat_chansts(chan);
@@ -1149,6 +1149,44 @@ static int ioat3_reset_hw(struct ioat_chan_common *chan)
        return ioat2_reset_sync(chan, msecs_to_jiffies(200));
 }
 
+static bool is_jf_ioat(struct pci_dev *pdev)
+{
+       switch (pdev->device) {
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF0:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF1:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF2:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF3:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF4:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF5:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF6:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF7:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF8:
+       case PCI_DEVICE_ID_INTEL_IOAT_JSF9:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool is_snb_ioat(struct pci_dev *pdev)
+{
+       switch (pdev->device) {
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB0:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB1:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB2:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB3:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB4:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB5:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB6:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB7:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB8:
+       case PCI_DEVICE_ID_INTEL_IOAT_SNB9:
+               return true;
+       default:
+               return false;
+       }
+}
+
 int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
 {
        struct pci_dev *pdev = device->pdev;
@@ -1169,6 +1207,9 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
        dma->device_alloc_chan_resources = ioat2_alloc_chan_resources;
        dma->device_free_chan_resources = ioat2_free_chan_resources;
 
+       if (is_jf_ioat(pdev) || is_snb_ioat(pdev))
+               dma->copy_align = 6;
+
        dma_cap_set(DMA_INTERRUPT, dma->cap_mask);
        dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock;
 
index da6c4c2c066a96b68cdb0765ba4e017112f1c7a6..79e3eba297029f465c4ba949f8e7c4a66a0c1a90 100644 (file)
@@ -1252,8 +1252,8 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device)
        struct page **pq_hw = &pq[IOP_ADMA_NUM_SRC_TEST+2];
        /* address conversion buffers (dma_map / page_address) */
        void *pq_sw[IOP_ADMA_NUM_SRC_TEST+2];
-       dma_addr_t pq_src[IOP_ADMA_NUM_SRC_TEST];
-       dma_addr_t pq_dest[2];
+       dma_addr_t pq_src[IOP_ADMA_NUM_SRC_TEST+2];
+       dma_addr_t *pq_dest = &pq_src[IOP_ADMA_NUM_SRC_TEST];
 
        int i;
        struct dma_async_tx_descriptor *tx;
index 1d5cf06f6c6b9757de37fc5ed86b50f93bb048e7..e99d00976189344193e974cc9b972512a8f7359e 100644 (file)
@@ -145,7 +145,11 @@ static int __devinit tile_edac_mc_probe(struct platform_device *pdev)
        mci->edac_ctl_cap = EDAC_FLAG_SECDED;
 
        mci->mod_name = DRV_NAME;
+#ifdef __tilegx__
+       mci->ctl_name = "TILEGx_Memory_Controller";
+#else
        mci->ctl_name = "TILEPro_Memory_Controller";
+#endif
        mci->dev_name = dev_name(&pdev->dev);
        mci->edac_check = tile_edac_check;
 
index edadbdad31d04c2f228166afa8f1971f21573044..e03653d6935778423a5f3dd44d4ac06722d5f15f 100644 (file)
@@ -430,7 +430,7 @@ config GPIO_ML_IOH
 
 config GPIO_SODAVILLE
        bool "Intel Sodaville GPIO support"
-       depends on X86 && PCI && OF && BROKEN
+       depends on X86 && PCI && OF
        select GPIO_GENERIC
        select GENERIC_IRQ_CHIP
        help
index 9ad1703d1408aa0c8661de5826e3247ddeaf3f30..ae5d7f12ce661f49900f9be1b7aec0d7374bdf90 100644 (file)
@@ -252,7 +252,7 @@ static irqreturn_t adp5588_irq_handler(int irq, void *devid)
                if (ret < 0)
                        memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat));
 
-               for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO);
+               for (bank = 0, bit = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO);
                        bank++, bit = 0) {
                        pending = dev->irq_stat[bank] & dev->irq_mask[bank];
 
index 46277877b7ecc1bea7448391d20a7a4f710c4577..19d6fc0229c3505d802e068553db8be4e5b1361e 100644 (file)
@@ -2382,8 +2382,8 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
 #endif
 };
 
-static struct samsung_gpio_chip exynos5_gpios_1[] = {
 #ifdef CONFIG_ARCH_EXYNOS5
+static struct samsung_gpio_chip exynos5_gpios_1[] = {
        {
                .chip   = {
                        .base   = EXYNOS5_GPA0(0),
@@ -2541,11 +2541,11 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = {
                        .to_irq = samsung_gpiolib_to_irq,
                },
        },
-#endif
 };
+#endif
 
-static struct samsung_gpio_chip exynos5_gpios_2[] = {
 #ifdef CONFIG_ARCH_EXYNOS5
+static struct samsung_gpio_chip exynos5_gpios_2[] = {
        {
                .chip   = {
                        .base   = EXYNOS5_GPE0(0),
@@ -2602,11 +2602,11 @@ static struct samsung_gpio_chip exynos5_gpios_2[] = {
 
                },
        },
-#endif
 };
+#endif
 
-static struct samsung_gpio_chip exynos5_gpios_3[] = {
 #ifdef CONFIG_ARCH_EXYNOS5
+static struct samsung_gpio_chip exynos5_gpios_3[] = {
        {
                .chip   = {
                        .base   = EXYNOS5_GPV0(0),
@@ -2638,11 +2638,11 @@ static struct samsung_gpio_chip exynos5_gpios_3[] = {
                        .label  = "GPV4",
                },
        },
-#endif
 };
+#endif
 
-static struct samsung_gpio_chip exynos5_gpios_4[] = {
 #ifdef CONFIG_ARCH_EXYNOS5
+static struct samsung_gpio_chip exynos5_gpios_4[] = {
        {
                .chip   = {
                        .base   = EXYNOS5_GPZ(0),
@@ -2650,8 +2650,8 @@ static struct samsung_gpio_chip exynos5_gpios_4[] = {
                        .label  = "GPZ",
                },
        },
-#endif
 };
+#endif
 
 
 #if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
index 9ba15d31d242f500315761ff8b74944ce3e8bb3e..031e5d24837dc6e8d8b8fe4a2016c306903d9f9a 100644 (file)
@@ -41,7 +41,7 @@
 struct sdv_gpio_chip_data {
        int irq_base;
        void __iomem *gpio_pub_base;
-       struct irq_domain id;
+       struct irq_domain *id;
        struct irq_chip_generic *gc;
        struct bgpio_chip bgpio;
 };
@@ -51,10 +51,9 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type)
        struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
        struct sdv_gpio_chip_data *sd = gc->private;
        void __iomem *type_reg;
-       u32 irq_offs = d->irq - sd->irq_base;
        u32 reg;
 
-       if (irq_offs < 8)
+       if (d->hwirq < 8)
                type_reg = sd->gpio_pub_base + GPIT1R0;
        else
                type_reg = sd->gpio_pub_base + GPIT1R1;
@@ -63,11 +62,11 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type)
 
        switch (type) {
        case IRQ_TYPE_LEVEL_HIGH:
-               reg &= ~BIT(4 * (irq_offs % 8));
+               reg &= ~BIT(4 * (d->hwirq % 8));
                break;
 
        case IRQ_TYPE_LEVEL_LOW:
-               reg |= BIT(4 * (irq_offs % 8));
+               reg |= BIT(4 * (d->hwirq % 8));
                break;
 
        default:
@@ -91,7 +90,7 @@ static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data)
                u32 irq_bit = __fls(irq_stat);
 
                irq_stat &= ~BIT(irq_bit);
-               generic_handle_irq(sd->irq_base + irq_bit);
+               generic_handle_irq(irq_find_mapping(sd->id, irq_bit));
        }
 
        return IRQ_HANDLED;
@@ -127,7 +126,7 @@ static int sdv_xlate(struct irq_domain *h, struct device_node *node,
 }
 
 static struct irq_domain_ops irq_domain_sdv_ops = {
-       .dt_translate   = sdv_xlate,
+       .xlate = sdv_xlate,
 };
 
 static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
@@ -149,10 +148,6 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
        if (ret)
                goto out_free_desc;
 
-       sd->id.irq_base = sd->irq_base;
-       sd->id.of_node = of_node_get(pdev->dev.of_node);
-       sd->id.ops = &irq_domain_sdv_ops;
-
        /*
         * This gpio irq controller latches level irqs. Testing shows that if
         * we unmask & ACK the IRQ before the source of the interrupt is gone
@@ -179,7 +174,10 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
                        IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST,
                        IRQ_LEVEL | IRQ_NOPROBE);
 
-       irq_domain_add(&sd->id);
+       sd->id = irq_domain_add_legacy(pdev->dev.of_node, SDV_NUM_PUB_GPIOS,
+                               sd->irq_base, 0, &irq_domain_sdv_ops, sd);
+       if (!sd->id)
+               goto out_free_irq;
        return 0;
 out_free_irq:
        free_irq(pdev->irq, sd);
@@ -260,7 +258,6 @@ static void sdv_gpio_remove(struct pci_dev *pdev)
 {
        struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev);
 
-       irq_domain_del(&sd->id);
        free_irq(pdev->irq, sd);
        irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS);
 
index 30372f7b2d457a8803e819d9050ccd3c525e7825..348b367debebdcf1823ac4f781915097e3fb027a 100644 (file)
@@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data,
  * \param arg pointer to a drm_buf_map structure.
  * \return zero on success or a negative number on failure.
  *
- * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
- * about each buffer into user space. For PCI buffers, it calls do_mmap() with
+ * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information
+ * about each buffer into user space. For PCI buffers, it calls vm_mmap() with
  * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
  * drm_mmap_dma().
  */
@@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data,
                                retcode = -EINVAL;
                                goto done;
                        }
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(file_priv->filp, 0, map->size,
+                       virtual = vm_mmap(file_priv->filp, 0, map->size,
                                          PROT_READ | PROT_WRITE,
                                          MAP_SHARED,
                                          token);
-                       up_write(&current->mm->mmap_sem);
                } else {
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
+                       virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,
                                          PROT_READ | PROT_WRITE,
                                          MAP_SHARED, 0);
-                       up_write(&current->mm->mmap_sem);
                }
                if (virtual > -1024UL) {
                        /* Real error */
index d3aaeb6ae2362167f360d3a8d1aa846028714fdd..c79870a75c2ffa426125d17bba4fc736ec3233e9 100644 (file)
@@ -3335,10 +3335,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 
        ret = crtc->funcs->page_flip(crtc, fb, e);
        if (ret) {
-               spin_lock_irqsave(&dev->event_lock, flags);
-               file_priv->event_space += sizeof e->event;
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-               kfree(e);
+               if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+                       spin_lock_irqsave(&dev->event_lock, flags);
+                       file_priv->event_space += sizeof e->event;
+                       spin_unlock_irqrestore(&dev->event_lock, flags);
+                       kfree(e);
+               }
        }
 
 out:
index cdfbf27b2b3ccf6bbda4d7e8c0ebef8b2c8e5381..123de28f94ef0613441b6656e9be9f309577c387 100644 (file)
@@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp)
 
        drm_events_release(file_priv);
 
-       if (dev->driver->driver_features & DRIVER_GEM)
-               drm_gem_release(dev, file_priv);
-
        if (dev->driver->driver_features & DRIVER_MODESET)
                drm_fb_release(file_priv);
 
+       if (dev->driver->driver_features & DRIVER_GEM)
+               drm_gem_release(dev, file_priv);
+
        mutex_lock(&dev->ctxlist_mutex);
        if (!list_empty(&dev->ctxlist)) {
                struct drm_ctx_list *pos, *n;
index c8c83dad2ce1443d67782ef94fd3ae70b0505983..37c9a523dd1c6f0c8391766023e43421b36ec57b 100644 (file)
@@ -1,6 +1,6 @@
 #include "drmP.h"
 #include <linux/usb.h>
-#include <linux/export.h>
+#include <linux/module.h>
 
 int drm_get_usb_dev(struct usb_interface *interface,
                    const struct usb_device_id *id,
@@ -114,3 +114,7 @@ void drm_usb_exit(struct drm_driver *driver,
        usb_deregister(udriver);
 }
 EXPORT_SYMBOL(drm_usb_exit);
+
+MODULE_AUTHOR("David Airlie");
+MODULE_DESCRIPTION("USB DRM support");
+MODULE_LICENSE("GPL and additional rights");
index 4a3a5f72ed4a42938dd38b998752c63baf953304..de8d2090bce32c769c3c04b0d8105933b648340a 100644 (file)
 static int lowlevel_buffer_allocate(struct drm_device *dev,
                unsigned int flags, struct exynos_drm_gem_buf *buf)
 {
-       dma_addr_t start_addr, end_addr;
+       dma_addr_t start_addr;
        unsigned int npages, page_size, i = 0;
        struct scatterlist *sgl;
        int ret = 0;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (flags & EXYNOS_BO_NONCONTIG) {
+       if (IS_NONCONTIG_BUFFER(flags)) {
                DRM_DEBUG_KMS("not support allocation type.\n");
                return -EINVAL;
        }
@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
        }
 
        if (buf->size >= SZ_1M) {
-               npages = (buf->size >> SECTION_SHIFT) + 1;
+               npages = buf->size >> SECTION_SHIFT;
                page_size = SECTION_SIZE;
        } else if (buf->size >= SZ_64K) {
-               npages = (buf->size >> 16) + 1;
+               npages = buf->size >> 16;
                page_size = SZ_64K;
        } else {
-               npages = (buf->size >> PAGE_SHIFT) + 1;
+               npages = buf->size >> PAGE_SHIFT;
                page_size = PAGE_SIZE;
        }
 
@@ -76,26 +76,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
                return -ENOMEM;
        }
 
-               buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
-                               &buf->dma_addr, GFP_KERNEL);
-               if (!buf->kvaddr) {
-                       DRM_ERROR("failed to allocate buffer.\n");
-                       ret = -ENOMEM;
-                       goto err1;
-               }
-
-               start_addr = buf->dma_addr;
-               end_addr = buf->dma_addr + buf->size;
-
-               buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
-               if (!buf->pages) {
-                       DRM_ERROR("failed to allocate pages.\n");
-                       ret = -ENOMEM;
-                       goto err2;
-               }
-
-       start_addr = buf->dma_addr;
-       end_addr = buf->dma_addr + buf->size;
+       buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
+                       &buf->dma_addr, GFP_KERNEL);
+       if (!buf->kvaddr) {
+               DRM_ERROR("failed to allocate buffer.\n");
+               ret = -ENOMEM;
+               goto err1;
+       }
 
        buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
        if (!buf->pages) {
@@ -105,23 +92,17 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
        }
 
        sgl = buf->sgt->sgl;
+       start_addr = buf->dma_addr;
 
        while (i < npages) {
                buf->pages[i] = phys_to_page(start_addr);
                sg_set_page(sgl, buf->pages[i], page_size, 0);
                sg_dma_address(sgl) = start_addr;
                start_addr += page_size;
-               if (end_addr - start_addr < page_size)
-                       break;
                sgl = sg_next(sgl);
                i++;
        }
 
-       buf->pages[i] = phys_to_page(start_addr);
-
-       sgl = sg_next(sgl);
-       sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
-
        DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
                        (unsigned long)buf->kvaddr,
                        (unsigned long)buf->dma_addr,
@@ -150,7 +131,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
         * non-continuous memory would be released by exynos
         * gem framework.
         */
-       if (flags & EXYNOS_BO_NONCONTIG) {
+       if (IS_NONCONTIG_BUFFER(flags)) {
                DRM_DEBUG_KMS("not support allocation type.\n");
                return;
        }
index 411832e8e17aa9fcd9eed13fc614be878f781403..eaf630dc5dba951e78f8a68c2d0bcc1b25ae40b3 100644 (file)
@@ -54,16 +54,18 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
                 *
                 * P.S. note that this driver is considered for modularization.
                 */
-               ret = subdrv->probe(dev, subdrv->manager.dev);
+               ret = subdrv->probe(dev, subdrv->dev);
                if (ret)
                        return ret;
        }
 
-       if (subdrv->is_local)
+       if (!subdrv->manager)
                return 0;
 
+       subdrv->manager->dev = subdrv->dev;
+
        /* create and initialize a encoder for this sub driver. */
-       encoder = exynos_drm_encoder_create(dev, &subdrv->manager,
+       encoder = exynos_drm_encoder_create(dev, subdrv->manager,
                        (1 << MAX_CRTC) - 1);
        if (!encoder) {
                DRM_ERROR("failed to create encoder\n");
@@ -186,7 +188,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
 
        list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
                if (subdrv->open) {
-                       ret = subdrv->open(dev, subdrv->manager.dev, file);
+                       ret = subdrv->open(dev, subdrv->dev, file);
                        if (ret)
                                goto err;
                }
@@ -197,7 +199,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
 err:
        list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
                if (subdrv->close)
-                       subdrv->close(dev, subdrv->manager.dev, file);
+                       subdrv->close(dev, subdrv->dev, file);
        }
        return ret;
 }
@@ -209,7 +211,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
 
        list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
                if (subdrv->close)
-                       subdrv->close(dev, subdrv->manager.dev, file);
+                       subdrv->close(dev, subdrv->dev, file);
        }
 }
 EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close);
index fbd0a232c93dea173fc4582ebf9aa98c3c620f90..1d814175cd491d39d0411b31fa330c498f02c8c3 100644 (file)
@@ -225,24 +225,25 @@ struct exynos_drm_private {
  * Exynos drm sub driver structure.
  *
  * @list: sub driver has its own list object to register to exynos drm driver.
+ * @dev: pointer to device object for subdrv device driver.
  * @drm_dev: pointer to drm_device and this pointer would be set
  *     when sub driver calls exynos_drm_subdrv_register().
- * @is_local: appear encoder and connector disrelated device.
+ * @manager: subdrv has its own manager to control a hardware appropriately
+ *     and we can access a hardware drawing on this manager.
  * @probe: this callback would be called by exynos drm driver after
  *     subdrv is registered to it.
  * @remove: this callback is used to release resources created
  *     by probe callback.
  * @open: this would be called with drm device file open.
  * @close: this would be called with drm device file close.
- * @manager: subdrv has its own manager to control a hardware appropriately
- *     and we can access a hardware drawing on this manager.
  * @encoder: encoder object owned by this sub driver.
  * @connector: connector object owned by this sub driver.
  */
 struct exynos_drm_subdrv {
        struct list_head list;
+       struct device *dev;
        struct drm_device *drm_dev;
-       bool is_local;
+       struct exynos_drm_manager *manager;
 
        int (*probe)(struct drm_device *drm_dev, struct device *dev);
        void (*remove)(struct drm_device *dev);
@@ -251,7 +252,6 @@ struct exynos_drm_subdrv {
        void (*close)(struct drm_device *drm_dev, struct device *dev,
                        struct drm_file *file);
 
-       struct exynos_drm_manager manager;
        struct drm_encoder *encoder;
        struct drm_connector *connector;
 };
index ecb6db2297008f420ebb7b05e9e19b333bd37286..29fdbfeb43cb79645d034da2d7f8a7aba27dbe5b 100644 (file)
@@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
 static void fimd_apply(struct device *subdrv_dev)
 {
        struct fimd_context *ctx = get_fimd_context(subdrv_dev);
-       struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
+       struct exynos_drm_manager *mgr = ctx->subdrv.manager;
        struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
        struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
        struct fimd_win_data *win_data;
@@ -577,6 +577,13 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = {
        .disable = fimd_win_disable,
 };
 
+static struct exynos_drm_manager fimd_manager = {
+       .pipe           = -1,
+       .ops            = &fimd_manager_ops,
+       .overlay_ops    = &fimd_overlay_ops,
+       .display_ops    = &fimd_display_ops,
+};
+
 static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
 {
        struct exynos_drm_private *dev_priv = drm_dev->dev_private;
@@ -628,7 +635,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
        struct fimd_context *ctx = (struct fimd_context *)dev_id;
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
        struct drm_device *drm_dev = subdrv->drm_dev;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
        u32 val;
 
        val = readl(ctx->regs + VIDINTCON1);
@@ -744,7 +751,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
 static int fimd_power_on(struct fimd_context *ctx, bool enable)
 {
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct device *dev = subdrv->manager.dev;
+       struct device *dev = subdrv->dev;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -867,13 +874,10 @@ static int __devinit fimd_probe(struct platform_device *pdev)
 
        subdrv = &ctx->subdrv;
 
+       subdrv->dev = dev;
+       subdrv->manager = &fimd_manager;
        subdrv->probe = fimd_subdrv_probe;
        subdrv->remove = fimd_subdrv_remove;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &fimd_manager_ops;
-       subdrv->manager.overlay_ops = &fimd_overlay_ops;
-       subdrv->manager.display_ops = &fimd_display_ops;
-       subdrv->manager.dev = dev;
 
        mutex_init(&ctx->lock);
 
index fa1aa94a3d8e3066f5abf21fdd02331b1d9b5219..392ce71ed6a18103db1562ee9024f70f51e6d46e 100644 (file)
@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg)
        return out_msg;
 }
 
-static unsigned int mask_gem_flags(unsigned int flags)
+static int check_gem_flags(unsigned int flags)
 {
-       return flags &= EXYNOS_BO_NONCONTIG;
+       if (flags & ~(EXYNOS_BO_MASK)) {
+               DRM_ERROR("invalid flags.\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
+{
+       if (!IS_NONCONTIG_BUFFER(flags)) {
+               if (size >= SZ_1M)
+                       return roundup(size, SECTION_SIZE);
+               else if (size >= SZ_64K)
+                       return roundup(size, SZ_64K);
+               else
+                       goto out;
+       }
+out:
+       return roundup(size, PAGE_SIZE);
 }
 
 static struct page **exynos_gem_get_pages(struct drm_gem_object *obj,
@@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
        struct exynos_drm_gem_buf *buf;
        int ret;
 
-       size = roundup(size, PAGE_SIZE);
-       DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
+       if (!size) {
+               DRM_ERROR("invalid size.\n");
+               return ERR_PTR(-EINVAL);
+       }
 
-       flags = mask_gem_flags(flags);
+       size = roundup_gem_size(size, flags);
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       ret = check_gem_flags(flags);
+       if (ret)
+               return ERR_PTR(ret);
 
        buf = exynos_drm_init_buf(dev, size);
        if (!buf)
@@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
        exynos_gem_obj = exynos_drm_gem_init(dev, size);
        if (!exynos_gem_obj) {
                ret = -ENOMEM;
-               goto err;
+               goto err_fini_buf;
        }
 
        exynos_gem_obj->buffer = buf;
@@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
                ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);
                if (ret < 0) {
                        drm_gem_object_release(&exynos_gem_obj->base);
-                       goto err;
+                       goto err_fini_buf;
                }
        } else {
                ret = exynos_drm_alloc_buf(dev, buf, flags);
                if (ret < 0) {
                        drm_gem_object_release(&exynos_gem_obj->base);
-                       goto err;
+                       goto err_fini_buf;
                }
        }
 
        return exynos_gem_obj;
-err:
+
+err_fini_buf:
        exynos_drm_fini_buf(dev, buf);
        return ERR_PTR(ret);
 }
@@ -554,10 +581,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
        obj->filp->f_op = &exynos_drm_gem_fops;
        obj->filp->private_data = obj;
 
-       down_write(&current->mm->mmap_sem);
-       addr = do_mmap(obj->filp, 0, args->size,
+       addr = vm_mmap(obj->filp, 0, args->size,
                        PROT_READ | PROT_WRITE, MAP_SHARED, 0);
-       up_write(&current->mm->mmap_sem);
 
        drm_gem_object_unreference_unlocked(obj);
 
index e40fbad8b70552abf83d2cf86ccd2cd4e10a5630..4ed842039505d5b6311b7252d5bdc514ec9df721 100644 (file)
@@ -29,6 +29,8 @@
 #define to_exynos_gem_obj(x)   container_of(x,\
                        struct exynos_drm_gem_obj, base)
 
+#define IS_NONCONTIG_BUFFER(f)         (f & EXYNOS_BO_NONCONTIG)
+
 /*
  * exynos drm gem buffer structure.
  *
index 14eb26b0ba1cb1fc70fb533be2adb38fd935ac71..3424463676e0997d4f653b11a400c7cf1f8aefd9 100644 (file)
@@ -30,9 +30,8 @@
                                        struct drm_hdmi_context, subdrv);
 
 /* these callback points shoud be set by specific drivers. */
-static struct exynos_hdmi_display_ops *hdmi_display_ops;
-static struct exynos_hdmi_manager_ops *hdmi_manager_ops;
-static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops;
+static struct exynos_hdmi_ops *hdmi_ops;
+static struct exynos_mixer_ops *mixer_ops;
 
 struct drm_hdmi_context {
        struct exynos_drm_subdrv        subdrv;
@@ -40,31 +39,20 @@ struct drm_hdmi_context {
        struct exynos_drm_hdmi_context  *mixer_ctx;
 };
 
-void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
-                                       *display_ops)
+void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
 {
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (display_ops)
-               hdmi_display_ops = display_ops;
+       if (ops)
+               hdmi_ops = ops;
 }
 
-void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
-                                       *manager_ops)
+void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
 {
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (manager_ops)
-               hdmi_manager_ops = manager_ops;
-}
-
-void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
-                                       *overlay_ops)
-{
-       DRM_DEBUG_KMS("%s\n", __FILE__);
-
-       if (overlay_ops)
-               hdmi_overlay_ops = overlay_ops;
+       if (ops)
+               mixer_ops = ops;
 }
 
 static bool drm_hdmi_is_connected(struct device *dev)
@@ -73,8 +61,8 @@ static bool drm_hdmi_is_connected(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->is_connected)
-               return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx);
+       if (hdmi_ops && hdmi_ops->is_connected)
+               return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
 
        return false;
 }
@@ -86,9 +74,9 @@ static int drm_hdmi_get_edid(struct device *dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->get_edid)
-               return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx,
-                               connector, edid, len);
+       if (hdmi_ops && hdmi_ops->get_edid)
+               return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid,
+                                         len);
 
        return 0;
 }
@@ -99,9 +87,8 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->check_timing)
-               return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx,
-                               timing);
+       if (hdmi_ops && hdmi_ops->check_timing)
+               return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
 
        return 0;
 }
@@ -112,8 +99,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->power_on)
-               return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode);
+       if (hdmi_ops && hdmi_ops->power_on)
+               return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode);
 
        return 0;
 }
@@ -130,13 +117,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev)
 {
        struct drm_hdmi_context *ctx = to_context(subdrv_dev);
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank)
-               return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx,
-                                                       manager->pipe);
+       if (mixer_ops && mixer_ops->enable_vblank)
+               return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
+                                               manager->pipe);
 
        return 0;
 }
@@ -147,8 +134,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank)
-               return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx);
+       if (mixer_ops && mixer_ops->disable_vblank)
+               return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
 }
 
 static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
@@ -160,9 +147,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup)
-               hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector,
-                                               mode, adjusted_mode);
+       if (hdmi_ops && hdmi_ops->mode_fixup)
+               hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode,
+                                    adjusted_mode);
 }
 
 static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
@@ -171,8 +158,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->mode_set)
-               hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
+       if (hdmi_ops && hdmi_ops->mode_set)
+               hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
 }
 
 static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
@@ -182,9 +169,8 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol)
-               hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width,
-                                                       height);
+       if (hdmi_ops && hdmi_ops->get_max_resol)
+               hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
 }
 
 static void drm_hdmi_commit(struct device *subdrv_dev)
@@ -193,8 +179,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->commit)
-               hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx);
+       if (hdmi_ops && hdmi_ops->commit)
+               hdmi_ops->commit(ctx->hdmi_ctx->ctx);
 }
 
 static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
@@ -209,8 +195,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               if (hdmi_manager_ops && hdmi_manager_ops->disable)
-                       hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx);
+               if (hdmi_ops && hdmi_ops->disable)
+                       hdmi_ops->disable(ctx->hdmi_ctx->ctx);
                break;
        default:
                DRM_DEBUG_KMS("unkown dps mode: %d\n", mode);
@@ -235,8 +221,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set)
-               hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
+       if (mixer_ops && mixer_ops->win_mode_set)
+               mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
 }
 
 static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
@@ -245,8 +231,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit)
-               hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
+       if (mixer_ops && mixer_ops->win_commit)
+               mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
 }
 
 static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
@@ -255,8 +241,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable)
-               hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
+       if (mixer_ops && mixer_ops->win_disable)
+               mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
 }
 
 static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
@@ -265,6 +251,12 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
        .disable = drm_mixer_disable,
 };
 
+static struct exynos_drm_manager hdmi_manager = {
+       .pipe           = -1,
+       .ops            = &drm_hdmi_manager_ops,
+       .overlay_ops    = &drm_hdmi_overlay_ops,
+       .display_ops    = &drm_hdmi_display_ops,
+};
 
 static int hdmi_subdrv_probe(struct drm_device *drm_dev,
                struct device *dev)
@@ -332,12 +324,9 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
 
        subdrv = &ctx->subdrv;
 
+       subdrv->dev = dev;
+       subdrv->manager = &hdmi_manager;
        subdrv->probe = hdmi_subdrv_probe;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &drm_hdmi_manager_ops;
-       subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops;
-       subdrv->manager.display_ops = &drm_hdmi_display_ops;
-       subdrv->manager.dev = dev;
 
        platform_set_drvdata(pdev, subdrv);
 
index 44497cfb6c74174ebb6faab6f5f0729ad712c43c..f3ae192c8dcf6e21b5977e5e210ceaf547f84999 100644 (file)
@@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context {
        void                    *ctx;
 };
 
-struct exynos_hdmi_display_ops {
+struct exynos_hdmi_ops {
+       /* display */
        bool (*is_connected)(void *ctx);
        int (*get_edid)(void *ctx, struct drm_connector *connector,
                        u8 *edid, int len);
        int (*check_timing)(void *ctx, void *timing);
        int (*power_on)(void *ctx, int mode);
-};
 
-struct exynos_hdmi_manager_ops {
+       /* manager */
        void (*mode_fixup)(void *ctx, struct drm_connector *connector,
                                struct drm_display_mode *mode,
                                struct drm_display_mode *adjusted_mode);
@@ -57,22 +57,17 @@ struct exynos_hdmi_manager_ops {
        void (*disable)(void *ctx);
 };
 
-struct exynos_hdmi_overlay_ops {
+struct exynos_mixer_ops {
+       /* manager */
        int (*enable_vblank)(void *ctx, int pipe);
        void (*disable_vblank)(void *ctx);
+
+       /* overlay */
        void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
        void (*win_commit)(void *ctx, int zpos);
        void (*win_disable)(void *ctx, int zpos);
 };
 
-extern struct platform_driver hdmi_driver;
-extern struct platform_driver mixer_driver;
-
-void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
-                                       *display_ops);
-void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
-                                       *manager_ops);
-void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
-                                       *overlay_ops);
-
+void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
+void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
 #endif
index c277a3a445f5a206209dc898ded6f15500b084a7..f92fe4c6174ad163bf250786e77949c9e2d9230e 100644 (file)
@@ -24,6 +24,10 @@ struct exynos_plane {
 
 static const uint32_t formats[] = {
        DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_NV12,
+       DRM_FORMAT_NV12M,
+       DRM_FORMAT_NV12MT,
 };
 
 static int
index 8e1339f9fe1fac6bcfde1a07e46d53f3e6558d00..7b9c153dceb610776f59711d4c5c3c303ff21228 100644 (file)
@@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode)
 static void vidi_apply(struct device *subdrv_dev)
 {
        struct vidi_context *ctx = get_vidi_context(subdrv_dev);
-       struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
+       struct exynos_drm_manager *mgr = ctx->subdrv.manager;
        struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
        struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
        struct vidi_win_data *win_data;
@@ -374,6 +374,13 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = {
        .disable = vidi_win_disable,
 };
 
+static struct exynos_drm_manager vidi_manager = {
+       .pipe           = -1,
+       .ops            = &vidi_manager_ops,
+       .overlay_ops    = &vidi_overlay_ops,
+       .display_ops    = &vidi_display_ops,
+};
+
 static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc)
 {
        struct exynos_drm_private *dev_priv = drm_dev->dev_private;
@@ -425,7 +432,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
        struct vidi_context *ctx = container_of(work, struct vidi_context,
                                        work);
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
 
        if (manager->pipe < 0)
                return;
@@ -471,7 +478,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev)
 static int vidi_power_on(struct vidi_context *ctx, bool enable)
 {
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct device *dev = subdrv->manager.dev;
+       struct device *dev = subdrv->dev;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -611,13 +618,10 @@ static int __devinit vidi_probe(struct platform_device *pdev)
        ctx->raw_edid = (struct edid *)fake_edid_info;
 
        subdrv = &ctx->subdrv;
+       subdrv->dev = dev;
+       subdrv->manager = &vidi_manager;
        subdrv->probe = vidi_subdrv_probe;
        subdrv->remove = vidi_subdrv_remove;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &vidi_manager_ops;
-       subdrv->manager.overlay_ops = &vidi_overlay_ops;
-       subdrv->manager.display_ops = &vidi_display_ops;
-       subdrv->manager.dev = dev;
 
        mutex_init(&ctx->lock);
 
index 575a8cbd35337b2719195b733485c4d04aee580c..b00353876458577f702f1b104f67bbd3c20915bf 100644 (file)
@@ -40,7 +40,6 @@
 
 #include "exynos_hdmi.h"
 
-#define HDMI_OVERLAY_NUMBER    3
 #define MAX_WIDTH              1920
 #define MAX_HEIGHT             1080
 #define get_hdmi_context(dev)  platform_get_drvdata(to_platform_device(dev))
@@ -1194,7 +1193,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata,
 
 static bool hdmi_is_connected(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
 
        if (val)
@@ -1207,7 +1206,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
                                u8 *edid, int len)
 {
        struct edid *raw_edid;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1275,7 +1274,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
 
 static int hdmi_check_timing(void *ctx, void *timing)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        struct fb_videomode *check_timing = timing;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1312,13 +1311,6 @@ static int hdmi_display_power_on(void *ctx, int mode)
        return 0;
 }
 
-static struct exynos_hdmi_display_ops display_ops = {
-       .is_connected   = hdmi_is_connected,
-       .get_edid       = hdmi_get_edid,
-       .check_timing   = hdmi_check_timing,
-       .power_on       = hdmi_display_power_on,
-};
-
 static void hdmi_set_acr(u32 freq, u8 *acr)
 {
        u32 n, cts;
@@ -1914,7 +1906,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
                                struct drm_display_mode *adjusted_mode)
 {
        struct drm_display_mode *m;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        int index;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1951,7 +1943,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
 
 static void hdmi_mode_set(void *ctx, void *mode)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        int conf_idx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1974,7 +1966,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width,
 
 static void hdmi_commit(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1985,7 +1977,7 @@ static void hdmi_commit(void *ctx)
 
 static void hdmi_disable(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1996,7 +1988,14 @@ static void hdmi_disable(void *ctx)
        }
 }
 
-static struct exynos_hdmi_manager_ops manager_ops = {
+static struct exynos_hdmi_ops hdmi_ops = {
+       /* display */
+       .is_connected   = hdmi_is_connected,
+       .get_edid       = hdmi_get_edid,
+       .check_timing   = hdmi_check_timing,
+       .power_on       = hdmi_display_power_on,
+
+       /* manager */
        .mode_fixup     = hdmi_mode_fixup,
        .mode_set       = hdmi_mode_set,
        .get_max_resol  = hdmi_get_max_resol,
@@ -2020,7 +2019,7 @@ static void hdmi_hotplug_func(struct work_struct *work)
 static irqreturn_t hdmi_irq_handler(int irq, void *arg)
 {
        struct exynos_drm_hdmi_context *ctx = arg;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
+       struct hdmi_context *hdata = ctx->ctx;
        u32 intc_flag;
 
        intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
@@ -2173,7 +2172,7 @@ static int hdmi_runtime_suspend(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __func__);
 
-       hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx);
+       hdmi_resource_poweroff(ctx->ctx);
 
        return 0;
 }
@@ -2184,7 +2183,7 @@ static int hdmi_runtime_resume(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __func__);
 
-       hdmi_resource_poweron((struct hdmi_context *)ctx->ctx);
+       hdmi_resource_poweron(ctx->ctx);
 
        return 0;
 }
@@ -2322,8 +2321,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
        hdata->irq = res->start;
 
        /* register specific callbacks to common hdmi. */
-       exynos_drm_display_ops_register(&display_ops);
-       exynos_drm_manager_ops_register(&manager_ops);
+       exynos_hdmi_ops_register(&hdmi_ops);
 
        hdmi_resource_poweron(hdata);
 
@@ -2351,7 +2349,7 @@ err_data:
 static int __devexit hdmi_remove(struct platform_device *pdev)
 {
        struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
+       struct hdmi_context *hdata = ctx->ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
index 4d5f41e19527f0514fd63d4d46fb958701247462..e15438c01129249e397a32ae2bea7c15eb10af86 100644 (file)
@@ -37,7 +37,8 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_hdmi.h"
 
-#define HDMI_OVERLAY_NUMBER    3
+#define MIXER_WIN_NR           3
+#define MIXER_DEFAULT_WIN      0
 
 #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
 
@@ -75,16 +76,12 @@ struct mixer_resources {
 };
 
 struct mixer_context {
-       struct fb_videomode     *default_timing;
-       unsigned int            default_win;
-       unsigned int            default_bpp;
        unsigned int            irq;
        int                     pipe;
        bool                    interlace;
-       bool                    vp_enabled;
 
        struct mixer_resources  mixer_res;
-       struct hdmi_win_data    win_data[HDMI_OVERLAY_NUMBER];
+       struct hdmi_win_data    win_data[MIXER_WIN_NR];
 };
 
 static const u8 filter_y_horiz_tap8[] = {
@@ -643,9 +640,9 @@ static void mixer_win_mode_set(void *ctx,
 
        win = overlay->zpos;
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -683,9 +680,9 @@ static void mixer_win_commit(void *ctx, int zpos)
        DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -706,9 +703,9 @@ static void mixer_win_disable(void *ctx, int zpos)
        DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -722,9 +719,12 @@ static void mixer_win_disable(void *ctx, int zpos)
        spin_unlock_irqrestore(&res->reg_slock, flags);
 }
 
-static struct exynos_hdmi_overlay_ops overlay_ops = {
+static struct exynos_mixer_ops mixer_ops = {
+       /* manager */
        .enable_vblank          = mixer_enable_vblank,
        .disable_vblank         = mixer_disable_vblank,
+
+       /* overlay */
        .win_mode_set           = mixer_win_mode_set,
        .win_commit             = mixer_win_commit,
        .win_disable            = mixer_win_disable,
@@ -771,8 +771,7 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
 static irqreturn_t mixer_irq_handler(int irq, void *arg)
 {
        struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
-       struct mixer_context *ctx =
-                       (struct mixer_context *)drm_hdmi_ctx->ctx;
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
        struct mixer_resources *res = &ctx->mixer_res;
        u32 val, val_base;
 
@@ -902,7 +901,7 @@ static int mixer_runtime_resume(struct device *dev)
 
        DRM_DEBUG_KMS("resume - start\n");
 
-       mixer_resource_poweron((struct mixer_context *)ctx->ctx);
+       mixer_resource_poweron(ctx->ctx);
 
        return 0;
 }
@@ -913,7 +912,7 @@ static int mixer_runtime_suspend(struct device *dev)
 
        DRM_DEBUG_KMS("suspend - start\n");
 
-       mixer_resource_poweroff((struct mixer_context *)ctx->ctx);
+       mixer_resource_poweroff(ctx->ctx);
 
        return 0;
 }
@@ -926,8 +925,7 @@ static const struct dev_pm_ops mixer_pm_ops = {
 static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
                                 struct platform_device *pdev)
 {
-       struct mixer_context *mixer_ctx =
-                       (struct mixer_context *)ctx->ctx;
+       struct mixer_context *mixer_ctx = ctx->ctx;
        struct device *dev = &pdev->dev;
        struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
        struct resource *res;
@@ -1076,7 +1074,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
                goto fail;
 
        /* register specific callback point to common hdmi. */
-       exynos_drm_overlay_ops_register(&overlay_ops);
+       exynos_mixer_ops_register(&mixer_ops);
 
        mixer_resource_poweron(ctx);
 
@@ -1093,7 +1091,7 @@ static int mixer_remove(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct exynos_drm_hdmi_context *drm_hdmi_ctx =
                                        platform_get_drvdata(pdev);
-       struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx;
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
 
        dev_info(dev, "remove successful\n");
 
index 21071cef92a4c60a7791969cd63771855fac4540..36eb0744841c7c2f4071da62b11ba45006d7b466 100644 (file)
@@ -29,7 +29,6 @@
 #define __MDFLD_DSI_OUTPUT_H__
 
 #include <linux/backlight.h>
-#include <linux/version.h>
 #include <drm/drmP.h>
 #include <drm/drm.h>
 #include <drm/drm_crtc.h>
index 2c8a60c3b98eacdbeac6673e75f763dff8e065da..f920fb5e42b63846e3d8b7b782b492e547e18eef 100644 (file)
@@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)
        if (buf_priv->currently_mapped == I810_BUF_MAPPED)
                return -EINVAL;
 
+       /* This is all entirely broken */
        down_write(&current->mm->mmap_sem);
        old_fops = file_priv->filp->f_op;
        file_priv->filp->f_op = &i810_buffer_fops;
@@ -157,11 +158,8 @@ static int i810_unmap_buffer(struct drm_buf *buf)
        if (buf_priv->currently_mapped != I810_BUF_MAPPED)
                return -EINVAL;
 
-       down_write(&current->mm->mmap_sem);
-       retcode = do_munmap(current->mm,
-                           (unsigned long)buf_priv->virtual,
+       retcode = vm_munmap((unsigned long)buf_priv->virtual,
                            (size_t) buf->total);
-       up_write(&current->mm->mmap_sem);
 
        buf_priv->currently_mapped = I810_BUF_UNMAPPED;
        buf_priv->virtual = NULL;
index dfa55e7478fb88501bdb73d29edbd14b5f8eecaa..ae8a64f9f8453266326803432156c81219d246ab 100644 (file)
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(semaphores,
                "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
 
 int i915_enable_rc6 __read_mostly = -1;
-module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
+module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
 MODULE_PARM_DESC(i915_enable_rc6,
                "Enable power-saving render C-state 6. "
                "Different stages can be selected via bitmask values "
index 4c65c639f7721d315a1b5875fe4f32478471fab3..0d1e4b7b4b99c9bb76460c2fca3ca3c5a6216b11 100644 (file)
@@ -1087,11 +1087,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
        if (obj == NULL)
                return -ENOENT;
 
-       down_write(&current->mm->mmap_sem);
-       addr = do_mmap(obj->filp, 0, args->size,
+       addr = vm_mmap(obj->filp, 0, args->size,
                       PROT_READ | PROT_WRITE, MAP_SHARED,
                       args->offset);
-       up_write(&current->mm->mmap_sem);
        drm_gem_object_unreference_unlocked(obj);
        if (IS_ERR((void *)addr))
                return addr;
@@ -1493,6 +1491,7 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj)
 {
        list_del_init(&obj->ring_list);
        obj->last_rendering_seqno = 0;
+       obj->last_fenced_seqno = 0;
 }
 
 static void
@@ -1521,6 +1520,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
        BUG_ON(!list_empty(&obj->gpu_write_list));
        BUG_ON(!obj->active);
        obj->ring = NULL;
+       obj->last_fenced_ring = NULL;
 
        i915_gem_object_move_off_active(obj);
        obj->fenced_gpu_access = false;
index 2abf4eb9403928be8cfb237910090cca0e8a4840..b4bb1ef77ddc967d060d0de226ffb1cf80f26468 100644 (file)
 #define  GT_FIFO_FREE_ENTRIES                  0x120008
 #define    GT_FIFO_NUM_RESERVED_ENTRIES                20
 
+#define GEN6_UCGCTL1                           0x9400
+# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE               (1 << 5)
+
 #define GEN6_UCGCTL2                           0x9404
 # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE               (1 << 13)
 # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE              (1 << 12)
index 91b35fd1db8c81ee06984de0aaae88824929cddd..5908cd563400f486f7ae5a302f6a12f4c62da8af 100644 (file)
@@ -2244,6 +2244,33 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
        return 0;
 }
 
+static int
+intel_finish_fb(struct drm_framebuffer *old_fb)
+{
+       struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
+       struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+       bool was_interruptible = dev_priv->mm.interruptible;
+       int ret;
+
+       wait_event(dev_priv->pending_flip_queue,
+                  atomic_read(&dev_priv->mm.wedged) ||
+                  atomic_read(&obj->pending_flip) == 0);
+
+       /* Big Hammer, we also need to ensure that any pending
+        * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+        * current scanout is retired before unpinning the old
+        * framebuffer.
+        *
+        * This should only fail upon a hung GPU, in which case we
+        * can safely continue.
+        */
+       dev_priv->mm.interruptible = false;
+       ret = i915_gem_object_finish_gpu(obj);
+       dev_priv->mm.interruptible = was_interruptible;
+
+       return ret;
+}
+
 static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                    struct drm_framebuffer *old_fb)
@@ -2282,25 +2309,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                return ret;
        }
 
-       if (old_fb) {
-               struct drm_i915_private *dev_priv = dev->dev_private;
-               struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
-
-               wait_event(dev_priv->pending_flip_queue,
-                          atomic_read(&dev_priv->mm.wedged) ||
-                          atomic_read(&obj->pending_flip) == 0);
-
-               /* Big Hammer, we also need to ensure that any pending
-                * MI_WAIT_FOR_EVENT inside a user batch buffer on the
-                * current scanout is retired before unpinning the old
-                * framebuffer.
-                *
-                * This should only fail upon a hung GPU, in which case we
-                * can safely continue.
-                */
-               ret = i915_gem_object_finish_gpu(obj);
-               (void) ret;
-       }
+       if (old_fb)
+               intel_finish_fb(old_fb);
 
        ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
                                         LEAVE_ATOMIC_MODE_SET);
@@ -3371,6 +3381,23 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
        struct drm_device *dev = crtc->dev;
 
+       /* Flush any pending WAITs before we disable the pipe. Note that
+        * we need to drop the struct_mutex in order to acquire it again
+        * during the lowlevel dpms routines around a couple of the
+        * operations. It does not look trivial nor desirable to move
+        * that locking higher. So instead we leave a window for the
+        * submission of further commands on the fb before we can actually
+        * disable it. This race with userspace exists anyway, and we can
+        * only rely on the pipe being disabled by userspace after it
+        * receives the hotplug notification and has flushed any pending
+        * batches.
+        */
+       if (crtc->fb) {
+               mutex_lock(&dev->struct_mutex);
+               intel_finish_fb(crtc->fb);
+               mutex_unlock(&dev->struct_mutex);
+       }
+
        crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
        assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
        assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
@@ -3451,8 +3478,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
                        return false;
        }
 
-       /* All interlaced capable intel hw wants timings in frames. */
-       drm_mode_set_crtcinfo(adjusted_mode, 0);
+       /* All interlaced capable intel hw wants timings in frames. Note though
+        * that intel_lvds_mode_fixup does some funny tricks with the crtc
+        * timings, so we need to be careful not to clobber these.*/
+       if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
+               drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        return true;
 }
@@ -7438,7 +7468,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
        OUT_RING(fb->pitches[0] | obj->tiling_mode);
        OUT_RING(obj->gtt_offset);
 
-       pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+       /* Contrary to the suggestions in the documentation,
+        * "Enable Panel Fitter" does not seem to be required when page
+        * flipping with a non-native mode, and worse causes a normal
+        * modeset to fail.
+        * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+        */
+       pf = 0;
        pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
        OUT_RING(pf | pipesrc);
        ADVANCE_LP_RING();
@@ -8529,6 +8565,10 @@ static void gen6_init_clock_gating(struct drm_device *dev)
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
 
+       I915_WRITE(GEN6_UCGCTL1,
+                  I915_READ(GEN6_UCGCTL1) |
+                  GEN6_BLBUNIT_CLOCK_GATE_DISABLE);
+
        /* 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
index 110552ff302c1dea71360dfc84da622d1cec1785..4b637919f74f6359b64fc996c04a2f2e6a353def 100644 (file)
@@ -219,14 +219,38 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
        return (max_link_clock * max_lanes * 8) / 10;
 }
 
+static bool
+intel_dp_adjust_dithering(struct intel_dp *intel_dp,
+                         struct drm_display_mode *mode,
+                         struct drm_display_mode *adjusted_mode)
+{
+       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
+       int max_lanes = intel_dp_max_lane_count(intel_dp);
+       int max_rate, mode_rate;
+
+       mode_rate = intel_dp_link_required(mode->clock, 24);
+       max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+
+       if (mode_rate > max_rate) {
+               mode_rate = intel_dp_link_required(mode->clock, 18);
+               if (mode_rate > max_rate)
+                       return false;
+
+               if (adjusted_mode)
+                       adjusted_mode->private_flags
+                               |= INTEL_MODE_DP_FORCE_6BPC;
+
+               return true;
+       }
+
+       return true;
+}
+
 static int
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
-       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
-       int max_lanes = intel_dp_max_lane_count(intel_dp);
-       int max_rate, mode_rate;
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
                if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
@@ -236,16 +260,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
                        return MODE_PANEL;
        }
 
-       mode_rate = intel_dp_link_required(mode->clock, 24);
-       max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
-
-       if (mode_rate > max_rate) {
-                       mode_rate = intel_dp_link_required(mode->clock, 18);
-                       if (mode_rate > max_rate)
-                               return MODE_CLOCK_HIGH;
-                       else
-                               mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC;
-       }
+       if (!intel_dp_adjust_dithering(intel_dp, mode, NULL))
+               return MODE_CLOCK_HIGH;
 
        if (mode->clock < 10000)
                return MODE_CLOCK_LOW;
@@ -672,7 +688,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
        int lane_count, clock;
        int max_lane_count = intel_dp_max_lane_count(intel_dp);
        int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
-       int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+       int bpp;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
@@ -686,6 +702,11 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                mode->clock = intel_dp->panel_fixed_mode->clock;
        }
 
+       if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode))
+               return false;
+
+       bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
index 5a14149b3794237ad26ee24bce00b5938e157b93..715afa15302528ac7523f883aee5bd7e3c428906 100644 (file)
 #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
 #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
 #define INTEL_MODE_DP_FORCE_6BPC (0x10)
+/* This flag must be set by the encoder's mode_fixup if it changes the crtc
+ * timings in the mode to prevent the crtc fixup from overwriting them.
+ * Currently only lvds needs that. */
+#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
 
 static inline void
 intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
index 19ecd78b8a2ce572c98b1407122e1d97d94c4781..6e9ee33fd4122110a4df115c7d74bb18c20fc386 100644 (file)
@@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev)
        struct drm_mode_config *config = &dev->mode_config;
        struct drm_plane *plane;
 
+       mutex_lock(&dev->mode_config.mutex);
+
        ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
        if (ret)
                DRM_DEBUG("failed to restore crtc mode\n");
@@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev)
        /* Be sure to shut off any planes that may be active */
        list_for_each_entry(plane, &config->plane_list, head)
                plane->funcs->disable_plane(plane);
+
+       mutex_unlock(&dev->mode_config.mutex);
 }
index 601c86e664afd237875aefc43fe65a0671930cb5..8fdc9570021853e3c94fec296a7bca3e14a60b7b 100644 (file)
@@ -390,7 +390,7 @@ int intel_setup_gmbus(struct drm_device *dev)
                bus->has_gpio = intel_gpio_setup(bus, i);
 
                /* XXX force bit banging until GMBUS is fully debugged */
-               if (bus->has_gpio && IS_GEN2(dev))
+               if (bus->has_gpio)
                        bus->force_bit = true;
        }
 
index 95db2e988227a8c6fe7cbac5d0984a879181f492..30e2c82101de0d8cb0c841d97f77db6acfc501aa 100644 (file)
@@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode,
 
        mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
        mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
+
+       mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
 }
 
 static void
@@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode,
 
        mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
        mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
+
+       mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
 }
 
 static inline u32 panel_fitter_scaling(u32 source, u32 target)
@@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
        for_each_pipe(pipe)
                I915_WRITE(BCLRPAT(pipe), 0);
 
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
+
        switch (intel_lvds->fitting_mode) {
        case DRM_MODE_SCALE_CENTER:
                /*
index 230a141dbea34da3feff3e4fc043d780a6975fdd..48177ec4720ed14bae9bc4cb2bdbc0a2d06e4985 100644 (file)
@@ -47,8 +47,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
        adjusted_mode->vtotal = fixed_mode->vtotal;
 
        adjusted_mode->clock = fixed_mode->clock;
-
-       drm_mode_set_crtcinfo(adjusted_mode, 0);
 }
 
 /* adjusted_mode has been preset to be the panel's fixed mode */
index e25581a9f60f3d80ea3cbd60ab282373da7bfe8b..f75806e5bff5c62273ddaee7d5f94bd15cb860e8 100644 (file)
@@ -1038,7 +1038,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
         * of the buffer.
         */
        ring->effective_size = ring->size;
-       if (IS_I830(ring->dev))
+       if (IS_I830(ring->dev) || IS_845G(ring->dev))
                ring->effective_size -= 128;
 
        return 0;
index a464771a724070a229e917d7b7e5e249d1058845..e90dfb625c4201137d1b8a893fa99342904059d4 100644 (file)
@@ -95,7 +95,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
        /* must disable */
        sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
        sprctl |= SPRITE_ENABLE;
-       sprctl |= SPRITE_DEST_KEY;
 
        /* Sizes are 0 based */
        src_w--;
index 34d591b7d4efe91d1221d0ae11131157efcdcca9..da3e7c3abab7090a3770413c02bd0cbbaa6134a3 100644 (file)
@@ -235,6 +235,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
                return -EPERM;
 
        strncpy(string, profile, sizeof(string));
+       string[sizeof(string) - 1] = 0;
        if ((ptr = strchr(string, '\n')))
                *ptr = '\0';
 
index a7844ab6a50cd5603b351eb026a62e763cb6a554..27464021247583a87fd5dfc1c6c79441da9e703c 100644 (file)
@@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
        static const u8 nv50[] = { 16, 8, 0, 24 };
-       if (dev_priv->card_type == 0xaf)
+       if (dev_priv->chipset == 0xaf)
                return nvaf[lane];
        return nv50[lane];
 }
index e607c4d7dd98bbccd9a709ab908b0c2c5b26a4b9..2d39f9977e005dd2ba5f8e53930569dc461db109 100644 (file)
@@ -230,6 +230,10 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
                return;
 
+       /* some R4xx chips have the wrong frev */
+       if (rdev->family <= CHIP_RV410)
+               frev = 1;
+
        switch (frev) {
        case 1:
                switch (crev) {
index 81801c176aa5c8b4cc45644df5c5a7a471128cd3..fe33d35dae8c6ca851103e476426e12194d7d4b1 100644 (file)
@@ -2553,7 +2553,7 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev)
         * or the chip could hang on a subsequent access
         */
        if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) {
-               udelay(5000);
+               mdelay(5);
        }
 
        /* This function is required to workaround a hardware bug in some (all?)
index 391bd2636a8054bb5e102388060e54a1b10f9c97..c8187c4b6ae8838f65fdd0445be43974cc040f1b 100644 (file)
@@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
        }
        if (rdev->flags & RADEON_IS_AGP) {
                size_bf = mc->gtt_start;
-               size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+               size_af = 0xFFFFFFFF - mc->gtt_end;
                if (size_bf > size_af) {
                        if (mc->mc_vram_size > size_bf) {
                                dev_warn(rdev->dev, "limiting VRAM\n");
@@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
                                mc->real_vram_size = size_af;
                                mc->mc_vram_size = size_af;
                        }
-                       mc->vram_start = mc->gtt_end;
+                       mc->vram_start = mc->gtt_end + 1;
                }
                mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
                dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
@@ -2839,7 +2839,7 @@ void r600_rlc_stop(struct radeon_device *rdev)
                /* r7xx asics need to soft reset RLC before halting */
                WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
                RREG32(SRBM_SOFT_RESET);
-               udelay(15000);
+               mdelay(15);
                WREG32(SRBM_SOFT_RESET, 0);
                RREG32(SRBM_SOFT_RESET);
        }
index 84c546250955bfc354456dc858f839c6bb27fcfa..75ed17c96115f30bca7aa4c7ca9fe7f65c035cb9 100644 (file)
@@ -407,7 +407,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
        fw_data = (const __be32 *)dev_priv->me_fw->data;
@@ -500,7 +500,7 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
        fw_data = (const __be32 *)dev_priv->pfp_fw->data;
@@ -1797,7 +1797,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
 
index 6ae0c75f016acfaaf7bcb705503c187a563f7198..9c6b29a4192773087b1db8b62326e76bb2d971d2 100644 (file)
@@ -633,7 +633,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp &= ~(R300_SCLK_FORCE_VAP);
                                tmp |= RADEON_SCLK_FORCE_CP;
                                WREG32_PLL(RADEON_SCLK_CNTL, tmp);
-                               udelay(15000);
+                               mdelay(15);
 
                                tmp = RREG32_PLL(R300_SCLK_CNTL2);
                                tmp &= ~(R300_SCLK_FORCE_TCL |
@@ -651,12 +651,12 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                        tmp |= (RADEON_ENGIN_DYNCLK_MODE |
                                (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
                        WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
                        tmp |= RADEON_SCLK_DYN_START_CNTL;
                        WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
                           to lockup randomly, leave them as set by BIOS.
@@ -696,7 +696,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                        tmp |= RADEON_SCLK_MORE_FORCEON;
                                }
                                WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
-                               udelay(15000);
+                               mdelay(15);
                        }
 
                        /* RV200::A11 A12, RV250::A11 A12 */
@@ -709,7 +709,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp |= RADEON_TCL_BYPASS_DISABLE;
                                WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
                        }
-                       udelay(15000);
+                       mdelay(15);
 
                        /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */
                        tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -722,14 +722,14 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                RADEON_PIXCLK_TMDS_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
                        tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
                                RADEON_PIXCLK_DAC_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
                }
        } else {
                /* Turn everything OFF (ForceON to everything) */
@@ -861,7 +861,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                        }
                        WREG32_PLL(RADEON_SCLK_CNTL, tmp);
 
-                       udelay(16000);
+                       mdelay(16);
 
                        if ((rdev->family == CHIP_R300) ||
                            (rdev->family == CHIP_R350)) {
@@ -870,7 +870,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                        R300_SCLK_FORCE_GA |
                                        R300_SCLK_FORCE_CBA);
                                WREG32_PLL(R300_SCLK_CNTL2, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        if (rdev->flags & RADEON_IS_IGP) {
@@ -878,7 +878,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp &= ~(RADEON_FORCEON_MCLKA |
                                         RADEON_FORCEON_YCLKA);
                                WREG32_PLL(RADEON_MCLK_CNTL, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        if ((rdev->family == CHIP_RV200) ||
@@ -887,7 +887,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
                                tmp |= RADEON_SCLK_MORE_FORCEON;
                                WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -900,7 +900,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                 RADEON_PIXCLK_TMDS_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
-                       udelay(16000);
+                       mdelay(16);
 
                        tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
                        tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
index 81fc100be7e18c321c088bc787e1154de96e11e3..2cad9fde92fca9277983dfdadc48948d66f3fb27 100644 (file)
@@ -2845,7 +2845,7 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
                                        case 4:
                                                val = RBIOS16(index);
                                                index += 2;
-                                               udelay(val * 1000);
+                                               mdelay(val);
                                                break;
                                        case 6:
                                                slave_addr = id & 0xff;
@@ -3044,7 +3044,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
                                        udelay(150);
                                        break;
                                case 2:
-                                       udelay(1000);
+                                       mdelay(1);
                                        break;
                                case 3:
                                        while (tmp--) {
@@ -3075,13 +3075,13 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
                                                /*mclk_cntl |= 0x00001111;*//* ??? */
                                                WREG32_PLL(RADEON_MCLK_CNTL,
                                                           mclk_cntl);
-                                               udelay(10000);
+                                               mdelay(10);
 #endif
                                                WREG32_PLL
                                                    (RADEON_CLK_PWRMGT_CNTL,
                                                     tmp &
                                                     ~RADEON_CG_NO1_DEBUG_0);
-                                               udelay(10000);
+                                               mdelay(10);
                                        }
                                        break;
                                default:
index bd05156edbdb07fc30188215fcba9d0bbef3c31f..3c2e7a000a2ad91cefff66c5aa3dde40f3d9649d 100644 (file)
@@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
 
                        encoder = obj_to_encoder(obj);
 
-                       if (encoder->encoder_type != DRM_MODE_ENCODER_DAC ||
+                       if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&
                            encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
                                continue;
 
@@ -1000,6 +1000,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
         * cases the DVI port is actually a virtual KVM port connected to the service
         * processor.
         */
+out:
        if ((!rdev->is_atom_bios) &&
            (ret == connector_status_disconnected) &&
            rdev->mode_info.bios_hardcoded_edid_size) {
@@ -1007,7 +1008,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
                ret = connector_status_connected;
        }
 
-out:
        /* updated in get modes as well since we need to know if it's analog or digital */
        radeon_connector_update_scratch_regs(connector, ret);
        return ret;
index 85bcfc8923a789bf73101a1c5ef7cadc9ec1300f..3edec1c198e3145addb0b47bbafdf3cf2abd1e49 100644 (file)
@@ -900,6 +900,10 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
        struct radeon_i2c_chan *i2c;
        int ret;
 
+       /* don't add the mm_i2c bus unless hw_i2c is enabled */
+       if (rec->mm_i2c && (radeon_hw_i2c == 0))
+               return NULL;
+
        i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
        if (i2c == NULL)
                return NULL;
index 66d5fe1c81747cfa73da445d1f2099d36e9e4261..65060b77c8058efea3c7f35aac4df40b777aac4c 100644 (file)
@@ -147,6 +147,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
            (rdev->pdev->subsystem_device == 0x01fd))
                return true;
 
+       /* RV515 seems to have MSI issues where it loses
+        * MSI rearms occasionally. This leads to lockups and freezes.
+        * disable it by default.
+        */
+       if (rdev->family == CHIP_RV515)
+               return false;
        if (rdev->flags & RADEON_IS_IGP) {
                /* APUs work fine with MSIs */
                if (rdev->family >= CHIP_PALM)
index 2f46e0c8df53256a9bf5d6271b55141be2f8b35a..42db254f6bb04e13f86c8ba238e6be7685a20578 100644 (file)
@@ -88,7 +88,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
                lvds_pll_cntl |= RADEON_LVDS_PLL_EN;
                WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
-               udelay(1000);
+               mdelay(1);
 
                lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
                lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
@@ -101,7 +101,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                                  (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT));
                if (is_mac)
                        lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                break;
        case DRM_MODE_DPMS_STANDBY:
@@ -118,10 +118,10 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                        WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                        lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
                }
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                break;
        }
 
@@ -656,7 +656,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
 
        WREG32(RADEON_DAC_MACRO_CNTL, tmp);
 
-       udelay(2000);
+       mdelay(2);
 
        if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT)
                found = connector_status_connected;
@@ -1499,7 +1499,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
        tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
        WREG32(RADEON_DAC_CNTL2, tmp);
 
-       udelay(10000);
+       mdelay(10);
 
        if (ASIC_IS_R300(rdev)) {
                if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B)
index c62ae4be3845f02df5934304d3b90e7b8582588c..cdab1aeaed6e443fe4d8d62b75cf2e6d03516ad5 100644 (file)
@@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
        }
        if (rdev->flags & RADEON_IS_AGP) {
                size_bf = mc->gtt_start;
-               size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+               size_af = 0xFFFFFFFF - mc->gtt_end;
                if (size_bf > size_af) {
                        if (mc->mc_vram_size > size_bf) {
                                dev_warn(rdev->dev, "limiting VRAM\n");
@@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
                                mc->real_vram_size = size_af;
                                mc->mc_vram_size = size_af;
                        }
-                       mc->vram_start = mc->gtt_end;
+                       mc->vram_start = mc->gtt_end + 1;
                }
                mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
                dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
index ac7a199ffece9cd3df519187561aa2b6a5617f59..27bda986fc2bd8a6ad948d19e819bb1e8ec415df 100644 (file)
@@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev)
        }
        r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
                          &rdev->rlc.save_restore_gpu_addr);
+       radeon_bo_unreserve(rdev->rlc.save_restore_obj);
        if (r) {
-               radeon_bo_unreserve(rdev->rlc.save_restore_obj);
                dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
                si_rlc_fini(rdev);
                return r;
@@ -3023,9 +3023,8 @@ int si_rlc_init(struct radeon_device *rdev)
        }
        r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
                          &rdev->rlc.clear_state_gpu_addr);
+       radeon_bo_unreserve(rdev->rlc.clear_state_obj);
        if (r) {
-
-               radeon_bo_unreserve(rdev->rlc.clear_state_obj);
                dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
                si_rlc_fini(rdev);
                return r;
index 031aaaf79ac2da2c2972dfbadade2530877a55cb..b6d8608375cde6b0063796d83ae763b4bd1b14db 100644 (file)
@@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
         * for locking on FreeBSD.
         */
        if (cmdbuf->size) {
-               kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL);
+               kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL);
                if (kcmd_addr == NULL)
                        return -ENOMEM;
 
@@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
                cmdbuf->vb_addr = kvb_addr;
        }
        if (cmdbuf->nbox) {
-               kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect),
-                                   GFP_KERNEL);
+               kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect),
+                                         GFP_KERNEL);
                if (kbox_addr == NULL) {
                        ret = -ENOMEM;
                        goto done;
index a3d033252995aeb388fbcabc1dab8a286e38cb51..ffddcba32af62b637baa09fd9487f515451fca4f 100644 (file)
@@ -34,7 +34,7 @@ config HID
 config HID_BATTERY_STRENGTH
        bool
        depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
-       default y
+       default n
 
 config HIDRAW
        bool "/dev/hidraw raw HID device support"
index de47039c708c5546232bc1c05606d2a3e89b99d2..9f85f827607fd6fca72b03152ca7a51b061ec82c 100644 (file)
@@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 
 static const struct hid_device_id tivo_devices[] = {
        /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */
-       { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
        { }
 };
index 145f13580ff0499e70ed3f32c52f72f532ef8782..9140236a0182b4f73d80efbab7d6fdac11aca539 100644 (file)
@@ -391,6 +391,7 @@ static ssize_t show_str(struct device *dev,
                break;
        default:
                BUG();
+               val = "";
        }
 
        return sprintf(buf, "%s\n", val);
index 7765e4f74ec56177ad8cc39476320d6d2436f719..1958f03efd7aaa43f72416f809eb42fe569b413f 100644 (file)
@@ -59,14 +59,11 @@ struct ads1015_data {
        struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
 };
 
-static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
-                             int *value)
+static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
 {
        u16 config;
-       s16 conversion;
        struct ads1015_data *data = i2c_get_clientdata(client);
        unsigned int pga = data->channel_data[channel].pga;
-       int fullscale;
        unsigned int data_rate = data->channel_data[channel].data_rate;
        unsigned int conversion_time_ms;
        int res;
@@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
        if (res < 0)
                goto err_unlock;
        config = res;
-       fullscale = fullscale_table[pga];
        conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
 
        /* setup and start single conversion */
@@ -105,33 +101,36 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
        }
 
        res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
-       if (res < 0)
-               goto err_unlock;
-       conversion = res;
-
-       mutex_unlock(&data->update_lock);
-
-       *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0);
-
-       return 0;
 
 err_unlock:
        mutex_unlock(&data->update_lock);
        return res;
 }
 
+static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel,
+                            s16 reg)
+{
+       struct ads1015_data *data = i2c_get_clientdata(client);
+       unsigned int pga = data->channel_data[channel].pga;
+       int fullscale = fullscale_table[pga];
+
+       return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0);
+}
+
 /* sysfs callback function */
 static ssize_t show_in(struct device *dev, struct device_attribute *da,
        char *buf)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
        struct i2c_client *client = to_i2c_client(dev);
-       int in;
        int res;
+       int index = attr->index;
 
-       res = ads1015_read_value(client, attr->index, &in);
+       res = ads1015_read_adc(client, index);
+       if (res < 0)
+               return res;
 
-       return (res < 0) ? res : sprintf(buf, "%d\n", in);
+       return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res));
 }
 
 static const struct sensor_device_attribute ads1015_in[] = {
index b7494af1e4a9ba8cb6952c83d96b845f19f9e7fd..37a8fc92b44acf50a16d086c9983a9794c03b838 100644 (file)
@@ -122,6 +122,38 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)
        return true;
 }
 
+/*
+ * Newer BKDG versions have an updated recommendation on how to properly
+ * initialize the running average range (was: 0xE, now: 0x9). This avoids
+ * counter saturations resulting in bogus power readings.
+ * We correct this value ourselves to cope with older BIOSes.
+ */
+static void __devinit tweak_runavg_range(struct pci_dev *pdev)
+{
+       u32 val;
+       const struct pci_device_id affected_device = {
+               PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) };
+
+       /*
+        * let this quirk apply only to the current version of the
+        * northbridge, since future versions may change the behavior
+        */
+       if (!pci_match_id(&affected_device, pdev))
+               return;
+
+       pci_bus_read_config_dword(pdev->bus,
+               PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+               REG_TDP_RUNNING_AVERAGE, &val);
+       if ((val & 0xf) != 0xe)
+               return;
+
+       val &= ~0xf;
+       val |=  0x9;
+       pci_bus_write_config_dword(pdev->bus,
+               PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+               REG_TDP_RUNNING_AVERAGE, val);
+}
+
 static void __devinit fam15h_power_init_data(struct pci_dev *f4,
                                             struct fam15h_power_data *data)
 {
@@ -155,6 +187,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,
        struct device *dev;
        int err;
 
+       /*
+        * though we ignore every other northbridge, we still have to
+        * do the tweaking on _each_ node in MCM processors as the counters
+        * are working hand-in-hand
+        */
+       tweak_runavg_range(pdev);
+
        if (!fam15h_power_is_internal_node0(pdev)) {
                err = -ENODEV;
                goto exit;
index be51037363c89b19fb3263084c37c5acbba4083b..29b319db573efed8c8d5ec38fce66a36cb265ed8 100644 (file)
@@ -710,13 +710,13 @@ static u16 pmbus_data2reg(struct pmbus_data *data,
  * If a negative value is stored in any of the referenced registers, this value
  * reflects an error code which will be returned.
  */
-static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val)
+static int pmbus_get_boolean(struct pmbus_data *data, int index)
 {
        u8 s1 = (index >> 24) & 0xff;
        u8 s2 = (index >> 16) & 0xff;
        u8 reg = (index >> 8) & 0xff;
        u8 mask = index & 0xff;
-       int status;
+       int ret, status;
        u8 regval;
 
        status = data->status[reg];
@@ -725,7 +725,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val)
 
        regval = status & mask;
        if (!s1 && !s2)
-               *val = !!regval;
+               ret = !!regval;
        else {
                long v1, v2;
                struct pmbus_sensor *sensor1, *sensor2;
@@ -739,9 +739,9 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val)
 
                v1 = pmbus_reg2data(data, sensor1);
                v2 = pmbus_reg2data(data, sensor2);
-               *val = !!(regval && v1 >= v2);
+               ret = !!(regval && v1 >= v2);
        }
-       return 0;
+       return ret;
 }
 
 static ssize_t pmbus_show_boolean(struct device *dev,
@@ -750,11 +750,10 @@ static ssize_t pmbus_show_boolean(struct device *dev,
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
        struct pmbus_data *data = pmbus_update_device(dev);
        int val;
-       int err;
 
-       err = pmbus_get_boolean(data, attr->index, &val);
-       if (err)
-               return err;
+       val = pmbus_get_boolean(data, attr->index);
+       if (val < 0)
+               return val;
        return snprintf(buf, PAGE_SIZE, "%d\n", val);
 }
 
index d3b778da3f8603cf80e9173dd7207a210fe11f35..c5f6be478bad2468dd495ec1c3659c9abf550f2e 100644 (file)
@@ -343,10 +343,11 @@ exit:
        return err;
 }
 
-static int __init smsc47b397_find(unsigned short *addr)
+static int __init smsc47b397_find(void)
 {
        u8 id, rev;
        char *name;
+       unsigned short addr;
 
        superio_enter();
        id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
@@ -370,14 +371,14 @@ static int __init smsc47b397_find(unsigned short *addr)
        rev = superio_inb(SUPERIO_REG_DEVREV);
 
        superio_select(SUPERIO_REG_LD8);
-       *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
+       addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
                 |  superio_inb(SUPERIO_REG_BASE_LSB);
 
        pr_info("found SMSC %s (base address 0x%04x, revision %u)\n",
-               name, *addr, rev);
+               name, addr, rev);
 
        superio_exit();
-       return 0;
+       return addr;
 }
 
 static int __init smsc47b397_init(void)
@@ -385,9 +386,10 @@ static int __init smsc47b397_init(void)
        unsigned short address;
        int ret;
 
-       ret = smsc47b397_find(&address);
-       if (ret)
+       ret = smsc47b397_find();
+       if (ret < 0)
                return ret;
+       address = ret;
 
        ret = platform_driver_register(&smsc47b397_driver);
        if (ret)
index c590c146979325d7be42431ca0c2f1fcd248fed4..b5aa38dd7ab90fe06a9cfbfb9d0bb6323a5237c4 100644 (file)
@@ -491,10 +491,10 @@ static const struct attribute_group smsc47m1_group = {
        .attrs = smsc47m1_attributes,
 };
 
-static int __init smsc47m1_find(unsigned short *addr,
-                               struct smsc47m1_sio_data *sio_data)
+static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
 {
        u8 val;
+       unsigned short addr;
 
        superio_enter();
        val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
@@ -546,9 +546,9 @@ static int __init smsc47m1_find(unsigned short *addr,
        }
 
        superio_select();
-       *addr = (superio_inb(SUPERIO_REG_BASE) << 8)
+       addr = (superio_inb(SUPERIO_REG_BASE) << 8)
              |  superio_inb(SUPERIO_REG_BASE + 1);
-       if (*addr == 0) {
+       if (addr == 0) {
                pr_info("Device address not set, will not use\n");
                superio_exit();
                return -ENODEV;
@@ -565,7 +565,7 @@ static int __init smsc47m1_find(unsigned short *addr,
        }
 
        superio_exit();
-       return 0;
+       return addr;
 }
 
 /* Restore device to its initial state */
@@ -938,13 +938,15 @@ static int __init sm_smsc47m1_init(void)
        unsigned short address;
        struct smsc47m1_sio_data sio_data;
 
-       if (smsc47m1_find(&address, &sio_data))
-               return -ENODEV;
+       err = smsc47m1_find(&sio_data);
+       if (err < 0)
+               return err;
+       address = err;
 
        /* Sets global pdev as a side effect */
        err = smsc47m1_device_add(address, &sio_data);
        if (err)
-               goto exit;
+               return err;
 
        err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe);
        if (err)
@@ -955,7 +957,6 @@ static int __init sm_smsc47m1_init(void)
 exit_device:
        platform_device_unregister(pdev);
        smsc47m1_restore(&sio_data);
-exit:
        return err;
 }
 
index 37f42113af31bc54da67d953938630c513955a4d..00e8f213f56e51ed15b12b551af627eff9ef00b7 100644 (file)
@@ -182,7 +182,6 @@ static int i2c_dw_pci_resume(struct device *dev)
        pci_restore_state(pdev);
 
        i2c_dw_init(i2c);
-       i2c_dw_enable(i2c);
        return 0;
 }
 
index 83b720ef6c3497eec02327e62a930a1c6d478667..246fdc1516524cbc31940a6ed946e9b14ec741e8 100644 (file)
@@ -179,7 +179,7 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
 {
        struct ib_port_attr attr;
        char *speed = "";
-       int rate = -1;          /* in deci-Gb/sec */
+       int rate;               /* in deci-Gb/sec */
        ssize_t ret;
 
        ret = ib_query_port(p->ibdev, p->port_num, &attr);
@@ -187,9 +187,6 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
                return ret;
 
        switch (attr.active_speed) {
-       case IB_SPEED_SDR:
-               rate = 25;
-               break;
        case IB_SPEED_DDR:
                speed = " DDR";
                rate = 50;
@@ -210,6 +207,10 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
                speed = " EDR";
                rate = 250;
                break;
+       case IB_SPEED_SDR:
+       default:                /* default to SDR for invalid rates */
+               rate = 25;
+               break;
        }
 
        rate *= ib_width_enum_to_int(attr.active_width);
index 75d30562930058b14dd38700e3fe441f3bdcc796..669673e814393b051c144018292037c973f2fc7b 100644 (file)
@@ -253,6 +253,11 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,
                if (out_mad->data[15] & 0x1)
                        props->active_speed = IB_SPEED_FDR10;
        }
+
+       /* Avoid wrong speed value returned by FW if the IB link is down. */
+       if (props->state == IB_PORT_DOWN)
+                props->active_speed = IB_SPEED_SDR;
+
 out:
        kfree(in_mad);
        kfree(out_mad);
index 69e2ad06e51593203df2a5abe99aeb353d1cdc3d..daf21b8999998781bde4856415a542bef142707e 100644 (file)
@@ -3232,6 +3232,7 @@ static void srpt_add_one(struct ib_device *device)
        srq_attr.attr.max_wr = sdev->srq_size;
        srq_attr.attr.max_sge = 1;
        srq_attr.attr.srq_limit = 0;
+       srq_attr.srq_type = IB_SRQT_BASIC;
 
        sdev->srq = ib_create_srq(sdev->pd, &srq_attr);
        if (IS_ERR(sdev->srq))
index 2d787796bf50a186d87652edbaad100217f85084..7faf4a7fcaa9219d278b67b75a77a6c10081f678 100644 (file)
@@ -380,8 +380,7 @@ config INPUT_TWL4030_VIBRA
 
 config INPUT_TWL6040_VIBRA
        tristate "Support for TWL6040 Vibrator"
-       depends on TWL4030_CORE
-       select TWL6040_CORE
+       depends on TWL6040_CORE
        select INPUT_FF_MEMLESS
        help
          This option enables support for TWL6040 Vibrator Driver.
index 34aebb8cd080602479de04d496ff3c5b9ee4b8f0..3c843cd725fac0ec0a7f4c63310f47ad942da0a0 100644 (file)
@@ -95,7 +95,8 @@ static int __devinit da9052_onkey_probe(struct platform_device *pdev)
        input_dev = input_allocate_device();
        if (!onkey || !input_dev) {
                dev_err(&pdev->dev, "Failed to allocate memory\n");
-               return -ENOMEM;
+               error = -ENOMEM;
+               goto err_free_mem;
        }
 
        onkey->input = input_dev;
index 45874fed523ab771e94f8b3d9dccf415b8cfa6af..14e94f56cb7d4dab69581335b2b82e9b822895f9 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
-#include <linux/i2c/twl.h>
+#include <linux/input.h>
 #include <linux/mfd/twl6040.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);
 
 static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
 {
-       struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
+       struct twl6040_vibra_data *pdata = pdev->dev.platform_data;
        struct vibra_info *info;
        int ret;
 
index d2c0db159b18dfc364c2ff7fc036863ef2de9614..479011004a111dcf41cc344356da29e3deb74902 100644 (file)
@@ -486,7 +486,6 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
        unsigned char *packet = psmouse->packet;
 
        input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
-       input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
        input_mt_report_pointer_emulation(dev, true);
        input_sync(dev);
 }
@@ -967,6 +966,7 @@ static int elantech_set_input_params(struct psmouse *psmouse)
        if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
                return -1;
 
+       __set_bit(INPUT_PROP_POINTER, dev->propbit);
        __set_bit(EV_KEY, dev->evbit);
        __set_bit(EV_ABS, dev->evbit);
        __clear_bit(EV_REL, dev->evbit);
@@ -1017,7 +1017,9 @@ static int elantech_set_input_params(struct psmouse *psmouse)
                         */
                        psmouse_warn(psmouse, "couldn't query resolution data.\n");
                }
-
+               /* v4 is clickpad, with only one button. */
+               __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
+               __clear_bit(BTN_RIGHT, dev->keybit);
                __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
                /* For X to recognize me as touchpad. */
                input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
@@ -1245,6 +1247,8 @@ static void elantech_disconnect(struct psmouse *psmouse)
  */
 static int elantech_reconnect(struct psmouse *psmouse)
 {
+       psmouse_reset(psmouse);
+
        if (elantech_detect(psmouse, 0))
                return -1;
 
@@ -1324,6 +1328,8 @@ int elantech_init(struct psmouse *psmouse)
        if (!etd)
                return -ENOMEM;
 
+       psmouse_reset(psmouse);
+
        etd->parity[0] = 1;
        for (i = 1; i < 256; i++)
                etd->parity[i] = etd->parity[i & (i - 1)] ^ 1;
index a9ad8e1402be217786574e88146d6e5d652a1e8e..39fe9b737cae5c57aca9a588247038cb75ff375c 100644 (file)
@@ -12,9 +12,9 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
+#include <linux/gpio.h>
 #include <linux/gpio_mouse.h>
 
-#include <asm/gpio.h>
 
 /*
  * Timer function which is run every scan_ms ms when the device is opened.
index a977bfaa6821faef1c2993c919f77a854b9a03d8..661a0ca3b3d6939df7b11efd2576f4eb8dcc55f5 100644 (file)
@@ -741,6 +741,14 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
                        }
                } else {
                        /* SFAC packet */
+                       if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) ==
+                               FSP_PB0_LBTN) {
+                               /* On-pad click in SFAC mode should be handled
+                                * by userspace.  On-pad clicks in MFMC mode
+                                * are real clickpad clicks, and not ignored.
+                                */
+                               packet[0] &= ~FSP_PB0_LBTN;
+                       }
 
                        /* no multi-finger information */
                        ad->last_mt_fgr = 0;
index 22b218018137d964fdae5987addd66a1b7272320..f3102494237d207ecf5639d11d78e36d09e78050 100644 (file)
@@ -304,7 +304,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
                return 0;
 
        if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) {
-               printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n");
+               psmouse_warn(psmouse, "failed to get extended button data\n");
                button_info = 0;
        }
 
@@ -326,16 +326,18 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 
        error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
        if (error) {
-               printk(KERN_ERR
-                       "trackpoint.c: failed to create sysfs attributes, error: %d\n",
-                       error);
+               psmouse_err(psmouse,
+                           "failed to create sysfs attributes, error: %d\n",
+                           error);
                kfree(psmouse->private);
                psmouse->private = NULL;
                return -1;
        }
 
-       printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
-               firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f);
+       psmouse_info(psmouse,
+                    "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
+                    firmware_id,
+                    (button_info & 0xf0) >> 4, button_info & 0x0f);
 
        return 0;
 }
index 6c6f6d8ea9b413d68b97b47c72e6d1e192e70e05..f7eda3d00fadb46216f09de8eaa9d7c911350d97 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * drivers/input/touchscreen/tps6507x_ts.c
- *
  * Touchscreen driver for the tps6507x chip.
  *
  * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com)
@@ -376,4 +374,4 @@ module_platform_driver(tps6507x_ts_driver);
 MODULE_AUTHOR("Todd Fischer <todd.fischer@ridgerun.com>");
 MODULE_DESCRIPTION("TPS6507x - TouchScreen driver");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tps6507x-tsc");
+MODULE_ALIAS("platform:tps6507x-ts");
index b3d6ac17272d2872c0afc7c3bf1b72497e67266b..a6d9fd2858f74d2b6690cfcf9c6edc832f641bb2 100644 (file)
@@ -176,7 +176,7 @@ static void if_close(struct tty_struct *tty, struct file *filp)
        struct cardstate *cs = tty->driver_data;
 
        if (!cs) { /* happens if we didn't find cs in open */
-               printk(KERN_DEBUG "%s: no cardstate\n", __func__);
+               gig_dbg(DEBUG_IF, "%s: no cardstate", __func__);
                return;
        }
 
index 800243b6037ed9edc5b945b74d226a17be05f712..64ad702a2ecc64eff2505fd0f4217126fd10bdf9 100644 (file)
@@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
  * NOTE:  we reuse the platform_data structure of GPIO leds,
  * but repurpose its "gpio" number as a PWM channel number.
  */
-static int __init pwmled_probe(struct platform_device *pdev)
+static int __devinit pwmled_probe(struct platform_device *pdev)
 {
        const struct gpio_led_platform_data     *pdata;
        struct pwmled                           *leds;
index 3d0dfa7a89a2d683c8ccdbe76eedd02260550cba..97e73e555d112c8762b7934bd9892d39f5c6e4ce 100644 (file)
@@ -539,9 +539,6 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
        bitmap->events_cleared = bitmap->mddev->events;
        sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
 
-       bitmap->flags |= BITMAP_HOSTENDIAN;
-       sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN);
-
        kunmap_atomic(sb);
 
        return 0;
@@ -1788,7 +1785,9 @@ int bitmap_load(struct mddev *mddev)
                 * re-add of a missing device */
                start = mddev->recovery_cp;
 
+       mutex_lock(&mddev->bitmap_info.mutex);
        err = bitmap_init_from_disk(bitmap, start);
+       mutex_unlock(&mddev->bitmap_info.mutex);
 
        if (err)
                goto out;
index b0ba52459ed7381d4a802acb94e69df02f979149..68965e663248e2f0b0158aaf9a75f2583be2704c 100644 (file)
@@ -859,7 +859,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
        int ret;
        unsigned redundancy = 0;
        struct raid_dev *dev;
-       struct md_rdev *rdev, *freshest;
+       struct md_rdev *rdev, *tmp, *freshest;
        struct mddev *mddev = &rs->md;
 
        switch (rs->raid_type->level) {
@@ -877,7 +877,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
        }
 
        freshest = NULL;
-       rdev_for_each(rdev, mddev) {
+       rdev_for_each_safe(rdev, tmp, mddev) {
                if (!rdev->meta_bdev)
                        continue;
 
index b572e1e386ceab73643f3d0ffc272c1989b91474..477eb2e180c031d84b33d659167d8aea760babfe 100644 (file)
@@ -7560,14 +7560,14 @@ void md_check_recovery(struct mddev *mddev)
                 * any transients in the value of "sync_action".
                 */
                set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
-               clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                /* Clear some bits that don't mean anything, but
                 * might be left set
                 */
                clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
                clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
 
-               if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
+               if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
+                   test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
                        goto unlock;
                /* no recovery is running.
                 * remove any failed drives, then
@@ -8140,7 +8140,8 @@ static int md_notify_reboot(struct notifier_block *this,
 
        for_each_mddev(mddev, tmp) {
                if (mddev_trylock(mddev)) {
-                       __md_stop_writes(mddev);
+                       if (mddev->pers)
+                               __md_stop_writes(mddev);
                        mddev->safemode = 2;
                        mddev_unlock(mddev);
                }
index d35e4c991e38262425cf4495ed6fe98676210ef8..15dd59b84e94442c50ae164cb2ec1c130a74bc52 100644 (file)
@@ -1712,6 +1712,7 @@ static int process_checks(struct r1bio *r1_bio)
        struct r1conf *conf = mddev->private;
        int primary;
        int i;
+       int vcnt;
 
        for (primary = 0; primary < conf->raid_disks * 2; primary++)
                if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
@@ -1721,9 +1722,9 @@ static int process_checks(struct r1bio *r1_bio)
                        break;
                }
        r1_bio->read_disk = primary;
+       vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
        for (i = 0; i < conf->raid_disks * 2; i++) {
                int j;
-               int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9);
                struct bio *pbio = r1_bio->bios[primary];
                struct bio *sbio = r1_bio->bios[i];
                int size;
index fff782189e48f017f3407bb93ec7847a1fe367fd..c8dbb84d53579ab3e5c9ebc012a06cdb5205058f 100644 (file)
@@ -1788,6 +1788,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
        struct r10conf *conf = mddev->private;
        int i, first;
        struct bio *tbio, *fbio;
+       int vcnt;
 
        atomic_set(&r10_bio->remaining, 1);
 
@@ -1802,10 +1803,10 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
        first = i;
        fbio = r10_bio->devs[i].bio;
 
+       vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9);
        /* now find blocks with errors */
        for (i=0 ; i < conf->copies ; i++) {
                int  j, d;
-               int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9);
 
                tbio = r10_bio->devs[i].bio;
 
@@ -1871,7 +1872,6 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
         */
        for (i = 0; i < conf->copies; i++) {
                int j, d;
-               int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9);
 
                tbio = r10_bio->devs[i].repl_bio;
                if (!tbio || !tbio->bi_end_io)
index 7f98984e4fad0526fbe98335a29b166cf6bba428..eab2ea42420090c7847cd5d4eaa889659bf351b4 100644 (file)
@@ -54,6 +54,7 @@ struct xc5000_priv {
        struct list_head hybrid_tuner_instance_list;
 
        u32 if_khz;
+       u32 xtal_khz;
        u32 freq_hz;
        u32 bandwidth;
        u8  video_standard;
@@ -214,9 +215,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
        .size = 12401,
 };
 
-static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = {
-       .name = "dvb-fe-xc5000c-41.024.5-31875.fw",
-       .size = 16503,
+static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
+       .name = "dvb-fe-xc5000c-41.024.5.fw",
+       .size = 16497,
 };
 
 static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
@@ -226,7 +227,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
        case XC5000A:
                return &xc5000a_1_6_114;
        case XC5000C:
-               return &xc5000c_41_024_5_31875;
+               return &xc5000c_41_024_5;
        }
 }
 
@@ -572,6 +573,31 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
        return found;
 }
 
+static int xc_set_xtal(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret = XC_RESULT_SUCCESS;
+
+       switch (priv->chip_id) {
+       default:
+       case XC5000A:
+               /* 32.000 MHz xtal is default */
+               break;
+       case XC5000C:
+               switch (priv->xtal_khz) {
+               default:
+               case 32000:
+                       /* 32.000 MHz xtal is default */
+                       break;
+               case 31875:
+                       /* 31.875 MHz xtal configuration */
+                       ret = xc_write_reg(priv, 0x000f, 0x8081);
+                       break;
+               }
+               break;
+       }
+       return ret;
+}
 
 static int xc5000_fwupload(struct dvb_frontend *fe)
 {
@@ -603,6 +629,8 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
        } else {
                printk(KERN_INFO "xc5000: firmware uploading...\n");
                ret = xc_load_i2c_sequence(fe,  fw->data);
+               if (XC_RESULT_SUCCESS == ret)
+                       ret = xc_set_xtal(fe);
                printk(KERN_INFO "xc5000: firmware upload complete...\n");
        }
 
@@ -1164,6 +1192,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
                priv->if_khz = cfg->if_khz;
        }
 
+       if (priv->xtal_khz == 0)
+               priv->xtal_khz = cfg->xtal_khz;
+
        if (priv->radio_input == 0)
                priv->radio_input = cfg->radio_input;
 
index 3396f8e02b40c2fb1363bedb891c76badbbf9da8..39a73bf01406c8e3d2df4a3f6cc53ac7f065467c 100644 (file)
@@ -34,6 +34,7 @@ struct xc5000_config {
        u8   i2c_address;
        u32  if_khz;
        u8   radio_input;
+       u32  xtal_khz;
 
        int chip_id;
 };
index 4555baa383b26ec58b987bb65fecbe8303d7c504..0f64d71826572d298d4cbf19050e8be254fce887 100644 (file)
@@ -143,10 +143,12 @@ struct dvb_frontend_private {
 static void dvb_frontend_wakeup(struct dvb_frontend *fe);
 static int dtv_get_frontend(struct dvb_frontend *fe,
                            struct dvb_frontend_parameters *p_out);
+static int dtv_property_legacy_params_sync(struct dvb_frontend *fe,
+                                          struct dvb_frontend_parameters *p);
 
 static bool has_get_frontend(struct dvb_frontend *fe)
 {
-       return fe->ops.get_frontend;
+       return fe->ops.get_frontend != NULL;
 }
 
 /*
@@ -697,6 +699,7 @@ restart:
                                        fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
                                        fepriv->delay = HZ / 2;
                                }
+                               dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
                                fe->ops.read_status(fe, &s);
                                if (s != fepriv->status) {
                                        dvb_frontend_add_event(fe, s); /* update event list */
@@ -1443,6 +1446,28 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
                                __func__);
                        return -EINVAL;
                }
+               /*
+                * Get a delivery system that is compatible with DVBv3
+                * NOTE: in order for this to work with softwares like Kaffeine that
+                *      uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
+                *      DVB-S, drivers that support both should put the SYS_DVBS entry
+                *      before the SYS_DVBS2, otherwise it won't switch back to DVB-S.
+                *      The real fix is that userspace applications should not use DVBv3
+                *      and not trust on calling FE_SET_FRONTEND to switch the delivery
+                *      system.
+                */
+               ncaps = 0;
+               while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+                       if (fe->ops.delsys[ncaps] == desired_system) {
+                               delsys = desired_system;
+                               break;
+                       }
+                       ncaps++;
+               }
+               if (delsys == SYS_UNDEFINED) {
+                       dprintk("%s() Couldn't find a delivery system that matches %d\n",
+                               __func__, desired_system);
+               }
        } else {
                /*
                 * This is a DVBv5 call. So, it likely knows the supported
@@ -1491,9 +1516,10 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
                                __func__);
                        return -EINVAL;
                }
-               c->delivery_system = delsys;
        }
 
+       c->delivery_system = delsys;
+
        /*
         * The DVBv3 or DVBv5 call is requesting a different system. So,
         * emulation is needed.
@@ -1832,6 +1858,13 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
        if (dvb_frontend_check_parameters(fe) < 0)
                return -EINVAL;
 
+       /*
+        * Initialize output parameters to match the values given by
+        * the user. FE_SET_FRONTEND triggers an initial frontend event
+        * with status = 0, which copies output parameters to userspace.
+        */
+       dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
+
        /*
         * Be sure that the bandwidth will be filled for all
         * non-satellite systems, as tuners need to know what
index 3b7b102f20ae076fe5033092db4333dfbcdbb8fe..482d249ca7f3f0613d8aee2bf7c3ca27804a908a 100644 (file)
@@ -238,12 +238,27 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg)
 
 static u32 it913x_query(struct usb_device *udev, u8 pro)
 {
-       int ret;
+       int ret, i;
        u8 data[4];
-       ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
-               0x1222, 0, &data[0], 3);
+       u8 ver;
+
+       for (i = 0; i < 5; i++) {
+               ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
+                       0x1222, 0, &data[0], 3);
+               ver = data[0];
+               if (ver > 0 && ver < 3)
+                       break;
+               msleep(100);
+       }
 
-       it913x_config.chip_ver = data[0];
+       if (ver < 1 || ver > 2) {
+               info("Failed to identify chip version applying 1");
+               it913x_config.chip_ver = 0x1;
+               it913x_config.chip_type = 0x9135;
+               return 0;
+       }
+
+       it913x_config.chip_ver = ver;
        it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
 
        info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver,
@@ -660,30 +675,41 @@ static int it913x_download_firmware(struct usb_device *udev,
                        if ((packet_size > min_pkt) || (i == fw->size)) {
                                fw_data = (u8 *)(fw->data + pos);
                                pos += packet_size;
-                               if (packet_size > 0)
-                                       ret |= it913x_io(udev, WRITE_DATA,
+                               if (packet_size > 0) {
+                                       ret = it913x_io(udev, WRITE_DATA,
                                                DEV_0, CMD_SCATTER_WRITE, 0,
                                                0, fw_data, packet_size);
+                                       if (ret < 0)
+                                               break;
+                               }
                                udelay(1000);
                        }
                }
                i++;
        }
 
-       ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
-
-       msleep(100);
-
        if (ret < 0)
-               info("FRM Firmware Download Failed (%04x)" , ret);
+               info("FRM Firmware Download Failed (%d)" , ret);
        else
                info("FRM Firmware Download Completed - Resetting Device");
 
-       ret |= it913x_return_status(udev);
+       msleep(30);
+
+       ret = it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
+       if (ret < 0)
+               info("FRM Device not responding to reboot");
+
+       ret = it913x_return_status(udev);
+       if (ret == 0) {
+               info("FRM Failed to reboot device");
+               return -ENODEV;
+       }
 
        msleep(30);
 
-       ret |= it913x_wr_reg(udev, DEV_0,  I2C_CLK, I2C_CLK_400);
+       ret = it913x_wr_reg(udev, DEV_0,  I2C_CLK, I2C_CLK_400);
+
+       msleep(30);
 
        /* Tuner function */
        if (it913x_config.dual_mode)
@@ -901,5 +927,5 @@ module_usb_driver(it913x_driver);
 
 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
 MODULE_DESCRIPTION("it913x USB 2 Driver");
-MODULE_VERSION("1.27");
+MODULE_VERSION("1.28");
 MODULE_LICENSE("GPL");
index 36d11756492f5f62471ba412786d8183e271aecc..a414b1f2b6a5a0f2cd1c4dcfef210ea45189f912 100644 (file)
@@ -1520,8 +1520,10 @@ static int scu_command(struct drxk_state *state,
        dprintk(1, "\n");
 
        if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
-           ((resultLen > 0) && (result == NULL)))
-               goto error;
+           ((resultLen > 0) && (result == NULL))) {
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+               return status;
+       }
 
        mutex_lock(&state->mutex);
 
index b09c5fae489bd020ea4748cd9c33d67dc12568b0..af526586fa263f63ccf6d2088f10a779724fb3a8 100644 (file)
@@ -1046,6 +1046,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
                goto exit_unregister_led;
        }
 
+       data->dev->driver_type = RC_DRIVER_IR_RAW;
        data->dev->driver_name = WBCIR_NAME;
        data->dev->input_name = WBCIR_NAME;
        data->dev->input_phys = "wbcir/cir0";
index f2479c5c0eb23071d6f3d29c6cd598b7f777e55b..ce1e7ba940f6c75ac2818b799010deee37553c48 100644 (file)
@@ -492,7 +492,7 @@ config VIDEO_VS6624
 
 config VIDEO_MT9M032
        tristate "MT9M032 camera sensor support"
-       depends on I2C && VIDEO_V4L2
+       depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
        select VIDEO_APTINA_PLL
        ---help---
          This driver supports MT9M032 camera sensors from Aptina, monochrome
index 5452beef8e117cf75a99963a5e04f204d13d5083..989e556913edd063f35013c3004677196bfa19f5 100644 (file)
@@ -1763,13 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
                if (iarg > AUDIO_STEREO_SWAPPED)
                        return -EINVAL;
-               return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg);
+               return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
 
        case AUDIO_BILINGUAL_CHANNEL_SELECT:
                IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
                if (iarg > AUDIO_STEREO_SWAPPED)
                        return -EINVAL;
-               return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg);
+               return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
 
        default:
                return -EINVAL;
index 7636672c3548a45fc1b76dc502d099b34c472533..645973c5feb01d7a9413310a106a35af59dd4c0d 100644 (file)
@@ -392,10 +392,11 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
        }
 
        /* Scaling is not supported, the format is thus fixed. */
-       ret = mt9m032_get_pad_format(subdev, fh, fmt);
+       fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
+       ret = 0;
 
 done:
-       mutex_lock(&sensor->lock);
+       mutex_unlock(&sensor->lock);
        return ret;
 }
 
index 4a44f9a1bae00e0610f8c3d382cd5110d422f851..b76b0ac0958f8d2d27a5a7193c623badfac5ee67 100644 (file)
@@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
        spin_unlock_irqrestore(&stream->clock.lock, flags);
 }
 
-static int uvc_video_clock_init(struct uvc_streaming *stream)
+static void uvc_video_clock_reset(struct uvc_streaming *stream)
 {
        struct uvc_clock *clock = &stream->clock;
 
-       spin_lock_init(&clock->lock);
        clock->head = 0;
        clock->count = 0;
-       clock->size = 32;
        clock->last_sof = -1;
        clock->sof_offset = -1;
+}
+
+static int uvc_video_clock_init(struct uvc_streaming *stream)
+{
+       struct uvc_clock *clock = &stream->clock;
+
+       spin_lock_init(&clock->lock);
+       clock->size = 32;
 
        clock->samples = kmalloc(clock->size * sizeof(*clock->samples),
                                 GFP_KERNEL);
        if (clock->samples == NULL)
                return -ENOMEM;
 
+       uvc_video_clock_reset(stream);
+
        return 0;
 }
 
@@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
 
        if (free_buffers)
                uvc_free_urb_buffers(stream);
-
-       uvc_video_clock_cleanup(stream);
 }
 
 /*
@@ -1555,10 +1561,6 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
 
        uvc_video_stats_start(stream);
 
-       ret = uvc_video_clock_init(stream);
-       if (ret < 0)
-               return ret;
-
        if (intf->num_altsetting > 1) {
                struct usb_host_endpoint *best_ep = NULL;
                unsigned int best_psize = 3 * 1024;
@@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset)
 
        stream->frozen = 0;
 
+       uvc_video_clock_reset(stream);
+
        ret = uvc_commit_video(stream, &stream->ctrl);
        if (ret < 0) {
                uvc_queue_enable(&stream->queue, 0);
@@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
                uvc_uninit_video(stream, 1);
                usb_set_interface(stream->dev->udev, stream->intfnum, 0);
                uvc_queue_enable(&stream->queue, 0);
+               uvc_video_clock_cleanup(stream);
                return 0;
        }
 
-       ret = uvc_queue_enable(&stream->queue, 1);
+       ret = uvc_video_clock_init(stream);
        if (ret < 0)
                return ret;
 
+       ret = uvc_queue_enable(&stream->queue, 1);
+       if (ret < 0)
+               goto error_queue;
+
        /* Commit the streaming parameters. */
        ret = uvc_commit_video(stream, &stream->ctrl);
-       if (ret < 0) {
-               uvc_queue_enable(&stream->queue, 0);
-               return ret;
-       }
+       if (ret < 0)
+               goto error_commit;
 
        ret = uvc_init_video(stream, GFP_KERNEL);
-       if (ret < 0) {
-               usb_set_interface(stream->dev->udev, stream->intfnum, 0);
-               uvc_queue_enable(&stream->queue, 0);
-       }
+       if (ret < 0)
+               goto error_video;
+
+       return 0;
+
+error_video:
+       usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+error_commit:
+       uvc_queue_enable(&stream->queue, 0);
+error_queue:
+       uvc_video_clock_cleanup(stream);
 
        return ret;
 }
index 29f463cc09cbc5dc56ec215a225548be8a65b900..11e44386fa9bba2287c3fda66b422b3f88c57963 100644 (file)
@@ -268,10 +268,17 @@ config TWL6030_PWM
          This is used to control charging LED brightness.
 
 config TWL6040_CORE
-       bool
-       depends on TWL4030_CORE && GENERIC_HARDIRQS
+       bool "Support for TWL6040 audio codec"
+       depends on I2C=y && GENERIC_HARDIRQS
        select MFD_CORE
+       select REGMAP_I2C
        default n
+       help
+         Say yes here if you want support for Texas Instruments TWL6040 audio
+         codec.
+         This driver provides common support for accessing the device,
+         additional drivers must be enabled in order to use the
+         functionality of the device (audio, vibra).
 
 config MFD_STMPE
        bool "Support STMicroelectronics STMPE"
index 1895cf9fab8c1b1c491cbc611335775f014760e0..1582c3d952579e66306e1ad8ce2713f3b0d03f9c 100644 (file)
@@ -527,7 +527,9 @@ static void asic3_gpio_set(struct gpio_chip *chip,
 
 static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-       return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO;
+       struct asic3 *asic = container_of(chip, struct asic3, gpio);
+
+       return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO;
 }
 
 static __init int asic3_gpio_probe(struct platform_device *pdev,
index ebc1e8658226bbfca7505f2d109d119a9598e690..5be32489714f61a279b4fe30ce7badb37d5833a4 100644 (file)
@@ -2788,6 +2788,7 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
                .constraints = {
                        .name = "db8500-vape",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                       .always_on = true,
                },
                .consumer_supplies = db8500_vape_consumers,
                .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers),
index 95a2e546a48962c18cfaa151aa7dc539e4c94035..c8aae6640e64cc00bdc4079f3326ac8ef512df34 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
-#include <linux/gpio.h>
 #include <plat/usb.h>
 #include <linux/pm_runtime.h>
 
@@ -502,19 +501,6 @@ static void omap_usbhs_init(struct device *dev)
        pm_runtime_get_sync(dev);
        spin_lock_irqsave(&omap->lock, flags);
 
-       if (pdata->ehci_data->phy_reset) {
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-                       gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
-                                        GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
-
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-                       gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
-                                        GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
-
-               /* Hold the PHY in RESET for enough time till DIR is high */
-               udelay(10);
-       }
-
        omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
        dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
 
@@ -593,39 +579,10 @@ static void omap_usbhs_init(struct device *dev)
                        usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
        }
 
-       if (pdata->ehci_data->phy_reset) {
-               /* Hold the PHY in RESET for enough time till
-                * PHY is settled and ready
-                */
-               udelay(10);
-
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-                       gpio_set_value
-                               (pdata->ehci_data->reset_gpio_port[0], 1);
-
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-                       gpio_set_value
-                               (pdata->ehci_data->reset_gpio_port[1], 1);
-       }
-
        spin_unlock_irqrestore(&omap->lock, flags);
        pm_runtime_put_sync(dev);
 }
 
-static void omap_usbhs_deinit(struct device *dev)
-{
-       struct usbhs_hcd_omap           *omap = dev_get_drvdata(dev);
-       struct usbhs_omap_platform_data *pdata = &omap->platdata;
-
-       if (pdata->ehci_data->phy_reset) {
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-                       gpio_free(pdata->ehci_data->reset_gpio_port[0]);
-
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-                       gpio_free(pdata->ehci_data->reset_gpio_port[1]);
-       }
-}
-
 
 /**
  * usbhs_omap_probe - initialize TI-based HCDs
@@ -860,7 +817,6 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
 {
        struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
 
-       omap_usbhs_deinit(&pdev->dev);
        iounmap(omap->tll_base);
        iounmap(omap->uhh_base);
        clk_put(omap->init_60m_fclk);
index 99ef944c621df5e00f1f440c05fe5e8938938415..44afae0a69ce75a5fada79d48acae246db1dfdb0 100644 (file)
@@ -80,44 +80,6 @@ static struct mfd_cell rc5t583_subdevs[] = {
        {.name = "rc5t583-key",      }
 };
 
-int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       return regmap_write(rc5t583->regmap, reg, val);
-}
-
-int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       unsigned int ival;
-       int ret;
-       ret = regmap_read(rc5t583->regmap, reg, &ival);
-       if (!ret)
-               *val = (uint8_t)ival;
-       return ret;
-}
-
-int rc5t583_set_bits(struct device *dev, unsigned int reg,
-                       unsigned int bit_mask)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
-}
-
-int rc5t583_clear_bits(struct device *dev, unsigned int reg,
-                       unsigned int bit_mask)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
-}
-
-int rc5t583_update(struct device *dev, unsigned int reg,
-               unsigned int val, unsigned int mask)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       return regmap_update_bits(rc5t583->regmap, reg, mask, val);
-}
-
 static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
        int id, int ext_pwr, int slots)
 {
@@ -197,6 +159,7 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id,
                        ds_id, ext_pwr_req);
        return 0;
 }
+EXPORT_SYMBOL(rc5t583_ext_power_req_config);
 
 static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,
        struct rc5t583_platform_data *pdata)
index b2d8e512d3cb002b6f3e809e47a12f01f96de588..2d6bedadca096d68eec4ce61332b57d6f08140a8 100644 (file)
@@ -30,7 +30,9 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
-#include <linux/i2c/twl.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/twl6040.h>
 
@@ -39,7 +41,7 @@
 int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
 {
        int ret;
-       u8 val = 0;
+       unsigned int val;
 
        mutex_lock(&twl6040->io_mutex);
        /* Vibra control registers from cache */
@@ -47,7 +49,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
                     reg == TWL6040_REG_VIBCTLR)) {
                val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
        } else {
-               ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
+               ret = regmap_read(twl6040->regmap, reg, &val);
                if (ret < 0) {
                        mutex_unlock(&twl6040->io_mutex);
                        return ret;
@@ -64,7 +66,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
        int ret;
 
        mutex_lock(&twl6040->io_mutex);
-       ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
+       ret = regmap_write(twl6040->regmap, reg, val);
        /* Cache the vibra control registers */
        if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
                twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
@@ -77,16 +79,9 @@ EXPORT_SYMBOL(twl6040_reg_write);
 int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
 {
        int ret;
-       u8 val;
 
        mutex_lock(&twl6040->io_mutex);
-       ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
-       if (ret)
-               goto out;
-
-       val |= mask;
-       ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+       ret = regmap_update_bits(twl6040->regmap, reg, mask, mask);
        mutex_unlock(&twl6040->io_mutex);
        return ret;
 }
@@ -95,16 +90,9 @@ EXPORT_SYMBOL(twl6040_set_bits);
 int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
 {
        int ret;
-       u8 val;
 
        mutex_lock(&twl6040->io_mutex);
-       ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
-       if (ret)
-               goto out;
-
-       val &= ~mask;
-       ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+       ret = regmap_update_bits(twl6040->regmap, reg, mask, 0);
        mutex_unlock(&twl6040->io_mutex);
        return ret;
 }
@@ -494,32 +482,58 @@ static struct resource twl6040_codec_rsrc[] = {
        },
 };
 
-static int __devinit twl6040_probe(struct platform_device *pdev)
+static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
 {
-       struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+       /* Register 0 is not readable */
+       if (!reg)
+               return false;
+       return true;
+}
+
+static struct regmap_config twl6040_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = TWL6040_REG_STATUS, /* 0x2e */
+
+       .readable_reg = twl6040_readable_reg,
+};
+
+static int __devinit twl6040_probe(struct i2c_client *client,
+                                    const struct i2c_device_id *id)
+{
+       struct twl6040_platform_data *pdata = client->dev.platform_data;
        struct twl6040 *twl6040;
        struct mfd_cell *cell = NULL;
        int ret, children = 0;
 
        if (!pdata) {
-               dev_err(&pdev->dev, "Platform data is missing\n");
+               dev_err(&client->dev, "Platform data is missing\n");
                return -EINVAL;
        }
 
        /* In order to operate correctly we need valid interrupt config */
-       if (!pdata->naudint_irq || !pdata->irq_base) {
-               dev_err(&pdev->dev, "Invalid IRQ configuration\n");
+       if (!client->irq || !pdata->irq_base) {
+               dev_err(&client->dev, "Invalid IRQ configuration\n");
                return -EINVAL;
        }
 
-       twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL);
-       if (!twl6040)
-               return -ENOMEM;
+       twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
+                              GFP_KERNEL);
+       if (!twl6040) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config);
+       if (IS_ERR(twl6040->regmap)) {
+               ret = PTR_ERR(twl6040->regmap);
+               goto err;
+       }
 
-       platform_set_drvdata(pdev, twl6040);
+       i2c_set_clientdata(client, twl6040);
 
-       twl6040->dev = &pdev->dev;
-       twl6040->irq = pdata->naudint_irq;
+       twl6040->dev = &client->dev;
+       twl6040->irq = client->irq;
        twl6040->irq_base = pdata->irq_base;
 
        mutex_init(&twl6040->mutex);
@@ -588,12 +602,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
        }
 
        if (children) {
-               ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells,
+               ret = mfd_add_devices(&client->dev, -1, twl6040->cells,
                                      children, NULL, 0);
                if (ret)
                        goto mfd_err;
        } else {
-               dev_err(&pdev->dev, "No platform data found for children\n");
+               dev_err(&client->dev, "No platform data found for children\n");
                ret = -ENODEV;
                goto mfd_err;
        }
@@ -608,14 +622,15 @@ gpio2_err:
        if (gpio_is_valid(twl6040->audpwron))
                gpio_free(twl6040->audpwron);
 gpio1_err:
-       platform_set_drvdata(pdev, NULL);
-       kfree(twl6040);
+       i2c_set_clientdata(client, NULL);
+       regmap_exit(twl6040->regmap);
+err:
        return ret;
 }
 
-static int __devexit twl6040_remove(struct platform_device *pdev)
+static int __devexit twl6040_remove(struct i2c_client *client)
 {
-       struct twl6040 *twl6040 = platform_get_drvdata(pdev);
+       struct twl6040 *twl6040 = i2c_get_clientdata(client);
 
        if (twl6040->power_count)
                twl6040_power(twl6040, 0);
@@ -626,23 +641,30 @@ static int __devexit twl6040_remove(struct platform_device *pdev)
        free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);
        twl6040_irq_exit(twl6040);
 
-       mfd_remove_devices(&pdev->dev);
-       platform_set_drvdata(pdev, NULL);
-       kfree(twl6040);
+       mfd_remove_devices(&client->dev);
+       i2c_set_clientdata(client, NULL);
+       regmap_exit(twl6040->regmap);
 
        return 0;
 }
 
-static struct platform_driver twl6040_driver = {
+static const struct i2c_device_id twl6040_i2c_id[] = {
+       { "twl6040", 0, },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id);
+
+static struct i2c_driver twl6040_driver = {
+       .driver = {
+               .name = "twl6040",
+               .owner = THIS_MODULE,
+       },
        .probe          = twl6040_probe,
        .remove         = __devexit_p(twl6040_remove),
-       .driver         = {
-               .owner  = THIS_MODULE,
-               .name   = "twl6040",
-       },
+       .id_table       = twl6040_i2c_id,
 };
 
-module_platform_driver(twl6040_driver);
+module_i2c_driver(twl6040_driver);
 
 MODULE_DESCRIPTION("TWL6040 MFD");
 MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
index eed213a5c8cba8f53ae8bdba6e2f6525eedc9657..dabec556ebb87421f04372ecf1452b645629ab17 100644 (file)
@@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
 {
        struct mmc_blk_data *md = mq->data;
        struct mmc_card *card = md->queue.card;
-       unsigned int from, nr, arg;
+       unsigned int from, nr, arg, trim_arg, erase_arg;
        int err = 0, type = MMC_BLK_SECDISCARD;
 
        if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
@@ -881,20 +881,26 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
                goto out;
        }
 
+       from = blk_rq_pos(req);
+       nr = blk_rq_sectors(req);
+
        /* The sanitize operation is supported at v4.5 only */
        if (mmc_can_sanitize(card)) {
-               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-                               EXT_CSD_SANITIZE_START, 1, 0);
-               goto out;
+               erase_arg = MMC_ERASE_ARG;
+               trim_arg = MMC_TRIM_ARG;
+       } else {
+               erase_arg = MMC_SECURE_ERASE_ARG;
+               trim_arg = MMC_SECURE_TRIM1_ARG;
        }
 
-       from = blk_rq_pos(req);
-       nr = blk_rq_sectors(req);
-
-       if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
-               arg = MMC_SECURE_TRIM1_ARG;
-       else
-               arg = MMC_SECURE_ERASE_ARG;
+       if (mmc_erase_group_aligned(card, from, nr))
+               arg = erase_arg;
+       else if (mmc_can_trim(card))
+               arg = trim_arg;
+       else {
+               err = -EINVAL;
+               goto out;
+       }
 retry:
        if (card->quirks & MMC_QUIRK_INAND_CMD38) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -904,25 +910,41 @@ retry:
                                 INAND_CMD38_ARG_SECERASE,
                                 0);
                if (err)
-                       goto out;
+                       goto out_retry;
        }
+
        err = mmc_erase(card, from, nr, arg);
-       if (!err && arg == MMC_SECURE_TRIM1_ARG) {
+       if (err == -EIO)
+               goto out_retry;
+       if (err)
+               goto out;
+
+       if (arg == MMC_SECURE_TRIM1_ARG) {
                if (card->quirks & MMC_QUIRK_INAND_CMD38) {
                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                         INAND_CMD38_ARG_EXT_CSD,
                                         INAND_CMD38_ARG_SECTRIM2,
                                         0);
                        if (err)
-                               goto out;
+                               goto out_retry;
                }
+
                err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
+               if (err == -EIO)
+                       goto out_retry;
+               if (err)
+                       goto out;
        }
-out:
-       if (err == -EIO && !mmc_blk_reset(md, card->host, type))
+
+       if (mmc_can_sanitize(card))
+               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                                EXT_CSD_SANITIZE_START, 1, 0);
+out_retry:
+       if (err && !mmc_blk_reset(md, card->host, type))
                goto retry;
        if (!err)
                mmc_blk_reset_success(md, type);
+out:
        spin_lock_irq(&md->lock);
        __blk_end_request(req, err, blk_rq_bytes(req));
        spin_unlock_irq(&md->lock);
@@ -1623,24 +1645,6 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
        return ret;
 }
 
-static int
-mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
-{
-       int err;
-
-       mmc_claim_host(card->host);
-       err = mmc_set_blocklen(card, 512);
-       mmc_release_host(card->host);
-
-       if (err) {
-               pr_err("%s: unable to set block size to 512: %d\n",
-                       md->disk->disk_name, err);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 static void mmc_blk_remove_req(struct mmc_blk_data *md)
 {
        struct mmc_card *card;
@@ -1768,7 +1772,6 @@ static const struct mmc_fixup blk_fixups[] =
 static int mmc_blk_probe(struct mmc_card *card)
 {
        struct mmc_blk_data *md, *part_md;
-       int err;
        char cap_str[10];
 
        /*
@@ -1781,10 +1784,6 @@ static int mmc_blk_probe(struct mmc_card *card)
        if (IS_ERR(md))
                return PTR_ERR(md);
 
-       err = mmc_blk_set_blksize(md, card);
-       if (err)
-               goto out;
-
        string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2,
                        cap_str, sizeof(cap_str));
        pr_info("%s: %s %s %s %s\n",
@@ -1809,7 +1808,7 @@ static int mmc_blk_probe(struct mmc_card *card)
  out:
        mmc_blk_remove_parts(card, md);
        mmc_blk_remove_req(md);
-       return err;
+       return 0;
 }
 
 static void mmc_blk_remove(struct mmc_card *card)
@@ -1825,7 +1824,7 @@ static void mmc_blk_remove(struct mmc_card *card)
 }
 
 #ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
+static int mmc_blk_suspend(struct mmc_card *card)
 {
        struct mmc_blk_data *part_md;
        struct mmc_blk_data *md = mmc_get_drvdata(card);
@@ -1845,8 +1844,6 @@ static int mmc_blk_resume(struct mmc_card *card)
        struct mmc_blk_data *md = mmc_get_drvdata(card);
 
        if (md) {
-               mmc_blk_set_blksize(md, card);
-
                /*
                 * Resume involves the card going into idle state,
                 * so current partition is always the main one.
index 2517547b4366a9bbdc6eea69ce1f1dc35ef09f08..996f8e36e23d8aa8bbf7c333fd6d6d56b8ec79ad 100644 (file)
@@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,
 
        queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
        q->limits.max_discard_sectors = max_discard;
-       if (card->erased_byte == 0)
+       if (card->erased_byte == 0 && !mmc_can_discard(card))
                q->limits.discard_zeroes_data = 1;
        q->limits.discard_granularity = card->pref_erase << 9;
        /* granularity must not be greater than max. discard */
index 5d011a39dfff3b68a88813e202c76a4722fa3c57..c60cee92a2b2fe9bfd4a9b863dbc95d0e76e2eae 100644 (file)
@@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev)
        return 0;
 }
 
-static int mmc_bus_suspend(struct device *dev, pm_message_t state)
+static int mmc_bus_suspend(struct device *dev)
 {
        struct mmc_driver *drv = to_mmc_driver(dev->driver);
        struct mmc_card *card = mmc_dev_to_card(dev);
        int ret = 0;
 
        if (dev->driver && drv->suspend)
-               ret = drv->suspend(card, state);
+               ret = drv->suspend(card);
        return ret;
 }
 
@@ -165,20 +165,14 @@ static int mmc_runtime_idle(struct device *dev)
        return pm_runtime_suspend(dev);
 }
 
+#endif /* !CONFIG_PM_RUNTIME */
+
 static const struct dev_pm_ops mmc_bus_pm_ops = {
-       .runtime_suspend        = mmc_runtime_suspend,
-       .runtime_resume         = mmc_runtime_resume,
-       .runtime_idle           = mmc_runtime_idle,
+       SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume,
+                       mmc_runtime_idle)
+       SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume)
 };
 
-#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops)
-
-#else /* !CONFIG_PM_RUNTIME */
-
-#define MMC_PM_OPS_PTR NULL
-
-#endif /* !CONFIG_PM_RUNTIME */
-
 static struct bus_type mmc_bus_type = {
        .name           = "mmc",
        .dev_attrs      = mmc_dev_attrs,
@@ -186,9 +180,7 @@ static struct bus_type mmc_bus_type = {
        .uevent         = mmc_bus_uevent,
        .probe          = mmc_bus_probe,
        .remove         = mmc_bus_remove,
-       .suspend        = mmc_bus_suspend,
-       .resume         = mmc_bus_resume,
-       .pm             = MMC_PM_OPS_PTR,
+       .pm             = &mmc_bus_pm_ops,
 };
 
 int mmc_register_bus(void)
@@ -267,6 +259,15 @@ int mmc_add_card(struct mmc_card *card)
 {
        int ret;
        const char *type;
+       const char *uhs_bus_speed_mode = "";
+       static const char *const uhs_speeds[] = {
+               [UHS_SDR12_BUS_SPEED] = "SDR12 ",
+               [UHS_SDR25_BUS_SPEED] = "SDR25 ",
+               [UHS_SDR50_BUS_SPEED] = "SDR50 ",
+               [UHS_SDR104_BUS_SPEED] = "SDR104 ",
+               [UHS_DDR50_BUS_SPEED] = "DDR50 ",
+       };
+
 
        dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca);
 
@@ -296,6 +297,10 @@ int mmc_add_card(struct mmc_card *card)
                break;
        }
 
+       if (mmc_sd_card_uhs(card) &&
+               (card->sd_bus_speed < ARRAY_SIZE(uhs_speeds)))
+               uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed];
+
        if (mmc_host_is_spi(card->host)) {
                pr_info("%s: new %s%s%s card on SPI\n",
                        mmc_hostname(card->host),
@@ -303,13 +308,13 @@ int mmc_add_card(struct mmc_card *card)
                        mmc_card_ddr_mode(card) ? "DDR " : "",
                        type);
        } else {
-               pr_info("%s: new %s%s%s%s card at address %04x\n",
+               pr_info("%s: new %s%s%s%s%s card at address %04x\n",
                        mmc_hostname(card->host),
                        mmc_card_uhs(card) ? "ultra high speed " :
                        (mmc_card_highspeed(card) ? "high speed " : ""),
                        (mmc_card_hs200(card) ? "HS200 " : ""),
                        mmc_card_ddr_mode(card) ? "DDR " : "",
-                       type, card->rca);
+                       uhs_bus_speed_mode, type, card->rca);
        }
 
 #ifdef CONFIG_DEBUG_FS
index 29de31e260dda56da18d0345f15a3886c6c1063a..2c14be73254c385d9a481c89db978c7c82c1b6e9 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
+#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index 14f262e9246d7a853ad2e1d78ce561e1c51d58c2..ba821fe70bca03dd3fbf17661e150ff737af242c 100644 (file)
@@ -527,10 +527,14 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
 
                if (data->flags & MMC_DATA_WRITE)
                        /*
-                        * The limit is really 250 ms, but that is
-                        * insufficient for some crappy cards.
+                        * The MMC spec "It is strongly recommended
+                        * for hosts to implement more than 500ms
+                        * timeout value even if the card indicates
+                        * the 250ms maximum busy length."  Even the
+                        * previous value of 300ms is known to be
+                        * insufficient for some cards.
                         */
-                       limit_us = 300000;
+                       limit_us = 3000000;
                else
                        limit_us = 100000;
 
@@ -1405,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
 {
        unsigned int erase_timeout;
 
-       if (card->ext_csd.erase_group_def & 1) {
+       if (arg == MMC_DISCARD_ARG ||
+           (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) {
+               erase_timeout = card->ext_csd.trim_timeout;
+       } else if (card->ext_csd.erase_group_def & 1) {
                /* High Capacity Erase Group Size uses HC timeouts */
                if (arg == MMC_TRIM_ARG)
                        erase_timeout = card->ext_csd.trim_timeout;
@@ -1677,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card)
 {
        if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
                return 1;
-       if (mmc_can_discard(card))
-               return 1;
        return 0;
 }
 EXPORT_SYMBOL(mmc_can_trim);
@@ -1697,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard);
 
 int mmc_can_sanitize(struct mmc_card *card)
 {
+       if (!mmc_can_trim(card) && !mmc_can_erase(card))
+               return 0;
        if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)
                return 1;
        return 0;
@@ -2231,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
                        mmc_card_is_removable(host))
                return err;
 
+       mmc_claim_host(host);
        if (card && mmc_card_mmc(card) &&
                        (card->ext_csd.cache_size > 0)) {
                enable = !!enable;
@@ -2248,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
                                card->ext_csd.cache_ctrl = enable;
                }
        }
+       mmc_release_host(host);
 
        return err;
 }
@@ -2265,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host)
 
        cancel_delayed_work(&host->detect);
        mmc_flush_scheduled_work();
-       if (mmc_try_claim_host(host)) {
-               err = mmc_cache_ctrl(host, 0);
-               mmc_release_host(host);
-       } else {
-               err = -EBUSY;
-       }
 
+       err = mmc_cache_ctrl(host, 0);
        if (err)
                goto out;
 
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
 
-               /*
-                * A long response time is not acceptable for device drivers
-                * when doing suspend. Prevent mmc_claim_host in the suspend
-                * sequence, to potentially wait "forever" by trying to
-                * pre-claim the host.
-                */
-               if (mmc_try_claim_host(host)) {
-                       if (host->bus_ops->suspend) {
-                               err = host->bus_ops->suspend(host);
-                       }
-                       mmc_release_host(host);
+               if (host->bus_ops->suspend)
+                       err = host->bus_ops->suspend(host);
 
-                       if (err == -ENOSYS || !host->bus_ops->resume) {
-                               /*
-                                * We simply "remove" the card in this case.
-                                * It will be redetected on resume.  (Calling
-                                * bus_ops->remove() with a claimed host can
-                                * deadlock.)
-                                */
-                               if (host->bus_ops->remove)
-                                       host->bus_ops->remove(host);
-                               mmc_claim_host(host);
-                               mmc_detach_bus(host);
-                               mmc_power_off(host);
-                               mmc_release_host(host);
-                               host->pm_flags = 0;
-                               err = 0;
-                       }
-               } else {
-                       err = -EBUSY;
+               if (err == -ENOSYS || !host->bus_ops->resume) {
+                       /*
+                        * We simply "remove" the card in this case.
+                        * It will be redetected on resume.  (Calling
+                        * bus_ops->remove() with a claimed host can
+                        * deadlock.)
+                        */
+                       if (host->bus_ops->remove)
+                               host->bus_ops->remove(host);
+                       mmc_claim_host(host);
+                       mmc_detach_bus(host);
+                       mmc_power_off(host);
+                       mmc_release_host(host);
+                       host->pm_flags = 0;
+                       err = 0;
                }
        }
        mmc_bus_put(host);
index 02914d609a91ab3d28577aed913702e119a695f6..54df5adc04137741ee7710d6ef5ee119add388d7 100644 (file)
@@ -695,6 +695,11 @@ static int mmc_select_powerclass(struct mmc_card *card,
                else if (host->ios.clock <= 200000000)
                        index = EXT_CSD_PWR_CL_200_195;
                break;
+       case MMC_VDD_27_28:
+       case MMC_VDD_28_29:
+       case MMC_VDD_29_30:
+       case MMC_VDD_30_31:
+       case MMC_VDD_31_32:
        case MMC_VDD_32_33:
        case MMC_VDD_33_34:
        case MMC_VDD_34_35:
@@ -1111,11 +1116,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
                                EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
                err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
-               if (err) {
-                       pr_err("%s: power class selection to bus width %d failed\n",
-                               mmc_hostname(card->host), 1 << bus_width);
-                       goto err;
-               }
+               if (err)
+                       pr_warning("%s: power class selection to bus width %d"
+                                  " failed\n", mmc_hostname(card->host),
+                                  1 << bus_width);
        }
 
        /*
@@ -1147,10 +1151,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                        err = mmc_select_powerclass(card, ext_csd_bits[idx][0],
                                                    ext_csd);
                        if (err)
-                               pr_err("%s: power class selection to "
-                                      "bus width %d failed\n",
-                                      mmc_hostname(card->host),
-                                      1 << bus_width);
+                               pr_warning("%s: power class selection to "
+                                          "bus width %d failed\n",
+                                          mmc_hostname(card->host),
+                                          1 << bus_width);
 
                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                         EXT_CSD_BUS_WIDTH,
@@ -1178,10 +1182,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                        err = mmc_select_powerclass(card, ext_csd_bits[idx][1],
                                                    ext_csd);
                        if (err)
-                               pr_err("%s: power class selection to "
-                                      "bus width %d ddr %d failed\n",
-                                      mmc_hostname(card->host),
-                                      1 << bus_width, ddr);
+                               pr_warning("%s: power class selection to "
+                                          "bus width %d ddr %d failed\n",
+                                          mmc_hostname(card->host),
+                                          1 << bus_width, ddr);
 
                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                         EXT_CSD_BUS_WIDTH,
index 40989e6bb53a588a8afa1e4281c1cd320999f117..236842ec955aa59f4af1ddc5fed8ab44a043dc89 100644 (file)
@@ -192,9 +192,15 @@ static int sdio_bus_remove(struct device *dev)
        return ret;
 }
 
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
+
+static int pm_no_operation(struct device *dev)
+{
+       return 0;
+}
 
 static const struct dev_pm_ops sdio_bus_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
        SET_RUNTIME_PM_OPS(
                pm_generic_runtime_suspend,
                pm_generic_runtime_resume,
@@ -204,11 +210,11 @@ static const struct dev_pm_ops sdio_bus_pm_ops = {
 
 #define SDIO_PM_OPS_PTR        (&sdio_bus_pm_ops)
 
-#else /* !CONFIG_PM_RUNTIME */
+#else /* !CONFIG_PM */
 
 #define SDIO_PM_OPS_PTR        NULL
 
-#endif /* !CONFIG_PM_RUNTIME */
+#endif /* !CONFIG_PM */
 
 static struct bus_type sdio_bus_type = {
        .name           = "sdio",
index 000b3ad0f5ca5d7e1bb1c5a0d81b2130c2279d73..787aba1682bb362efa7f06baf16370f4551f2074 100644 (file)
@@ -31,6 +31,7 @@
 # define ATMCI_MR_PDCFBYTE             (  1 << 13)     /* Force Byte Transfer */
 # define ATMCI_MR_PDCPADV              (  1 << 14)     /* Padding Value */
 # define ATMCI_MR_PDCMODE              (  1 << 15)     /* PDC-oriented Mode */
+# define ATMCI_MR_CLKODD(x)            ((x) << 16)     /* LSB of Clock Divider */
 #define ATMCI_DTOR                     0x0008  /* Data Timeout */
 # define ATMCI_DTOCYC(x)               ((x) <<  0)     /* Data Timeout Cycles */
 # define ATMCI_DTOMUL(x)               ((x) <<  4)     /* Data Timeout Multiplier */
index 9819dc09ce08d24f7bd2924fd35d786cc013b0ac..e94476beca181287b39c3af3a0b542a519bef353 100644 (file)
@@ -77,6 +77,7 @@ struct atmel_mci_caps {
        bool    has_cstor_reg;
        bool    has_highspeed;
        bool    has_rwproof;
+       bool    has_odd_clk_div;
 };
 
 struct atmel_mci_dma {
@@ -482,7 +483,14 @@ err:
 static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
                                        unsigned int ns)
 {
-       return (ns * (host->bus_hz / 1000000) + 999) / 1000;
+       /*
+        * It is easier here to use us instead of ns for the timeout,
+        * it prevents from overflows during calculation.
+        */
+       unsigned int us = DIV_ROUND_UP(ns, 1000);
+
+       /* Maximum clock frequency is host->bus_hz/2 */
+       return us * (DIV_ROUND_UP(host->bus_hz, 2000000));
 }
 
 static void atmci_set_timeout(struct atmel_mci *host,
@@ -1127,16 +1135,27 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                }
 
                /* Calculate clock divider */
-               clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
-               if (clkdiv > 255) {
-                       dev_warn(&mmc->class_dev,
-                               "clock %u too slow; using %lu\n",
-                               clock_min, host->bus_hz / (2 * 256));
-                       clkdiv = 255;
+               if (host->caps.has_odd_clk_div) {
+                       clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2;
+                       if (clkdiv > 511) {
+                               dev_warn(&mmc->class_dev,
+                                        "clock %u too slow; using %lu\n",
+                                        clock_min, host->bus_hz / (511 + 2));
+                               clkdiv = 511;
+                       }
+                       host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1)
+                                        | ATMCI_MR_CLKODD(clkdiv & 1);
+               } else {
+                       clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
+                       if (clkdiv > 255) {
+                               dev_warn(&mmc->class_dev,
+                                        "clock %u too slow; using %lu\n",
+                                        clock_min, host->bus_hz / (2 * 256));
+                               clkdiv = 255;
+                       }
+                       host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
                }
 
-               host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
-
                /*
                 * WRPROOF and RDPROOF prevent overruns/underruns by
                 * stopping the clock when the FIFO is full/empty.
@@ -2007,35 +2026,35 @@ static void __init atmci_get_cap(struct atmel_mci *host)
                        "version: 0x%x\n", version);
 
        host->caps.has_dma = 0;
-       host->caps.has_pdc = 0;
+       host->caps.has_pdc = 1;
        host->caps.has_cfg_reg = 0;
        host->caps.has_cstor_reg = 0;
        host->caps.has_highspeed = 0;
        host->caps.has_rwproof = 0;
+       host->caps.has_odd_clk_div = 0;
 
        /* keep only major version number */
        switch (version & 0xf00) {
-       case 0x100:
-       case 0x200:
-               host->caps.has_pdc = 1;
-               host->caps.has_rwproof = 1;
-               break;
-       case 0x300:
-       case 0x400:
        case 0x500:
+               host->caps.has_odd_clk_div = 1;
+       case 0x400:
+       case 0x300:
 #ifdef CONFIG_AT_HDMAC
                host->caps.has_dma = 1;
 #else
-               host->caps.has_dma = 0;
                dev_info(&host->pdev->dev,
                        "has dma capability but dma engine is not selected, then use pio\n");
 #endif
+               host->caps.has_pdc = 0;
                host->caps.has_cfg_reg = 1;
                host->caps.has_cstor_reg = 1;
                host->caps.has_highspeed = 1;
+       case 0x200:
                host->caps.has_rwproof = 1;
+       case 0x100:
                break;
        default:
+               host->caps.has_pdc = 0;
                dev_warn(&host->pdev->dev,
                                "Unmanaged mci version, set minimum capabilities\n");
                break;
index bf3c9b456aaf1080d6db5163eacefb3e7805787a..ab3fc46171079d4c8d07da35d5d00792032854d0 100644 (file)
@@ -526,8 +526,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
                return -ENODEV;
 
        sg_len = dw_mci_pre_dma_transfer(host, data, 0);
-       if (sg_len < 0)
+       if (sg_len < 0) {
+               host->dma_ops->stop(host);
                return sg_len;
+       }
 
        host->using_dma = 1;
 
@@ -1879,7 +1881,8 @@ static void dw_mci_init_dma(struct dw_mci *host)
        if (!host->dma_ops)
                goto no_dma;
 
-       if (host->dma_ops->init) {
+       if (host->dma_ops->init && host->dma_ops->start &&
+           host->dma_ops->stop && host->dma_ops->cleanup) {
                if (host->dma_ops->init(host)) {
                        dev_err(&host->dev, "%s: Unable to initialize "
                                "DMA Controller.\n", __func__);
index 47adb161d3adfd98e4c14279d04f4015d7283d2a..56d4499d43889e42a971fcfffb9bd0c334645294 100644 (file)
@@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on,
         * the pbias cell programming support is still missing when
         * booting with Device tree
         */
-       if (of_have_populated_dt() && !vdd)
+       if (dev->of_node && !vdd)
                return 0;
 
        if (mmc_slot(host).before_set_reg)
@@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                         * can't be allowed when booting with device
                         * tree.
                         */
-                       (!of_have_populated_dt())) {
+                       !host->dev->of_node) {
                                /*
                                 * The mmc_select_voltage fn of the core does
                                 * not seem to set the power_mode to
@@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = {
                .data = &omap4_reg_offset,
        },
        {},
-}
+};
 MODULE_DEVICE_TABLE(of, omap_mmc_of_match);
 
 static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
@@ -1785,7 +1785,7 @@ static inline struct omap_mmc_platform_data
 }
 #endif
 
-static int __init omap_hsmmc_probe(struct platform_device *pdev)
+static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
 {
        struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
        struct mmc_host *mmc;
@@ -1818,8 +1818,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
        if (res == NULL || irq < 0)
                return -ENXIO;
 
-       res->start += pdata->reg_offset;
-       res->end += pdata->reg_offset;
        res = request_mem_region(res->start, resource_size(res), pdev->name);
        if (res == NULL)
                return -EBUSY;
@@ -1843,7 +1841,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
        host->dma_ch    = -1;
        host->irq       = irq;
        host->slot_id   = 0;
-       host->mapbase   = res->start;
+       host->mapbase   = res->start + pdata->reg_offset;
        host->base      = ioremap(host->mapbase, SZ_4K);
        host->power_mode = MMC_POWER_OFF;
        host->next_data.cookie = 1;
@@ -1875,8 +1873,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
                goto err1;
        }
 
-       omap_hsmmc_context_save(host);
-
        if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) {
                dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n");
                mmc->caps2 |= MMC_CAP2_NO_MULTI_READ;
@@ -1887,6 +1883,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
        pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY);
        pm_runtime_use_autosuspend(host->dev);
 
+       omap_hsmmc_context_save(host);
+
        if (cpu_is_omap2430()) {
                host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
                /*
@@ -2018,8 +2016,7 @@ err_reg:
 err_irq_cd_init:
        free_irq(host->irq, host);
 err_irq:
-       pm_runtime_mark_last_busy(host->dev);
-       pm_runtime_put_autosuspend(host->dev);
+       pm_runtime_put_sync(host->dev);
        pm_runtime_disable(host->dev);
        clk_put(host->fclk);
        if (host->got_dbclk) {
@@ -2037,35 +2034,33 @@ err:
        return ret;
 }
 
-static int omap_hsmmc_remove(struct platform_device *pdev)
+static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
 {
        struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
        struct resource *res;
 
-       if (host) {
-               pm_runtime_get_sync(host->dev);
-               mmc_remove_host(host->mmc);
-               if (host->use_reg)
-                       omap_hsmmc_reg_put(host);
-               if (host->pdata->cleanup)
-                       host->pdata->cleanup(&pdev->dev);
-               free_irq(host->irq, host);
-               if (mmc_slot(host).card_detect_irq)
-                       free_irq(mmc_slot(host).card_detect_irq, host);
-
-               pm_runtime_put_sync(host->dev);
-               pm_runtime_disable(host->dev);
-               clk_put(host->fclk);
-               if (host->got_dbclk) {
-                       clk_disable(host->dbclk);
-                       clk_put(host->dbclk);
-               }
+       pm_runtime_get_sync(host->dev);
+       mmc_remove_host(host->mmc);
+       if (host->use_reg)
+               omap_hsmmc_reg_put(host);
+       if (host->pdata->cleanup)
+               host->pdata->cleanup(&pdev->dev);
+       free_irq(host->irq, host);
+       if (mmc_slot(host).card_detect_irq)
+               free_irq(mmc_slot(host).card_detect_irq, host);
 
-               mmc_free_host(host->mmc);
-               iounmap(host->base);
-               omap_hsmmc_gpio_free(pdev->dev.platform_data);
+       pm_runtime_put_sync(host->dev);
+       pm_runtime_disable(host->dev);
+       clk_put(host->fclk);
+       if (host->got_dbclk) {
+               clk_disable(host->dbclk);
+               clk_put(host->dbclk);
        }
 
+       mmc_free_host(host->mmc);
+       iounmap(host->base);
+       omap_hsmmc_gpio_free(pdev->dev.platform_data);
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res)
                release_mem_region(res->start, resource_size(res));
@@ -2078,49 +2073,45 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
 static int omap_hsmmc_suspend(struct device *dev)
 {
        int ret = 0;
-       struct platform_device *pdev = to_platform_device(dev);
-       struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
+       struct omap_hsmmc_host *host = dev_get_drvdata(dev);
 
-       if (host && host->suspended)
+       if (!host)
                return 0;
 
-       if (host) {
-               pm_runtime_get_sync(host->dev);
-               host->suspended = 1;
-               if (host->pdata->suspend) {
-                       ret = host->pdata->suspend(&pdev->dev,
-                                                       host->slot_id);
-                       if (ret) {
-                               dev_dbg(mmc_dev(host->mmc),
-                                       "Unable to handle MMC board"
-                                       " level suspend\n");
-                               host->suspended = 0;
-                               return ret;
-                       }
-               }
-               ret = mmc_suspend_host(host->mmc);
+       if (host && host->suspended)
+               return 0;
 
+       pm_runtime_get_sync(host->dev);
+       host->suspended = 1;
+       if (host->pdata->suspend) {
+               ret = host->pdata->suspend(dev, host->slot_id);
                if (ret) {
+                       dev_dbg(dev, "Unable to handle MMC board"
+                                       " level suspend\n");
                        host->suspended = 0;
-                       if (host->pdata->resume) {
-                               ret = host->pdata->resume(&pdev->dev,
-                                                         host->slot_id);
-                               if (ret)
-                                       dev_dbg(mmc_dev(host->mmc),
-                                               "Unmask interrupt failed\n");
-                       }
-                       goto err;
+                       return ret;
                }
+       }
+       ret = mmc_suspend_host(host->mmc);
 
-               if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) {
-                       omap_hsmmc_disable_irq(host);
-                       OMAP_HSMMC_WRITE(host->base, HCTL,
-                               OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
+       if (ret) {
+               host->suspended = 0;
+               if (host->pdata->resume) {
+                       ret = host->pdata->resume(dev, host->slot_id);
+                       if (ret)
+                               dev_dbg(dev, "Unmask interrupt failed\n");
                }
-               if (host->got_dbclk)
-                       clk_disable(host->dbclk);
+               goto err;
+       }
 
+       if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) {
+               omap_hsmmc_disable_irq(host);
+               OMAP_HSMMC_WRITE(host->base, HCTL,
+                               OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
        }
+
+       if (host->got_dbclk)
+               clk_disable(host->dbclk);
 err:
        pm_runtime_put_sync(host->dev);
        return ret;
@@ -2130,38 +2121,37 @@ err:
 static int omap_hsmmc_resume(struct device *dev)
 {
        int ret = 0;
-       struct platform_device *pdev = to_platform_device(dev);
-       struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
+       struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+       if (!host)
+               return 0;
 
        if (host && !host->suspended)
                return 0;
 
-       if (host) {
-               pm_runtime_get_sync(host->dev);
+       pm_runtime_get_sync(host->dev);
 
-               if (host->got_dbclk)
-                       clk_enable(host->dbclk);
+       if (host->got_dbclk)
+               clk_enable(host->dbclk);
 
-               if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
-                       omap_hsmmc_conf_bus_power(host);
+       if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
+               omap_hsmmc_conf_bus_power(host);
 
-               if (host->pdata->resume) {
-                       ret = host->pdata->resume(&pdev->dev, host->slot_id);
-                       if (ret)
-                               dev_dbg(mmc_dev(host->mmc),
-                                       "Unmask interrupt failed\n");
-               }
+       if (host->pdata->resume) {
+               ret = host->pdata->resume(dev, host->slot_id);
+               if (ret)
+                       dev_dbg(dev, "Unmask interrupt failed\n");
+       }
 
-               omap_hsmmc_protect_card(host);
+       omap_hsmmc_protect_card(host);
 
-               /* Notify the core to resume the host */
-               ret = mmc_resume_host(host->mmc);
-               if (ret == 0)
-                       host->suspended = 0;
+       /* Notify the core to resume the host */
+       ret = mmc_resume_host(host->mmc);
+       if (ret == 0)
+               host->suspended = 0;
 
-               pm_runtime_mark_last_busy(host->dev);
-               pm_runtime_put_autosuspend(host->dev);
-       }
+       pm_runtime_mark_last_busy(host->dev);
+       pm_runtime_put_autosuspend(host->dev);
 
        return ret;
 
@@ -2178,7 +2168,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)
 
        host = platform_get_drvdata(to_platform_device(dev));
        omap_hsmmc_context_save(host);
-       dev_dbg(mmc_dev(host->mmc), "disabled\n");
+       dev_dbg(dev, "disabled\n");
 
        return 0;
 }
@@ -2189,7 +2179,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
 
        host = platform_get_drvdata(to_platform_device(dev));
        omap_hsmmc_context_restore(host);
-       dev_dbg(mmc_dev(host->mmc), "enabled\n");
+       dev_dbg(dev, "enabled\n");
 
        return 0;
 }
@@ -2202,7 +2192,8 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
 };
 
 static struct platform_driver omap_hsmmc_driver = {
-       .remove         = omap_hsmmc_remove,
+       .probe          = omap_hsmmc_probe,
+       .remove         = __devexit_p(omap_hsmmc_remove),
        .driver         = {
                .name = DRIVER_NAME,
                .owner = THIS_MODULE,
@@ -2211,21 +2202,7 @@ static struct platform_driver omap_hsmmc_driver = {
        },
 };
 
-static int __init omap_hsmmc_init(void)
-{
-       /* Register the MMC driver */
-       return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe);
-}
-
-static void __exit omap_hsmmc_cleanup(void)
-{
-       /* Unregister MMC driver */
-       platform_driver_unregister(&omap_hsmmc_driver);
-}
-
-module_init(omap_hsmmc_init);
-module_exit(omap_hsmmc_cleanup);
-
+module_platform_driver(omap_hsmmc_driver);
 MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRIVER_NAME);
index 46fd1fd1b605033b8f437a70da844f11f5e04226..177f697b5835529aa3a4079966229c751f7bc428 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/mmc/host.h>
 
 #include "sdhci-pltfm.h"
index 6193a0d7bde52b8cc29e52837179d90eed50faeb..8abdaf6697a8db6e0bf0949e9c54900cb2ac0889 100644 (file)
@@ -467,8 +467,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
        clk_prepare_enable(clk);
        pltfm_host->clk = clk;
 
-       if (!is_imx25_esdhc(imx_data))
-               host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+       host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
        if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
                /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
index fbbebe251e016cf8b24906aa6a0b4ad31f64cd40..69ef0beae104f3a83d4a36277b129e20ba5db207 100644 (file)
@@ -1418,8 +1418,6 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
 
        slots = chip->num_slots;        /* Quirk may have changed this */
 
-       pci_enable_msi(pdev);
-
        for (i = 0; i < slots; i++) {
                slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i);
                if (IS_ERR(slot)) {
@@ -1438,8 +1436,6 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
        return 0;
 
 free:
-       pci_disable_msi(pdev);
-
        pci_set_drvdata(pdev, NULL);
        kfree(chip);
 
@@ -1462,8 +1458,6 @@ static void __devexit sdhci_pci_remove(struct pci_dev *pdev)
                for (i = 0; i < chip->num_slots; i++)
                        sdhci_pci_remove_slot(chip->slots[i]);
 
-               pci_disable_msi(pdev);
-
                pci_set_drvdata(pdev, NULL);
                kfree(chip);
        }
index b19e7d435f8d6d1561a60156dff038c7508e0e2e..55a164fcaa157ece64d9c2be581e5c7b46b71e9d 100644 (file)
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/mmc/host.h>
 
@@ -53,6 +57,18 @@ struct sdhci_s3c {
        struct clk              *clk_bus[MAX_BUS_CLK];
 };
 
+/**
+ * struct sdhci_s3c_driver_data - S3C SDHCI platform specific driver data
+ * @sdhci_quirks: sdhci host specific quirks.
+ *
+ * Specifies platform specific configuration of sdhci controller.
+ * Note: A structure for driver specific platform data is used for future
+ * expansion of its usage.
+ */
+struct sdhci_s3c_drv_data {
+       unsigned int    sdhci_quirks;
+};
+
 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
 {
        return sdhci_priv(host);
@@ -132,10 +148,10 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
                return UINT_MAX;
 
        /*
-        * Clock divider's step is different as 1 from that of host controller
-        * when 'clk_type' is S3C_SDHCI_CLK_DIV_EXTERNAL.
+        * If controller uses a non-standard clock division, find the best clock
+        * speed possible with selected clock source and skip the division.
         */
-       if (ourhost->pdata->clk_type) {
+       if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
                rate = clk_round_rate(clksrc, wanted);
                return wanted - rate;
        }
@@ -272,6 +288,8 @@ static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host)
 static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 {
        struct sdhci_s3c *ourhost = to_s3c(host);
+       unsigned long timeout;
+       u16 clk = 0;
 
        /* don't bother if the clock is going off */
        if (clock == 0)
@@ -282,6 +300,25 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
        clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
 
        host->clock = clock;
+
+       clk = SDHCI_CLOCK_INT_EN;
+       sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+       /* Wait max 20 ms */
+       timeout = 20;
+       while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+               & SDHCI_CLOCK_INT_STABLE)) {
+               if (timeout == 0) {
+                       printk(KERN_ERR "%s: Internal clock never "
+                               "stabilised.\n", mmc_hostname(host->mmc));
+                       return;
+               }
+               timeout--;
+               mdelay(1);
+       }
+
+       clk |= SDHCI_CLOCK_CARD_EN;
+       sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 }
 
 /**
@@ -382,16 +419,24 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
        }
 }
 
+static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
+                       struct platform_device *pdev)
+{
+       return (struct sdhci_s3c_drv_data *)
+                       platform_get_device_id(pdev)->driver_data;
+}
+
 static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 {
-       struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
+       struct s3c_sdhci_platdata *pdata;
+       struct sdhci_s3c_drv_data *drv_data;
        struct device *dev = &pdev->dev;
        struct sdhci_host *host;
        struct sdhci_s3c *sc;
        struct resource *res;
        int ret, irq, ptr, clks;
 
-       if (!pdata) {
+       if (!pdev->dev.platform_data) {
                dev_err(dev, "no device data specified\n");
                return -ENOENT;
        }
@@ -402,18 +447,20 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
                return irq;
        }
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "no memory specified\n");
-               return -ENOENT;
-       }
-
        host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
        if (IS_ERR(host)) {
                dev_err(dev, "sdhci_alloc_host() failed\n");
                return PTR_ERR(host);
        }
 
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata) {
+               ret = -ENOMEM;
+               goto err_io_clk;
+       }
+       memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+
+       drv_data = sdhci_s3c_get_driver_data(pdev);
        sc = sdhci_priv(host);
 
        sc->host = host;
@@ -464,15 +511,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
                goto err_no_busclks;
        }
 
-       sc->ioarea = request_mem_region(res->start, resource_size(res),
-                                       mmc_hostname(host->mmc));
-       if (!sc->ioarea) {
-               dev_err(dev, "failed to reserve register area\n");
-               ret = -ENXIO;
-               goto err_req_regs;
-       }
-
-       host->ioaddr = ioremap_nocache(res->start, resource_size(res));
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       host->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
        if (!host->ioaddr) {
                dev_err(dev, "failed to map registers\n");
                ret = -ENXIO;
@@ -491,6 +531,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
        /* Setup quirks for the controller */
        host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
        host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
+       if (drv_data)
+               host->quirks |= drv_data->sdhci_quirks;
 
 #ifndef CONFIG_MMC_SDHCI_S3C_DMA
 
@@ -518,6 +560,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
        if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
                host->mmc->caps = MMC_CAP_NONREMOVABLE;
 
+       switch (pdata->max_width) {
+       case 8:
+               host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+       case 4:
+               host->mmc->caps |= MMC_CAP_4_BIT_DATA;
+               break;
+       }
+
        if (pdata->pm_caps)
                host->mmc->pm_caps |= pdata->pm_caps;
 
@@ -531,7 +581,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
         * If controller does not have internal clock divider,
         * we can use overriding functions instead of default.
         */
-       if (pdata->clk_type) {
+       if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
                sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
                sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
                sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
@@ -544,10 +594,17 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
        if (pdata->host_caps2)
                host->mmc->caps2 |= pdata->host_caps2;
 
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+       pm_runtime_use_autosuspend(&pdev->dev);
+       pm_suspend_ignore_children(&pdev->dev, 1);
+
        ret = sdhci_add_host(host);
        if (ret) {
                dev_err(dev, "sdhci_add_host() failed\n");
-               goto err_add_host;
+               pm_runtime_forbid(&pdev->dev);
+               pm_runtime_get_noresume(&pdev->dev);
+               goto err_req_regs;
        }
 
        /* The following two methods of card detection might call
@@ -561,10 +618,6 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 
        return 0;
 
- err_add_host:
-       release_resource(sc->ioarea);
-       kfree(sc->ioarea);
-
  err_req_regs:
        for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
                if (sc->clk_bus[ptr]) {
@@ -601,6 +654,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
 
        sdhci_remove_host(host, 1);
 
+       pm_runtime_disable(&pdev->dev);
+
        for (ptr = 0; ptr < 3; ptr++) {
                if (sc->clk_bus[ptr]) {
                        clk_disable(sc->clk_bus[ptr]);
@@ -610,18 +665,13 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
        clk_disable(sc->clk_io);
        clk_put(sc->clk_io);
 
-       iounmap(host->ioaddr);
-       release_resource(sc->ioarea);
-       kfree(sc->ioarea);
-
        sdhci_free_host(host);
        platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
 
-#ifdef CONFIG_PM
-
+#ifdef CONFIG_PM_SLEEP
 static int sdhci_s3c_suspend(struct device *dev)
 {
        struct sdhci_host *host = dev_get_drvdata(dev);
@@ -635,10 +685,29 @@ static int sdhci_s3c_resume(struct device *dev)
 
        return sdhci_resume_host(host);
 }
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+static int sdhci_s3c_runtime_suspend(struct device *dev)
+{
+       struct sdhci_host *host = dev_get_drvdata(dev);
+
+       return sdhci_runtime_suspend_host(host);
+}
 
+static int sdhci_s3c_runtime_resume(struct device *dev)
+{
+       struct sdhci_host *host = dev_get_drvdata(dev);
+
+       return sdhci_runtime_resume_host(host);
+}
+#endif
+
+#ifdef CONFIG_PM
 static const struct dev_pm_ops sdhci_s3c_pmops = {
-       .suspend        = sdhci_s3c_suspend,
-       .resume         = sdhci_s3c_resume,
+       SET_SYSTEM_SLEEP_PM_OPS(sdhci_s3c_suspend, sdhci_s3c_resume)
+       SET_RUNTIME_PM_OPS(sdhci_s3c_runtime_suspend, sdhci_s3c_runtime_resume,
+                          NULL)
 };
 
 #define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops)
@@ -647,9 +716,31 @@ static const struct dev_pm_ops sdhci_s3c_pmops = {
 #define SDHCI_S3C_PMOPS NULL
 #endif
 
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
+static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
+       .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
+};
+#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
+#else
+#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)NULL)
+#endif
+
+static struct platform_device_id sdhci_s3c_driver_ids[] = {
+       {
+               .name           = "s3c-sdhci",
+               .driver_data    = (kernel_ulong_t)NULL,
+       }, {
+               .name           = "exynos4-sdhci",
+               .driver_data    = EXYNOS4_SDHCI_DRV_DATA,
+       },
+       { }
+};
+MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids);
+
 static struct platform_driver sdhci_s3c_driver = {
        .probe          = sdhci_s3c_probe,
        .remove         = __devexit_p(sdhci_s3c_remove),
+       .id_table       = sdhci_s3c_driver_ids,
        .driver         = {
                .owner  = THIS_MODULE,
                .name   = "s3c-sdhci",
index 8262cadfdab77b82e5590da88ff0042479d3a697..ccefdebeff1458a6041f269c7494fc26cac0d8a3 100644 (file)
@@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
        u32 present, irqs;
 
        if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
-           !mmc_card_is_removable(host->mmc))
+           (host->mmc->caps & MMC_CAP_NONREMOVABLE))
                return;
 
        present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
@@ -2782,8 +2782,9 @@ int sdhci_add_host(struct sdhci_host *host)
            mmc_card_is_removable(mmc))
                mmc->caps |= MMC_CAP_NEEDS_POLL;
 
-       /* UHS-I mode(s) supported by the host controller. */
-       if (host->version >= SDHCI_SPEC_300)
+       /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
+       if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+                      SDHCI_SUPPORT_DDR50))
                mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
 
        /* SDR104 supports also implies SDR50 support */
index aafaf0b6eb1c96bcf298307b180dca75a259b424..724b35e85a265f70faa11fe8f603931a687f04af 100644 (file)
@@ -454,7 +454,8 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
                sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
        else
                sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
-                               ((fls(host->clk / clk) - 1) << 16));
+                               ((fls(DIV_ROUND_UP(host->clk,
+                                                  clk) - 1) - 1) << 16));
 
        sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
 }
@@ -1297,14 +1298,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
        spin_lock_init(&host->lock);
 
        mmc->ops = &sh_mmcif_ops;
-       mmc->f_max = host->clk;
-       /* close to 400KHz */
-       if (mmc->f_max < 51200000)
-               mmc->f_min = mmc->f_max / 128;
-       else if (mmc->f_max < 102400000)
-               mmc->f_min = mmc->f_max / 256;
-       else
-               mmc->f_min = mmc->f_max / 512;
+       mmc->f_max = host->clk / 2;
+       mmc->f_min = host->clk / 512;
        if (pd->ocr)
                mmc->ocr_avail = pd->ocr;
        mmc->caps = MMC_CAP_MMC_HIGHSPEED;
index 94eb05b1afdfd2bcab367a6e6fa6dbab0667dca9..58fc65f5c8176d130bef3795ccb5163328489be6 100644 (file)
@@ -106,16 +106,14 @@ static int mtdchar_open(struct inode *inode, struct file *file)
        }
 
        if (mtd->type == MTD_ABSENT) {
-               put_mtd_device(mtd);
                ret = -ENODEV;
-               goto out;
+               goto out1;
        }
 
        mtd_ino = iget_locked(mnt->mnt_sb, devnum);
        if (!mtd_ino) {
-               put_mtd_device(mtd);
                ret = -ENOMEM;
-               goto out;
+               goto out1;
        }
        if (mtd_ino->i_state & I_NEW) {
                mtd_ino->i_private = mtd;
@@ -127,23 +125,25 @@ static int mtdchar_open(struct inode *inode, struct file *file)
 
        /* You can't open it RW if it's not a writeable device */
        if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
-               iput(mtd_ino);
-               put_mtd_device(mtd);
                ret = -EACCES;
-               goto out;
+               goto out2;
        }
 
        mfi = kzalloc(sizeof(*mfi), GFP_KERNEL);
        if (!mfi) {
-               iput(mtd_ino);
-               put_mtd_device(mtd);
                ret = -ENOMEM;
-               goto out;
+               goto out2;
        }
        mfi->ino = mtd_ino;
        mfi->mtd = mtd;
        file->private_data = mfi;
+       mutex_unlock(&mtd_mutex);
+       return 0;
 
+out2:
+       iput(mtd_ino);
+out1:
+       put_mtd_device(mtd);
 out:
        mutex_unlock(&mtd_mutex);
        simple_release_fs(&mnt, &count);
index 25197b698dd64efad9243bc6579f4808d6a93802..b8b4c7ba884f0c2ed9499e1ede4a20ad1df4f732 100644 (file)
@@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev)
        BUGLVL(D_NORMAL) printk(VERSION);
        BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
 
-       BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n",
+       BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n",
               dev->dev_addr[0], dev->mem_start, dev->irq);
 
        if (dev->mem_start <= 0 || dev->irq <= 0) {
-               BUGMSG(D_NORMAL, "No autoprobe for RIM I; you "
+               BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you "
                       "must specify the shmem and irq!\n");
                return -ENODEV;
        }
        if (dev->dev_addr[0] == 0) {
-               BUGMSG(D_NORMAL, "You need to specify your card's station "
+               BUGLVL(D_NORMAL) printk("You need to specify your card's station "
                       "ID!\n");
                return -ENODEV;
        }
@@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev)
         * will be taken.
         */
        if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) {
-               BUGMSG(D_NORMAL, "Card memory already allocated\n");
+               BUGLVL(D_NORMAL) printk("Card memory already allocated\n");
                return -ENODEV;
        }
        return arcrimi_found(dev);
index 9a66e2a910ae21f586ff59439b8116fe891d4c95..9c1c8cd5223f4144f90d6eb034d7a2bfcf0ff429 100644 (file)
@@ -744,14 +744,14 @@ static void cfhsi_wake_up(struct work_struct *work)
                size_t fifo_occupancy = 0;
 
                /* Wakeup timeout */
-               dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n",
+               dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n",
                        __func__);
 
                /* Check FIFO to check if modem has sent something. */
                WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,
                                        &fifo_occupancy));
 
-               dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",
+               dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",
                                __func__, (unsigned) fifo_occupancy);
 
                /* Check if we misssed the interrupt. */
@@ -1210,7 +1210,7 @@ int cfhsi_probe(struct platform_device *pdev)
 
 static void cfhsi_shutdown(struct cfhsi *cfhsi)
 {
-       u8 *tx_buf, *rx_buf;
+       u8 *tx_buf, *rx_buf, *flip_buf;
 
        /* Stop TXing */
        netif_tx_stop_all_queues(cfhsi->ndev);
@@ -1234,7 +1234,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)
        /* Store bufferes: will be freed later. */
        tx_buf = cfhsi->tx_buf;
        rx_buf = cfhsi->rx_buf;
-
+       flip_buf = cfhsi->rx_flip_buf;
        /* Flush transmit queues. */
        cfhsi_abort_tx(cfhsi);
 
@@ -1247,6 +1247,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)
        /* Free buffers. */
        kfree(tx_buf);
        kfree(rx_buf);
+       kfree(flip_buf);
 }
 
 int cfhsi_remove(struct platform_device *pdev)
index 5234586dff15d32a4ac63dc42246a414ada41760..629c4ba5d49d95792717f75b3a8919543a60b5d0 100644 (file)
@@ -875,6 +875,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
                                            PCAN_USBPRO_INFO_FW,
                                            &fi, sizeof(fi));
                if (err) {
+                       kfree(usb_if);
                        dev_err(dev->netdev->dev.parent,
                                "unable to read %s firmware info (err %d)\n",
                                pcan_usb_pro.name, err);
@@ -885,6 +886,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
                                            PCAN_USBPRO_INFO_BL,
                                            &bi, sizeof(bi));
                if (err) {
+                       kfree(usb_if);
                        dev_err(dev->netdev->dev.parent,
                                "unable to read %s bootloader info (err %d)\n",
                                pcan_usb_pro.name, err);
index d5c6d92f1ee77b1df16d59faf4c18e6d5889c07c..442d91a2747b9d8136dd5809ec3d192fc8c1e04c 100644 (file)
@@ -107,14 +107,14 @@ static int dummy_dev_init(struct net_device *dev)
        return 0;
 }
 
-static void dummy_dev_free(struct net_device *dev)
+static void dummy_dev_uninit(struct net_device *dev)
 {
        free_percpu(dev->dstats);
-       free_netdev(dev);
 }
 
 static const struct net_device_ops dummy_netdev_ops = {
        .ndo_init               = dummy_dev_init,
+       .ndo_uninit             = dummy_dev_uninit,
        .ndo_start_xmit         = dummy_xmit,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_rx_mode        = set_multicast_list,
@@ -128,7 +128,7 @@ static void dummy_setup(struct net_device *dev)
 
        /* Initialize the device structure. */
        dev->netdev_ops = &dummy_netdev_ops;
-       dev->destructor = dummy_dev_free;
+       dev->destructor = free_netdev;
 
        /* Fill in device structure with ethernet-generic values. */
        dev->tx_queue_len = 0;
index 40ac414365490b59ac1eacab9fbd11123af39f23..c926857e8205fd79226cc7c0f0a897d7cb65ab88 100644 (file)
@@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
                                        "pcie phy link down %x\n", status);
                        if (netif_running(adapter->netdev)) {   /* reset MAC */
                                iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-                               schedule_work(&adapter->pcie_dma_to_rst_task);
+                               schedule_work(&adapter->reset_dev_task);
                                return IRQ_HANDLED;
                        }
                }
@@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
                                        "pcie DMA r/w error (status = 0x%x)\n",
                                        status);
                        iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-                       schedule_work(&adapter->pcie_dma_to_rst_task);
+                       schedule_work(&adapter->reset_dev_task);
                        return IRQ_HANDLED;
                }
 
@@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter)
        atl1_clean_rx_ring(adapter);
 }
 
-static void atl1_tx_timeout_task(struct work_struct *work)
+static void atl1_reset_dev_task(struct work_struct *work)
 {
        struct atl1_adapter *adapter =
-               container_of(work, struct atl1_adapter, tx_timeout_task);
+               container_of(work, struct atl1_adapter, reset_dev_task);
        struct net_device *netdev = adapter->netdev;
 
        netif_device_detach(netdev);
@@ -3038,12 +3038,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
                    (unsigned long)adapter);
        adapter->phy_timer_pending = false;
 
-       INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
+       INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);
 
        INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
 
-       INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
-
        err = register_netdev(netdev);
        if (err)
                goto err_common;
index 109d6da8be97c14927c2e7fa79fc1b1073f84bb6..e04bf4d71e4657618655ac94f89da96c5cef96fa 100644 (file)
@@ -758,9 +758,8 @@ struct atl1_adapter {
        u16 link_speed;
        u16 link_duplex;
        spinlock_t lock;
-       struct work_struct tx_timeout_task;
+       struct work_struct reset_dev_task;
        struct work_struct link_chg_task;
-       struct work_struct pcie_dma_to_rst_task;
 
        struct timer_list phy_config_timer;
        bool phy_timer_pending;
index 3cd8837236dc1de68727991cc399b6906e30d5c3..c9e9dc57986c0743b3f7800273303f536fa47fc6 100644 (file)
@@ -194,7 +194,7 @@ static void atlx_tx_timeout(struct net_device *netdev)
 {
        struct atlx_adapter *adapter = netdev_priv(netdev);
        /* Do the reset outside of interrupt context */
-       schedule_work(&adapter->tx_timeout_task);
+       schedule_work(&adapter->reset_dev_task);
 }
 
 /*
index ad95324dc0420681c21e12ead836eafdceb35a59..64392ec410a3898b3b4372523db4a19d3614b390 100644 (file)
@@ -942,6 +942,12 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
        const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
                DCBX_E3B0_MAX_NUM_COS_PORT0;
 
+       if (pri >= max_num_of_cos) {
+               DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
+                  "parameter Illegal strict priority\n");
+           return -EINVAL;
+       }
+
        if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
                DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
                                   "parameter There can't be two COS's with "
@@ -949,12 +955,6 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
                return -EINVAL;
        }
 
-       if (pri > max_num_of_cos) {
-               DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
-                  "parameter Illegal strict priority\n");
-           return -EINVAL;
-       }
-
        sp_pri_to_cos[pri] = cos_entry;
        return 0;
 
index 062ac333fde60be0732572f39e0a7a46335da499..ceeab8e852ef6a2cf86b682bb17bd0f17ab5ade8 100644 (file)
@@ -879,8 +879,13 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
                if (sblk->status & SD_STATUS_LINK_CHG)
                        work_exists = 1;
        }
-       /* check for RX/TX work to do */
-       if (sblk->idx[0].tx_consumer != tnapi->tx_cons ||
+
+       /* check for TX work to do */
+       if (sblk->idx[0].tx_consumer != tnapi->tx_cons)
+               work_exists = 1;
+
+       /* check for RX work to do */
+       if (tnapi->rx_rcb_prod_idx &&
            *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
                work_exists = 1;
 
@@ -6124,6 +6129,9 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
                        return work_done;
        }
 
+       if (!tnapi->rx_rcb_prod_idx)
+               return work_done;
+
        /* run RX thread, within the bounds set by NAPI.
         * All RX "locking" is done by ensuring outside
         * code synchronizes with tg3->napi.poll()
@@ -7567,6 +7575,12 @@ static int tg3_alloc_consistent(struct tg3 *tp)
                 */
                switch (i) {
                default:
+                       if (tg3_flag(tp, ENABLE_RSS)) {
+                               tnapi->rx_rcb_prod_idx = NULL;
+                               break;
+                       }
+                       /* Fall through */
+               case 1:
                        tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;
                        break;
                case 2:
index 63bfdd10bd6d857b33cb52f4702919f1843fd094..abb6ce7c1b7ed2a67ee6b064377698df2efcb9c6 100644 (file)
@@ -1149,6 +1149,48 @@ release_tpsram:
        return ret;
 }
 
+/**
+ * t3_synchronize_rx - wait for current Rx processing on a port to complete
+ * @adap: the adapter
+ * @p: the port
+ *
+ * Ensures that current Rx processing on any of the queues associated with
+ * the given port completes before returning.  We do this by acquiring and
+ * releasing the locks of the response queues associated with the port.
+ */
+static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
+{
+       int i;
+
+       for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
+               struct sge_rspq *q = &adap->sge.qs[i].rspq;
+
+               spin_lock_irq(&q->lock);
+               spin_unlock_irq(&q->lock);
+       }
+}
+
+static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features)
+{
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+
+       if (adapter->params.rev > 0) {
+               t3_set_vlan_accel(adapter, 1 << pi->port_id,
+                                 features & NETIF_F_HW_VLAN_RX);
+       } else {
+               /* single control for all ports */
+               unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX;
+
+               for_each_port(adapter, i)
+                       have_vlans |=
+                               adapter->port[i]->features & NETIF_F_HW_VLAN_RX;
+
+               t3_set_vlan_accel(adapter, 1, have_vlans);
+       }
+       t3_synchronize_rx(adapter, pi);
+}
+
 /**
  *     cxgb_up - enable the adapter
  *     @adapter: adapter being enabled
@@ -1161,7 +1203,7 @@ release_tpsram:
  */
 static int cxgb_up(struct adapter *adap)
 {
-       int err;
+       int i, err;
 
        if (!(adap->flags & FULL_INIT_DONE)) {
                err = t3_check_fw_version(adap);
@@ -1198,6 +1240,9 @@ static int cxgb_up(struct adapter *adap)
                if (err)
                        goto out;
 
+               for_each_port(adap, i)
+                       cxgb_vlan_mode(adap->port[i], adap->port[i]->features);
+
                setup_rss(adap);
                if (!(adap->flags & NAPI_INIT))
                        init_napi(adap);
@@ -2508,48 +2553,6 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p)
        return 0;
 }
 
-/**
- * t3_synchronize_rx - wait for current Rx processing on a port to complete
- * @adap: the adapter
- * @p: the port
- *
- * Ensures that current Rx processing on any of the queues associated with
- * the given port completes before returning.  We do this by acquiring and
- * releasing the locks of the response queues associated with the port.
- */
-static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
-{
-       int i;
-
-       for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
-               struct sge_rspq *q = &adap->sge.qs[i].rspq;
-
-               spin_lock_irq(&q->lock);
-               spin_unlock_irq(&q->lock);
-       }
-}
-
-static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features)
-{
-       struct port_info *pi = netdev_priv(dev);
-       struct adapter *adapter = pi->adapter;
-
-       if (adapter->params.rev > 0) {
-               t3_set_vlan_accel(adapter, 1 << pi->port_id,
-                                 features & NETIF_F_HW_VLAN_RX);
-       } else {
-               /* single control for all ports */
-               unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX;
-
-               for_each_port(adapter, i)
-                       have_vlans |=
-                               adapter->port[i]->features & NETIF_F_HW_VLAN_RX;
-
-               t3_set_vlan_accel(adapter, 1, have_vlans);
-       }
-       t3_synchronize_rx(adapter, pi);
-}
-
 static netdev_features_t cxgb_fix_features(struct net_device *dev,
        netdev_features_t features)
 {
@@ -3353,9 +3356,6 @@ static int __devinit init_one(struct pci_dev *pdev,
        err = sysfs_create_group(&adapter->port[0]->dev.kobj,
                                 &cxgb3_attr_group);
 
-       for_each_port(adapter, i)
-               cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features);
-
        print_port_info(adapter, ai);
        return 0;
 
index b2dc2c81a147f66581d1302f1b8eb1ee92346288..2e09edb9cdf84b3d1cc49d7dad5167a2ce3be75a 100644 (file)
@@ -1259,55 +1259,21 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
        int phy_addr;
        struct netdev_private *np = netdev_priv(dev);
-       struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
-
-       struct netdev_desc *desc;
-       int i;
+       struct mii_ioctl_data *miidata = if_mii(rq);
 
        phy_addr = np->phy_addr;
        switch (cmd) {
-       case SIOCDEVPRIVATE:
-               break;
-
-       case SIOCDEVPRIVATE + 1:
-               miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);
+       case SIOCGMIIPHY:
+               miidata->phy_id = phy_addr;
                break;
-       case SIOCDEVPRIVATE + 2:
-               mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value);
+       case SIOCGMIIREG:
+               miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);
                break;
-       case SIOCDEVPRIVATE + 3:
-               break;
-       case SIOCDEVPRIVATE + 4:
-               break;
-       case SIOCDEVPRIVATE + 5:
-               netif_stop_queue (dev);
+       case SIOCSMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);
                break;
-       case SIOCDEVPRIVATE + 6:
-               netif_wake_queue (dev);
-               break;
-       case SIOCDEVPRIVATE + 7:
-               printk
-                   ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",
-                    netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,
-                    np->old_rx);
-               break;
-       case SIOCDEVPRIVATE + 8:
-               printk("TX ring:\n");
-               for (i = 0; i < TX_RING_SIZE; i++) {
-                       desc = &np->tx_ring[i];
-                       printk
-                           ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
-                            i,
-                            (u32) (np->tx_ring_dma + i * sizeof (*desc)),
-                            (u32)le64_to_cpu(desc->next_desc),
-                            (u32)le64_to_cpu(desc->status),
-                            (u32)(le64_to_cpu(desc->fraginfo) >> 32),
-                            (u32)le64_to_cpu(desc->fraginfo));
-                       printk ("\n");
-               }
-               printk ("\n");
-               break;
-
        default:
                return -EOPNOTSUPP;
        }
index ba0adcafa55ad71c2dd63098796ce003a4cb6701..30c2da3de548f92ce0ebe794dc9c894af284c010 100644 (file)
@@ -365,13 +365,6 @@ struct ioctl_data {
        char *data;
 };
 
-struct mii_data {
-       __u16 reserved;
-       __u16 reg_num;
-       __u16 in_value;
-       __u16 out_value;
-};
-
 /* The Rx and Tx buffer descriptors. */
 struct netdev_desc {
        __le64 next_desc;
index 17a46e76123f92a510b39d2ebaa29eeecf8e97ab..9ac14f8048512a66aef3a8fc2bba992d198393ef 100644 (file)
@@ -116,10 +116,10 @@ static struct ucc_geth_info ugeth_primary_info = {
        .maxGroupAddrInHash = 4,
        .maxIndAddrInHash = 4,
        .prel = 7,
-       .maxFrameLength = 1518,
+       .maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */
        .minFrameLength = 64,
-       .maxD1Length = 1520,
-       .maxD2Length = 1520,
+       .maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */
+       .maxD2Length = 1520+16, /* Add extra bytes for VLANs etc. */
        .vlantype = 0x8100,
        .ecamptr = ((uint32_t) NULL),
        .eventRegMask = UCCE_OTHER,
index 2e395a2566b8d6221747f79828cbdfb70f72947c..f71b3e7b12defe7c92489ca967fbfe72819ab382 100644 (file)
@@ -877,7 +877,7 @@ struct ucc_geth_hardware_statistics {
 
 /* Driver definitions */
 #define TX_BD_RING_LEN                          0x10
-#define RX_BD_RING_LEN                          0x10
+#define RX_BD_RING_LEN                          0x20
 
 #define TX_RING_MOD_MASK(size)                  (size-1)
 #define RX_RING_MOD_MASK(size)                  (size-1)
index 3516e17a399d3137ccf0e2eea06318c0171aeba4..c9069a28832b0bfa39e4b118c7399a744ac0c8a2 100644 (file)
@@ -290,16 +290,18 @@ static void ehea_update_bcmc_registrations(void)
 
                                arr[i].adh = adapter->handle;
                                arr[i].port_id = port->logical_port_id;
-                               arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
-                                                 EHEA_BCMC_MULTICAST |
+                               arr[i].reg_type = EHEA_BCMC_MULTICAST |
                                                  EHEA_BCMC_UNTAGGED;
+                               if (mc_entry->macaddr == 0)
+                                       arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;
                                arr[i++].macaddr = mc_entry->macaddr;
 
                                arr[i].adh = adapter->handle;
                                arr[i].port_id = port->logical_port_id;
-                               arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
-                                                 EHEA_BCMC_MULTICAST |
+                               arr[i].reg_type = EHEA_BCMC_MULTICAST |
                                                  EHEA_BCMC_VLANID_ALL;
+                               if (mc_entry->macaddr == 0)
+                                       arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;
                                arr[i++].macaddr = mc_entry->macaddr;
                                num_registrations -= 2;
                        }
@@ -1838,8 +1840,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
        u64 hret;
        u8 reg_type;
 
-       reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST
-                | EHEA_BCMC_UNTAGGED;
+       reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED;
+       if (mc_mac_addr == 0)
+               reg_type |= EHEA_BCMC_SCOPE_ALL;
 
        hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,
                                     port->logical_port_id,
@@ -1847,8 +1850,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
        if (hret)
                goto out;
 
-       reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST
-                | EHEA_BCMC_VLANID_ALL;
+       reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL;
+       if (mc_mac_addr == 0)
+               reg_type |= EHEA_BCMC_SCOPE_ALL;
 
        hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,
                                     port->logical_port_id,
@@ -1898,7 +1902,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)
                                netdev_err(dev,
                                           "failed enabling IFF_ALLMULTI\n");
                }
-       } else
+       } else {
                if (!enable) {
                        /* Disable ALLMULTI */
                        hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC);
@@ -1908,6 +1912,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)
                                netdev_err(dev,
                                           "failed disabling IFF_ALLMULTI\n");
                }
+       }
 }
 
 static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr)
@@ -1941,11 +1946,7 @@ static void ehea_set_multicast_list(struct net_device *dev)
        struct netdev_hw_addr *ha;
        int ret;
 
-       if (port->promisc) {
-               ehea_promiscuous(dev, 1);
-               return;
-       }
-       ehea_promiscuous(dev, 0);
+       ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC));
 
        if (dev->flags & IFF_ALLMULTI) {
                ehea_allmulti(dev, 1);
@@ -2463,6 +2464,7 @@ static int ehea_down(struct net_device *dev)
                return 0;
 
        ehea_drop_multicast_list(dev);
+       ehea_allmulti(dev, 0);
        ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 
        ehea_free_interrupts(dev);
@@ -3261,6 +3263,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
        struct ehea_adapter *adapter;
        const u64 *adapter_handle;
        int ret;
+       int i;
 
        if (!dev || !dev->dev.of_node) {
                pr_err("Invalid ibmebus device probed\n");
@@ -3314,17 +3317,9 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
        tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
                     (unsigned long)adapter);
 
-       ret = ibmebus_request_irq(adapter->neq->attr.ist1,
-                                 ehea_interrupt_neq, IRQF_DISABLED,
-                                 "ehea_neq", adapter);
-       if (ret) {
-               dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
-               goto out_kill_eq;
-       }
-
        ret = ehea_create_device_sysfs(dev);
        if (ret)
-               goto out_free_irq;
+               goto out_kill_eq;
 
        ret = ehea_setup_ports(adapter);
        if (ret) {
@@ -3332,15 +3327,28 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
                goto out_rem_dev_sysfs;
        }
 
+       ret = ibmebus_request_irq(adapter->neq->attr.ist1,
+                                 ehea_interrupt_neq, IRQF_DISABLED,
+                                 "ehea_neq", adapter);
+       if (ret) {
+               dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
+               goto out_shutdown_ports;
+       }
+
+
        ret = 0;
        goto out;
 
+out_shutdown_ports:
+       for (i = 0; i < EHEA_MAX_PORTS; i++)
+               if (adapter->port[i]) {
+                       ehea_shutdown_single_port(adapter->port[i]);
+                       adapter->port[i] = NULL;
+               }
+
 out_rem_dev_sysfs:
        ehea_remove_device_sysfs(dev);
 
-out_free_irq:
-       ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
-
 out_kill_eq:
        ehea_destroy_eq(adapter->neq);
 
index 52c456ec4d6cf811567f82f80477b4e32910ee9a..8364815c32ff63f04fd7942d2f240b980e156f2f 100644 (file)
@@ -450,7 +450,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,
                            void *cb_addr);
 
 #define H_REGBCMC_PN            EHEA_BMASK_IBM(48, 63)
-#define H_REGBCMC_REGTYPE       EHEA_BMASK_IBM(61, 63)
+#define H_REGBCMC_REGTYPE       EHEA_BMASK_IBM(60, 63)
 #define H_REGBCMC_MACADDR       EHEA_BMASK_IBM(16, 63)
 #define H_REGBCMC_VLANID        EHEA_BMASK_IBM(52, 63)
 
index 64c76443a7aa2f2c661f5ea0f0f3455055eb2306..b461c24945e3abc707d13ab5ba64f549c12949c8 100644 (file)
@@ -1310,10 +1310,6 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
 
                if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)
                        oem_reg |= HV_OEM_BITS_LPLU;
-
-               /* Set Restart auto-neg to activate the bits */
-               if (!hw->phy.ops.check_reset_block(hw))
-                       oem_reg |= HV_OEM_BITS_RESTART_AN;
        } else {
                if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE |
                               E1000_PHY_CTRL_NOND0A_GBE_DISABLE))
@@ -1324,6 +1320,11 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
                        oem_reg |= HV_OEM_BITS_LPLU;
        }
 
+       /* Set Restart auto-neg to activate the bits */
+       if ((d0_state || (hw->mac.type != e1000_pchlan)) &&
+           !hw->phy.ops.check_reset_block(hw))
+               oem_reg |= HV_OEM_BITS_RESTART_AN;
+
        ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);
 
 release:
@@ -3682,7 +3683,11 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
 
        if (hw->mac.type >= e1000_pchlan) {
                e1000_oem_bits_config_ich8lan(hw, false);
-               e1000_phy_hw_reset_ich8lan(hw);
+
+               /* Reset PHY to activate OEM bits on 82577/8 */
+               if (hw->mac.type == e1000_pchlan)
+                       e1000e_phy_hw_reset_generic(hw);
+
                ret_val = hw->phy.ops.acquire(hw);
                if (ret_val)
                        return;
index 19ab2154802c171fcadaeceb82419681b51c90f2..9520a6ac1f3069592be3cc199c9d5e2ee99215b3 100644 (file)
@@ -3799,7 +3799,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
        /* fire an unusual interrupt on the test handler */
        ew32(ICS, E1000_ICS_RXSEQ);
        e1e_flush();
-       msleep(50);
+       msleep(100);
 
        e1000_irq_disable(adapter);
 
index ff796e42c3ebbf1b146a28b677e7bb885e1f6bf6..16adeb9418a8903e5ccbb7503e513f1918978930 100644 (file)
@@ -106,7 +106,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
 /*
  * Interrupt Throttle Rate (interrupts/sec)
  *
- * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
+ * Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative
  */
 E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
 #define DEFAULT_ITR 3
@@ -344,53 +344,60 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 
                if (num_InterruptThrottleRate > bd) {
                        adapter->itr = InterruptThrottleRate[bd];
-                       switch (adapter->itr) {
-                       case 0:
-                               e_info("%s turned off\n", opt.name);
-                               break;
-                       case 1:
-                               e_info("%s set to dynamic mode\n", opt.name);
-                               adapter->itr_setting = adapter->itr;
-                               adapter->itr = 20000;
-                               break;
-                       case 3:
-                               e_info("%s set to dynamic conservative mode\n",
-                                       opt.name);
-                               adapter->itr_setting = adapter->itr;
-                               adapter->itr = 20000;
-                               break;
-                       case 4:
-                               e_info("%s set to simplified (2000-8000 ints) "
-                                      "mode\n", opt.name);
-                               adapter->itr_setting = 4;
-                               break;
-                       default:
-                               /*
-                                * Save the setting, because the dynamic bits
-                                * change itr.
-                                */
-                               if (e1000_validate_option(&adapter->itr, &opt,
-                                                         adapter) &&
-                                   (adapter->itr == 3)) {
-                                       /*
-                                        * In case of invalid user value,
-                                        * default to conservative mode.
-                                        */
-                                       adapter->itr_setting = adapter->itr;
-                                       adapter->itr = 20000;
-                               } else {
-                                       /*
-                                        * Clear the lower two bits because
-                                        * they are used as control.
-                                        */
-                                       adapter->itr_setting =
-                                               adapter->itr & ~3;
-                               }
-                               break;
-                       }
+
+                       /*
+                        * Make sure a message is printed for non-special
+                        * values.  And in case of an invalid option, display
+                        * warning, use default and got through itr/itr_setting
+                        * adjustment logic below
+                        */
+                       if ((adapter->itr > 4) &&
+                           e1000_validate_option(&adapter->itr, &opt, adapter))
+                               adapter->itr = opt.def;
                } else {
-                       adapter->itr_setting = opt.def;
+                       /*
+                        * If no option specified, use default value and go
+                        * through the logic below to adjust itr/itr_setting
+                        */
+                       adapter->itr = opt.def;
+
+                       /*
+                        * Make sure a message is printed for non-special
+                        * default values
+                        */
+                       if (adapter->itr > 40)
+                               e_info("%s set to default %d\n", opt.name,
+                                      adapter->itr);
+               }
+
+               adapter->itr_setting = adapter->itr;
+               switch (adapter->itr) {
+               case 0:
+                       e_info("%s turned off\n", opt.name);
+                       break;
+               case 1:
+                       e_info("%s set to dynamic mode\n", opt.name);
+                       adapter->itr = 20000;
+                       break;
+               case 3:
+                       e_info("%s set to dynamic conservative mode\n",
+                              opt.name);
                        adapter->itr = 20000;
+                       break;
+               case 4:
+                       e_info("%s set to simplified (2000-8000 ints) mode\n",
+                              opt.name);
+                       break;
+               default:
+                       /*
+                        * Save the setting, because the dynamic bits
+                        * change itr.
+                        *
+                        * Clear the lower two bits because
+                        * they are used as control.
+                        */
+                       adapter->itr_setting &= ~3;
+                       break;
                }
        }
        { /* Interrupt Mode */
index d61ca2a732f0ef341ccaf036ce0dcb6efb468013..8ec74b07f940a234ccc1691e9dcd2b67691e0f4b 100644 (file)
@@ -2731,14 +2731,14 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
                        netdev->addr_len);
        }
 
-       if (!is_valid_ether_addr(netdev->perm_addr)) {
+       if (!is_valid_ether_addr(netdev->dev_addr)) {
                dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
                        netdev->dev_addr);
                err = -EIO;
                goto err_hw_init;
        }
 
-       memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
+       memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 
        setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
                    (unsigned long) adapter);
index 77ea4b7165351707192dde0ea3c678950502a71b..bc07933d67dadec6845fb667fbc9cc1edf025c3e 100644 (file)
@@ -437,6 +437,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
         */
        if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&
            (fctl & FC_FC_END_SEQ)) {
+               skb_linearize(skb);
                crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
                crc->fcoe_eof = FC_EOF_T;
        }
index 027d7a75be39b025c6de30a63d63a30a528424a2..ed1b47dc0834f5a5c1f76fc667e810e23125ba03 100644 (file)
@@ -622,6 +622,16 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, int v_idx,
                if (adapter->hw.mac.type == ixgbe_mac_82599EB)
                        set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state);
 
+#ifdef IXGBE_FCOE
+               if (adapter->netdev->features & NETIF_F_FCOE_MTU) {
+                       struct ixgbe_ring_feature *f;
+                       f = &adapter->ring_feature[RING_F_FCOE];
+                       if ((rxr_idx >= f->mask) &&
+                           (rxr_idx < f->mask + f->indices))
+                               set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state);
+               }
+
+#endif /* IXGBE_FCOE */
                /* apply Rx specific ring traits */
                ring->count = adapter->rx_ring_count;
                ring->queue_index = rxr_idx;
index 3e26b1f9ac75f0811e9b6e4662b4b77c94a77c25..88f6b2e9b72db2ddb22b917fcb4e4ae4c9b99514 100644 (file)
@@ -3154,14 +3154,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
                        set_ring_rsc_enabled(rx_ring);
                else
                        clear_ring_rsc_enabled(rx_ring);
-#ifdef IXGBE_FCOE
-               if (netdev->features & NETIF_F_FCOE_MTU) {
-                       struct ixgbe_ring_feature *f;
-                       f = &adapter->ring_feature[RING_F_FCOE];
-                       if ((i >= f->mask) && (i < f->mask + f->indices))
-                               set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state);
-               }
-#endif /* IXGBE_FCOE */
        }
 }
 
@@ -4836,7 +4828,9 @@ static int ixgbe_resume(struct pci_dev *pdev)
 
        pci_wake_from_d3(pdev, false);
 
+       rtnl_lock();
        err = ixgbe_init_interrupt_scheme(adapter);
+       rtnl_unlock();
        if (err) {
                e_dev_err("Cannot initialize interrupts for device\n");
                return err;
@@ -4879,10 +4873,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
        }
 
        ixgbe_clear_interrupt_scheme(adapter);
-#ifdef CONFIG_DCB
-       kfree(adapter->ixgbe_ieee_pfc);
-       kfree(adapter->ixgbe_ieee_ets);
-#endif
 
 #ifdef CONFIG_PM
        retval = pci_save_state(pdev);
@@ -4893,6 +4883,16 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
        if (wufc) {
                ixgbe_set_rx_mode(netdev);
 
+               /*
+                * enable the optics for both mult-speed fiber and
+                * 82599 SFP+ fiber as we can WoL.
+                */
+               if (hw->mac.ops.enable_tx_laser &&
+                   (hw->phy.multispeed_fiber ||
+                   (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber &&
+                    hw->mac.type == ixgbe_mac_82599EB)))
+                       hw->mac.ops.enable_tx_laser(hw);
+
                /* turn on all-multi mode if wake on multicast is enabled */
                if (wufc & IXGBE_WUFC_MC) {
                        fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
@@ -7220,6 +7220,11 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 
        ixgbe_release_hw_control(adapter);
 
+#ifdef CONFIG_DCB
+       kfree(adapter->ixgbe_ieee_pfc);
+       kfree(adapter->ixgbe_ieee_ets);
+
+#endif
        iounmap(adapter->hw.hw_addr);
        pci_release_selected_regions(pdev, pci_select_bars(pdev,
                                     IORESOURCE_MEM));
index c9b504e2dfc3bfdc4707dd0f3db240b1f365ec0c..487a6c8bd4eccf6c21dc394c317e408cabe9aa12 100644 (file)
@@ -2494,8 +2494,13 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
                skb_copy_from_linear_data(re->skb, skb->data, length);
                skb->ip_summed = re->skb->ip_summed;
                skb->csum = re->skb->csum;
+               skb->rxhash = re->skb->rxhash;
+               skb->vlan_tci = re->skb->vlan_tci;
+
                pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
                                               length, PCI_DMA_FROMDEVICE);
+               re->skb->vlan_tci = 0;
+               re->skb->rxhash = 0;
                re->skb->ip_summed = CHECKSUM_NONE;
                skb_put(skb, length);
        }
@@ -2580,9 +2585,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
        struct sk_buff *skb = NULL;
        u16 count = (status & GMR_FS_LEN) >> 16;
 
-       if (status & GMR_FS_VLAN)
-               count -= VLAN_HLEN;     /* Account for vlan tag */
-
        netif_printk(sky2, rx_status, KERN_DEBUG, dev,
                     "rx slot %u status 0x%x len %d\n",
                     sky2->rx_next, status, length);
@@ -2590,6 +2592,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
        sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
        prefetch(sky2->rx_ring + sky2->rx_next);
 
+       if (vlan_tx_tag_present(re->skb))
+               count -= VLAN_HLEN;     /* Account for vlan tag */
+
        /* This chip has hardware problems that generates bogus status.
         * So do only marginal checking and expect higher level protocols
         * to handle crap frames.
@@ -2647,11 +2652,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
 }
 
 static inline void sky2_skb_rx(const struct sky2_port *sky2,
-                              u32 status, struct sk_buff *skb)
+                              struct sk_buff *skb)
 {
-       if (status & GMR_FS_VLAN)
-               __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
-
        if (skb->ip_summed == CHECKSUM_NONE)
                netif_receive_skb(skb);
        else
@@ -2705,6 +2707,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
        }
 }
 
+static void sky2_rx_tag(struct sky2_port *sky2, u16 length)
+{
+       struct sk_buff *skb;
+
+       skb = sky2->rx_ring[sky2->rx_next].skb;
+       __vlan_hwaccel_put_tag(skb, be16_to_cpu(length));
+}
+
 static void sky2_rx_hash(struct sky2_port *sky2, u32 status)
 {
        struct sk_buff *skb;
@@ -2763,8 +2773,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
                        }
 
                        skb->protocol = eth_type_trans(skb, dev);
-
-                       sky2_skb_rx(sky2, status, skb);
+                       sky2_skb_rx(sky2, skb);
 
                        /* Stop after net poll weight */
                        if (++work_done >= to_do)
@@ -2772,11 +2781,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
                        break;
 
                case OP_RXVLAN:
-                       sky2->rx_tag = length;
+                       sky2_rx_tag(sky2, length);
                        break;
 
                case OP_RXCHKSVLAN:
-                       sky2->rx_tag = length;
+                       sky2_rx_tag(sky2, length);
                        /* fall through */
                case OP_RXCHKS:
                        if (likely(dev->features & NETIF_F_RXCSUM))
index ff6f58bf822aa378ffa0975140733fa40bf41f5d..3c896ce80b71ec1facc6f04f666ab80711c5dfe3 100644 (file)
@@ -2241,7 +2241,6 @@ struct sky2_port {
        u16                  rx_pending;
        u16                  rx_data_size;
        u16                  rx_nfrags;
-       u16                  rx_tag;
 
        struct {
                unsigned long last;
index c722aa607d074796985b9028c5c91752459aad8e..f8dda009d3c04722e54c659bfa3bb921d8b62fa8 100644 (file)
@@ -889,16 +889,17 @@ static int ks8851_net_stop(struct net_device *dev)
        netif_stop_queue(dev);
 
        mutex_lock(&ks->lock);
+       /* turn off the IRQs and ack any outstanding */
+       ks8851_wrreg16(ks, KS_IER, 0x0000);
+       ks8851_wrreg16(ks, KS_ISR, 0xffff);
+       mutex_unlock(&ks->lock);
 
        /* stop any outstanding work */
        flush_work(&ks->irq_work);
        flush_work(&ks->tx_work);
        flush_work(&ks->rxctrl_work);
 
-       /* turn off the IRQs and ack any outstanding */
-       ks8851_wrreg16(ks, KS_IER, 0x0000);
-       ks8851_wrreg16(ks, KS_ISR, 0xffff);
-
+       mutex_lock(&ks->lock);
        /* shutdown RX process */
        ks8851_wrreg16(ks, KS_RXCR1, 0x0000);
 
@@ -907,6 +908,7 @@ static int ks8851_net_stop(struct net_device *dev)
 
        /* set powermode to soft power down to save power */
        ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN);
+       mutex_unlock(&ks->lock);
 
        /* ensure any queued tx buffers are dumped */
        while (!skb_queue_empty(&ks->txq)) {
@@ -918,7 +920,6 @@ static int ks8851_net_stop(struct net_device *dev)
                dev_kfree_skb(txb);
        }
 
-       mutex_unlock(&ks->lock);
        return 0;
 }
 
@@ -1418,6 +1419,7 @@ static int __devinit ks8851_probe(struct spi_device *spi)
        struct net_device *ndev;
        struct ks8851_net *ks;
        int ret;
+       unsigned cider;
 
        ndev = alloc_etherdev(sizeof(struct ks8851_net));
        if (!ndev)
@@ -1484,8 +1486,8 @@ static int __devinit ks8851_probe(struct spi_device *spi)
        ks8851_soft_reset(ks, GRR_GSR);
 
        /* simple check for a valid chip being connected to the bus */
-
-       if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
+       cider = ks8851_rdreg16(ks, KS_CIDER);
+       if ((cider & ~CIDER_REV_MASK) != CIDER_ID) {
                dev_err(&spi->dev, "failed to read device ID\n");
                ret = -ENODEV;
                goto err_id;
@@ -1516,15 +1518,14 @@ static int __devinit ks8851_probe(struct spi_device *spi)
        }
 
        netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n",
-                   CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)),
-                   ndev->dev_addr, ndev->irq,
+                   CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq,
                    ks->rc_ccr & CCR_EEPROM ? "has" : "no");
 
        return 0;
 
 
 err_netdev:
-       free_irq(ndev->irq, ndev);
+       free_irq(ndev->irq, ks);
 
 err_id:
 err_irq:
index b8104d9f40810871525eb360edaf16e483f6e945..5ffde23ac8fb729526a9dc9c7cfebd95fb2e9b09 100644 (file)
@@ -40,7 +40,7 @@
 #define        DRV_NAME        "ks8851_mll"
 
 static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
-#define MAX_RECV_FRAMES                        32
+#define MAX_RECV_FRAMES                        255
 #define MAX_BUF_SIZE                   2048
 #define TX_BUF_SIZE                    2000
 #define RX_BUF_SIZE                    2000
index ef723b185d853794746a3882cf54e4c00a205699..eaf9ff0262a9c63594e7d80c617d87098c957fa6 100644 (file)
@@ -5675,7 +5675,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr)
                memcpy(hw->override_addr, mac->sa_data, ETH_ALEN);
        }
 
-       memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN);
+       memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);
 
        interrupt = hw_block_intr(hw);
 
index abc79076f867baa5220361e0d6810d11e7edc8ef..b3287c0fe279b95636f80325549833edd137f590 100644 (file)
@@ -958,6 +958,11 @@ static inline void cp_start_hw (struct cp_private *cp)
        cpw8(Cmd, RxOn | TxOn);
 }
 
+static void cp_enable_irq(struct cp_private *cp)
+{
+       cpw16_f(IntrMask, cp_intr_mask);
+}
+
 static void cp_init_hw (struct cp_private *cp)
 {
        struct net_device *dev = cp->dev;
@@ -997,8 +1002,6 @@ static void cp_init_hw (struct cp_private *cp)
 
        cpw16(MultiIntr, 0);
 
-       cpw16_f(IntrMask, cp_intr_mask);
-
        cpw8_f(Cfg9346, Cfg9346_Lock);
 }
 
@@ -1130,6 +1133,8 @@ static int cp_open (struct net_device *dev)
        if (rc)
                goto err_out_hw;
 
+       cp_enable_irq(cp);
+
        netif_carrier_off(dev);
        mii_check_media(&cp->mii_if, netif_msg_link(cp), true);
        netif_start_queue(dev);
@@ -2031,6 +2036,7 @@ static int cp_resume (struct pci_dev *pdev)
        /* FIXME: sh*t may happen if the Rx ring buffer is depleted */
        cp_init_rings_index (cp);
        cp_init_hw (cp);
+       cp_enable_irq(cp);
        netif_start_queue (dev);
 
        spin_lock_irqsave (&cp->lock, flags);
index 4a6971027076613f7765a187e2c28eb11df56104..cd3defb11ffb3e09822b5f20555796ddd8960fd2 100644 (file)
@@ -1166,10 +1166,8 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)
 
 /* Quickly dumps bad packets */
 static void
-smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
+smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords)
 {
-       unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2;
-
        if (likely(pktwords >= 4)) {
                unsigned int timeout = 500;
                unsigned int val;
@@ -1233,7 +1231,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
                        continue;
                }
 
-               skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);
+               skb = netdev_alloc_skb(dev, pktwords << 2);
                if (unlikely(!skb)) {
                        SMSC_WARN(pdata, rx_err,
                                  "Unable to allocate skb for rx packet");
@@ -1243,14 +1241,12 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
                        break;
                }
 
-               skb->data = skb->head;
-               skb_reset_tail_pointer(skb);
+               pdata->ops->rx_readfifo(pdata,
+                                (unsigned int *)skb->data, pktwords);
 
                /* Align IP on 16B boundary */
                skb_reserve(skb, NET_IP_ALIGN);
                skb_put(skb, pktlength - 4);
-               pdata->ops->rx_readfifo(pdata,
-                                (unsigned int *)skb->head, pktwords);
                skb->protocol = eth_type_trans(skb, dev);
                skb_checksum_none_assert(skb);
                netif_receive_skb(skb);
@@ -1565,7 +1561,7 @@ static int smsc911x_open(struct net_device *dev)
        smsc911x_reg_write(pdata, FIFO_INT, temp);
 
        /* set RX Data offset to 2 bytes for alignment */
-       smsc911x_reg_write(pdata, RX_CFG, (2 << 8));
+       smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8));
 
        /* enable NAPI polling before enabling RX interrupts */
        napi_enable(&pdata->napi);
@@ -2382,7 +2378,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        pdata = netdev_priv(dev);
-
        dev->irq = irq_res->start;
        irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
        pdata->ioaddr = ioremap_nocache(res->start, res_size);
@@ -2446,7 +2441,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
        if (retval) {
                SMSC_WARN(pdata, probe,
                          "Unable to claim requested irq: %d", dev->irq);
-               goto out_free_irq;
+               goto out_disable_resources;
        }
 
        retval = register_netdev(dev);
index 558409ff40582fa9f5cd1ae91248f9d214c51d3e..4ba969096717a7ce59e55eaa97f40bdc974ef8b2 100644 (file)
@@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
        netif_device_detach(dev);
 
        /* Switch off chip, remember WOL setting */
-       gp->asleep_wol = gp->wake_on_lan;
+       gp->asleep_wol = !!gp->wake_on_lan;
        gem_do_stop(dev, gp->asleep_wol);
 
        /* Unlock the network stack */
index 174a3348f6762d67a661801342ea6cbe95a7810f..08aff1a2087c920207f544bf540917b481c35344 100644 (file)
@@ -1511,7 +1511,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
 
 static int match_first_device(struct device *dev, void *data)
 {
-       return 1;
+       return !strncmp(dev_name(dev), "davinci_mdio", 12);
 }
 
 /**
index 2757c7d6e6330460c179d025a1ddc2267d32b27d..e4e47088e26b98fe0118c16ae17da61ec0f07dde 100644 (file)
@@ -181,6 +181,11 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)
                __davinci_mdio_reset(data);
                return -EAGAIN;
        }
+
+       reg = __raw_readl(&regs->user[0].access);
+       if ((reg & USERACCESS_GO) == 0)
+               return 0;
+
        dev_err(data->dev, "timed out waiting for user access\n");
        return -ETIMEDOUT;
 }
index 817ad3bc49574670ab6040b6805528c5b863c852..efd36691ce5450881dd14114037071708df4e7c1 100644 (file)
@@ -228,7 +228,7 @@ tlan_get_skb(const struct tlan_list *tag)
        unsigned long addr;
 
        addr = tag->buffer[9].address;
-       addr |= (tag->buffer[8].address << 16) << 16;
+       addr |= ((unsigned long) tag->buffer[8].address << 16) << 16;
        return (struct sk_buff *) addr;
 }
 
index 261356c2dc99ed4bdff8af73afb132c9baa6f3e7..3d501ec7fad7f67775ca1f11fe4c3870db4f61d7 100644 (file)
@@ -342,6 +342,21 @@ inline int __netio_fastio1(u32 fastio_index, u32 arg0)
 }
 
 
+static void tile_net_return_credit(struct tile_net_cpu *info)
+{
+       struct tile_netio_queue *queue = &info->queue;
+       netio_queue_user_impl_t *qup = &queue->__user_part;
+
+       /* Return four credits after every fourth packet. */
+       if (--qup->__receive_credit_remaining == 0) {
+               u32 interval = qup->__receive_credit_interval;
+               qup->__receive_credit_remaining = interval;
+               __netio_fastio_return_credits(qup->__fastio_index, interval);
+       }
+}
+
+
+
 /*
  * Provide a linux buffer to LIPP.
  */
@@ -433,7 +448,7 @@ static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info,
        struct sk_buff **skb_ptr;
 
        /* Request 96 extra bytes for alignment purposes. */
-       skb = netdev_alloc_skb(info->napi->dev, len + padding);
+       skb = netdev_alloc_skb(info->napi.dev, len + padding);
        if (skb == NULL)
                return false;
 
@@ -864,19 +879,11 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)
 
                stats->rx_packets++;
                stats->rx_bytes += len;
-
-               if (small)
-                       info->num_needed_small_buffers++;
-               else
-                       info->num_needed_large_buffers++;
        }
 
-       /* Return four credits after every fourth packet. */
-       if (--qup->__receive_credit_remaining == 0) {
-               u32 interval = qup->__receive_credit_interval;
-               qup->__receive_credit_remaining = interval;
-               __netio_fastio_return_credits(qup->__fastio_index, interval);
-       }
+       /* ISSUE: It would be nice to defer this until the packet has */
+       /* actually been processed. */
+       tile_net_return_credit(info);
 
        /* Consume this packet. */
        qup->__packet_receive_read = index2;
@@ -1543,7 +1550,7 @@ static int tile_net_drain_lipp_buffers(struct tile_net_priv *priv)
 
        /* Drain all the LIPP buffers. */
        while (true) {
-               int buffer;
+               unsigned int buffer;
 
                /* NOTE: This should never fail. */
                if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&buffer,
@@ -1707,7 +1714,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
                if (!hash_default) {
                        void *va = pfn_to_kaddr(pfn) + f->page_offset;
                        BUG_ON(PageHighMem(skb_frag_page(f)));
-                       finv_buffer_remote(va, f->size, 0);
+                       finv_buffer_remote(va, skb_frag_size(f), 0);
                }
 
                cpa = ((phys_addr_t)pfn << PAGE_SHIFT) + f->page_offset;
@@ -1735,8 +1742,8 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
  * Sometimes, if "sendfile()" requires copying, we will be called with
  * "data" containing the header and payload, with "frags" being empty.
  *
- * In theory, "sh->nr_frags" could be 3, but in practice, it seems
- * that this will never actually happen.
+ * Sometimes, for example when using NFS over TCP, a single segment can
+ * span 3 fragments, which must be handled carefully in LEPP.
  *
  * See "emulate_large_send_offload()" for some reference code, which
  * does not handle checksumming.
@@ -1844,10 +1851,8 @@ static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev)
 
        spin_lock_irqsave(&priv->eq_lock, irqflags);
 
-       /*
-        * Handle completions if needed to make room.
-        * HACK: Spin until there is sufficient room.
-        */
+       /* Handle completions if needed to make room. */
+       /* NOTE: Return NETDEV_TX_BUSY if there is still no room. */
        if (lepp_num_free_comp_slots(eq) == 0) {
                nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 0);
                if (nolds == 0) {
@@ -1861,6 +1866,7 @@ busy:
        cmd_tail = eq->cmd_tail;
 
        /* Prepare to advance, detecting full queue. */
+       /* NOTE: Return NETDEV_TX_BUSY if the queue is full. */
        cmd_next = cmd_tail + cmd_size;
        if (cmd_tail < cmd_head && cmd_next >= cmd_head)
                goto busy;
@@ -2023,10 +2029,8 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)
 
        spin_lock_irqsave(&priv->eq_lock, irqflags);
 
-       /*
-        * Handle completions if needed to make room.
-        * HACK: Spin until there is sufficient room.
-        */
+       /* Handle completions if needed to make room. */
+       /* NOTE: Return NETDEV_TX_BUSY if there is still no room. */
        if (lepp_num_free_comp_slots(eq) == 0) {
                nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 0);
                if (nolds == 0) {
@@ -2040,6 +2044,7 @@ busy:
        cmd_tail = eq->cmd_tail;
 
        /* Copy the commands, or fail. */
+       /* NOTE: Return NETDEV_TX_BUSY if the queue is full. */
        for (i = 0; i < num_frags; i++) {
 
                /* Prepare to advance, detecting full queue. */
@@ -2261,6 +2266,23 @@ static int tile_net_get_mac(struct net_device *dev)
        return 0;
 }
 
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void tile_net_netpoll(struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+       disable_percpu_irq(priv->intr_id);
+       tile_net_handle_ingress_interrupt(priv->intr_id, dev);
+       enable_percpu_irq(priv->intr_id, 0);
+}
+#endif
+
+
 static const struct net_device_ops tile_net_ops = {
        .ndo_open = tile_net_open,
        .ndo_stop = tile_net_stop,
@@ -2269,7 +2291,10 @@ static const struct net_device_ops tile_net_ops = {
        .ndo_get_stats = tile_net_get_stats,
        .ndo_change_mtu = tile_net_change_mtu,
        .ndo_tx_timeout = tile_net_tx_timeout,
-       .ndo_set_mac_address = tile_net_set_mac_address
+       .ndo_set_mac_address = tile_net_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller = tile_net_netpoll,
+#endif
 };
 
 
@@ -2409,7 +2434,7 @@ static void tile_net_cleanup(void)
  */
 static int tile_net_init_module(void)
 {
-       pr_info("Tilera IPP Net Driver\n");
+       pr_info("Tilera Network Driver\n");
 
        tile_net_devs[0] = tile_net_dev_init("xgbe0");
        tile_net_devs[1] = tile_net_dev_init("xgbe1");
index cc83af083fd7b7b17a650471436ca42e74f8fbe0..44b8d2bad8c3efd09a1d572d2ef7cf36f8d4a227 100644 (file)
@@ -2,9 +2,7 @@
  * Definitions for Xilinx Axi Ethernet device driver.
  *
  * Copyright (c) 2009 Secret Lab Technologies, Ltd.
- * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
- * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
- * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.
  */
 
 #ifndef XILINX_AXIENET_H
index 2fcbeba6814bead15acdae0feff0e3e264c5656d..9c365e192a3197dc11267f37ce572985c12f274b 100644 (file)
@@ -4,9 +4,9 @@
  * Copyright (c) 2008 Nissin Systems Co., Ltd.,  Yoshio Kashiwagi
  * Copyright (c) 2005-2008 DLA Systems,  David H. Lynch Jr. <dhlii@dlasys.net>
  * Copyright (c) 2008-2009 Secret Lab Technologies Ltd.
- * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
- * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
- * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (c) 2010 - 2011 PetaLogix
+ * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.
  *
  * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6
  * and Spartan6.
index d70b6e79f6c0cd4a9236a67a1dcd8b67f327aeb3..e90e1f46121ef2e0fcacc1a1b3ec5b198b2df94d 100644 (file)
@@ -2,9 +2,9 @@
  * MDIO bus driver for the Xilinx Axi Ethernet device
  *
  * Copyright (c) 2009 Secret Lab Technologies, Ltd.
- * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
- * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
- * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (c) 2010 - 2011 PetaLogix
+ * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.
  */
 
 #include <linux/of_address.h>
index dd294783b5c5b77c3d48ecd14067921d9e90d4bb..2d59138db7f3fd688840d6bf5ce1f449838271be 100644 (file)
@@ -44,6 +44,7 @@ struct net_device_context {
        /* point back to our device context */
        struct hv_device *device_ctx;
        struct delayed_work dwork;
+       struct work_struct work;
 };
 
 
@@ -51,30 +52,22 @@ static int ring_size = 128;
 module_param(ring_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
 
-struct set_multicast_work {
-       struct work_struct work;
-       struct net_device *net;
-};
-
 static void do_set_multicast(struct work_struct *w)
 {
-       struct set_multicast_work *swk =
-               container_of(w, struct set_multicast_work, work);
-       struct net_device *net = swk->net;
-
-       struct net_device_context *ndevctx = netdev_priv(net);
+       struct net_device_context *ndevctx =
+               container_of(w, struct net_device_context, work);
        struct netvsc_device *nvdev;
        struct rndis_device *rdev;
 
        nvdev = hv_get_drvdata(ndevctx->device_ctx);
-       if (nvdev == NULL)
-               goto out;
+       if (nvdev == NULL || nvdev->ndev == NULL)
+               return;
 
        rdev = nvdev->extension;
        if (rdev == NULL)
-               goto out;
+               return;
 
-       if (net->flags & IFF_PROMISC)
+       if (nvdev->ndev->flags & IFF_PROMISC)
                rndis_filter_set_packet_filter(rdev,
                        NDIS_PACKET_TYPE_PROMISCUOUS);
        else
@@ -82,21 +75,13 @@ static void do_set_multicast(struct work_struct *w)
                        NDIS_PACKET_TYPE_BROADCAST |
                        NDIS_PACKET_TYPE_ALL_MULTICAST |
                        NDIS_PACKET_TYPE_DIRECTED);
-
-out:
-       kfree(w);
 }
 
 static void netvsc_set_multicast_list(struct net_device *net)
 {
-       struct set_multicast_work *swk =
-               kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC);
-       if (swk == NULL)
-               return;
+       struct net_device_context *net_device_ctx = netdev_priv(net);
 
-       swk->net = net;
-       INIT_WORK(&swk->work, do_set_multicast);
-       schedule_work(&swk->work);
+       schedule_work(&net_device_ctx->work);
 }
 
 static int netvsc_open(struct net_device *net)
@@ -125,6 +110,8 @@ static int netvsc_close(struct net_device *net)
 
        netif_tx_disable(net);
 
+       /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */
+       cancel_work_sync(&net_device_ctx->work);
        ret = rndis_filter_close(device_obj);
        if (ret != 0)
                netdev_err(net, "unable to close device (ret %d).\n", ret);
@@ -335,6 +322,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
 
        nvdev->start_remove = true;
        cancel_delayed_work_sync(&ndevctx->dwork);
+       cancel_work_sync(&ndevctx->work);
        netif_tx_disable(ndev);
        rndis_filter_device_remove(hdev);
 
@@ -403,6 +391,7 @@ static int netvsc_probe(struct hv_device *dev,
        net_device_ctx->device_ctx = dev;
        hv_set_drvdata(dev, net);
        INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp);
+       INIT_WORK(&net_device_ctx->work, do_set_multicast);
 
        net->netdev_ops = &device_ops;
 
@@ -456,6 +445,7 @@ static int netvsc_remove(struct hv_device *dev)
 
        ndev_ctx = netdev_priv(net);
        cancel_delayed_work_sync(&ndev_ctx->dwork);
+       cancel_work_sync(&ndev_ctx->work);
 
        /* Stop outbound asap */
        netif_tx_disable(net);
index f08c85acf761d3893b54f3d2f70e2fddcb6c5904..5ac46f5226f3c5b4b1d35e3450ec922326902896 100644 (file)
@@ -40,6 +40,7 @@ MODULE_LICENSE("GPL");
 #define IP1001_PHASE_SEL_MASK          3       /* IP1001 RX/TXPHASE_SEL */
 #define IP1001_APS_ON                  11      /* IP1001 APS Mode  bit */
 #define IP101A_G_APS_ON                        2       /* IP101A/G APS Mode bit */
+#define IP101A_G_IRQ_CONF_STATUS       0x11    /* Conf Info IRQ & Status Reg */
 
 static int ip175c_config_init(struct phy_device *phydev)
 {
@@ -185,6 +186,15 @@ static int ip175c_config_aneg(struct phy_device *phydev)
        return 0;
 }
 
+static int ip101a_g_ack_interrupt(struct phy_device *phydev)
+{
+       int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
 static struct phy_driver ip175c_driver = {
        .phy_id         = 0x02430d80,
        .name           = "ICPlus IP175C",
@@ -204,7 +214,6 @@ static struct phy_driver ip1001_driver = {
        .phy_id_mask    = 0x0ffffff0,
        .features       = PHY_GBIT_FEATURES | SUPPORTED_Pause |
                          SUPPORTED_Asym_Pause,
-       .flags          = PHY_HAS_INTERRUPT,
        .config_init    = &ip1001_config_init,
        .config_aneg    = &genphy_config_aneg,
        .read_status    = &genphy_read_status,
@@ -220,6 +229,7 @@ static struct phy_driver ip101a_g_driver = {
        .features       = PHY_BASIC_FEATURES | SUPPORTED_Pause |
                          SUPPORTED_Asym_Pause,
        .flags          = PHY_HAS_INTERRUPT,
+       .ack_interrupt  = ip101a_g_ack_interrupt,
        .config_init    = &ip101a_g_config_init,
        .config_aneg    = &genphy_config_aneg,
        .read_status    = &genphy_read_status,
index 33f8c51968b6da62cff64d968445fcf0d55249d9..21d7151fb0ab3ea03c93208cf6d0c2749d1b825b 100644 (file)
@@ -235,7 +235,7 @@ struct ppp_net {
 /* Prototypes. */
 static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
                        struct file *file, unsigned int cmd, unsigned long arg);
-static int ppp_xmit_process(struct ppp *ppp);
+static void ppp_xmit_process(struct ppp *ppp);
 static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
 static void ppp_push(struct ppp *ppp);
 static void ppp_channel_push(struct channel *pch);
@@ -969,8 +969,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
        put_unaligned_be16(proto, pp);
 
        skb_queue_tail(&ppp->file.xq, skb);
-       if (!ppp_xmit_process(ppp))
-               netif_stop_queue(dev);
+       ppp_xmit_process(ppp);
        return NETDEV_TX_OK;
 
  outf:
@@ -1048,11 +1047,10 @@ static void ppp_setup(struct net_device *dev)
  * Called to do any work queued up on the transmit side
  * that can now be done.
  */
-static int
+static void
 ppp_xmit_process(struct ppp *ppp)
 {
        struct sk_buff *skb;
-       int ret = 0;
 
        ppp_xmit_lock(ppp);
        if (!ppp->closing) {
@@ -1062,13 +1060,12 @@ ppp_xmit_process(struct ppp *ppp)
                        ppp_send_frame(ppp, skb);
                /* If there's no work left to do, tell the core net
                   code that we can accept some more. */
-               if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq)) {
+               if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))
                        netif_wake_queue(ppp->dev);
-                       ret = 1;
-               }
+               else
+                       netif_stop_queue(ppp->dev);
        }
        ppp_xmit_unlock(ppp);
-       return ret;
 }
 
 static inline struct sk_buff *
index 5ee032cafadea0f8405f4d8f66cb356eec236262..42b5151aa78ae8523b27493394ba87e9900338a5 100644 (file)
@@ -355,7 +355,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
        u32 packet_len;
        u32 padbytes = 0xffff0000;
 
-       padlen = ((skb->len + 4) % 512) ? 0 : 4;
+       padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;
 
        if ((!skb_cloned(skb)) &&
            ((headroom + tailroom) >= (4 + padlen))) {
@@ -377,7 +377,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
        cpu_to_le32s(&packet_len);
        skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len));
 
-       if ((skb->len % 512) == 0) {
+       if (padlen) {
                cpu_to_le32s(&padbytes);
                memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));
                skb_put(skb, sizeof(padbytes));
index 552d24bf862e124cdae480ed301418469053ccdd..d316503b35d477c3d0338c2ceeb8ba1cc5b107cf 100644 (file)
@@ -365,6 +365,27 @@ static const struct driver_info    qmi_wwan_force_int4 = {
        .data           = BIT(4), /* interface whitelist bitmap */
 };
 
+/* Sierra Wireless provide equally useless interface descriptors
+ * Devices in QMI mode can be switched between two different
+ * configurations:
+ *   a) USB interface #8 is QMI/wwan
+ *   b) USB interfaces #8, #19 and #20 are QMI/wwan
+ *
+ * Both configurations provide a number of other interfaces (serial++),
+ * some of which have the same endpoint configuration as we expect, so
+ * a whitelist or blacklist is necessary.
+ *
+ * FIXME: The below whitelist should include BIT(20).  It does not
+ * because I cannot get it to work...
+ */
+static const struct driver_info        qmi_wwan_sierra = {
+       .description    = "Sierra Wireless wwan/QMI device",
+       .flags          = FLAG_WWAN,
+       .bind           = qmi_wwan_bind_gobi,
+       .unbind         = qmi_wwan_unbind_shared,
+       .manage_power   = qmi_wwan_manage_power,
+       .data           = BIT(8) | BIT(19), /* interface whitelist bitmap */
+};
 
 #define HUAWEI_VENDOR_ID       0x12D1
 #define QMI_GOBI_DEVICE(vend, prod) \
@@ -445,6 +466,15 @@ static const struct usb_device_id products[] = {
                .bInterfaceProtocol = 0xff,
                .driver_info        = (unsigned long)&qmi_wwan_force_int4,
        },
+       {       /* Sierra Wireless MC77xx in QMI mode */
+               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor           = 0x1199,
+               .idProduct          = 0x68a2,
+               .bInterfaceClass    = 0xff,
+               .bInterfaceSubClass = 0xff,
+               .bInterfaceProtocol = 0xff,
+               .driver_info        = (unsigned long)&qmi_wwan_sierra,
+       },
        {QMI_GOBI_DEVICE(0x05c6, 0x9212)},      /* Acer Gobi Modem Device */
        {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)},      /* HP un2400 Gobi Modem Device */
        {QMI_GOBI_DEVICE(0x03f0, 0x371d)},      /* HP un2430 Mobile Broadband Module */
index 187d01ccb97367099b04ce40f8b44fe2824293d5..00103a8c5e04d69e17408d32f139c9bee93aa03c 100644 (file)
@@ -98,7 +98,7 @@ static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
 
        if (unlikely(ret < 0))
                netdev_warn(dev->net,
-                       "Failed to read register index 0x%08x", index);
+                       "Failed to read reg index 0x%08x: %d", index, ret);
 
        le32_to_cpus(buf);
        *data = *buf;
@@ -128,7 +128,7 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
 
        if (unlikely(ret < 0))
                netdev_warn(dev->net,
-                       "Failed to write register index 0x%08x", index);
+                       "Failed to write reg index 0x%08x: %d", index, ret);
 
        kfree(buf);
 
@@ -171,7 +171,7 @@ static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
        idx &= dev->mii.reg_num_mask;
        addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
                | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
-               | MII_ACCESS_READ;
+               | MII_ACCESS_READ | MII_ACCESS_BUSY;
        ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
        check_warn_goto_done(ret, "Error writing MII_ACCESS");
 
@@ -210,7 +210,7 @@ static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
        idx &= dev->mii.reg_num_mask;
        addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
                | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
-               | MII_ACCESS_WRITE;
+               | MII_ACCESS_WRITE | MII_ACCESS_BUSY;
        ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
        check_warn_goto_done(ret, "Error writing MII_ACCESS");
 
@@ -508,9 +508,10 @@ static int smsc75xx_link_reset(struct usbnet *dev)
        u16 lcladv, rmtadv;
        int ret;
 
-       /* clear interrupt status */
+       /* read and write to clear phy interrupt status */
        ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
        check_warn_return(ret, "Error reading PHY_INT_SRC");
+       smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff);
 
        ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
        check_warn_return(ret, "Error writing INT_STS");
@@ -643,7 +644,7 @@ static int smsc75xx_set_mac_address(struct usbnet *dev)
 
 static int smsc75xx_phy_initialize(struct usbnet *dev)
 {
-       int bmcr, timeout = 0;
+       int bmcr, ret, timeout = 0;
 
        /* Initialize MII structure */
        dev->mii.dev = dev->net;
@@ -651,6 +652,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
        dev->mii.mdio_write = smsc75xx_mdio_write;
        dev->mii.phy_id_mask = 0x1f;
        dev->mii.reg_num_mask = 0x1f;
+       dev->mii.supports_gmii = 1;
        dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
 
        /* reset phy and wait for reset to complete */
@@ -661,7 +663,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
                bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
                check_warn_return(bmcr, "Error reading MII_BMCR");
                timeout++;
-       } while ((bmcr & MII_BMCR) && (timeout < 100));
+       } while ((bmcr & BMCR_RESET) && (timeout < 100));
 
        if (timeout >= 100) {
                netdev_warn(dev->net, "timeout on PHY Reset");
@@ -671,10 +673,13 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
        smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
                ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
                ADVERTISE_PAUSE_ASYM);
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
+               ADVERTISE_1000FULL);
 
-       /* read to clear */
-       smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
-       check_warn_return(bmcr, "Error reading PHY_INT_SRC");
+       /* read and write to clear phy interrupt status */
+       ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
+       check_warn_return(ret, "Error reading PHY_INT_SRC");
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff);
 
        smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
                PHY_INT_MASK_DEFAULT);
@@ -946,6 +951,14 @@ static int smsc75xx_reset(struct usbnet *dev)
        ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
        check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
 
+       /* allow mac to detect speed and duplex from phy */
+       ret = smsc75xx_read_reg(dev, MAC_CR, &buf);
+       check_warn_return(ret, "Failed to read MAC_CR: %d", ret);
+
+       buf |= (MAC_CR_ADD | MAC_CR_ASD);
+       ret = smsc75xx_write_reg(dev, MAC_CR, buf);
+       check_warn_return(ret, "Failed to write MAC_CR: %d", ret);
+
        ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
        check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
 
@@ -1051,6 +1064,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
        dev->net->flags |= IFF_MULTICAST;
        dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
        return 0;
 }
 
@@ -1211,7 +1225,7 @@ static const struct driver_info smsc75xx_info = {
        .rx_fixup       = smsc75xx_rx_fixup,
        .tx_fixup       = smsc75xx_tx_fixup,
        .status         = smsc75xx_status,
-       .flags          = FLAG_ETHER | FLAG_SEND_ZLP,
+       .flags          = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
 };
 
 static const struct usb_device_id products[] = {
index 5f19f84d3494696254793320cda6a1f132a0e6e1..94ae66999f592a4a8a1c45fdc24505050271d086 100644 (file)
@@ -1017,6 +1017,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
        dev->net->flags |= IFF_MULTICAST;
        dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
        return 0;
 }
 
@@ -1191,7 +1192,7 @@ static const struct driver_info smsc95xx_info = {
        .rx_fixup       = smsc95xx_rx_fixup,
        .tx_fixup       = smsc95xx_tx_fixup,
        .status         = smsc95xx_status,
-       .flags          = FLAG_ETHER | FLAG_SEND_ZLP,
+       .flags          = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
 };
 
 static const struct usb_device_id products[] = {
index b7b3f5b0d40654c3c50b18ae56c969c03382c71c..2d927fb4adf4ea6805b2aeb02d06c8cb5108f496 100644 (file)
@@ -210,6 +210,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
                } else {
                        usb_fill_int_urb(dev->interrupt, dev->udev, pipe,
                                buf, maxp, intr_complete, dev, period);
+                       dev->interrupt->transfer_flags |= URB_FREE_BUFFER;
                        dev_dbg(&intf->dev,
                                "status ep%din, %d bytes period %d\n",
                                usb_pipeendpoint(pipe), maxp, period);
@@ -1443,7 +1444,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 
        status = register_netdev (net);
        if (status)
-               goto out3;
+               goto out4;
        netif_info(dev, probe, dev->net,
                   "register '%s' at usb-%s-%s, %s, %pM\n",
                   udev->dev.driver->name,
@@ -1461,6 +1462,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 
        return 0;
 
+out4:
+       usb_free_urb(dev->interrupt);
 out3:
        if (info->unbind)
                info->unbind (dev, udev);
index 4de2760c593762634f0925cf9ccb1ab9c7f2c111..af8acc85f4bbd15bf01e939db20932845d7b8312 100644 (file)
@@ -626,16 +626,15 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* This can happen with OOM and indirect buffers. */
        if (unlikely(capacity < 0)) {
                if (likely(capacity == -ENOMEM)) {
-                       if (net_ratelimit()) {
+                       if (net_ratelimit())
                                dev_warn(&dev->dev,
                                         "TX queue failure: out of memory\n");
-                       } else {
+               } else {
                        dev->stats.tx_fifo_errors++;
                        if (net_ratelimit())
                                dev_warn(&dev->dev,
                                         "Unexpected TX queue failure: %d\n",
                                         capacity);
-                       }
                }
                dev->stats.tx_dropped++;
                kfree_skb(skb);
index ebb9f24eefb5e568f90b859e2b3e47028a868a70..1a623183cbe54d63f8392f924953b127ded83c1f 100644 (file)
@@ -2483,6 +2483,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                pr_err("Control memory remap failed\n");
                pci_release_regions(pdev);
                pci_disable_device(pdev);
+               iounmap(card->mem);
                kfree(card);
                return -ENODEV;
        }
index 663b32c2e93185f60b391b2706cbc847e4c8ffd2..0ebbb1906c308ba69ff0cff0125a84562e85116d 100644 (file)
@@ -1965,7 +1965,7 @@ static int __init netif_init(void)
        if (xen_initial_domain())
                return 0;
 
-       if (!xen_platform_pci_unplug)
+       if (xen_hvm_domain() && !xen_platform_pci_unplug)
                return -ENODEV;
 
        printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n");
index bba81216b4dbbbaee8b097a10a2ce505bd4bea9d..bf984b6dc477ce837c0a49ff265830e6efad2d80 100644 (file)
@@ -140,7 +140,7 @@ int of_gpio_simple_xlate(struct gpio_chip *gc,
        if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
                return -EINVAL;
 
-       if (gpiospec->args[0] > gc->ngpio)
+       if (gpiospec->args[0] >= gc->ngpio)
                return -EINVAL;
 
        if (flags)
index 815674415267d831a2618b1e1f977c080d34ac92..111569ccab434dda8262e1ddeb3a9aab04043171 100644 (file)
@@ -967,16 +967,59 @@ pci_save_state(struct pci_dev *dev)
        return 0;
 }
 
+static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
+                                    u32 saved_val, int retry)
+{
+       u32 val;
+
+       pci_read_config_dword(pdev, offset, &val);
+       if (val == saved_val)
+               return;
+
+       for (;;) {
+               dev_dbg(&pdev->dev, "restoring config space at offset "
+                       "%#x (was %#x, writing %#x)\n", offset, val, saved_val);
+               pci_write_config_dword(pdev, offset, saved_val);
+               if (retry-- <= 0)
+                       return;
+
+               pci_read_config_dword(pdev, offset, &val);
+               if (val == saved_val)
+                       return;
+
+               mdelay(1);
+       }
+}
+
+static void pci_restore_config_space_range(struct pci_dev *pdev,
+                                          int start, int end, int retry)
+{
+       int index;
+
+       for (index = end; index >= start; index--)
+               pci_restore_config_dword(pdev, 4 * index,
+                                        pdev->saved_config_space[index],
+                                        retry);
+}
+
+static void pci_restore_config_space(struct pci_dev *pdev)
+{
+       if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
+               pci_restore_config_space_range(pdev, 10, 15, 0);
+               /* Restore BARs before the command register. */
+               pci_restore_config_space_range(pdev, 4, 9, 10);
+               pci_restore_config_space_range(pdev, 0, 3, 0);
+       } else {
+               pci_restore_config_space_range(pdev, 0, 15, 0);
+       }
+}
+
 /** 
  * pci_restore_state - Restore the saved state of a PCI device
  * @dev: - PCI device that we're dealing with
  */
 void pci_restore_state(struct pci_dev *dev)
 {
-       int i;
-       u32 val;
-       int tries;
-
        if (!dev->state_saved)
                return;
 
@@ -984,24 +1027,8 @@ void pci_restore_state(struct pci_dev *dev)
        pci_restore_pcie_state(dev);
        pci_restore_ats_state(dev);
 
-       /*
-        * The Base Address register should be programmed before the command
-        * register(s)
-        */
-       for (i = 15; i >= 0; i--) {
-               pci_read_config_dword(dev, i * 4, &val);
-               tries = 10;             
-               while (tries && val != dev->saved_config_space[i]) {
-                       dev_dbg(&dev->dev, "restoring config "
-                               "space at offset %#x (was %#x, writing %#x)\n",
-                               i, val, (int)dev->saved_config_space[i]);
-                       pci_write_config_dword(dev,i * 4,
-                               dev->saved_config_space[i]);
-                       pci_read_config_dword(dev, i * 4, &val);
-                       mdelay(10);
-                       tries--;
-               }
-       }
+       pci_restore_config_space(dev);
+
        pci_restore_pcix_state(dev);
        pci_restore_msi_state(dev);
        pci_restore_iov_state(dev);
index fd00ff02ab4d0c51cf7b6eabe6b2a5ce9880fb12..d6cc62cb4cf7465fe22cb643fbde7a3f79f88a29 100644 (file)
@@ -290,6 +290,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
                } else {
                        printk(KERN_DEBUG "enable msix get value %x\n",
                                op.value);
+                       err = op.value;
                }
        } else {
                dev_err(&dev->dev, "enable msix get err %x\n", err);
index ec3b8cc188af512c2ba3645b6beec39b97f1ae40..df6296c5f47b4d6bfac67b8b47a14ad9d78b950e 100644 (file)
@@ -908,10 +908,6 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
        const struct pinctrl_ops *ops = pctldev->desc->pctlops;
        unsigned selector = 0;
 
-       /* No grouping */
-       if (!ops)
-               return 0;
-
        mutex_lock(&pinctrl_mutex);
 
        seq_puts(s, "registered pin groups:\n");
@@ -1225,6 +1221,19 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev)
 
 #endif
 
+static int pinctrl_check_ops(struct pinctrl_dev *pctldev)
+{
+       const struct pinctrl_ops *ops = pctldev->desc->pctlops;
+
+       if (!ops ||
+           !ops->list_groups ||
+           !ops->get_group_name ||
+           !ops->get_group_pins)
+               return -EINVAL;
+
+       return 0;
+}
+
 /**
  * pinctrl_register() - register a pin controller device
  * @pctldesc: descriptor for this pin controller
@@ -1256,6 +1265,14 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
        INIT_LIST_HEAD(&pctldev->gpio_ranges);
        pctldev->dev = dev;
 
+       /* check core ops for sanity */
+       ret = pinctrl_check_ops(pctldev);
+       if (ret) {
+               pr_err("%s pinctrl ops lacks necessary functions\n",
+                       pctldesc->name);
+               goto out_err;
+       }
+
        /* If we're implementing pinmuxing, check the ops for sanity */
        if (pctldesc->pmxops) {
                ret = pinmux_check_ops(pctldev);
index 53969af17558d39aa56a8e942e6219f0fd754eb7..81fd606e47bc8d198d8bbab301b651e061d9a74d 100644 (file)
@@ -214,7 +214,7 @@ static struct of_device_id __devinitdata of_anatop_regulator_match_tbl[] = {
        { /* end */ }
 };
 
-static struct platform_driver anatop_regulator = {
+static struct platform_driver anatop_regulator_driver = {
        .driver = {
                .name   = "anatop_regulator",
                .owner  = THIS_MODULE,
@@ -226,13 +226,13 @@ static struct platform_driver anatop_regulator = {
 
 static int __init anatop_regulator_init(void)
 {
-       return platform_driver_register(&anatop_regulator);
+       return platform_driver_register(&anatop_regulator_driver);
 }
 postcore_initcall(anatop_regulator_init);
 
 static void __exit anatop_regulator_exit(void)
 {
-       platform_driver_unregister(&anatop_regulator);
+       platform_driver_unregister(&anatop_regulator_driver);
 }
 module_exit(anatop_regulator_exit);
 
index 550292304b0fd6d0f30d47c5f07a0fdcaf2236fc..c9f890b088daa8d7a7e4de184a321183416a1af1 100644 (file)
@@ -213,7 +213,6 @@ static struct platform_driver efi_rtc_driver = {
                .name = "rtc-efi",
                .owner = THIS_MODULE,
        },
-       .probe = efi_rtc_probe,
        .remove = __exit_p(efi_rtc_remove),
 };
 
index 692de7360e94100dfbc28e5b1dda51d824c24b89..684ef4bbfce432026bcbb526c6bccbd067f15cd8 100644 (file)
@@ -339,8 +339,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
        dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision);
 
        /* Enable the clockwatch on ST Variants */
-       if ((ldata->hw_designer == AMBA_VENDOR_ST) &&
-           (ldata->hw_revision > 1))
+       if (ldata->hw_designer == AMBA_VENDOR_ST)
                writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
                       ldata->base + RTC_CR);
 
index 7f8e6c247935d36ba3b79ffcc835374cadbaa60d..33b6ba0afa0de1b5034970ef7b78d7d3b468ed4f 100644 (file)
@@ -122,6 +122,7 @@ static const struct rtc_class_ops r9701_rtc_ops = {
 static int __devinit r9701_probe(struct spi_device *spi)
 {
        struct rtc_device *rtc;
+       struct rtc_time dt;
        unsigned char tmp;
        int res;
 
@@ -132,6 +133,27 @@ static int __devinit r9701_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
+       /*
+        * The device seems to be present. Now check if the registers
+        * contain invalid values. If so, try to write a default date:
+        * 2000/1/1 00:00:00
+        */
+       r9701_get_datetime(&spi->dev, &dt);
+       if (rtc_valid_tm(&dt)) {
+               dev_info(&spi->dev, "trying to repair invalid date/time\n");
+               dt.tm_sec  = 0;
+               dt.tm_min  = 0;
+               dt.tm_hour = 0;
+               dt.tm_mday = 1;
+               dt.tm_mon  = 0;
+               dt.tm_year = 100;
+
+               if (r9701_set_datetime(&spi->dev, &dt)) {
+                       dev_err(&spi->dev, "cannot repair RTC register\n");
+                       return -ENODEV;
+               }
+       }
+
        rtc = rtc_device_register("r9701",
                                &spi->dev, &r9701_rtc_ops, THIS_MODULE);
        if (IS_ERR(rtc))
index 9ccea134a9965a1b2878f6873ae933fb72ca0b1a..3f3a29752369b092c7b99cca4ff33232f6fa605b 100644 (file)
@@ -40,6 +40,10 @@ enum s3c_cpu_type {
        TYPE_S3C64XX,
 };
 
+struct s3c_rtc_drv_data {
+       int cpu_type;
+};
+
 /* I have yet to find an S3C implementation with more than one
  * of these rtc blocks in */
 
@@ -446,10 +450,12 @@ static const struct of_device_id s3c_rtc_dt_match[];
 static inline int s3c_rtc_get_driver_data(struct platform_device *pdev)
 {
 #ifdef CONFIG_OF
+       struct s3c_rtc_drv_data *data;
        if (pdev->dev.of_node) {
                const struct of_device_id *match;
                match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node);
-               return match->data;
+               data = (struct s3c_rtc_drv_data *) match->data;
+               return data->cpu_type;
        }
 #endif
        return platform_get_device_id(pdev)->driver_data;
@@ -664,20 +670,27 @@ static int s3c_rtc_resume(struct platform_device *pdev)
 #define s3c_rtc_resume  NULL
 #endif
 
+static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = {
+       [TYPE_S3C2410] = { TYPE_S3C2410 },
+       [TYPE_S3C2416] = { TYPE_S3C2416 },
+       [TYPE_S3C2443] = { TYPE_S3C2443 },
+       [TYPE_S3C64XX] = { TYPE_S3C64XX },
+};
+
 #ifdef CONFIG_OF
 static const struct of_device_id s3c_rtc_dt_match[] = {
        {
-               .compatible = "samsung,s3c2410-rtc"
-               .data = TYPE_S3C2410,
+               .compatible = "samsung,s3c2410-rtc",
+               .data = &s3c_rtc_drv_data_array[TYPE_S3C2410],
        }, {
-               .compatible = "samsung,s3c2416-rtc"
-               .data = TYPE_S3C2416,
+               .compatible = "samsung,s3c2416-rtc",
+               .data = &s3c_rtc_drv_data_array[TYPE_S3C2416],
        }, {
-               .compatible = "samsung,s3c2443-rtc"
-               .data = TYPE_S3C2443,
+               .compatible = "samsung,s3c2443-rtc",
+               .data = &s3c_rtc_drv_data_array[TYPE_S3C2443],
        }, {
-               .compatible = "samsung,s3c6410-rtc"
-               .data = TYPE_S3C64XX,
+               .compatible = "samsung,s3c6410-rtc",
+               .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX],
        },
        {},
 };
index 4c2c6df2a9efc38efe61ab559df44d17898ab2ec..258abeabf6246a1ed7e4db116713bb3128009fa0 100644 (file)
@@ -112,6 +112,7 @@ static const u8 twl6030_rtc_reg_map[] = {
 #define BIT_RTC_CTRL_REG_TEST_MODE_M             0x10
 #define BIT_RTC_CTRL_REG_SET_32_COUNTER_M        0x20
 #define BIT_RTC_CTRL_REG_GET_TIME_M              0x40
+#define BIT_RTC_CTRL_REG_RTC_V_OPT               0x80
 
 /* RTC_STATUS_REG bitfields */
 #define BIT_RTC_STATUS_REG_RUN_M                 0x02
@@ -235,25 +236,57 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm)
        unsigned char rtc_data[ALL_TIME_REGS + 1];
        int ret;
        u8 save_control;
+       u8 rtc_control;
 
        ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
-       if (ret < 0)
+       if (ret < 0) {
+               dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret);
                return ret;
+       }
+       /* for twl6030/32 make sure BIT_RTC_CTRL_REG_GET_TIME_M is clear */
+       if (twl_class_is_6030()) {
+               if (save_control & BIT_RTC_CTRL_REG_GET_TIME_M) {
+                       save_control &= ~BIT_RTC_CTRL_REG_GET_TIME_M;
+                       ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+                       if (ret < 0) {
+                               dev_err(dev, "%s clr GET_TIME, error %d\n",
+                                       __func__, ret);
+                               return ret;
+                       }
+               }
+       }
 
-       save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
+       /* Copy RTC counting registers to static registers or latches */
+       rtc_control = save_control | BIT_RTC_CTRL_REG_GET_TIME_M;
 
-       ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
-       if (ret < 0)
+       /* for twl6030/32 enable read access to static shadowed registers */
+       if (twl_class_is_6030())
+               rtc_control |= BIT_RTC_CTRL_REG_RTC_V_OPT;
+
+       ret = twl_rtc_write_u8(rtc_control, REG_RTC_CTRL_REG);
+       if (ret < 0) {
+               dev_err(dev, "%s: writing CTRL_REG, error %d\n", __func__, ret);
                return ret;
+       }
 
        ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data,
                        (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
 
        if (ret < 0) {
-               dev_err(dev, "rtc_read_time error %d\n", ret);
+               dev_err(dev, "%s: reading data, error %d\n", __func__, ret);
                return ret;
        }
 
+       /* for twl6030 restore original state of rtc control register */
+       if (twl_class_is_6030()) {
+               ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+               if (ret < 0) {
+                       dev_err(dev, "%s: restore CTRL_REG, error %d\n",
+                               __func__, ret);
+                       return ret;
+               }
+       }
+
        tm->tm_sec = bcd2bin(rtc_data[0]);
        tm->tm_min = bcd2bin(rtc_data[1]);
        tm->tm_hour = bcd2bin(rtc_data[2]);
index c21871a4e73da92c06119fa3e0f3b7ad93298274..bc2e8a7c265b518e8049bdb1877e0cf57a1b19a2 100644 (file)
@@ -2844,6 +2844,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
        sector_t recid, trkid;
        unsigned int offs;
        unsigned int count, count_to_trk_end;
+       int ret;
 
        basedev = block->base;
        if (rq_data_dir(req) == READ) {
@@ -2884,8 +2885,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
 
        itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
        if (IS_ERR(itcw)) {
-               dasd_sfree_request(cqr, startdev);
-               return ERR_PTR(-EINVAL);
+               ret = -EINVAL;
+               goto out_error;
        }
        cqr->cpaddr = itcw_get_tcw(itcw);
        if (prepare_itcw(itcw, first_trk, last_trk,
@@ -2897,8 +2898,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                /* Clock not in sync and XRC is enabled.
                 * Try again later.
                 */
-               dasd_sfree_request(cqr, startdev);
-               return ERR_PTR(-EAGAIN);
+               ret = -EAGAIN;
+               goto out_error;
        }
        len_to_track_end = 0;
        /*
@@ -2937,8 +2938,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                                        tidaw_flags = 0;
                                last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
                                                            dst, part_len);
-                               if (IS_ERR(last_tidaw))
-                                       return ERR_PTR(-EINVAL);
+                               if (IS_ERR(last_tidaw)) {
+                                       ret = -EINVAL;
+                                       goto out_error;
+                               }
                                dst += part_len;
                        }
                }
@@ -2947,8 +2950,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                        dst = page_address(bv->bv_page) + bv->bv_offset;
                        last_tidaw = itcw_add_tidaw(itcw, 0x00,
                                                    dst, bv->bv_len);
-                       if (IS_ERR(last_tidaw))
-                               return ERR_PTR(-EINVAL);
+                       if (IS_ERR(last_tidaw)) {
+                               ret = -EINVAL;
+                               goto out_error;
+                       }
                }
        }
        last_tidaw->flags |= TIDAW_FLAGS_LAST;
@@ -2968,6 +2973,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
        cqr->buildclk = get_clock();
        cqr->status = DASD_CQR_FILLED;
        return cqr;
+out_error:
+       dasd_sfree_request(cqr, startdev);
+       return ERR_PTR(ret);
 }
 
 static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
index 85f4a9a5d12e5d00a7e445bd1e1e0a784eaf7cd0..73bef0bd394cab2df006f64bf5e3c25ecce7bb3f 100644 (file)
@@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev)
                goto fail_urdev_put;
        }
 
-       cdev_init(urd->char_device, &ur_fops);
+       urd->char_device->ops = &ur_fops;
        urd->char_device->dev = MKDEV(major, minor);
        urd->char_device->owner = ur_fops.owner;
 
index 120955c66410faf8e4c8254baebba15895d38aa9..8334dadc681de98eeb7ac78fed5755336ff58d63 100644 (file)
@@ -1672,7 +1672,8 @@ static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd)
 {
        QETH_DBF_TEXT(SETUP, 2, "cfgblkt");
 
-       if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) {
+       if (prcd[74] == 0xF0 && prcd[75] == 0xF0 &&
+           (prcd[76] == 0xF5 || prcd[76] == 0xF6)) {
                card->info.blkt.time_total = 250;
                card->info.blkt.inter_packet = 5;
                card->info.blkt.inter_packet_jumbo = 15;
@@ -4540,7 +4541,8 @@ static void qeth_determine_capabilities(struct qeth_card *card)
                goto out_offline;
        }
        qeth_configure_unitaddr(card, prcd);
-       qeth_configure_blkt_default(card, prcd);
+       if (ddev_offline)
+               qeth_configure_blkt_default(card, prcd);
        kfree(prcd);
 
        rc = qdio_get_ssqd_desc(ddev, &card->ssqd);
index 2cfcbffa41fd559b075e7c75eae57e2c7f637488..386f0c53bea7e17cf2b74fe29af5d1d7176c25b9 100644 (file)
@@ -835,7 +835,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
 
        scsi_eh_restore_cmnd(scmd, &ses);
 
-       if (sdrv->eh_action)
+       if (sdrv && sdrv->eh_action)
                rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn);
 
        return rtn;
index 31bfba805cf473e51edbeb437a72666f9b735595..9b2901feaf78d4bf3783c9b8b3491f57bfdc2e83 100644 (file)
@@ -653,7 +653,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
                        dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n",
                                                                rx_buf_count);
                        if (t->tx_buf)
-                               dma_unmap_single(NULL, t->tx_dma, t->len,
+                               dma_unmap_single(&spi->dev, t->tx_dma, t->len,
                                                                DMA_TO_DEVICE);
                        return -ENOMEM;
                }
@@ -692,10 +692,10 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
        if (spicfg->io_type == SPI_IO_TYPE_DMA) {
 
                if (t->tx_buf)
-                       dma_unmap_single(NULL, t->tx_dma, t->len,
+                       dma_unmap_single(&spi->dev, t->tx_dma, t->len,
                                                                DMA_TO_DEVICE);
 
-               dma_unmap_single(NULL, t->rx_dma, rx_buf_count,
+               dma_unmap_single(&spi->dev, t->rx_dma, rx_buf_count,
                                                        DMA_FROM_DEVICE);
 
                clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN);
index 24cacff577867b56eca075c13d22f68acd967852..5f748c0d96bdf5444e85408fa21b515b5873639f 100644 (file)
@@ -139,10 +139,12 @@ static void fsl_spi_change_mode(struct spi_device *spi)
 static void fsl_spi_chipselect(struct spi_device *spi, int value)
 {
        struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
-       struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data;
+       struct fsl_spi_platform_data *pdata;
        bool pol = spi->mode & SPI_CS_HIGH;
        struct spi_mpc8xxx_cs   *cs = spi->controller_state;
 
+       pdata = spi->dev.parent->parent->platform_data;
+
        if (value == BITBANG_CS_INACTIVE) {
                if (pdata->cs_control)
                        pdata->cs_control(spi, !pol);
index 31054e3de4c11e496ba6f102fbf41c78d1b9d334..570f22053be89fb56d99b464ecc36a9443e2cc8d 100644 (file)
@@ -83,7 +83,7 @@ struct spi_imx_data {
        struct spi_bitbang bitbang;
 
        struct completion xfer_done;
-       void *base;
+       void __iomem *base;
        int irq;
        struct clk *clk;
        unsigned long spi_clk;
@@ -766,8 +766,12 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
        }
 
        ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs);
-       if (ret < 0)
-               num_cs = mxc_platform_info->num_chipselect;
+       if (ret < 0) {
+               if (mxc_platform_info)
+                       num_cs = mxc_platform_info->num_chipselect;
+               else
+                       return ret;
+       }
 
        master = spi_alloc_master(&pdev->dev,
                        sizeof(struct spi_imx_data) + sizeof(int) * num_cs);
@@ -784,7 +788,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 
        for (i = 0; i < master->num_chipselect; i++) {
                int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
-               if (cs_gpio < 0)
+               if (cs_gpio < 0 && mxc_platform_info)
                        cs_gpio = mxc_platform_info->chipselect[i];
 
                spi_imx->chipselect[i] = cs_gpio;
index 96f0da66b185b5cbb41c6cdf01d7e969e5b341ed..09c925aaf3207dac61b61278cfdddf0f59b39f4c 100644 (file)
@@ -2195,7 +2195,6 @@ static int pl022_runtime_suspend(struct device *dev)
        struct pl022 *pl022 = dev_get_drvdata(dev);
 
        clk_disable(pl022->clk);
-       amba_vcore_disable(pl022->adev);
 
        return 0;
 }
@@ -2204,7 +2203,6 @@ static int pl022_runtime_resume(struct device *dev)
 {
        struct pl022 *pl022 = dev_get_drvdata(dev);
 
-       amba_vcore_enable(pl022->adev);
        clk_enable(pl022->clk);
 
        return 0;
index 08a3b1133d29ed476ed21e99a3a75d39a74cda3d..eb1dee26bda3662972d9e9e6e4595402ba775ee5 100644 (file)
@@ -27,13 +27,14 @@ config ANDROID_LOGGER
 
 config ANDROID_PERSISTENT_RAM
        bool
+       depends on HAVE_MEMBLOCK
        select REED_SOLOMON
        select REED_SOLOMON_ENC8
        select REED_SOLOMON_DEC8
 
 config ANDROID_RAM_CONSOLE
        bool "Android RAM buffer console"
-       depends on !S390 && !UML
+       depends on !S390 && !UML && HAVE_MEMBLOCK
        select ANDROID_PERSISTENT_RAM
        default n
 
index 052b43e4e505148aa0da8b4da5b611da85b5dd3c..b91e4bc332a77c2e6ea1219e99f92c5ee924c418 100644 (file)
@@ -55,7 +55,6 @@ static int lowmem_minfree[6] = {
 };
 static int lowmem_minfree_size = 4;
 
-static struct task_struct *lowmem_deathpending;
 static unsigned long lowmem_deathpending_timeout;
 
 #define lowmem_print(level, x...)                      \
@@ -64,24 +63,6 @@ static unsigned long lowmem_deathpending_timeout;
                        printk(x);                      \
        } while (0)
 
-static int
-task_notify_func(struct notifier_block *self, unsigned long val, void *data);
-
-static struct notifier_block task_nb = {
-       .notifier_call  = task_notify_func,
-};
-
-static int
-task_notify_func(struct notifier_block *self, unsigned long val, void *data)
-{
-       struct task_struct *task = data;
-
-       if (task == lowmem_deathpending)
-               lowmem_deathpending = NULL;
-
-       return NOTIFY_OK;
-}
-
 static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 {
        struct task_struct *tsk;
@@ -97,19 +78,6 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
        int other_file = global_page_state(NR_FILE_PAGES) -
                                                global_page_state(NR_SHMEM);
 
-       /*
-        * If we already have a death outstanding, then
-        * bail out right away; indicating to vmscan
-        * that we have nothing further to offer on
-        * this pass.
-        *
-        * Note: Currently you need CONFIG_PROFILING
-        * for this to work correctly.
-        */
-       if (lowmem_deathpending &&
-           time_before_eq(jiffies, lowmem_deathpending_timeout))
-               return 0;
-
        if (lowmem_adj_size < array_size)
                array_size = lowmem_adj_size;
        if (lowmem_minfree_size < array_size)
@@ -148,6 +116,12 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
                if (!p)
                        continue;
 
+               if (test_tsk_thread_flag(p, TIF_MEMDIE) &&
+                   time_before_eq(jiffies, lowmem_deathpending_timeout)) {
+                       task_unlock(p);
+                       rcu_read_unlock();
+                       return 0;
+               }
                oom_score_adj = p->signal->oom_score_adj;
                if (oom_score_adj < min_score_adj) {
                        task_unlock(p);
@@ -174,15 +148,9 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
                lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n",
                             selected->pid, selected->comm,
                             selected_oom_score_adj, selected_tasksize);
-               /*
-                * If CONFIG_PROFILING is off, then we don't want to stall
-                * the killer by setting lowmem_deathpending.
-                */
-#ifdef CONFIG_PROFILING
-               lowmem_deathpending = selected;
                lowmem_deathpending_timeout = jiffies + HZ;
-#endif
                send_sig(SIGKILL, selected, 0);
+               set_tsk_thread_flag(selected, TIF_MEMDIE);
                rem -= selected_tasksize;
        }
        lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n",
@@ -198,7 +166,6 @@ static struct shrinker lowmem_shrinker = {
 
 static int __init lowmem_init(void)
 {
-       task_handoff_register(&task_nb);
        register_shrinker(&lowmem_shrinker);
        return 0;
 }
@@ -206,7 +173,6 @@ static int __init lowmem_init(void)
 static void __exit lowmem_exit(void)
 {
        unregister_shrinker(&lowmem_shrinker);
-       task_handoff_unregister(&task_nb);
 }
 
 module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
index e08f2574e30a94e7ddf4acff35ccaa4a63df9d2b..8d8c1e33e0ff11790bea6071cbeb1e9d52b36ecb 100644 (file)
@@ -399,12 +399,12 @@ static  __init
 struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
 {
        struct persistent_ram_zone *prz;
-       int ret;
+       int ret = -ENOMEM;
 
        prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL);
        if (!prz) {
                pr_err("persistent_ram: failed to allocate persistent ram zone\n");
-               return ERR_PTR(-ENOMEM);
+               goto err;
        }
 
        INIT_LIST_HEAD(&prz->node);
@@ -412,13 +412,13 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
        ret = persistent_ram_buffer_init(dev_name(dev), prz);
        if (ret) {
                pr_err("persistent_ram: failed to initialize buffer\n");
-               return ERR_PTR(ret);
+               goto err;
        }
 
        prz->ecc = ecc;
        ret = persistent_ram_init_ecc(prz, prz->buffer_size);
        if (ret)
-               return ERR_PTR(ret);
+               goto err;
 
        if (prz->buffer->sig == PERSISTENT_RAM_SIG) {
                if (buffer_size(prz) > prz->buffer_size ||
@@ -442,6 +442,9 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
        atomic_set(&prz->buffer->size, 0);
 
        return prz;
+err:
+       kfree(prz);
+       return ERR_PTR(ret);
 }
 
 struct persistent_ram_zone * __init
index bc723eff11aff0c988786690f2f83673372f007c..45c522cbe78446e0b0eb5e72fbf14e4a26f1d8b1 100644 (file)
@@ -85,7 +85,7 @@ static int timed_gpio_probe(struct platform_device *pdev)
        struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
        struct timed_gpio *cur_gpio;
        struct timed_gpio_data *gpio_data, *gpio_dat;
-       int i, j, ret = 0;
+       int i, ret;
 
        if (!pdata)
                return -EBUSY;
@@ -108,18 +108,12 @@ static int timed_gpio_probe(struct platform_device *pdev)
                gpio_dat->dev.get_time = gpio_get_time;
                gpio_dat->dev.enable = gpio_enable;
                ret = gpio_request(cur_gpio->gpio, cur_gpio->name);
-               if (ret >= 0) {
-                       ret = timed_output_dev_register(&gpio_dat->dev);
-                       if (ret < 0)
-                               gpio_free(cur_gpio->gpio);
-               }
+               if (ret < 0)
+                       goto err_out;
+               ret = timed_output_dev_register(&gpio_dat->dev);
                if (ret < 0) {
-                       for (j = 0; j < i; j++) {
-                               timed_output_dev_unregister(&gpio_data[i].dev);
-                               gpio_free(gpio_data[i].gpio);
-                       }
-                       kfree(gpio_data);
-                       return ret;
+                       gpio_free(cur_gpio->gpio);
+                       goto err_out;
                }
 
                gpio_dat->gpio = cur_gpio->gpio;
@@ -131,6 +125,15 @@ static int timed_gpio_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, gpio_data);
 
        return 0;
+
+err_out:
+       while (--i >= 0) {
+               timed_output_dev_unregister(&gpio_data[i].dev);
+               gpio_free(gpio_data[i].gpio);
+       }
+       kfree(gpio_data);
+
+       return ret;
 }
 
 static int timed_gpio_remove(struct platform_device *pdev)
index de2c8ea649653f9eb50be0eb0b571fdc53792483..ef07a02bf5421b662e95e3dffde2a0aebc42898a 100644 (file)
@@ -82,6 +82,7 @@ int iio_map_array_unregister(struct iio_dev *indio_dev,
                        ret = -ENODEV;
                        goto error_ret;
                }
+               i++;
        }
 error_ret:
        mutex_unlock(&iio_map_list_lock);
index d5ddac3d88311a64a0a31922b3a33cae8ed2d4a0..ebc2d0840caf4c867eb967c7ed6a8a5c93fee6f2 100644 (file)
@@ -108,7 +108,8 @@ static const int ak8975_index_to_reg[] = {
 static int ak8975_write_data(struct i2c_client *client,
                             u8 reg, u8 val, u8 mask, u8 shift)
 {
-       struct ak8975_data *data = i2c_get_clientdata(client);
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct ak8975_data *data = iio_priv(indio_dev);
        u8 regval;
        int ret;
 
@@ -159,7 +160,8 @@ static int ak8975_read_data(struct i2c_client *client,
  */
 static int ak8975_setup(struct i2c_client *client)
 {
-       struct ak8975_data *data = i2c_get_clientdata(client);
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct ak8975_data *data = iio_priv(indio_dev);
        u8 device_id;
        int ret;
 
@@ -509,6 +511,7 @@ static int ak8975_probe(struct i2c_client *client,
                goto exit_gpio;
        }
        data = iio_priv(indio_dev);
+       i2c_set_clientdata(client, indio_dev);
        /* Perform some basic start-of-day setup of the device. */
        err = ak8975_setup(client);
        if (err < 0) {
@@ -516,7 +519,6 @@ static int ak8975_probe(struct i2c_client *client,
                goto exit_free_iio;
        }
 
-       i2c_set_clientdata(client, indio_dev);
        data->client = client;
        mutex_init(&data->lock);
        data->eoc_irq = client->irq;
index 91dd3da70cb4961a9751c107bb9eb7565d48e3db..e00b416c4d331a428b1c7b8c0a799174fa96b33b 100644 (file)
@@ -521,7 +521,9 @@ static int hmc5843_detect(struct i2c_client *client,
 /* Called when we have found a new HMC5843. */
 static void hmc5843_init_client(struct i2c_client *client)
 {
-       struct hmc5843_data *data = i2c_get_clientdata(client);
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct hmc5843_data *data = iio_priv(indio_dev);
+
        hmc5843_set_meas_conf(client, data->meas_conf);
        hmc5843_set_rate(client, data->rate);
        hmc5843_configure(client, data->operating_mode);
index 43ebc43e6b9a1e1841fcb3dc87e4811216359311..1075fb1df0d9c04a967634e56eb2e5a581d3421b 100644 (file)
@@ -165,7 +165,7 @@ error:
 int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap)
 {
        int errno = -EFAULT;
-       const struct firmware *firmware;
+       const struct firmware *firmware = NULL;
        unsigned char *cmd_buf = NULL;
        char *fw1, *fw2;
        struct usb_device *dev = bus_adap->usb_dev;
index 3df5b4c58ecd73feeeff3d7b5edc9ccaa0d05fd0..620b8d54223d987f00dbf421fa7d0b34a25451d1 100644 (file)
@@ -803,9 +803,6 @@ static void pdev_shutdown(struct platform_device *device)
 static int pdev_probe(struct platform_device *device)
 {
        DBG("%s", device->name);
-       if (platform_driver_register(&omap_dmm_driver))
-               dev_err(&device->dev, "DMM registration failed\n");
-
        return drm_platform_init(&omap_drm_driver, device);
 }
 
@@ -833,6 +830,10 @@ struct platform_driver pdev = {
 static int __init omap_drm_init(void)
 {
        DBG("init");
+       if (platform_driver_register(&omap_dmm_driver)) {
+               /* we can continue on without DMM.. so not fatal */
+               dev_err(NULL, "DMM registration failed\n");
+       }
        return platform_driver_register(&pdev);
 }
 
index f7a9c122f596b7afbff8d175532345d93d89b173..c2d30a7112f30f8ae507e5a3e31b61b5d0c9184f 100644 (file)
@@ -8,5 +8,7 @@ TODO:
        - code review by USB developer community.
        - testing with as many devices as possible.
 
-Please send any patches for this driver to Chris Kelly <ckelly@ozmodevices.com>
+Please send any patches for this driver to
+Rupesh Gujare <rgujare@ozmodevices.com>
+Chris Kelly <ckelly@ozmodevices.com>
 and Greg Kroah-Hartman <gregkh@linuxfoundation.org>.
index 8b57b87edda47208c3737787b76593d4b9ab0e2c..4af1f8d4b9533816b9b571d6681a2abc5ae01d78 100644 (file)
@@ -1,10 +1,6 @@
-# Dependency on CONFIG_BROKEN is because there is a commit dependency
-# on a cleancache naming change to be submitted by Konrad Wilk
-# a39c00ded70339603ffe1b0ffdf3ade85bcf009a "Merge branch 'stable/cleancache.v13'
-# into linux-next.  Once this commit is present, BROKEN can be removed
 config RAMSTER
        bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem"
-       depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && BROKEN
+       depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM
        select LZO_COMPRESS
        select LZO_DECOMPRESS
        default n
index 66341dff8c99160e54c29dcdb45dabdb9a11c3f4..f9a4498984cc005f516a998a06bb061d2b9dcc8c 100644 (file)
@@ -3498,7 +3498,8 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32
 
                log_blk++;
 
-               for (seg_no = 0; seg_no < sizeof(ms_start_idx)/2; seg_no++) {
+               for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1;
+                               seg_no++) {
                        if (log_blk < ms_start_idx[seg_no+1])
                                break;
                }
index a7feb3e328a0e32c3c2ada165dcb939eddfee315..1dccd933a7e412603be0e1904c79273fd13d668f 100644 (file)
@@ -1000,6 +1000,11 @@ static int __devinit rtsx_probe(struct pci_dev *pci,
 
        rtsx_init_chip(dev->chip);
 
+       /* set the supported max_lun and max_id for the scsi host
+        * NOTE: the minimal value of max_id is 1 */
+       host->max_id = 1;
+       host->max_lun = dev->chip->max_lun;
+
        /* Start up our control thread */
        th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME);
        if (IS_ERR(th)) {
index 4e3d2c106af085d9d79d6cb6bcf356b0124bee9f..9b2e5c99870f3096571bea1eab7e24991948de86 100644 (file)
@@ -335,6 +335,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
        int sg_cnt, i, resid;
        int err = 0;
        long timeleft;
+       struct scatterlist *sg_ptr;
        u32 val = TRIG_DMA;
 
        if ((sg == NULL) || (num_sg <= 0) || !offset || !index)
@@ -371,7 +372,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
        sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
 
        resid = size;
-
+       sg_ptr = sg;
        chip->sgi = 0;
        /* Usually the next entry will be @sg@ + 1, but if this sg element
         * is part of a chained scatterlist, it could jump to the start of
@@ -379,14 +380,14 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
         * the proper sg
         */
        for (i = 0; i < *index; i++)
-               sg = sg_next(sg);
+               sg_ptr = sg_next(sg_ptr);
        for (i = *index; i < sg_cnt; i++) {
                dma_addr_t addr;
                unsigned int len;
                u8 option;
 
-               addr = sg_dma_address(sg);
-               len = sg_dma_len(sg);
+               addr = sg_dma_address(sg_ptr);
+               len = sg_dma_len(sg_ptr);
 
                RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
                             (unsigned int)addr, len);
@@ -415,7 +416,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
                if (!resid)
                        break;
 
-               sg = sg_next(sg);
+               sg_ptr = sg_next(sg_ptr);
        }
 
        RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
index ad54c2e5c9324b872b79cc82101eac0f7b0a6a13..f1701bc6e31238e2647be5edd8b58ea4ec4c1db9 100644 (file)
@@ -3114,7 +3114,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                        current->pid);
                if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
                                  &call_status->status)) {
-                       dev_warn(&sep->pdev->dev,
+                       dev_dbg(&sep->pdev->dev,
                                "[PID%d] dcb prep needed before send msg\n",
                                current->pid);
                        error = -EPROTO;
@@ -3122,9 +3122,9 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                }
 
                if (!arg) {
-                       dev_warn(&sep->pdev->dev,
+                       dev_dbg(&sep->pdev->dev,
                                "[PID%d] dcb null arg\n", current->pid);
-                       error = EINVAL;
+                       error = -EINVAL;
                        goto end_function;
                }
 
index 9fedc442a7790a3dce9a1f52dde38e4d6327f9cd..573c80003f0c75073ce35e6cac068e4df8d6b0ec 100644 (file)
@@ -35,10 +35,10 @@ static int vector[PIO2_CARDS_MAX];
 static int vector_num;
 static int level[PIO2_CARDS_MAX];
 static int level_num;
-static const char *variant[PIO2_CARDS_MAX];
+static char *variant[PIO2_CARDS_MAX];
 static int variant_num;
 
-static int loopback;
+static bool loopback;
 
 static int pio2_match(struct vme_dev *);
 static int __devinit pio2_probe(struct vme_dev *);
index 0ff8d7bbf2a7879af4536dfe37d2708c6890f525..774b0d4a7e068b811242924ff708ca48b0463d35 100644 (file)
@@ -655,6 +655,9 @@ bool KeybSetDefaultKey (
         return (false);
     }
 
+    if (uKeyLength > MAX_KEY_LEN)
+           return false;
+
     pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true;
     for(ii=0;ii<ETH_ALEN;ii++)
         pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
index 1463d76895f023fe339d3ea8cf3a67a16544706f..d59456c29df15db61b310281841c16164e6cc4dc 100644 (file)
@@ -565,7 +565,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
                        result = -ENOMEM;
                        break;
                }
-               pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
+               pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
                if (pNodeList == NULL) {
                        result = -ENOMEM;
                        break;
@@ -601,6 +601,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
                        }
                }
                if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) {
+                       kfree(pNodeList);
                        result = -EFAULT;
                        break;
                }
index 27bb523c8a97853db0c8ca8911b05062d1fd62cb..ee62a06a75f4bfb0dd06fc6b93a0dfa0c6c98769 100644 (file)
@@ -684,6 +684,9 @@ BOOL KeybSetDefaultKey(
         return (FALSE);
     }
 
+    if (uKeyLength > MAX_KEY_LEN)
+           return false;
+
     pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE;
     for (ii = 0; ii < ETH_ALEN; ii++)
         pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
index 94d5c35e22fbce7af40f176692e70b4a1712efa3..3650bbff7686243e54d1d925f5e8de17000eac84 100644 (file)
@@ -61,7 +61,7 @@ XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
                }
                temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
                /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
-               if ((temp & 0x88) == 0x80)
+               if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
                        data = 0; /* DDR */
                else
                        data = 1; /* DDRII */
index 2919924213c42fddacb5fa80802d943366f1d1a5..60d4adf99923a1dcf79fd2870dff084f9f9ef7b1 100644 (file)
@@ -152,6 +152,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
                pVBInfo->pXGINew_CR97 = &XG20_CR97;
 
        if (ChipType == XG27) {
+               unsigned char temp;
                pVBInfo->MCLKData
                        = (struct SiS_MCLKData *) XGI27New_MCLKData;
                pVBInfo->CR40 = XGI27_cr41;
@@ -162,7 +163,13 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
                pVBInfo->pCRDE = XG27_CRDE;
                pVBInfo->pSR40 = &XG27_SR40;
                pVBInfo->pSR41 = &XG27_SR41;
+               pVBInfo->SR15 = XG27_SR13;
 
+               /*Z11m DDR*/
+               temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
+               /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+               if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
+                       pVBInfo->pXGINew_CR97 = &Z11m_CR97;
        }
 
        if (ChipType >= XG20) {
index dddf261ed53d5e8d1a33dcb16a6db65fff0cccb1..e8d6f674b274f745da615283ca9ef119c34dcf69 100644 (file)
@@ -33,6 +33,13 @@ static struct XGI_ECLKDataStruct XGI340_ECLKData[] = {
        {0x5c, 0x23, 0x01, 166}
 };
 
+static unsigned char XG27_SR13[4][8] = {
+       {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */
+       {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */
+       {0x32, 0x32, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */
+       {0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}  /* SR1B */
+};
+
 static unsigned char XGI340_SR13[4][8] = {
        {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */
        {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */
@@ -71,7 +78,7 @@ static unsigned char XGI27_cr41[24][8] = {
        {0x20, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */
        {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */
        {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */
-       {0xB5, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7],
+       {0xB3, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7],
                                                               CR99[2:0],
                                                               CR45[3:0]*/
        {0xf0, 0xf5, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4 CR59 */
@@ -2803,6 +2810,8 @@ static unsigned char XG27_CRDE[2];
 static unsigned char XG27_SR40 = 0x04 ;
 static unsigned char XG27_SR41 = 0x00 ;
 
+static unsigned char Z11m_CR97 = 0x80 ;
+
 static struct XGI330_VCLKDataStruct XGI_VCLKData[] = {
        /* SR2B,SR2C,SR2D */
        {0x1B, 0xE1,  25}, /* 00 (25.175MHz) */
index 09caa4f2687e04f9a3ce353dbe96838a8b8f1928..917461c66014a23252399d2f7ac974c3777a0b8f 100644 (file)
@@ -267,33 +267,39 @@ static unsigned long obj_idx_to_offset(struct page *page,
        return off + obj_idx * class_size;
 }
 
+static void reset_page(struct page *page)
+{
+       clear_bit(PG_private, &page->flags);
+       clear_bit(PG_private_2, &page->flags);
+       set_page_private(page, 0);
+       page->mapping = NULL;
+       page->freelist = NULL;
+       reset_page_mapcount(page);
+}
+
 static void free_zspage(struct page *first_page)
 {
-       struct page *nextp, *tmp;
+       struct page *nextp, *tmp, *head_extra;
 
        BUG_ON(!is_first_page(first_page));
        BUG_ON(first_page->inuse);
 
-       nextp = (struct page *)page_private(first_page);
+       head_extra = (struct page *)page_private(first_page);
 
-       clear_bit(PG_private, &first_page->flags);
-       clear_bit(PG_private_2, &first_page->flags);
-       set_page_private(first_page, 0);
-       first_page->mapping = NULL;
-       first_page->freelist = NULL;
-       reset_page_mapcount(first_page);
+       reset_page(first_page);
        __free_page(first_page);
 
        /* zspage with only 1 system page */
-       if (!nextp)
+       if (!head_extra)
                return;
 
-       list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) {
+       list_for_each_entry_safe(nextp, tmp, &head_extra->lru, lru) {
                list_del(&nextp->lru);
-               clear_bit(PG_private_2, &nextp->flags);
-               nextp->index = 0;
+               reset_page(nextp);
                __free_page(nextp);
        }
+       reset_page(head_extra);
+       __free_page(head_extra);
 }
 
 /* Initialize a newly allocated zspage */
index 830657908db82d56627aec24ccc7f8844091c19a..c5eb3c33c3dbed83db4b647c07619e44f320659f 100644 (file)
@@ -122,6 +122,7 @@ struct ft_cmd {
        /* Local sense buffer */
        unsigned char ft_sense_buffer[TRANSPORT_SENSE_BUFFER];
        u32 was_ddp_setup:1;            /* Set only if ddp is setup */
+       u32 aborted:1;                  /* Set if aborted by reset or timeout */
        struct scatterlist *sg;         /* Set only if DDP is setup */
        u32 sg_cnt;                     /* No. of item in scatterlist */
 };
index 62dec9715ce57a37643e18d26caad8751349adab..a375f257aabcc80b19ca4d369ba4d54e5663881a 100644 (file)
@@ -121,6 +121,8 @@ int ft_queue_status(struct se_cmd *se_cmd)
        struct fc_exch *ep;
        size_t len;
 
+       if (cmd->aborted)
+               return 0;
        ft_dump_cmd(cmd, __func__);
        ep = fc_seq_exch(cmd->seq);
        lport = ep->lp;
@@ -187,6 +189,8 @@ int ft_write_pending(struct se_cmd *se_cmd)
 
        ft_dump_cmd(cmd, __func__);
 
+       if (cmd->aborted)
+               return 0;
        ep = fc_seq_exch(cmd->seq);
        lport = ep->lp;
        fp = fc_frame_alloc(lport, sizeof(*txrdy));
@@ -252,10 +256,10 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg)
        struct ft_cmd *cmd = arg;
        struct fc_frame_header *fh;
 
-       if (IS_ERR(fp)) {
+       if (unlikely(IS_ERR(fp))) {
                /* XXX need to find cmd if queued */
                cmd->seq = NULL;
-               transport_generic_free_cmd(&cmd->se_cmd, 0);
+               cmd->aborted = true;
                return;
        }
 
@@ -399,6 +403,8 @@ int ft_queue_tm_resp(struct se_cmd *se_cmd)
        struct se_tmr_req *tmr = se_cmd->se_tmr_req;
        enum fcp_resp_rsp_codes code;
 
+       if (cmd->aborted)
+               return 0;
        switch (tmr->response) {
        case TMR_FUNCTION_COMPLETE:
                code = FCP_TMF_CMPL;
index f357039349ba56b2b9ee2ed3b0b154bc7bd96fa9..2948dc9446196f2f2c9fa9c8b87dc85d16300f74 100644 (file)
@@ -300,6 +300,7 @@ static struct se_portal_group *ft_add_tpg(
 {
        struct ft_lport_acl *lacl;
        struct ft_tpg *tpg;
+       struct workqueue_struct *wq;
        unsigned long index;
        int ret;
 
@@ -321,18 +322,20 @@ static struct se_portal_group *ft_add_tpg(
        tpg->lport_acl = lacl;
        INIT_LIST_HEAD(&tpg->lun_list);
 
-       ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
-                               tpg, TRANSPORT_TPG_TYPE_NORMAL);
-       if (ret < 0) {
+       wq = alloc_workqueue("tcm_fc", 0, 1);
+       if (!wq) {
                kfree(tpg);
                return NULL;
        }
 
-       tpg->workqueue = alloc_workqueue("tcm_fc", 0, 1);
-       if (!tpg->workqueue) {
+       ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
+                               tpg, TRANSPORT_TPG_TYPE_NORMAL);
+       if (ret < 0) {
+               destroy_workqueue(wq);
                kfree(tpg);
                return NULL;
        }
+       tpg->workqueue = wq;
 
        mutex_lock(&ft_lport_lock);
        list_add_tail(&tpg->list, &lacl->tpg_list);
index 2b693eefac556064c6dd54747fa7516cdb008469..dc7c0db26e20f2aa8e1be2e0ec7b471cce59b0ab 100644 (file)
@@ -81,6 +81,8 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
        void *from;
        void *to = NULL;
 
+       if (cmd->aborted)
+               return 0;
        ep = fc_seq_exch(cmd->seq);
        lport = ep->lp;
        cmd->seq = lport->tt.seq_start_next(cmd->seq);
index 24145c30c9b069104564df2f9e14b19f8728740b..6cc4358f68c12ad2c779c7837207ce875968cf40 100644 (file)
@@ -1073,8 +1073,10 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
                    (new_serial.close_delay != port->close_delay) ||
                    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
                    ((new_serial.flags & ~ASYNC_USR_MASK) !=
-                    (port->flags & ~ASYNC_USR_MASK)))
+                    (port->flags & ~ASYNC_USR_MASK))) {
+                       tty_unlock();
                        return -EPERM;
+               }
                port->flags = ((port->flags & ~ASYNC_USR_MASK) |
                               (new_serial.flags & ASYNC_USR_MASK));
                state->custom_divisor = new_serial.custom_divisor;
index 5b149b466ec8a090d9707b51b18b4dd5123f768f..5c27f7e6c9f1b575130eb637c7ab970913851b6a 100644 (file)
@@ -1572,13 +1572,11 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
        do {
                struct uart_8250_port *up;
                struct uart_port *port;
-               bool skip;
 
                up = list_entry(l, struct uart_8250_port, list);
                port = &up->port;
-               skip = pass_counter && up->port.flags & UPF_IIR_ONCE;
 
-               if (!skip && port->handle_irq(port)) {
+               if (port->handle_irq(port)) {
                        handled = 1;
                        end = NULL;
                } else if (end == NULL)
@@ -2037,10 +2035,12 @@ static int serial8250_startup(struct uart_port *port)
                spin_unlock_irqrestore(&port->lock, flags);
 
                /*
-                * If the interrupt is not reasserted, setup a timer to
-                * kick the UART on a regular basis.
+                * If the interrupt is not reasserted, or we otherwise
+                * don't trust the iir, setup a timer to kick the UART
+                * on a regular basis.
                 */
-               if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
+               if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) ||
+                   up->port.flags & UPF_BUG_THRE) {
                        up->bugs |= UART_BUG_THRE;
                        pr_debug("ttyS%d - using backup timer\n",
                                 serial_index(port));
index da2b0b0a183fff27805e6c5509c655c88648353d..858dca865d6ab6b35fd04beb21c826d892050f76 100644 (file)
@@ -1096,7 +1096,7 @@ static int kt_serial_setup(struct serial_private *priv,
                           const struct pciserial_board *board,
                           struct uart_port *port, int idx)
 {
-       port->flags |= UPF_IIR_ONCE;
+       port->flags |= UPF_BUG_THRE;
        return skip_tx_en_setup(priv, board, port, idx);
 }
 
@@ -1118,18 +1118,6 @@ pci_xr17c154_setup(struct serial_private *priv,
        return pci_default_setup(priv, board, port, idx);
 }
 
-static int try_enable_msi(struct pci_dev *dev)
-{
-       /* use msi if available, but fallback to legacy otherwise */
-       pci_enable_msi(dev);
-       return 0;
-}
-
-static void disable_msi(struct pci_dev *dev)
-{
-       pci_disable_msi(dev);
-}
-
 #define PCI_VENDOR_ID_SBSMODULARIO     0x124B
 #define PCI_SUBVENDOR_ID_SBSMODULARIO  0x124B
 #define PCI_DEVICE_ID_OCTPRO           0x0001
@@ -1249,9 +1237,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .device         = PCI_DEVICE_ID_INTEL_PATSBURG_KT,
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
-               .init           = try_enable_msi,
                .setup          = kt_serial_setup,
-               .exit           = disable_msi,
        },
        /*
         * ITE
index 665beb68f67087a8dab9f73a8344b317964609c1..070b442c1f81abb08ffee6cd69e3ffe0ab87b209 100644 (file)
@@ -1041,7 +1041,7 @@ config SERIAL_OMAP
 
 config SERIAL_OMAP_CONSOLE
        bool "Console on OMAP serial port"
-       depends on SERIAL_OMAP
+       depends on SERIAL_OMAP=y
        select SERIAL_CORE_CONSOLE
        help
          Select this option if you would like to use omap serial port as
index e7903751e0582bb4a89a3c76e50a7f6f34342c6e..1f0330915d5a014dc9fb0cae1e66a631a703d0df 100644 (file)
@@ -556,7 +556,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
        res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res_mem)
                port->mapbase = res_mem->start;
-       else if (platp->mapbase)
+       else if (platp)
                port->mapbase = platp->mapbase;
        else
                return -EINVAL;
@@ -564,7 +564,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
        res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (res_irq)
                port->irq = res_irq->start;
-       else if (platp->irq)
+       else if (platp)
                port->irq = platp->irq;
 
        /* Check platform data first so we can override device node data */
index 0c65c9e669867bf70ed3c86e61e06b3846bf5b60..3d569cd68f58d5a6550fc37bb87f6d571eeb5de3 100644 (file)
@@ -1946,10 +1946,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
                goto unmap;
        }
 
-       /* Ensure interrupts from this UART are masked and cleared */
-       writew(0, uap->port.membase + UART011_IMSC);
-       writew(0xffff, uap->port.membase + UART011_ICR);
-
        uap->vendor = vendor;
        uap->lcrh_rx = vendor->lcrh_rx;
        uap->lcrh_tx = vendor->lcrh_tx;
@@ -1967,6 +1963,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
        uap->port.line = i;
        pl011_dma_probe(uap);
 
+       /* Ensure interrupts from this UART are masked and cleared */
+       writew(0, uap->port.membase + UART011_IMSC);
+       writew(0xffff, uap->port.membase + UART011_ICR);
+
        snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev));
 
        amba_ports[i] = uap;
index f9a6be7a9bed62103f24f461f593fec7a6a0a89c..3d7e1ee2fa57a4a6db1deb0a7a173b90769298a3 100644 (file)
@@ -389,6 +389,8 @@ static void atmel_start_rx(struct uart_port *port)
 {
        UART_PUT_CR(port, ATMEL_US_RSTSTA);  /* reset status and receiver */
 
+       UART_PUT_CR(port, ATMEL_US_RXEN);
+
        if (atmel_use_dma_rx(port)) {
                /* enable PDC controller */
                UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
@@ -404,6 +406,8 @@ static void atmel_start_rx(struct uart_port *port)
  */
 static void atmel_stop_rx(struct uart_port *port)
 {
+       UART_PUT_CR(port, ATMEL_US_RXDIS);
+
        if (atmel_use_dma_rx(port)) {
                /* disable PDC receive */
                UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS);
index e6c3dbd781d61fd21e9dcafd3d85c1a0799f1f66..836fe2731234bbeabe690ef41ee230588cedea1b 100644 (file)
@@ -154,10 +154,9 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
                port->x_char = 0;
                return IRQ_HANDLED;
        }
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-               clps711xuart_stop_tx(port);
-               return IRQ_HANDLED;
-       }
+
+       if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+               goto disable_tx_irq;
 
        count = port->fifosize >> 1;
        do {
@@ -171,8 +170,11 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit))
-               clps711xuart_stop_tx(port);
+       if (uart_circ_empty(xmit)) {
+       disable_tx_irq:
+               disable_irq_nosync(TX_IRQ(port));
+               tx_enabled(port) = 0;
+       }
 
        return IRQ_HANDLED;
 }
index 0121486ac4fafbf3bf162ef3744772255e8380e5..d00b38eb268e84cf58ca94f52735622198ad954c 100644 (file)
@@ -1381,29 +1381,24 @@ static int serial_omap_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       if (!request_mem_region(mem->start, resource_size(mem),
+       if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
                                pdev->dev.driver->name)) {
                dev_err(&pdev->dev, "memory region already claimed\n");
                return -EBUSY;
        }
 
        dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
-       if (!dma_rx) {
-               ret = -EINVAL;
-               goto err;
-       }
+       if (!dma_rx)
+               return -ENXIO;
 
        dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
-       if (!dma_tx) {
-               ret = -EINVAL;
-               goto err;
-       }
+       if (!dma_tx)
+               return -ENXIO;
+
+       up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL);
+       if (!up)
+               return -ENOMEM;
 
-       up = kzalloc(sizeof(*up), GFP_KERNEL);
-       if (up == NULL) {
-               ret = -ENOMEM;
-               goto do_release_region;
-       }
        up->pdev = pdev;
        up->port.dev = &pdev->dev;
        up->port.type = PORT_OMAP;
@@ -1423,16 +1418,17 @@ static int serial_omap_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n",
                                                                up->port.line);
                ret = -ENODEV;
-               goto err;
+               goto err_port_line;
        }
 
        sprintf(up->name, "OMAP UART%d", up->port.line);
        up->port.mapbase = mem->start;
-       up->port.membase = ioremap(mem->start, resource_size(mem));
+       up->port.membase = devm_ioremap(&pdev->dev, mem->start,
+                                               resource_size(mem));
        if (!up->port.membase) {
                dev_err(&pdev->dev, "can't ioremap UART\n");
                ret = -ENOMEM;
-               goto err;
+               goto err_ioremap;
        }
 
        up->port.flags = omap_up_info->flags;
@@ -1478,16 +1474,19 @@ static int serial_omap_probe(struct platform_device *pdev)
 
        ret = uart_add_one_port(&serial_omap_reg, &up->port);
        if (ret != 0)
-               goto do_release_region;
+               goto err_add_port;
 
        pm_runtime_put(&pdev->dev);
        platform_set_drvdata(pdev, up);
        return 0;
-err:
+
+err_add_port:
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+err_ioremap:
+err_port_line:
        dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
                                pdev->id, __func__, ret);
-do_release_region:
-       release_mem_region(mem->start, resource_size(mem));
        return ret;
 }
 
@@ -1499,8 +1498,6 @@ static int serial_omap_remove(struct platform_device *dev)
                pm_runtime_disable(&up->pdev->dev);
                uart_remove_one_port(&serial_omap_reg, &up->port);
                pm_qos_remove_request(&up->pm_qos_request);
-
-               kfree(up);
        }
 
        platform_set_drvdata(dev, NULL);
index 08b9962b8fdab8813bbb453f120870eb1fbb96d3..c2816f4948070157f1c969898bfde97b58bd6841 100644 (file)
@@ -210,6 +210,7 @@ enum {
 #define CMITC_UARTCLK   192000000 /* 192.0000 MHz */
 #define FRI2_64_UARTCLK  64000000 /*  64.0000 MHz */
 #define FRI2_48_UARTCLK  48000000 /*  48.0000 MHz */
+#define NTC1_UARTCLK     64000000 /*  64.0000 MHz */
 
 struct pch_uart_buffer {
        unsigned char *buf;
@@ -384,6 +385,12 @@ static int pch_uart_get_uartclk(void)
        if (cmp && strstr(cmp, "Fish River Island II"))
                return FRI2_48_UARTCLK;
 
+       /* Kontron COMe-mTT10 (nanoETXexpress-TT) */
+       cmp = dmi_get_system_info(DMI_BOARD_NAME);
+       if (cmp && (strstr(cmp, "COMe-mTT") ||
+                   strstr(cmp, "nanoETXexpress-TT")))
+               return NTC1_UARTCLK;
+
        return DEFAULT_UARTCLK;
 }
 
@@ -1440,9 +1447,11 @@ static int pch_uart_verify_port(struct uart_port *port,
                        __func__);
                return -EOPNOTSUPP;
 #endif
-               priv->use_dma = 1;
                priv->use_dma_flag = 1;
                dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n");
+               if (!priv->use_dma)
+                       pch_request_dma(port);
+               priv->use_dma = 1;
        }
 
        return 0;
@@ -1651,6 +1660,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
        }
 
        pci_enable_msi(pdev);
+       pci_set_master(pdev);
 
        iobase = pci_resource_start(pdev, 0);
        mapbase = pci_resource_start(pdev, 1);
index de249d265beca004c2dc59dc663976baff63b746..d8b0aee35632ede1a2f98ea7a1a751926a3c3e0a 100644 (file)
@@ -982,6 +982,7 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
 
        ucon &= ucon_mask;
        wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
+       wr_regl(port, S3C2410_ULCON, cfg->ulcon);
 
        /* reset both fifos */
        wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
index bf461cf99616c04aa9e2655eaee8e62d21c782db..3158e17b665cc6fb1c5eb214674610bd42611235 100644 (file)
@@ -355,9 +355,6 @@ static void sci_serial_out(struct uart_port *p, int offset, int value)
                WARN(1, "Invalid register access\n");
 }
 
-#define sci_in(up, offset)             (up->serial_in(up, offset))
-#define sci_out(up, offset, value)     (up->serial_out(up, offset, value))
-
 static int sci_probe_regmap(struct plat_sci_port *cfg)
 {
        switch (cfg->type) {
@@ -422,9 +419,9 @@ static int sci_poll_get_char(struct uart_port *port)
        int c;
 
        do {
-               status = sci_in(port, SCxSR);
+               status = serial_port_in(port, SCxSR);
                if (status & SCxSR_ERRORS(port)) {
-                       sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+                       serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
                        continue;
                }
                break;
@@ -433,11 +430,11 @@ static int sci_poll_get_char(struct uart_port *port)
        if (!(status & SCxSR_RDxF(port)))
                return NO_POLL_CHAR;
 
-       c = sci_in(port, SCxRDR);
+       c = serial_port_in(port, SCxRDR);
 
        /* Dummy read */
-       sci_in(port, SCxSR);
-       sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+       serial_port_in(port, SCxSR);
+       serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
 
        return c;
 }
@@ -448,11 +445,11 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
        unsigned short status;
 
        do {
-               status = sci_in(port, SCxSR);
+               status = serial_port_in(port, SCxSR);
        } while (!(status & SCxSR_TDxE(port)));
 
-       sci_out(port, SCxTDR, c);
-       sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
+       serial_port_out(port, SCxTDR, c);
+       serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
 }
 #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
 
@@ -480,10 +477,10 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
            ((!(cflag & CRTSCTS)))) {
                unsigned short status;
 
-               status = sci_in(port, SCSPTR);
+               status = serial_port_in(port, SCSPTR);
                status &= ~SCSPTR_CTSIO;
                status |= SCSPTR_RTSIO;
-               sci_out(port, SCSPTR, status); /* Set RTS = 1 */
+               serial_port_out(port, SCSPTR, status); /* Set RTS = 1 */
        }
 }
 
@@ -493,13 +490,13 @@ static int sci_txfill(struct uart_port *port)
 
        reg = sci_getreg(port, SCTFDR);
        if (reg->size)
-               return sci_in(port, SCTFDR) & 0xff;
+               return serial_port_in(port, SCTFDR) & 0xff;
 
        reg = sci_getreg(port, SCFDR);
        if (reg->size)
-               return sci_in(port, SCFDR) >> 8;
+               return serial_port_in(port, SCFDR) >> 8;
 
-       return !(sci_in(port, SCxSR) & SCI_TDRE);
+       return !(serial_port_in(port, SCxSR) & SCI_TDRE);
 }
 
 static int sci_txroom(struct uart_port *port)
@@ -513,13 +510,13 @@ static int sci_rxfill(struct uart_port *port)
 
        reg = sci_getreg(port, SCRFDR);
        if (reg->size)
-               return sci_in(port, SCRFDR) & 0xff;
+               return serial_port_in(port, SCRFDR) & 0xff;
 
        reg = sci_getreg(port, SCFDR);
        if (reg->size)
-               return sci_in(port, SCFDR) & ((port->fifosize << 1) - 1);
+               return serial_port_in(port, SCFDR) & ((port->fifosize << 1) - 1);
 
-       return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
+       return (serial_port_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
 }
 
 /*
@@ -547,14 +544,14 @@ static void sci_transmit_chars(struct uart_port *port)
        unsigned short ctrl;
        int count;
 
-       status = sci_in(port, SCxSR);
+       status = serial_port_in(port, SCxSR);
        if (!(status & SCxSR_TDxE(port))) {
-               ctrl = sci_in(port, SCSCR);
+               ctrl = serial_port_in(port, SCSCR);
                if (uart_circ_empty(xmit))
                        ctrl &= ~SCSCR_TIE;
                else
                        ctrl |= SCSCR_TIE;
-               sci_out(port, SCSCR, ctrl);
+               serial_port_out(port, SCSCR, ctrl);
                return;
        }
 
@@ -573,27 +570,27 @@ static void sci_transmit_chars(struct uart_port *port)
                        break;
                }
 
-               sci_out(port, SCxTDR, c);
+               serial_port_out(port, SCxTDR, c);
 
                port->icount.tx++;
        } while (--count > 0);
 
-       sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+       serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
        if (uart_circ_empty(xmit)) {
                sci_stop_tx(port);
        } else {
-               ctrl = sci_in(port, SCSCR);
+               ctrl = serial_port_in(port, SCSCR);
 
                if (port->type != PORT_SCI) {
-                       sci_in(port, SCxSR); /* Dummy read */
-                       sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+                       serial_port_in(port, SCxSR); /* Dummy read */
+                       serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
                }
 
                ctrl |= SCSCR_TIE;
-               sci_out(port, SCSCR, ctrl);
+               serial_port_out(port, SCSCR, ctrl);
        }
 }
 
@@ -608,7 +605,7 @@ static void sci_receive_chars(struct uart_port *port)
        unsigned short status;
        unsigned char flag;
 
-       status = sci_in(port, SCxSR);
+       status = serial_port_in(port, SCxSR);
        if (!(status & SCxSR_RDxF(port)))
                return;
 
@@ -621,7 +618,7 @@ static void sci_receive_chars(struct uart_port *port)
                        break;
 
                if (port->type == PORT_SCI) {
-                       char c = sci_in(port, SCxRDR);
+                       char c = serial_port_in(port, SCxRDR);
                        if (uart_handle_sysrq_char(port, c) ||
                            sci_port->break_flag)
                                count = 0;
@@ -629,9 +626,9 @@ static void sci_receive_chars(struct uart_port *port)
                                tty_insert_flip_char(tty, c, TTY_NORMAL);
                } else {
                        for (i = 0; i < count; i++) {
-                               char c = sci_in(port, SCxRDR);
+                               char c = serial_port_in(port, SCxRDR);
 
-                               status = sci_in(port, SCxSR);
+                               status = serial_port_in(port, SCxSR);
 #if defined(CONFIG_CPU_SH3)
                                /* Skip "chars" during break */
                                if (sci_port->break_flag) {
@@ -672,8 +669,8 @@ static void sci_receive_chars(struct uart_port *port)
                        }
                }
 
-               sci_in(port, SCxSR); /* dummy read */
-               sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+               serial_port_in(port, SCxSR); /* dummy read */
+               serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
 
                copied += count;
                port->icount.rx += count;
@@ -683,8 +680,8 @@ static void sci_receive_chars(struct uart_port *port)
                /* Tell the rest of the system the news. New characters! */
                tty_flip_buffer_push(tty);
        } else {
-               sci_in(port, SCxSR); /* dummy read */
-               sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+               serial_port_in(port, SCxSR); /* dummy read */
+               serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
        }
 }
 
@@ -726,7 +723,7 @@ static void sci_break_timer(unsigned long data)
 static int sci_handle_errors(struct uart_port *port)
 {
        int copied = 0;
-       unsigned short status = sci_in(port, SCxSR);
+       unsigned short status = serial_port_in(port, SCxSR);
        struct tty_struct *tty = port->state->port.tty;
        struct sci_port *s = to_sci_port(port);
 
@@ -804,8 +801,8 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
        if (!reg->size)
                return 0;
 
-       if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
-               sci_out(port, SCLSR, 0);
+       if ((serial_port_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
+               serial_port_out(port, SCLSR, 0);
 
                port->icount.overrun++;
 
@@ -822,7 +819,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
 static int sci_handle_breaks(struct uart_port *port)
 {
        int copied = 0;
-       unsigned short status = sci_in(port, SCxSR);
+       unsigned short status = serial_port_in(port, SCxSR);
        struct tty_struct *tty = port->state->port.tty;
        struct sci_port *s = to_sci_port(port);
 
@@ -859,8 +856,8 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
        struct sci_port *s = to_sci_port(port);
 
        if (s->chan_rx) {
-               u16 scr = sci_in(port, SCSCR);
-               u16 ssr = sci_in(port, SCxSR);
+               u16 scr = serial_port_in(port, SCSCR);
+               u16 ssr = serial_port_in(port, SCxSR);
 
                /* Disable future Rx interrupts */
                if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
@@ -869,9 +866,9 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
                } else {
                        scr &= ~SCSCR_RIE;
                }
-               sci_out(port, SCSCR, scr);
+               serial_port_out(port, SCSCR, scr);
                /* Clear current interrupt */
-               sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
+               serial_port_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
                dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n",
                        jiffies, s->rx_timeout);
                mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
@@ -909,15 +906,15 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
        if (port->type == PORT_SCI) {
                if (sci_handle_errors(port)) {
                        /* discard character in rx buffer */
-                       sci_in(port, SCxSR);
-                       sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+                       serial_port_in(port, SCxSR);
+                       serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
                }
        } else {
                sci_handle_fifo_overrun(port);
                sci_rx_interrupt(irq, ptr);
        }
 
-       sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+       serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
 
        /* Kick the transmission */
        sci_tx_interrupt(irq, ptr);
@@ -931,7 +928,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
 
        /* Handle BREAKs */
        sci_handle_breaks(port);
-       sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
+       serial_port_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
 
        return IRQ_HANDLED;
 }
@@ -955,8 +952,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
        struct sci_port *s = to_sci_port(port);
        irqreturn_t ret = IRQ_NONE;
 
-       ssr_status = sci_in(port, SCxSR);
-       scr_status = sci_in(port, SCSCR);
+       ssr_status = serial_port_in(port, SCxSR);
+       scr_status = serial_port_in(port, SCSCR);
        err_enabled = scr_status & port_rx_irq_mask(port);
 
        /* Tx Interrupt */
@@ -1170,7 +1167,7 @@ static void sci_free_gpios(struct sci_port *port)
 
 static unsigned int sci_tx_empty(struct uart_port *port)
 {
-       unsigned short status = sci_in(port, SCxSR);
+       unsigned short status = serial_port_in(port, SCxSR);
        unsigned short in_tx_fifo = sci_txfill(port);
 
        return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
@@ -1198,7 +1195,7 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
                 */
                reg = sci_getreg(port, SCFCR);
                if (reg->size)
-                       sci_out(port, SCFCR, sci_in(port, SCFCR) | 1);
+                       serial_port_out(port, SCFCR, serial_port_in(port, SCFCR) | 1);
        }
 }
 
@@ -1240,8 +1237,8 @@ static void sci_dma_tx_complete(void *arg)
        } else {
                s->cookie_tx = -EINVAL;
                if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-                       u16 ctrl = sci_in(port, SCSCR);
-                       sci_out(port, SCSCR, ctrl & ~SCSCR_TIE);
+                       u16 ctrl = serial_port_in(port, SCSCR);
+                       serial_port_out(port, SCSCR, ctrl & ~SCSCR_TIE);
                }
        }
 
@@ -1494,13 +1491,13 @@ static void sci_start_tx(struct uart_port *port)
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
        if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-               u16 new, scr = sci_in(port, SCSCR);
+               u16 new, scr = serial_port_in(port, SCSCR);
                if (s->chan_tx)
                        new = scr | 0x8000;
                else
                        new = scr & ~0x8000;
                if (new != scr)
-                       sci_out(port, SCSCR, new);
+                       serial_port_out(port, SCSCR, new);
        }
 
        if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
@@ -1512,8 +1509,8 @@ static void sci_start_tx(struct uart_port *port)
 
        if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
                /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
-               ctrl = sci_in(port, SCSCR);
-               sci_out(port, SCSCR, ctrl | SCSCR_TIE);
+               ctrl = serial_port_in(port, SCSCR);
+               serial_port_out(port, SCSCR, ctrl | SCSCR_TIE);
        }
 }
 
@@ -1522,40 +1519,40 @@ static void sci_stop_tx(struct uart_port *port)
        unsigned short ctrl;
 
        /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
-       ctrl = sci_in(port, SCSCR);
+       ctrl = serial_port_in(port, SCSCR);
 
        if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
                ctrl &= ~0x8000;
 
        ctrl &= ~SCSCR_TIE;
 
-       sci_out(port, SCSCR, ctrl);
+       serial_port_out(port, SCSCR, ctrl);
 }
 
 static void sci_start_rx(struct uart_port *port)
 {
        unsigned short ctrl;
 
-       ctrl = sci_in(port, SCSCR) | port_rx_irq_mask(port);
+       ctrl = serial_port_in(port, SCSCR) | port_rx_irq_mask(port);
 
        if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
                ctrl &= ~0x4000;
 
-       sci_out(port, SCSCR, ctrl);
+       serial_port_out(port, SCSCR, ctrl);
 }
 
 static void sci_stop_rx(struct uart_port *port)
 {
        unsigned short ctrl;
 
-       ctrl = sci_in(port, SCSCR);
+       ctrl = serial_port_in(port, SCSCR);
 
        if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
                ctrl &= ~0x4000;
 
        ctrl &= ~port_rx_irq_mask(port);
 
-       sci_out(port, SCSCR, ctrl);
+       serial_port_out(port, SCSCR, ctrl);
 }
 
 static void sci_enable_ms(struct uart_port *port)
@@ -1589,13 +1586,13 @@ static void rx_timer_fn(unsigned long arg)
 {
        struct sci_port *s = (struct sci_port *)arg;
        struct uart_port *port = &s->port;
-       u16 scr = sci_in(port, SCSCR);
+       u16 scr = serial_port_in(port, SCSCR);
 
        if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
                scr &= ~0x4000;
                enable_irq(s->cfg->irqs[1]);
        }
-       sci_out(port, SCSCR, scr | SCSCR_RIE);
+       serial_port_out(port, SCSCR, scr | SCSCR_RIE);
        dev_dbg(port->dev, "DMA Rx timed out\n");
        schedule_work(&s->work_rx);
 }
@@ -1776,14 +1773,14 @@ static void sci_reset(struct uart_port *port)
        unsigned int status;
 
        do {
-               status = sci_in(port, SCxSR);
+               status = serial_port_in(port, SCxSR);
        } while (!(status & SCxSR_TEND(port)));
 
-       sci_out(port, SCSCR, 0x00);     /* TE=0, RE=0, CKE1=0 */
+       serial_port_out(port, SCSCR, 0x00);     /* TE=0, RE=0, CKE1=0 */
 
        reg = sci_getreg(port, SCFCR);
        if (reg->size)
-               sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+               serial_port_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
 }
 
 static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
@@ -1812,7 +1809,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
        sci_reset(port);
 
-       smr_val = sci_in(port, SCSMR) & 3;
+       smr_val = serial_port_in(port, SCSMR) & 3;
 
        if ((termios->c_cflag & CSIZE) == CS7)
                smr_val |= 0x40;
@@ -1825,19 +1822,19 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
        uart_update_timeout(port, termios->c_cflag, baud);
 
-       sci_out(port, SCSMR, smr_val);
+       serial_port_out(port, SCSMR, smr_val);
 
        dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
                s->cfg->scscr);
 
        if (t > 0) {
                if (t >= 256) {
-                       sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
+                       serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1);
                        t >>= 2;
                } else
-                       sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3);
+                       serial_port_out(port, SCSMR, serial_port_in(port, SCSMR) & ~3);
 
-               sci_out(port, SCBRR, t);
+               serial_port_out(port, SCBRR, t);
                udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
        }
 
@@ -1845,7 +1842,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
        reg = sci_getreg(port, SCFCR);
        if (reg->size) {
-               unsigned short ctrl = sci_in(port, SCFCR);
+               unsigned short ctrl = serial_port_in(port, SCFCR);
 
                if (s->cfg->capabilities & SCIx_HAVE_RTSCTS) {
                        if (termios->c_cflag & CRTSCTS)
@@ -1861,10 +1858,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
                 */
                ctrl &= ~(SCFCR_RFRST | SCFCR_TFRST);
 
-               sci_out(port, SCFCR, ctrl);
+               serial_port_out(port, SCFCR, ctrl);
        }
 
-       sci_out(port, SCSCR, s->cfg->scscr);
+       serial_port_out(port, SCSCR, s->cfg->scscr);
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
        /*
@@ -2166,7 +2163,7 @@ static void serial_console_write(struct console *co, const char *s,
 
        /* wait until fifo is empty and last bit has been transmitted */
        bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
-       while ((sci_in(port, SCxSR) & bits) != bits)
+       while ((serial_port_in(port, SCxSR) & bits) != bits)
                cpu_relax();
 
        sci_port_disable(sci_port);
@@ -2260,12 +2257,12 @@ static int sci_runtime_suspend(struct device *dev)
        if (uart_console(port)) {
                struct plat_sci_reg *reg;
 
-               sci_port->saved_smr = sci_in(port, SCSMR);
-               sci_port->saved_brr = sci_in(port, SCBRR);
+               sci_port->saved_smr = serial_port_in(port, SCSMR);
+               sci_port->saved_brr = serial_port_in(port, SCBRR);
 
                reg = sci_getreg(port, SCFCR);
                if (reg->size)
-                       sci_port->saved_fcr = sci_in(port, SCFCR);
+                       sci_port->saved_fcr = serial_port_in(port, SCFCR);
                else
                        sci_port->saved_fcr = 0;
        }
@@ -2279,13 +2276,13 @@ static int sci_runtime_resume(struct device *dev)
 
        if (uart_console(port)) {
                sci_reset(port);
-               sci_out(port, SCSMR, sci_port->saved_smr);
-               sci_out(port, SCBRR, sci_port->saved_brr);
+               serial_port_out(port, SCSMR, sci_port->saved_smr);
+               serial_port_out(port, SCBRR, sci_port->saved_brr);
 
                if (sci_port->saved_fcr)
-                       sci_out(port, SCFCR, sci_port->saved_fcr);
+                       serial_port_out(port, SCFCR, sci_port->saved_fcr);
 
-               sci_out(port, SCSCR, sci_port->cfg->scscr);
+               serial_port_out(port, SCSCR, sci_port->cfg->scscr);
        }
        return 0;
 }
index a1a2d364f92b6a5fa92e865e4fd91954ce6119dc..4c22a1529aac7c2304aeb15b302a6c9021c1174d 100644 (file)
     defined(CONFIG_ARCH_SH7372) || \
     defined(CONFIG_ARCH_R8A7740)
 
-# define SCxSR_RDxF_CLEAR(port)         (sci_in(port, SCxSR) & 0xfffc)
-# define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73)
-# define SCxSR_TDxE_CLEAR(port)         (sci_in(port, SCxSR) & 0xffdf)
-# define SCxSR_BREAK_CLEAR(port) (sci_in(port, SCxSR) & 0xffe3)
+# define SCxSR_RDxF_CLEAR(port)         (serial_port_in(port, SCxSR) & 0xfffc)
+# define SCxSR_ERROR_CLEAR(port) (serial_port_in(port, SCxSR) & 0xfd73)
+# define SCxSR_TDxE_CLEAR(port)         (serial_port_in(port, SCxSR) & 0xffdf)
+# define SCxSR_BREAK_CLEAR(port) (serial_port_in(port, SCxSR) & 0xffe3)
 #else
 # define SCxSR_RDxF_CLEAR(port)         (((port)->type == PORT_SCI) ? 0xbc : 0x00fc)
 # define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073)
index 3bdd4b19dd06b6c90dd6cea689f3a31bb54454c4..2156188db4a64e73d41d8a7aa5cc8d4980f356e1 100644 (file)
@@ -2932,11 +2932,10 @@ static int __init con_init(void)
        gotoxy(vc, vc->vc_x, vc->vc_y);
        csi_J(vc, 0);
        update_screen(vc);
-       pr_info("Console: %s %s %dx%d",
+       pr_info("Console: %s %s %dx%d\n",
                vc->vc_can_do_color ? "colour" : "mono",
                display_desc, vc->vc_cols, vc->vc_rows);
        printable = 1;
-       printk("\n");
 
        console_unlock();
 
index cbd8f5f805962a2d1e6b87bce4f7c37137bb5e4c..76316a33061b91b48a62a60f6be1b921227c6ed8 100644 (file)
@@ -2,14 +2,6 @@
 # USB device configuration
 #
 
-menuconfig USB_SUPPORT
-       bool "USB support"
-       depends on HAS_IOMEM
-       default y
-       ---help---
-         This option adds core support for Universal Serial Bus (USB).
-         You will also need drivers from the following menu to make use of it.
-
 # many non-PCI SOC chips embed OHCI
 config USB_ARCH_HAS_OHCI
        boolean
@@ -63,6 +55,14 @@ config USB_ARCH_HAS_XHCI
        boolean
        default PCI
 
+menuconfig USB_SUPPORT
+       bool "USB support"
+       depends on HAS_IOMEM
+       default y
+       ---help---
+         This option adds core support for Universal Serial Bus (USB).
+         You will also need drivers from the following menu to make use of it.
+
 if USB_SUPPORT
 
 config USB_COMMON
index f8e2d6d52e5c4bf645c3679807456d8a4303ec9d..9a56635dc19ceb980ea71986dd97bb9d9ea725e8 100644 (file)
@@ -1189,8 +1189,13 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
        if (status == 0) {
                status = usb_suspend_device(udev, msg);
 
-               /* Again, ignore errors during system sleep transitions */
-               if (!PMSG_IS_AUTO(msg))
+               /*
+                * Ignore errors from non-root-hub devices during
+                * system sleep transitions.  For the most part,
+                * these devices should go to low power anyway when
+                * the entire bus is suspended.
+                */
+               if (udev->parent && !PMSG_IS_AUTO(msg))
                        status = 0;
        }
 
index 9d7fc9a399338854426bb2a23c6990e4077b3525..140d3e11f2124291f7051fb6e743a10f74c8f541 100644 (file)
@@ -1978,6 +1978,18 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
        if (status == 0) {
                usb_set_device_state(rhdev, USB_STATE_SUSPENDED);
                hcd->state = HC_STATE_SUSPENDED;
+
+               /* Did we race with a root-hub wakeup event? */
+               if (rhdev->do_remote_wakeup) {
+                       char    buffer[6];
+
+                       status = hcd->driver->hub_status_data(hcd, buffer);
+                       if (status != 0) {
+                               dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n");
+                               hcd_bus_resume(rhdev, PMSG_AUTO_RESUME);
+                               status = -EBUSY;
+                       }
+               }
        } else {
                spin_lock_irq(&hcd_root_hub_lock);
                if (!HCD_DEAD(hcd)) {
index 28664eb7f5554cfe07f017d9d5e24be65671e85b..ec6c97dadbe4dba5e3cf8a47980e23256a44bff5 100644 (file)
@@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)
 {
        struct usb_device       *udev = *pdev;
        int                     i;
-       struct usb_hcd          *hcd = bus_to_hcd(udev->bus);
 
        /* mark the device as inactive, so any further urb submissions for
         * this device (and any of its children) will fail immediately.
@@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev)
         * so that the hardware is now fully quiesced.
         */
        dev_dbg (&udev->dev, "unregistering device\n");
-       mutex_lock(hcd->bandwidth_mutex);
        usb_disable_device(udev, 0);
-       mutex_unlock(hcd->bandwidth_mutex);
        usb_hcd_synchronize_unlinks(udev);
 
        usb_remove_ep_devs(&udev->ep0);
@@ -3163,6 +3160,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
        if (retval)
                goto fail;
 
+       /*
+        * Some superspeed devices have finished the link training process
+        * and attached to a superspeed hub port, but the device descriptor
+        * got from those devices show they aren't superspeed devices. Warm
+        * reset the port attached by the devices can fix them.
+        */
+       if ((udev->speed == USB_SPEED_SUPER) &&
+                       (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
+               dev_err(&udev->dev, "got a wrong device descriptor, "
+                               "warm reset device\n");
+               hub_port_reset(hub, port1, udev,
+                               HUB_BH_RESET_TIME, true);
+               retval = -EINVAL;
+               goto fail;
+       }
+
        if (udev->descriptor.bMaxPacketSize0 == 0xff ||
                        udev->speed == USB_SPEED_SUPER)
                i = 512;
index b3bdfede45e68721376c381a42950044da9625ad..ca717da3be95ddbab8d4b5211e78af699fcb1399 100644 (file)
@@ -308,7 +308,8 @@ static void sg_complete(struct urb *urb)
                                retval = usb_unlink_urb(io->urbs [i]);
                                if (retval != -EINPROGRESS &&
                                    retval != -ENODEV &&
-                                   retval != -EBUSY)
+                                   retval != -EBUSY &&
+                                   retval != -EIDRM)
                                        dev_err(&io->dev->dev,
                                                "%s, unlink --> %d\n",
                                                __func__, retval);
@@ -317,7 +318,6 @@ static void sg_complete(struct urb *urb)
                }
                spin_lock(&io->lock);
        }
-       urb->dev = NULL;
 
        /* on the last completion, signal usb_sg_wait() */
        io->bytes += urb->actual_length;
@@ -524,7 +524,6 @@ void usb_sg_wait(struct usb_sg_request *io)
                case -ENXIO:    /* hc didn't queue this one */
                case -EAGAIN:
                case -ENOMEM:
-                       io->urbs[i]->dev = NULL;
                        retval = 0;
                        yield();
                        break;
@@ -542,7 +541,6 @@ void usb_sg_wait(struct usb_sg_request *io)
 
                        /* fail any uncompleted urbs */
                default:
-                       io->urbs[i]->dev = NULL;
                        io->urbs[i]->status = retval;
                        dev_dbg(&io->dev->dev, "%s, submit --> %d\n",
                                __func__, retval);
@@ -593,7 +591,10 @@ void usb_sg_cancel(struct usb_sg_request *io)
                        if (!io->urbs [i]->dev)
                                continue;
                        retval = usb_unlink_urb(io->urbs [i]);
-                       if (retval != -EINPROGRESS && retval != -EBUSY)
+                       if (retval != -EINPROGRESS
+                                       && retval != -ENODEV
+                                       && retval != -EBUSY
+                                       && retval != -EIDRM)
                                dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
                                        __func__, retval);
                }
@@ -1135,8 +1136,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
  * Deallocates hcd/hardware state for the endpoints (nuking all or most
  * pending urbs) and usbcore state for the interfaces, so that usbcore
  * must usb_set_configuration() before any interfaces could be used.
- *
- * Must be called with hcd->bandwidth_mutex held.
  */
 void usb_disable_device(struct usb_device *dev, int skip_ep0)
 {
@@ -1189,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                        usb_disable_endpoint(dev, i + USB_DIR_IN, false);
                }
                /* Remove endpoints from the host controller internal state */
+               mutex_lock(hcd->bandwidth_mutex);
                usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+               mutex_unlock(hcd->bandwidth_mutex);
                /* Second pass: remove endpoint pointers */
        }
        for (i = skip_ep0; i < 16; ++i) {
@@ -1749,7 +1750,6 @@ free_interfaces:
        /* if it's already configured, clear out old state first.
         * getting rid of old interfaces means unbinding their drivers.
         */
-       mutex_lock(hcd->bandwidth_mutex);
        if (dev->state != USB_STATE_ADDRESS)
                usb_disable_device(dev, 1);     /* Skip ep0 */
 
@@ -1762,6 +1762,7 @@ free_interfaces:
         * host controller will not allow submissions to dropped endpoints.  If
         * this call fails, the device state is unchanged.
         */
+       mutex_lock(hcd->bandwidth_mutex);
        ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
        if (ret < 0) {
                mutex_unlock(hcd->bandwidth_mutex);
index 7239a73c1b8c840f89fb22ab19b351bec1dd2b53..cd9b3a2cd8a73cef173d19971213778343edad30 100644 (file)
@@ -539,6 +539,10 @@ EXPORT_SYMBOL_GPL(usb_submit_urb);
  * never submitted, or it was unlinked before, or the hardware is already
  * finished with it), even if the completion handler has not yet run.
  *
+ * The URB must not be deallocated while this routine is running.  In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
  * Unlinking and Endpoint Queues:
  *
  * [The behaviors and guarantees described below do not apply to virtual
@@ -603,6 +607,10 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
  * with error -EPERM.  Thus even if the URB's completion handler always
  * tries to resubmit, it will not succeed and the URB will become idle.
  *
+ * The URB must not be deallocated while this routine is running.  In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
  * This routine may not be used in an interrupt context (such as a bottom
  * half or a completion handler), or when holding a spinlock, or in other
  * situations where the caller can't schedule().
@@ -640,6 +648,10 @@ EXPORT_SYMBOL_GPL(usb_kill_urb);
  * with error -EPERM.  Thus even if the URB's completion handler always
  * tries to resubmit, it will not succeed and the URB will become idle.
  *
+ * The URB must not be deallocated while this routine is running.  In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
  * This routine may not be used in an interrupt context (such as a bottom
  * half or a completion handler), or when holding a spinlock, or in other
  * situations where the caller can't schedule().
index 7bd815a507e8c3c94f9faaf0545b465f7ed3a781..99b58d84553acd56263ad0ed1e774f9d9eb2afec 100644 (file)
@@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
 
        for (i = 0; i < dwc->num_event_buffers; i++) {
                evt = dwc->ev_buffs[i];
-               if (evt) {
+               if (evt)
                        dwc3_free_one_event_buffer(dwc, evt);
-                       dwc->ev_buffs[i] = NULL;
-               }
        }
+
+       kfree(dwc->ev_buffs);
 }
 
 /**
index 25910e251c04b4fb7ce0ef8bb9685573e859b9b9..3584a169886f3dfa23b8513c3850dd71f71e22e0 100644 (file)
@@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 
                        dwc->test_mode_nr = wIndex >> 8;
                        dwc->test_mode = true;
+                       break;
+               default:
+                       return -EINVAL;
                }
                break;
 
@@ -559,15 +562,20 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
        length = trb->size & DWC3_TRB_SIZE_MASK;
 
        if (dwc->ep0_bounced) {
+               unsigned transfer_size = ur->length;
+               unsigned maxp = ep0->endpoint.maxpacket;
+
+               transfer_size += (maxp - (transfer_size % maxp));
                transferred = min_t(u32, ur->length,
-                               ep0->endpoint.maxpacket - length);
+                               transfer_size - length);
                memcpy(ur->buf, dwc->ep0_bounce, transferred);
                dwc->ep0_bounced = false;
        } else {
                transferred = ur->length - length;
-               ur->actual += transferred;
        }
 
+       ur->actual += transferred;
+
        if ((epnum & 1) && ur->actual < ur->length) {
                /* for some reason we did not get everything out */
 
index 0c935d7c65bdf7379f466e5c3f1522fb88a7e266..9d7bcd910074d0715a282c35d0e439539cdd3367 100644 (file)
@@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
                        mod_timer(&udc->vbus_timer,
                                  jiffies + VBUS_POLL_TIMEOUT);
                } else {
-                       if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
-                                       0, driver_name, udc)) {
+                       if (request_irq(gpio_to_irq(udc->board.vbus_pin),
+                                       at91_vbus_irq, 0, driver_name, udc)) {
                                DBG("request vbus irq %d failed\n",
                                    udc->board.vbus_pin);
                                retval = -EBUSY;
@@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
        return 0;
 fail4:
        if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled)
-               free_irq(udc->board.vbus_pin, udc);
+               free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
 fail3:
        if (gpio_is_valid(udc->board.vbus_pin))
                gpio_free(udc->board.vbus_pin);
@@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)
        device_init_wakeup(&pdev->dev, 0);
        remove_debug_file(udc);
        if (gpio_is_valid(udc->board.vbus_pin)) {
-               free_irq(udc->board.vbus_pin, udc);
+               free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
                gpio_free(udc->board.vbus_pin);
        }
        free_irq(udc->udp_irq, udc);
index 1cbba70836bcd7c1516c21253b3a54dd24a5849a..f52cb1ae45d9a5ab27a46cb40b34cdb94e93a484 100644 (file)
@@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
        if (code == FUNCTIONFS_INTERFACE_REVMAP) {
                struct ffs_function *func = ffs->func;
                ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
-       } else if (gadget->ops->ioctl) {
+       } else if (gadget && gadget->ops->ioctl) {
                ret = gadget->ops->ioctl(gadget, code, value);
        } else {
                ret = -ENOTTY;
@@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)
                ffs->ep0req = NULL;
                ffs->gadget = NULL;
                ffs_data_put(ffs);
+               clear_bit(FFS_FL_BOUND, &ffs->flags);
        }
 }
 
index 7b1cf18df5e3e4cd0706422d3e16d17bc1aad075..52343654f5df5218929e86bf7bdac64bf2577b9e 100644 (file)
@@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
                        if (buf) {
                                memcpy(req->buf, buf, n);
                                req->complete = rndis_response_complete;
+                               req->context = rndis;
                                rndis_free_response(rndis->config, buf);
                                value = n;
                        }
index 5f94e79cd6b9b3f8856dad2d97d1e74677f62bad..55abfb6bd612dc96da58c67fb59def9e0cc14ea0 100644 (file)
@@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
                : (1 << (ep_index(ep)));
 
        /* check if the pipe is empty */
-       if (!(list_empty(&ep->queue))) {
+       if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {
                /* Add td to the end */
                struct fsl_req *lastreq;
                lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
@@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
                return -ENOMEM;
        }
 
-       /* Update ep0 state */
-       if ((ep_index(ep) == 0))
-               udc->ep0_state = DATA_STATE_XMIT;
-
        /* irq handler advances the queue */
        if (req != NULL)
                list_add_tail(&req->queue, &ep->queue);
@@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
                udc->ep0_dir = USB_DIR_OUT;
 
        ep = &udc->eps[0];
-       udc->ep0_state = WAIT_FOR_OUT_STATUS;
+       if (udc->ep0_state != DATA_STATE_XMIT)
+               udc->ep0_state = WAIT_FOR_OUT_STATUS;
 
        req->ep = ep;
        req->req.length = 0;
@@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
 
        list_add_tail(&req->queue, &ep->queue);
        udc->ep0_state = DATA_STATE_XMIT;
+       if (ep0_prime_status(udc, EP_DIR_OUT))
+               ep0stall(udc);
+
        return;
 stall:
        ep0stall(udc);
@@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,
                spin_lock(&udc->lock);
                udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
                                ?  DATA_STATE_XMIT : DATA_STATE_RECV;
+               /*
+                * If the data stage is IN, send status prime immediately.
+                * See 2.0 Spec chapter 8.5.3.3 for detail.
+                */
+               if (udc->ep0_state == DATA_STATE_XMIT)
+                       if (ep0_prime_status(udc, EP_DIR_OUT))
+                               ep0stall(udc);
+
        } else {
                /* No data phase, IN status from gadget */
                udc->ep0_dir = USB_DIR_IN;
@@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
 
        switch (udc->ep0_state) {
        case DATA_STATE_XMIT:
-               /* receive status phase */
-               if (ep0_prime_status(udc, EP_DIR_OUT))
-                       ep0stall(udc);
+               /* already primed at setup_received_irq */
+               udc->ep0_state = WAIT_FOR_OUT_STATUS;
                break;
        case DATA_STATE_RECV:
                /* send status phase */
index 331cd6729d3cf4d1ac8bccf9b4ca5746d4d79821..a85eaf40b948592f4df5746cd1dca2a87141cf8d 100644 (file)
@@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = {
 static struct ffs_data *gfs_ffs_data;
 static unsigned long gfs_registered;
 
-static int  gfs_init(void)
+static int __init gfs_init(void)
 {
        ENTER();
 
@@ -169,7 +169,7 @@ static int  gfs_init(void)
 }
 module_init(gfs_init);
 
-static void  gfs_exit(void)
+static void __exit gfs_exit(void)
 {
        ENTER();
 
index 8793f32bab113524fcd5f184c0fed016be0e189f..e58b1644297172a8c1136fc78b2aea802df17f41 100644 (file)
@@ -1574,7 +1574,6 @@ static void destroy_ep_files (struct dev_data *dev)
        DBG (dev, "%s %d\n", __func__, dev->state);
 
        /* dev->state must prevent interference */
-restart:
        spin_lock_irq (&dev->lock);
        while (!list_empty(&dev->epfiles)) {
                struct ep_data  *ep;
index 69295ba9d99ae12f29738533fb15f5a7b4cce046..105b206cd8443dbe01bfd32b14555a51b22438b6 100644 (file)
@@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
        /* currently we allocate TX FIFOs for all possible endpoints,
         * and assume that they are all the same size. */
 
-       for (ep = 0; ep <= 15; ep++) {
+       for (ep = 1; ep <= 15; ep++) {
                val = addr;
                val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
                addr += size;
@@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
        /* write size / packets */
        writel(epsize, hsotg->regs + epsize_reg);
 
-       if (using_dma(hsotg)) {
+       if (using_dma(hsotg) && !continuing) {
                unsigned int dma_reg;
 
                /* write DMA address to control register, buffer already
@@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,
        reg |= mpsval;
        writel(reg, regs + S3C_DIEPCTL(ep));
 
-       reg = readl(regs + S3C_DOEPCTL(ep));
-       reg &= ~S3C_DxEPCTL_MPS_MASK;
-       reg |= mpsval;
-       writel(reg, regs + S3C_DOEPCTL(ep));
+       if (ep) {
+               reg = readl(regs + S3C_DOEPCTL(ep));
+               reg &= ~S3C_DxEPCTL_MPS_MASK;
+               reg |= mpsval;
+               writel(reg, regs + S3C_DOEPCTL(ep));
+       }
 
        return;
 
@@ -1919,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
                    ints & S3C_DIEPMSK_TxFIFOEmpty) {
                        dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
                                __func__, idx);
-                       s3c_hsotg_trytx(hsotg, hs_ep);
+                       if (!using_dma(hsotg))
+                               s3c_hsotg_trytx(hsotg, hs_ep);
                }
        }
 }
index 56da49f31d6c35a0f61611c1bb651b51e59732ab..2fa9865babedb0d76e28d6cfa2ac2ad6cf859628 100644 (file)
@@ -264,8 +264,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
        if (udc_is_newstyle(udc)) {
                udc->driver->disconnect(udc->gadget);
                udc->driver->unbind(udc->gadget);
-               usb_gadget_udc_stop(udc->gadget, udc->driver);
                usb_gadget_disconnect(udc->gadget);
+               usb_gadget_udc_stop(udc->gadget, udc->driver);
        } else {
                usb_gadget_stop(udc->gadget, udc->driver);
        }
@@ -411,8 +411,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
        struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
 
        if (sysfs_streq(buf, "connect")) {
+               if (udc_is_newstyle(udc))
+                       usb_gadget_udc_start(udc->gadget, udc->driver);
                usb_gadget_connect(udc->gadget);
        } else if (sysfs_streq(buf, "disconnect")) {
+               if (udc_is_newstyle(udc))
+                       usb_gadget_udc_stop(udc->gadget, udc->driver);
                usb_gadget_disconnect(udc->gadget);
        } else {
                dev_err(dev, "unsupported command '%s'\n", buf);
index d776adb2da675c24f0d669d9a931f0a15abcf37f..0cdf89d32a15817d78ce0388a76f32909b29240c 100644 (file)
@@ -543,11 +543,11 @@ done:
        return ret;
 }
 
+/* called with queue->irqlock held.. */
 static struct uvc_buffer *
 uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
 {
        struct uvc_buffer *nextbuf;
-       unsigned long flags;
 
        if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
            buf->buf.length != buf->buf.bytesused) {
@@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
                return buf;
        }
 
-       spin_lock_irqsave(&queue->irqlock, flags);
        list_del(&buf->queue);
        if (!list_empty(&queue->irqqueue))
                nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
                                           queue);
        else
                nextbuf = NULL;
-       spin_unlock_irqrestore(&queue->irqlock, flags);
 
        buf->buf.sequence = queue->sequence++;
        do_gettimeofday(&buf->buf.timestamp);
index 3e7345172e03a86b56b31f48f66dfc601955b899..d0a84bd3f3ebe5bca473e2c6c99711bf02069c3f 100644 (file)
@@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
        u32 portsc;
        struct usb_hcd *hcd = ehci_to_hcd(ehci);
        void __iomem *non_ehci = hcd->regs;
+       struct fsl_usb2_platform_data *pdata;
+
+       pdata = hcd->self.controller->platform_data;
 
        portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
        portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
@@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
                /* fall through */
        case FSL_USB2_PHY_UTMI:
                /* enable UTMI PHY */
-               setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN);
+               if (pdata->have_sysif_regs)
+                       setbits32(non_ehci + FSL_SOC_USB_CTRL,
+                                 CTRL_UTMI_PHY_EN);
                portsc |= PORT_PTS_UTMI;
                break;
        case FSL_USB2_PHY_NONE:
index 057cdda7a48978999ebf5ac4cbb8ecee7acc60e0..4a3bc5b7a06f82d395c9a6dae0a025ba9660cf02 100644 (file)
@@ -347,6 +347,8 @@ static int ehci_reset (struct ehci_hcd *ehci)
        if (ehci->debug)
                dbgp_external_startup();
 
+       ehci->port_c_suspend = ehci->suspended_ports =
+                       ehci->resuming_ports = 0;
        return retval;
 }
 
@@ -856,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                goto dead;
        }
 
+       /*
+        * We don't use STS_FLR, but some controllers don't like it to
+        * remain on, so mask it out along with the other status bits.
+        */
+       masked_status = status & (INTR_MASK | STS_FLR);
+
        /* Shared IRQ? */
-       masked_status = status & INTR_MASK;
        if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
                spin_unlock(&ehci->lock);
                return IRQ_NONE;
@@ -908,7 +915,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                pcd_status = status;
 
                /* resume root hub? */
-               if (!(cmd & CMD_RUN))
+               if (ehci->rh_state == EHCI_RH_SUSPENDED)
                        usb_hcd_resume_root_hub(hcd);
 
                /* get per-port change detect bits */
@@ -939,6 +946,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                         * like usb_port_resume() does.
                         */
                        ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
+                       set_bit(i, &ehci->resuming_ports);
                        ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
                        mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
                }
index 256fbd42e48c19b02c808fccda6025b93a3392c5..38fe076231522875bec58c60ec74fc7b14932960 100644 (file)
@@ -223,15 +223,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
         * remote wakeup, we must fail the suspend.
         */
        if (hcd->self.root_hub->do_remote_wakeup) {
-               port = HCS_N_PORTS(ehci->hcs_params);
-               while (port--) {
-                       if (ehci->reset_done[port] != 0) {
-                               spin_unlock_irq(&ehci->lock);
-                               ehci_dbg(ehci, "suspend failed because "
-                                               "port %d is resuming\n",
-                                               port + 1);
-                               return -EBUSY;
-                       }
+               if (ehci->resuming_ports) {
+                       spin_unlock_irq(&ehci->lock);
+                       ehci_dbg(ehci, "suspend failed because a port is resuming\n");
+                       return -EBUSY;
                }
        }
 
@@ -554,16 +549,12 @@ static int
 ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
 {
        struct ehci_hcd *ehci = hcd_to_ehci (hcd);
-       u32             temp, status = 0;
+       u32             temp, status;
        u32             mask;
        int             ports, i, retval = 1;
        unsigned long   flags;
        u32             ppcd = 0;
 
-       /* if !USB_SUSPEND, root hub timers won't get shut down ... */
-       if (ehci->rh_state != EHCI_RH_RUNNING)
-               return 0;
-
        /* init status to no-changes */
        buf [0] = 0;
        ports = HCS_N_PORTS (ehci->hcs_params);
@@ -572,6 +563,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
                retval++;
        }
 
+       /* Inform the core about resumes-in-progress by returning
+        * a non-zero value even if there are no status changes.
+        */
+       status = ehci->resuming_ports;
+
        /* Some boards (mostly VIA?) report bogus overcurrent indications,
         * causing massive log spam unless we completely ignore them.  It
         * may be relevant that VIA VT8235 controllers, where PORT_POWER is
@@ -846,6 +842,7 @@ static int ehci_hub_control (
                                ehci_writel(ehci,
                                        temp & ~(PORT_RWC_BITS | PORT_RESUME),
                                        status_reg);
+                               clear_bit(wIndex, &ehci->resuming_ports);
                                retval = handshake(ehci, status_reg,
                                           PORT_RESUME, 0, 2000 /* 2msec */);
                                if (retval != 0) {
@@ -864,6 +861,7 @@ static int ehci_hub_control (
                                        ehci->reset_done[wIndex])) {
                        status |= USB_PORT_STAT_C_RESET << 16;
                        ehci->reset_done [wIndex] = 0;
+                       clear_bit(wIndex, &ehci->resuming_ports);
 
                        /* force reset to complete */
                        ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
@@ -884,8 +882,10 @@ static int ehci_hub_control (
                                        ehci_readl(ehci, status_reg));
                }
 
-               if (!(temp & (PORT_RESUME|PORT_RESET)))
+               if (!(temp & (PORT_RESUME|PORT_RESET))) {
                        ehci->reset_done[wIndex] = 0;
+                       clear_bit(wIndex, &ehci->resuming_ports);
+               }
 
                /* transfer dedicated ports to the companion hc */
                if ((temp & PORT_CONNECT) &&
@@ -920,6 +920,7 @@ static int ehci_hub_control (
                        status |= USB_PORT_STAT_SUSPEND;
                } else if (test_bit(wIndex, &ehci->suspended_ports)) {
                        clear_bit(wIndex, &ehci->suspended_ports);
+                       clear_bit(wIndex, &ehci->resuming_ports);
                        ehci->reset_done[wIndex] = 0;
                        if (temp & PORT_PE)
                                set_bit(wIndex, &ehci->port_c_suspend);
index bba9850f32f09f78c668a04d2d024d99d3320857..5c78f9e71466ef7a81df23535ead8927dd73af24 100644 (file)
@@ -42,6 +42,7 @@
 #include <plat/usb.h>
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
+#include <linux/gpio.h>
 
 /* EHCI Register Set */
 #define EHCI_INSNREG04                                 (0xA0)
@@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
                }
        }
 
+       if (pdata->phy_reset) {
+               if (gpio_is_valid(pdata->reset_gpio_port[0]))
+                       gpio_request_one(pdata->reset_gpio_port[0],
+                                        GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
+
+               if (gpio_is_valid(pdata->reset_gpio_port[1]))
+                       gpio_request_one(pdata->reset_gpio_port[1],
+                                        GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
+
+               /* Hold the PHY in RESET for enough time till DIR is high */
+               udelay(10);
+       }
+
        pm_runtime_enable(dev);
        pm_runtime_get_sync(dev);
 
@@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
        /* root ports should always stay powered */
        ehci_port_power(omap_ehci, 1);
 
+       if (pdata->phy_reset) {
+               /* Hold the PHY in RESET for enough time till
+                * PHY is settled and ready
+                */
+               udelay(10);
+
+               if (gpio_is_valid(pdata->reset_gpio_port[0]))
+                       gpio_set_value(pdata->reset_gpio_port[0], 1);
+
+               if (gpio_is_valid(pdata->reset_gpio_port[1]))
+                       gpio_set_value(pdata->reset_gpio_port[1], 1);
+       }
+
        return 0;
 
 err_add_hcd:
@@ -259,8 +286,9 @@ err_io:
  */
 static int ehci_hcd_omap_remove(struct platform_device *pdev)
 {
-       struct device *dev      = &pdev->dev;
-       struct usb_hcd *hcd     = dev_get_drvdata(dev);
+       struct device *dev                              = &pdev->dev;
+       struct usb_hcd *hcd                             = dev_get_drvdata(dev);
+       struct ehci_hcd_omap_platform_data *pdata       = dev->platform_data;
 
        usb_remove_hcd(hcd);
        disable_put_regulator(dev->platform_data);
@@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
        pm_runtime_put_sync(dev);
        pm_runtime_disable(dev);
 
+       if (pdata->phy_reset) {
+               if (gpio_is_valid(pdata->reset_gpio_port[0]))
+                       gpio_free(pdata->reset_gpio_port[0]);
+
+               if (gpio_is_valid(pdata->reset_gpio_port[1]))
+                       gpio_free(pdata->reset_gpio_port[1]);
+       }
        return 0;
 }
 
index 3de48a2d79550df7b9af8efe0132ff73e2535fdd..86183366647f7803f256d2ef6d05da639818c8e5 100644 (file)
@@ -224,6 +224,7 @@ static int tegra_ehci_hub_control(
                temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
                /* start resume signalling */
                ehci_writel(ehci, temp | PORT_RESUME, status_reg);
+               set_bit(wIndex-1, &ehci->resuming_ports);
 
                spin_unlock_irqrestore(&ehci->lock, flags);
                msleep(20);
@@ -236,6 +237,7 @@ static int tegra_ehci_hub_control(
                        pr_err("%s: timeout waiting for SUSPEND\n", __func__);
 
                ehci->reset_done[wIndex-1] = 0;
+               clear_bit(wIndex-1, &ehci->resuming_ports);
 
                tegra->port_resuming = 1;
                goto done;
@@ -729,7 +731,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)
                err = -ENODEV;
                goto fail;
        }
-       set_irq_flags(irq, IRQF_VALID);
 
 #ifdef CONFIG_USB_OTG_UTILS
        if (pdata->operating_mode == TEGRA_USB_OTG) {
index 8f9acbc96fde03bf320ed1a696f0fb7b164a45e3..2694ed6558d2d954c03a4ba3b77eabdc64f9c7f6 100644 (file)
@@ -117,6 +117,8 @@ struct ehci_hcd {                   /* one per controller */
                        the change-suspend feature turned on */
        unsigned long           suspended_ports;        /* which ports are
                        suspended */
+       unsigned long           resuming_ports;         /* which ports have
+                       started to resume */
 
        /* per-HC memory pools (could be per-bus, but ...) */
        struct dma_pool         *qh_pool;       /* qh per active urb */
index 09f597ad6e00ad739ab4e0924800a0c81e0abbfc..13ebeca8e73e3e5f78f52b6001ebc3464f40a432 100644 (file)
@@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
@@ -108,7 +108,7 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
  * then invokes the start() method for the HCD associated with it
  * through the hotplug entry's driver_data.
  */
-static int usb_hcd_at91_probe(const struct hc_driver *driver,
+static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
                        struct platform_device *pdev)
 {
        int retval;
@@ -203,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
  * context, "rmmod" or something similar.
  *
  */
-static void usb_hcd_at91_remove(struct usb_hcd *hcd,
+static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
                                struct platform_device *pdev)
 {
        usb_remove_hcd(hcd);
@@ -545,7 +545,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
+static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 {
        struct at91_usbh_data   *pdata;
        int                     i;
@@ -620,7 +620,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
        return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
 }
 
-static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
+static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)
 {
        struct at91_usbh_data   *pdata = pdev->dev.platform_data;
        int                     i;
@@ -696,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci");
 
 static struct platform_driver ohci_hcd_at91_driver = {
        .probe          = ohci_hcd_at91_drv_probe,
-       .remove         = ohci_hcd_at91_drv_remove,
+       .remove         = __devexit_p(ohci_hcd_at91_drv_remove),
        .shutdown       = usb_hcd_platform_shutdown,
        .suspend        = ohci_hcd_at91_drv_suspend,
        .resume         = ohci_hcd_at91_drv_resume,
index 11de5f1be9819311254bae707cff67cb56c6cd99..32dada8c8b4f31e639227d120203482fe487d229 100644 (file)
@@ -825,9 +825,13 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
                }
        }
 
-       /* Disable any BIOS SMIs */
-       writel(XHCI_LEGACY_DISABLE_SMI,
-                       base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
+       val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
+       /* Mask off (turn off) any enabled SMIs */
+       val &= XHCI_LEGACY_DISABLE_SMI;
+       /* Mask all SMI events bits, RW1C */
+       val |= XHCI_LEGACY_SMI_EVENTS;
+       /* Disable any BIOS SMIs and clear all SMI events*/
+       writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
 
        if (usb_is_intel_switchable_xhci(pdev))
                usb_enable_xhci_ports(pdev);
index 045cde4cbc3deafca332c28974b47cb826bae423..768d54295a20742a8f38d6224ce1a9bb1de85556 100644 (file)
@@ -196,11 +196,12 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
        status = get_hub_status_data(uhci, buf);
 
        switch (uhci->rh_state) {
-           case UHCI_RH_SUSPENDING:
            case UHCI_RH_SUSPENDED:
                /* if port change, ask to be resumed */
-               if (status || uhci->resuming_ports)
+               if (status || uhci->resuming_ports) {
+                       status = 1;
                        usb_hcd_resume_root_hub(hcd);
+               }
                break;
 
            case UHCI_RH_AUTO_STOPPED:
index e9b0f043455db2ccc7e09ecaf99a1fe2eaa7a6be..4b436f5a41711bc1a7747f3c7b187ff547c7acbd 100644 (file)
@@ -119,7 +119,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci)
        xhci_dbg(xhci, "  Event Interrupts %s\n",
                        (temp & CMD_EIE) ? "enabled " : "disabled");
        xhci_dbg(xhci, "  Host System Error Interrupts %s\n",
-                       (temp & CMD_EIE) ? "enabled " : "disabled");
+                       (temp & CMD_HSEIE) ? "enabled " : "disabled");
        xhci_dbg(xhci, "  HC has %sfinished light reset\n",
                        (temp & CMD_LRESET) ? "not " : "");
 }
index c7f33123d4c08e59954d5ac8d561f9cd6e3c9fef..377f4242dabb8cac56456258506b0c3982495b2a 100644 (file)
@@ -62,8 +62,9 @@
 /* USB Legacy Support Control and Status Register  - section 7.1.2 */
 /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */
 #define XHCI_LEGACY_CONTROL_OFFSET     (0x04)
-/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
-#define        XHCI_LEGACY_DISABLE_SMI         ((0x3 << 1) + (0xff << 5) + (0x7 << 17))
+/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
+#define        XHCI_LEGACY_DISABLE_SMI         ((0x7 << 1) + (0xff << 5) + (0x7 << 17))
+#define XHCI_LEGACY_SMI_EVENTS         (0x7 << 29)
 
 /* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */
 #define XHCI_L1C               (1 << 16)
index cae4c6f2845a39c8ea58199a61f933b317f6cac0..68eaa908ac8eaa10eca2e1d9a6a9573b14efd5a0 100644 (file)
@@ -1796,11 +1796,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        int i;
 
        /* Free the Event Ring Segment Table and the actual Event Ring */
-       if (xhci->ir_set) {
-               xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
-               xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
-               xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
-       }
        size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
        if (xhci->erst.entries)
                dma_free_coherent(&pdev->dev, size,
@@ -1812,7 +1807,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        xhci->event_ring = NULL;
        xhci_dbg(xhci, "Freed event ring\n");
 
-       xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
        if (xhci->cmd_ring)
                xhci_ring_free(xhci, xhci->cmd_ring);
        xhci->cmd_ring = NULL;
@@ -1841,7 +1835,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        xhci->medium_streams_pool = NULL;
        xhci_dbg(xhci, "Freed medium stream array pool\n");
 
-       xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);
        if (xhci->dcbaa)
                dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa),
                                xhci->dcbaa, xhci->dcbaa->dma);
@@ -2459,6 +2452,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 
 fail:
        xhci_warn(xhci, "Couldn't initialize memory\n");
+       xhci_halt(xhci);
+       xhci_reset(xhci);
        xhci_mem_cleanup(xhci);
        return -ENOMEM;
 }
index ef98b38626fbb5910aa6c486aecb856f1f4b7df5..7a856a767e77c5f9190666293ddf56a0e7a863d1 100644 (file)
@@ -95,6 +95,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                xhci->quirks |= XHCI_RESET_ON_RESUME;
                xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
        }
+       if (pdev->vendor == PCI_VENDOR_ID_VIA)
+               xhci->quirks |= XHCI_RESET_ON_RESUME;
 }
 
 /* called during probe() after chip reset completes */
@@ -326,7 +328,7 @@ int __init xhci_register_pci(void)
        return pci_register_driver(&xhci_pci_driver);
 }
 
-void __exit xhci_unregister_pci(void)
+void xhci_unregister_pci(void)
 {
        pci_unregister_driver(&xhci_pci_driver);
 }
index 6bd9d53062eb3bdbb25d7b83a83c337640dc912b..3d9422f16a20b66f2eb54aaffacebaf209b76868 100644 (file)
@@ -2417,7 +2417,7 @@ hw_died:
                u32 irq_pending;
                /* Acknowledge the PCI interrupt */
                irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-               irq_pending |= 0x3;
+               irq_pending |= IMAN_IP;
                xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending);
        }
 
@@ -2734,7 +2734,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                                urb->dev->speed == USB_SPEED_FULL)
                        urb->interval /= 8;
        }
-       return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
+       return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index);
 }
 
 /*
@@ -3514,7 +3514,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
        }
        ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free;
 
-       return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
+       return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index);
 }
 
 /****          Command Ring Operations         ****/
index e1963d4a430f2952c8383b5a25fff8debc6c0014..36641a7f23719058d5ebfe463feb00ac085b99f3 100644 (file)
@@ -106,6 +106,9 @@ int xhci_halt(struct xhci_hcd *xhci)
                        STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
        if (!ret)
                xhci->xhc_state |= XHCI_STATE_HALTED;
+       else
+               xhci_warn(xhci, "Host not halted after %u microseconds.\n",
+                               XHCI_MAX_HALT_USEC);
        return ret;
 }
 
@@ -664,11 +667,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci)
        xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification);
        xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
        xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg);
-       xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-       xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);
        xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size);
        xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base);
        xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+       xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+       xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);
 }
 
 static void xhci_restore_registers(struct xhci_hcd *xhci)
@@ -677,10 +680,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
        xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification);
        xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr);
        xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg);
-       xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending);
-       xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
        xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size);
        xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);
+       xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue);
+       xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending);
+       xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
 }
 
 static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
index 91074fdab3eb6cbcfd772b6c7066083155beed91..3d69c4b2b54277d57e6cb15cbf403127d70aeb1f 100644 (file)
@@ -205,6 +205,10 @@ struct xhci_op_regs {
 #define CMD_PM_INDEX   (1 << 11)
 /* bits 12:31 are reserved (and should be preserved on writes). */
 
+/* IMAN - Interrupt Management Register */
+#define IMAN_IP                (1 << 1)
+#define IMAN_IE                (1 << 0)
+
 /* USBSTS - USB status - status bitmasks */
 /* HC not running - set to 1 when run/stop bit is cleared. */
 #define STS_HALT       XHCI_STS_HALT
index 959145baf3cf8dd87669be5ed292de99541b4ed3..9dcb68f04f03025265f3747e6f7bf072ab1b8958 100644 (file)
@@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary)
        unsigned                i;
        unsigned                size = max;
 
-       sg = kmalloc(nents * sizeof *sg, GFP_KERNEL);
+       sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);
        if (!sg)
                return NULL;
        sg_init_table(sg, nents);
@@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
        struct ctrl_ctx         context;
        int                     i;
 
+       if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen)
+               return -EOPNOTSUPP;
+
        spin_lock_init(&context.lock);
        context.dev = dev;
        init_completion(&context.complete);
@@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 
        /* queued control messaging */
        case 10:
-               if (param->sglen == 0)
-                       break;
                retval = 0;
                dev_info(&intf->dev,
                                "TEST 10:  queue %d control calls, %d times\n",
@@ -2276,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
                        if (status < 0) {
                                WARNING(dev, "couldn't get endpoints, %d\n",
                                                status);
+                               kfree(dev->buf);
+                               kfree(dev);
                                return status;
                        }
                        /* may find bulk or ISO pipes */
index 897edda422709c016b36d469b5930532a104a30c..70201462e19c0e57d8615432a7d3e5e5813aed85 100644 (file)
@@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref)
        usb_put_dev(dev->udev);
        if (dev->cntl_urb) {
                usb_kill_urb(dev->cntl_urb);
-               if (dev->cntl_req)
-                       usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
-                               dev->cntl_req, dev->cntl_urb->setup_dma);
+               kfree(dev->cntl_req);
                if (dev->cntl_buffer)
                        usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
                                dev->cntl_buffer, dev->cntl_urb->transfer_dma);
@@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        }
 
        /* allocate buffer for control req */
-       dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
-                                          GFP_KERNEL,
-                                          &dev->cntl_urb->setup_dma);
+       dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
        if (!dev->cntl_req) {
                err("Could not allocate cntl_req");
                goto error;
@@ -286,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
                         usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
                         dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
                         dev, 1);
-       dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
                retval = -EIO;
                err("Could not submitting URB");
index 0f8b82918a40f8038d5c75567b18e2b62d454829..66aaccf04490487f83c1aa926be58e2410d12eea 100644 (file)
@@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
        int     i = 0;
        u8      r;
        u8      power;
+       int     ret;
+
+       pm_runtime_get_sync(phy->io_dev);
 
        /* Make sure the transceiver is not in low power mode */
        power = musb_readb(addr, MUSB_POWER);
@@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
        while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
                                & MUSB_ULPI_REG_CMPLT)) {
                i++;
-               if (i == 10000)
-                       return -ETIMEDOUT;
+               if (i == 10000) {
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
 
        }
        r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
        r &= ~MUSB_ULPI_REG_CMPLT;
        musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
 
-       return musb_readb(addr, MUSB_ULPI_REG_DATA);
+       ret = musb_readb(addr, MUSB_ULPI_REG_DATA);
+
+out:
+       pm_runtime_put(phy->io_dev);
+
+       return ret;
 }
 
 static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
@@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
        int     i = 0;
        u8      r = 0;
        u8      power;
+       int     ret = 0;
+
+       pm_runtime_get_sync(phy->io_dev);
 
        /* Make sure the transceiver is not in low power mode */
        power = musb_readb(addr, MUSB_POWER);
@@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
        while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
                                & MUSB_ULPI_REG_CMPLT)) {
                i++;
-               if (i == 10000)
-                       return -ETIMEDOUT;
+               if (i == 10000) {
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
        }
 
        r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
        r &= ~MUSB_ULPI_REG_CMPLT;
        musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
 
-       return 0;
+out:
+       pm_runtime_put(phy->io_dev);
+
+       return ret;
 }
 #else
 #define musb_ulpi_read         NULL
@@ -1904,14 +1922,17 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 
        if (!musb->isr) {
                status = -ENODEV;
-               goto fail3;
+               goto fail2;
        }
 
        if (!musb->xceiv->io_ops) {
+               musb->xceiv->io_dev = musb->controller;
                musb->xceiv->io_priv = musb->mregs;
                musb->xceiv->io_ops = &musb_ulpi_access;
        }
 
+       pm_runtime_get_sync(musb->controller);
+
 #ifndef CONFIG_MUSB_PIO_ONLY
        if (use_dma && dev->dma_mask) {
                struct dma_controller   *c;
@@ -2023,6 +2044,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
                goto fail5;
 #endif
 
+       pm_runtime_put(musb->controller);
+
        dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
                        ({char *s;
                         switch (musb->board_mode) {
@@ -2047,6 +2070,9 @@ fail4:
                musb_gadget_cleanup(musb);
 
 fail3:
+       pm_runtime_put_sync(musb->controller);
+
+fail2:
        if (musb->irq_wake)
                device_init_wakeup(dev, 0);
        musb_platform_exit(musb);
index 79cb0af779fa07dac0702ee9b2b2d43e0a22b738..ef8d744800ac29c58dc24e089a645211fcd665ff 100644 (file)
@@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
        }
 
        /* turn off DMA requests, discard state, stop polling ... */
-       if (is_in) {
+       if (ep->epnum && is_in) {
                /* giveback saves bulk toggle */
                csr = musb_h_flush_rxfifo(ep, 0);
 
index 2ae0bb3099940404044d84eb40740e7a82f52586..c7785e81254cdf96eef46f352ee134fc8ca759aa 100644 (file)
@@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
 
 static int omap2430_musb_init(struct musb *musb)
 {
-       u32 l, status = 0;
+       u32 l;
+       int status = 0;
        struct device *dev = musb->controller;
        struct musb_hdrc_platform_data *plat = dev->platform_data;
        struct omap_musb_board_data *data = plat->board_data;
@@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb)
 
        status = pm_runtime_get_sync(dev);
        if (status < 0) {
-               dev_err(dev, "pm_runtime_get_sync FAILED");
+               dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
                goto err1;
        }
 
@@ -333,6 +334,7 @@ static int omap2430_musb_init(struct musb *musb)
 
        setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 
+       pm_runtime_put_noidle(musb->controller);
        return 0;
 
 err1:
@@ -452,14 +454,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
                goto err2;
        }
 
+       pm_runtime_enable(&pdev->dev);
+
        ret = platform_device_add(musb);
        if (ret) {
                dev_err(&pdev->dev, "failed to register musb device\n");
                goto err2;
        }
 
-       pm_runtime_enable(&pdev->dev);
-
        return 0;
 
 err2:
@@ -478,7 +480,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)
 
        platform_device_del(glue->musb);
        platform_device_put(glue->musb);
-       pm_runtime_put(&pdev->dev);
        kfree(glue);
 
        return 0;
@@ -491,11 +492,13 @@ static int omap2430_runtime_suspend(struct device *dev)
        struct omap2430_glue            *glue = dev_get_drvdata(dev);
        struct musb                     *musb = glue_to_musb(glue);
 
-       musb->context.otg_interfsel = musb_readl(musb->mregs,
-                                               OTG_INTERFSEL);
+       if (musb) {
+               musb->context.otg_interfsel = musb_readl(musb->mregs,
+                               OTG_INTERFSEL);
 
-       omap2430_low_level_exit(musb);
-       usb_phy_set_suspend(musb->xceiv, 1);
+               omap2430_low_level_exit(musb);
+               usb_phy_set_suspend(musb->xceiv, 1);
+       }
 
        return 0;
 }
@@ -505,11 +508,13 @@ static int omap2430_runtime_resume(struct device *dev)
        struct omap2430_glue            *glue = dev_get_drvdata(dev);
        struct musb                     *musb = glue_to_musb(glue);
 
-       omap2430_low_level_init(musb);
-       musb_writel(musb->mregs, OTG_INTERFSEL,
-                                       musb->context.otg_interfsel);
+       if (musb) {
+               omap2430_low_level_init(musb);
+               musb_writel(musb->mregs, OTG_INTERFSEL,
+                               musb->context.otg_interfsel);
 
-       usb_phy_set_suspend(musb->xceiv, 0);
+               usb_phy_set_suspend(musb->xceiv, 0);
+       }
 
        return 0;
 }
index 7f547dc3a5903fd25e0837441115007320ae122d..ed8adb052ca74f136a14a423dea5cbe397c4d381 100644 (file)
@@ -60,8 +60,6 @@ static int usb_serial_device_probe(struct device *dev)
                retval = -ENODEV;
                goto exit;
        }
-       if (port->dev_state != PORT_REGISTERING)
-               goto exit;
 
        driver = port->serial->type;
        if (driver->port_probe) {
@@ -98,9 +96,6 @@ static int usb_serial_device_remove(struct device *dev)
        if (!port)
                return -ENODEV;
 
-       if (port->dev_state != PORT_UNREGISTERING)
-               return retval;
-
        device_remove_file(&port->dev, &dev_attr_port_number);
 
        driver = port->serial->type;
index 0310e2df59f5b78029ed5832e61039c826ae082d..ec30f95ef399e3b8bc907084c00c50592734791d 100644 (file)
@@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
        /* Issue the request, attempting to read 'size' bytes */
        result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                                request, REQTYPE_DEVICE_TO_HOST, 0x0000,
-                               port_priv->bInterfaceNumber, buf, size, 300);
+                               port_priv->bInterfaceNumber, buf, size,
+                               USB_CTRL_GET_TIMEOUT);
 
        /* Convert data into an array of integers */
        for (i = 0; i < length; i++)
@@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
                result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0),
                                request, REQTYPE_HOST_TO_DEVICE, 0x0000,
-                               port_priv->bInterfaceNumber, buf, size, 300);
+                               port_priv->bInterfaceNumber, buf, size,
+                               USB_CTRL_SET_TIMEOUT);
        } else {
                result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0),
                                request, REQTYPE_HOST_TO_DEVICE, data[0],
-                               port_priv->bInterfaceNumber, NULL, 0, 300);
+                               port_priv->bInterfaceNumber, NULL, 0,
+                               USB_CTRL_SET_TIMEOUT);
        }
 
        kfree(buf);
index ff8605b4b4be4679a7d6b9abf177bba8ee7f630b..02e7f2d32d52601156bc85f131599e4d2b7c95cd 100644 (file)
@@ -75,7 +75,8 @@ struct ftdi_private {
        unsigned long last_dtr_rts;     /* saved modem control outputs */
        struct async_icount     icount;
        wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
-       char prev_status, diff_status;        /* Used for TIOCMIWAIT */
+       char prev_status;        /* Used for TIOCMIWAIT */
+       bool dev_gone;        /* Used to abort TIOCMIWAIT */
        char transmit_empty;    /* If transmitter is empty or not */
        struct usb_serial_port *port;
        __u16 interface;        /* FT2232C, FT2232H or FT4232H port interface
@@ -1681,6 +1682,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
        init_waitqueue_head(&priv->delta_msr_wait);
 
        priv->flags = ASYNC_LOW_LATENCY;
+       priv->dev_gone = false;
 
        if (quirk && quirk->port_probe)
                quirk->port_probe(priv);
@@ -1839,6 +1841,9 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
 
        dbg("%s", __func__);
 
+       priv->dev_gone = true;
+       wake_up_interruptible_all(&priv->delta_msr_wait);
+
        remove_sysfs_attrs(port);
 
        kref_put(&priv->kref, ftdi_sio_priv_release);
@@ -1982,17 +1987,19 @@ static int ftdi_process_packet(struct tty_struct *tty,
           N.B. packet may be processed more than once, but differences
           are only processed once.  */
        status = packet[0] & FTDI_STATUS_B0_MASK;
-       if (status & FTDI_RS0_CTS)
-               priv->icount.cts++;
-       if (status & FTDI_RS0_DSR)
-               priv->icount.dsr++;
-       if (status & FTDI_RS0_RI)
-               priv->icount.rng++;
-       if (status & FTDI_RS0_RLSD)
-               priv->icount.dcd++;
        if (status != priv->prev_status) {
-               priv->diff_status |= status ^ priv->prev_status;
-               wake_up_interruptible(&priv->delta_msr_wait);
+               char diff_status = status ^ priv->prev_status;
+
+               if (diff_status & FTDI_RS0_CTS)
+                       priv->icount.cts++;
+               if (diff_status & FTDI_RS0_DSR)
+                       priv->icount.dsr++;
+               if (diff_status & FTDI_RS0_RI)
+                       priv->icount.rng++;
+               if (diff_status & FTDI_RS0_RLSD)
+                       priv->icount.dcd++;
+
+               wake_up_interruptible_all(&priv->delta_msr_wait);
                priv->prev_status = status;
        }
 
@@ -2395,15 +2402,12 @@ static int ftdi_ioctl(struct tty_struct *tty,
         */
        case TIOCMIWAIT:
                cprev = priv->icount;
-               while (1) {
+               while (!priv->dev_gone) {
                        interruptible_sleep_on(&priv->delta_msr_wait);
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
                        cnow = priv->icount;
-                       if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
-                           cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-                               return -EIO; /* no change => error */
                        if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
                            ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
                            ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
@@ -2412,7 +2416,7 @@ static int ftdi_ioctl(struct tty_struct *tty,
                        }
                        cprev = cnow;
                }
-               /* not reached */
+               return -EIO;
                break;
        case TIOCSERGETLSR:
                return get_lsr_info(port, (struct serial_struct __user *)arg);
index 6e1622f2a297f95948a4d5fc72f132801142c26e..08d16e8c002d5b59444c1b12b44585ee8fd19a6d 100644 (file)
@@ -27,8 +27,8 @@
 
 /* Product information. */
 #define FOCUS_VENDOR_ID                        0x0C2E
-#define FOCUS_PRODUCT_ID               0x0720
-#define FOCUS_PRODUCT_ID_UNI           0x0710
+#define FOCUS_PRODUCT_ID_BI            0x0720
+#define FOCUS_PRODUCT_ID_UNI           0x0700
 
 #define METROUSB_SET_REQUEST_TYPE      0x40
 #define METROUSB_SET_MODEM_CTRL_REQUEST        10
@@ -47,7 +47,7 @@ struct metrousb_private {
 
 /* Device table list. */
 static struct usb_device_id id_table[] = {
-       { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) },
+       { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) },
        { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) },
        { }, /* Terminating entry. */
 };
index 836cfa9a515fe9f2523f3a387995ac386f915ec8..f4465ccddc351b14f6f9f3f61dbdd82bab34008a 100644 (file)
@@ -708,6 +708,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) },
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) },
index ff4a174fa5de8e536572584b32b08a41defc7e1e..a1a9062954c471f57f4b173490a7bcd2a62a210c 100644 (file)
@@ -420,7 +420,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
        control = priv->line_control;
        if ((cflag & CBAUD) == B0)
                priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
-       else
+       else if ((old_termios->c_cflag & CBAUD) == B0)
                priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
        if (control != priv->line_control) {
                control = priv->line_control;
index f14465a83dd1f53e1688c399a950bf67f3ed501a..8c8bf806f6faf9b779c8ed002a273c7aba5c96c0 100644 (file)
@@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = {
 };
 
 /* 'blacklist' of interfaces not served by this driver */
-static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
+static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
 static const struct sierra_iface_info direct_ip_interface_blacklist = {
        .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
        .ifaceinfo = direct_ip_non_serial_ifaces,
@@ -298,6 +298,9 @@ static const struct usb_device_id id_table[] = {
        /* Sierra Wireless HSPA Non-Composite Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
        { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
+       { USB_DEVICE(0x1199, 0x68A2),   /* Sierra Wireless MC77xx in QMI mode */
+         .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+       },
        { USB_DEVICE(0x1199, 0x68A3),   /* Sierra Wireless Direct IP modems */
          .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
        },
index 69230f01056ab32f551c2a0e8e953e1fee03649e..97355a15bbea8b5a36f3c7e52fd0eb5d4c3caa8a 100644 (file)
@@ -1059,6 +1059,12 @@ int usb_serial_probe(struct usb_interface *interface,
                serial->attached = 1;
        }
 
+       /* Avoid race with tty_open and serial_install by setting the
+        * disconnected flag and not clearing it until all ports have been
+        * registered.
+        */
+       serial->disconnected = 1;
+
        if (get_free_serial(serial, num_ports, &minor) == NULL) {
                dev_err(&interface->dev, "No more free serial devices\n");
                goto probe_error;
@@ -1070,19 +1076,16 @@ int usb_serial_probe(struct usb_interface *interface,
                port = serial->port[i];
                dev_set_name(&port->dev, "ttyUSB%d", port->number);
                dbg ("%s - registering %s", __func__, dev_name(&port->dev));
-               port->dev_state = PORT_REGISTERING;
                device_enable_async_suspend(&port->dev);
 
                retval = device_add(&port->dev);
-               if (retval) {
+               if (retval)
                        dev_err(&port->dev, "Error registering port device, "
                                "continuing\n");
-                       port->dev_state = PORT_UNREGISTERED;
-               } else {
-                       port->dev_state = PORT_REGISTERED;
-               }
        }
 
+       serial->disconnected = 0;
+
        usb_serial_console_init(debug, minor);
 
 exit:
@@ -1124,22 +1127,8 @@ void usb_serial_disconnect(struct usb_interface *interface)
                        }
                        kill_traffic(port);
                        cancel_work_sync(&port->work);
-                       if (port->dev_state == PORT_REGISTERED) {
-
-                               /* Make sure the port is bound so that the
-                                * driver's port_remove method is called.
-                                */
-                               if (!port->dev.driver) {
-                                       int rc;
-
-                                       port->dev.driver =
-                                                       &serial->type->driver;
-                                       rc = device_bind_driver(&port->dev);
-                               }
-                               port->dev_state = PORT_UNREGISTERING;
+                       if (device_is_registered(&port->dev))
                                device_del(&port->dev);
-                               port->dev_state = PORT_UNREGISTERED;
-                       }
                }
        }
        serial->type->disconnect(serial);
index c18538e4a6db1e0adeb26437b3b6f2de38b6b38c..2653e73db6233eabcf83f527019451820157e65d 100644 (file)
@@ -132,6 +132,35 @@ static struct us_unusual_dev for_dynamic_ids =
 #undef COMPLIANT_DEV
 #undef USUAL_DEV
 
+#ifdef CONFIG_LOCKDEP
+
+static struct lock_class_key us_interface_key[USB_MAXINTERFACES];
+
+static void us_set_lock_class(struct mutex *mutex,
+               struct usb_interface *intf)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct usb_host_config *config = udev->actconfig;
+       int i;
+
+       for (i = 0; i < config->desc.bNumInterfaces; i++) {
+               if (config->interface[i] == intf)
+                       break;
+       }
+
+       BUG_ON(i == config->desc.bNumInterfaces);
+
+       lockdep_set_class(mutex, &us_interface_key[i]);
+}
+
+#else
+
+static void us_set_lock_class(struct mutex *mutex,
+               struct usb_interface *intf)
+{
+}
+
+#endif
 
 #ifdef CONFIG_PM       /* Minimal support for suspend and resume */
 
@@ -895,6 +924,7 @@ int usb_stor_probe1(struct us_data **pus,
        *pus = us = host_to_us(host);
        memset(us, 0, sizeof(struct us_data));
        mutex_init(&(us->dev_mutex));
+       us_set_lock_class(&us->dev_mutex, intf);
        init_completion(&us->cmnd_ready);
        init_completion(&(us->notify));
        init_waitqueue_head(&us->delay_wait);
index 66797e9c5010d35cd5c21563a99faec79cd8a175..810c90ae2c5584fc57113813f2a9251422724840 100644 (file)
@@ -645,7 +645,8 @@ void hwarc_neep_cb(struct urb *urb)
                dev_err(dev, "NEEP: URB error %d\n", urb->status);
        }
        result = usb_submit_urb(urb, GFP_ATOMIC);
-       if (result < 0) {
+       if (result < 0 && result != -ENODEV && result != -EPERM) {
+               /* ignoring unrecoverable errors */
                dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",
                        result);
                goto error;
index a269937be1b8230898f991eb5f430e3f79ac9824..8cb71bb333c2ea830881ddc8bf19afd4096b3d60 100644 (file)
@@ -107,6 +107,7 @@ struct uwb_rc_neh {
        u8 evt_type;
        __le16 evt;
        u8 context;
+       u8 completed;
        uwb_rc_cmd_cb_f cb;
        void *arg;
 
@@ -409,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
        struct device *dev = &rc->uwb_dev.dev;
        struct uwb_rc_neh *neh;
        struct uwb_rceb *notif;
+       unsigned long flags;
 
        if (rceb->bEventContext == 0) {
                notif = kmalloc(size, GFP_ATOMIC);
@@ -422,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
        } else {
                neh = uwb_rc_neh_lookup(rc, rceb);
                if (neh) {
-                       del_timer_sync(&neh->timer);
+                       spin_lock_irqsave(&rc->neh_lock, flags);
+                       /* to guard against a timeout */
+                       neh->completed = 1;
+                       del_timer(&neh->timer);
+                       spin_unlock_irqrestore(&rc->neh_lock, flags);
                        uwb_rc_neh_cb(neh, rceb, size);
                } else
                        dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
@@ -568,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg)
        unsigned long flags;
 
        spin_lock_irqsave(&rc->neh_lock, flags);
+       if (neh->completed) {
+               spin_unlock_irqrestore(&rc->neh_lock, flags);
+               return;
+       }
        if (neh->context)
                __uwb_rc_neh_rm(rc, neh);
        else
index f0da2c32fbdefce2ff9d791f9fa23a73ac49de8d..1f21d2a1e52885af8db0a691170b8ab0364aa7b4 100644 (file)
@@ -238,7 +238,7 @@ static void handle_tx(struct vhost_net *net)
 
                                vq->heads[vq->upend_idx].len = len;
                                ubuf->callback = vhost_zerocopy_callback;
-                               ubuf->arg = vq->ubufs;
+                               ubuf->ctx = vq->ubufs;
                                ubuf->desc = vq->upend_idx;
                                msg.msg_control = ubuf;
                                msg.msg_controllen = sizeof(ubuf);
index fc9a1d75281f33d57be305b3c724195c578334de..3de00d9fae2e6b7f186ed1767bed6e6424f08c76 100644 (file)
@@ -155,7 +155,7 @@ static int vhost_test_release(struct inode *inode, struct file *f)
 
        vhost_test_stop(n, &private);
        vhost_test_flush(n);
-       vhost_dev_cleanup(&n->dev);
+       vhost_dev_cleanup(&n->dev, false);
        /* We do an extra flush before freeing memory,
         * since jobs can re-queue themselves. */
        vhost_test_flush(n);
index 947f00d8e091a3f2f3c01cc7cc23f5f2658d37df..51e4c1eeec4f0b09af84b5feb58c63313cd7d0cb 100644 (file)
@@ -1598,10 +1598,9 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
        kfree(ubufs);
 }
 
-void vhost_zerocopy_callback(void *arg)
+void vhost_zerocopy_callback(struct ubuf_info *ubuf)
 {
-       struct ubuf_info *ubuf = arg;
-       struct vhost_ubuf_ref *ubufs = ubuf->arg;
+       struct vhost_ubuf_ref *ubufs = ubuf->ctx;
        struct vhost_virtqueue *vq = ubufs->vq;
 
        /* set len = 1 to mark this desc buffers done DMA */
index 8dcf4cca6bf224ec5c36f105a994ba76b0b19188..8de1fd5b8efba8a39c20e7872a23b517e710b9ec 100644 (file)
@@ -188,7 +188,7 @@ bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *);
 
 int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
                    unsigned int log_num, u64 len);
-void vhost_zerocopy_callback(void *arg);
+void vhost_zerocopy_callback(struct ubuf_info *);
 int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq);
 
 #define vq_err(vq, fmt, ...) do {                                  \
index befcbd8ef019970eb156441d891712bca4006bac..ffbce4525468955a06051bb2df31caf83c522606 100644 (file)
@@ -499,7 +499,8 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
        au1100fb_fix.mmio_start = regs_res->start;
        au1100fb_fix.mmio_len = resource_size(regs_res);
 
-       if (!devm_request_mem_region(au1100fb_fix.mmio_start,
+       if (!devm_request_mem_region(&dev->dev,
+                                    au1100fb_fix.mmio_start,
                                     au1100fb_fix.mmio_len,
                                     DRIVER_NAME)) {
                print_err("fail to lock memory region at 0x%08lx",
@@ -516,7 +517,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
        fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
                        (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
 
-       fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev,
+       fbdev->fb_mem = dmam_alloc_coherent(&dev->dev,
                                            PAGE_ALIGN(fbdev->fb_len),
                                            &fbdev->fb_phys, GFP_KERNEL);
        if (!fbdev->fb_mem) {
index 3e9a773db09f18540382bd42c77a696a842ed13b..7ca79f02056ebc9d967af326800687529dae37a8 100644 (file)
@@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
                /* Allocate the framebuffer to the maximum screen size */
                fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
 
-               fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev,
+               fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev,
                                PAGE_ALIGN(fbdev->fb_len),
                                &fbdev->fb_phys, GFP_KERNEL);
                if (!fbdev->fb_mem) {
index 5d62698825892f857211acd61e5ffa0982b77e91..50f4670e92523a629cb2834cbac6e09e729003df 100644 (file)
@@ -73,210 +73,210 @@ typedef enum _OVRL_PIX_FORMAT {
 /* Register Table */
 typedef struct {
        /* 0h  */
-       volatile unsigned long Thread0Enable;   /* 0x0000 */
-       volatile unsigned long Thread1Enable;   /* 0x0004 */
-       volatile unsigned long Thread0Recover;  /* 0x0008 */
-       volatile unsigned long Thread1Recover;  /* 0x000C */
-       volatile unsigned long Thread0Step;     /* 0x0010 */
-       volatile unsigned long Thread1Step;     /* 0x0014 */
-       volatile unsigned long VideoInStatus;   /* 0x0018 */
-       volatile unsigned long Core2InSignStart;        /* 0x001C */
-       volatile unsigned long Core1ResetVector;        /* 0x0020 */
-       volatile unsigned long Core1ROMOffset;  /* 0x0024 */
-       volatile unsigned long Core1ArbiterPriority;    /* 0x0028 */
-       volatile unsigned long VideoInControl;  /* 0x002C */
-       volatile unsigned long VideoInReg0CtrlA;        /* 0x0030 */
-       volatile unsigned long VideoInReg0CtrlB;        /* 0x0034 */
-       volatile unsigned long VideoInReg1CtrlA;        /* 0x0038 */
-       volatile unsigned long VideoInReg1CtrlB;        /* 0x003C */
-       volatile unsigned long Thread0Kicker;   /* 0x0040 */
-       volatile unsigned long Core2InputSign;  /* 0x0044 */
-       volatile unsigned long Thread0ProgCtr;  /* 0x0048 */
-       volatile unsigned long Thread1ProgCtr;  /* 0x004C */
-       volatile unsigned long Thread1Kicker;   /* 0x0050 */
-       volatile unsigned long GPRegister1;     /* 0x0054 */
-       volatile unsigned long GPRegister2;     /* 0x0058 */
-       volatile unsigned long GPRegister3;     /* 0x005C */
-       volatile unsigned long GPRegister4;     /* 0x0060 */
-       volatile unsigned long SerialIntA;      /* 0x0064 */
-
-       volatile unsigned long Fill0[6];        /* GAP 0x0068 - 0x007C */
-
-       volatile unsigned long SoftwareReset;   /* 0x0080 */
-       volatile unsigned long SerialIntB;      /* 0x0084 */
-
-       volatile unsigned long Fill1[37];       /* GAP 0x0088 - 0x011C */
-
-       volatile unsigned long ROMELQV; /* 0x011C */
-       volatile unsigned long WLWH;    /* 0x0120 */
-       volatile unsigned long ROMELWL; /* 0x0124 */
-
-       volatile unsigned long dwFill_1;        /* GAP 0x0128 */
-
-       volatile unsigned long IntStatus;       /* 0x012C */
-       volatile unsigned long IntMask; /* 0x0130 */
-       volatile unsigned long IntClear;        /* 0x0134 */
-
-       volatile unsigned long Fill2[6];        /* GAP 0x0138 - 0x014C */
-
-       volatile unsigned long ROMGPIOA;        /* 0x0150 */
-       volatile unsigned long ROMGPIOB;        /* 0x0154 */
-       volatile unsigned long ROMGPIOC;        /* 0x0158 */
-       volatile unsigned long ROMGPIOD;        /* 0x015C */
-
-       volatile unsigned long Fill3[2];        /* GAP 0x0160 - 0x0168 */
-
-       volatile unsigned long AGPIntID;        /* 0x0168 */
-       volatile unsigned long AGPIntClassCode; /* 0x016C */
-       volatile unsigned long AGPIntBIST;      /* 0x0170 */
-       volatile unsigned long AGPIntSSID;      /* 0x0174 */
-       volatile unsigned long AGPIntPMCSR;     /* 0x0178 */
-       volatile unsigned long VGAFrameBufBase; /* 0x017C */
-       volatile unsigned long VGANotify;       /* 0x0180 */
-       volatile unsigned long DACPLLMode;      /* 0x0184 */
-       volatile unsigned long Core1VideoClockDiv;      /* 0x0188 */
-       volatile unsigned long AGPIntStat;      /* 0x018C */
+       volatile u32 Thread0Enable;     /* 0x0000 */
+       volatile u32 Thread1Enable;     /* 0x0004 */
+       volatile u32 Thread0Recover;    /* 0x0008 */
+       volatile u32 Thread1Recover;    /* 0x000C */
+       volatile u32 Thread0Step;       /* 0x0010 */
+       volatile u32 Thread1Step;       /* 0x0014 */
+       volatile u32 VideoInStatus;     /* 0x0018 */
+       volatile u32 Core2InSignStart;  /* 0x001C */
+       volatile u32 Core1ResetVector;  /* 0x0020 */
+       volatile u32 Core1ROMOffset;    /* 0x0024 */
+       volatile u32 Core1ArbiterPriority;      /* 0x0028 */
+       volatile u32 VideoInControl;    /* 0x002C */
+       volatile u32 VideoInReg0CtrlA;  /* 0x0030 */
+       volatile u32 VideoInReg0CtrlB;  /* 0x0034 */
+       volatile u32 VideoInReg1CtrlA;  /* 0x0038 */
+       volatile u32 VideoInReg1CtrlB;  /* 0x003C */
+       volatile u32 Thread0Kicker;     /* 0x0040 */
+       volatile u32 Core2InputSign;    /* 0x0044 */
+       volatile u32 Thread0ProgCtr;    /* 0x0048 */
+       volatile u32 Thread1ProgCtr;    /* 0x004C */
+       volatile u32 Thread1Kicker;     /* 0x0050 */
+       volatile u32 GPRegister1;       /* 0x0054 */
+       volatile u32 GPRegister2;       /* 0x0058 */
+       volatile u32 GPRegister3;       /* 0x005C */
+       volatile u32 GPRegister4;       /* 0x0060 */
+       volatile u32 SerialIntA;        /* 0x0064 */
+
+       volatile u32 Fill0[6];  /* GAP 0x0068 - 0x007C */
+
+       volatile u32 SoftwareReset;     /* 0x0080 */
+       volatile u32 SerialIntB;        /* 0x0084 */
+
+       volatile u32 Fill1[37]; /* GAP 0x0088 - 0x011C */
+
+       volatile u32 ROMELQV;   /* 0x011C */
+       volatile u32 WLWH;      /* 0x0120 */
+       volatile u32 ROMELWL;   /* 0x0124 */
+
+       volatile u32 dwFill_1;  /* GAP 0x0128 */
+
+       volatile u32 IntStatus; /* 0x012C */
+       volatile u32 IntMask;   /* 0x0130 */
+       volatile u32 IntClear;  /* 0x0134 */
+
+       volatile u32 Fill2[6];  /* GAP 0x0138 - 0x014C */
+
+       volatile u32 ROMGPIOA;  /* 0x0150 */
+       volatile u32 ROMGPIOB;  /* 0x0154 */
+       volatile u32 ROMGPIOC;  /* 0x0158 */
+       volatile u32 ROMGPIOD;  /* 0x015C */
+
+       volatile u32 Fill3[2];  /* GAP 0x0160 - 0x0168 */
+
+       volatile u32 AGPIntID;  /* 0x0168 */
+       volatile u32 AGPIntClassCode;   /* 0x016C */
+       volatile u32 AGPIntBIST;        /* 0x0170 */
+       volatile u32 AGPIntSSID;        /* 0x0174 */
+       volatile u32 AGPIntPMCSR;       /* 0x0178 */
+       volatile u32 VGAFrameBufBase;   /* 0x017C */
+       volatile u32 VGANotify; /* 0x0180 */
+       volatile u32 DACPLLMode;        /* 0x0184 */
+       volatile u32 Core1VideoClockDiv;        /* 0x0188 */
+       volatile u32 AGPIntStat;        /* 0x018C */
 
        /*
-          volatile unsigned long Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400
-          volatile unsigned long Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table
-          volatile unsigned long Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604
-          volatile unsigned long Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680
-          volatile unsigned long Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC
+          volatile u32 Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400
+          volatile u32 Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table
+          volatile u32 Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604
+          volatile u32 Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680
+          volatile u32 Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC
         */
-       volatile unsigned long Fill4[412];      /* 0x0190 - 0x07FC */
-
-       volatile unsigned long TACtrlStreamBase;        /* 0x0800 */
-       volatile unsigned long TAObjDataBase;   /* 0x0804 */
-       volatile unsigned long TAPtrDataBase;   /* 0x0808 */
-       volatile unsigned long TARegionDataBase;        /* 0x080C */
-       volatile unsigned long TATailPtrBase;   /* 0x0810 */
-       volatile unsigned long TAPtrRegionSize; /* 0x0814 */
-       volatile unsigned long TAConfiguration; /* 0x0818 */
-       volatile unsigned long TAObjDataStartAddr;      /* 0x081C */
-       volatile unsigned long TAObjDataEndAddr;        /* 0x0820 */
-       volatile unsigned long TAXScreenClip;   /* 0x0824 */
-       volatile unsigned long TAYScreenClip;   /* 0x0828 */
-       volatile unsigned long TARHWClamp;      /* 0x082C */
-       volatile unsigned long TARHWCompare;    /* 0x0830 */
-       volatile unsigned long TAStart; /* 0x0834 */
-       volatile unsigned long TAObjReStart;    /* 0x0838 */
-       volatile unsigned long TAPtrReStart;    /* 0x083C */
-       volatile unsigned long TAStatus1;       /* 0x0840 */
-       volatile unsigned long TAStatus2;       /* 0x0844 */
-       volatile unsigned long TAIntStatus;     /* 0x0848 */
-       volatile unsigned long TAIntMask;       /* 0x084C */
-
-       volatile unsigned long Fill5[235];      /* GAP 0x0850 - 0x0BF8 */
-
-       volatile unsigned long TextureAddrThresh;       /* 0x0BFC */
-       volatile unsigned long Core1Translation;        /* 0x0C00 */
-       volatile unsigned long TextureAddrReMap;        /* 0x0C04 */
-       volatile unsigned long RenderOutAGPRemap;       /* 0x0C08 */
-       volatile unsigned long _3DRegionReadTrans;      /* 0x0C0C */
-       volatile unsigned long _3DPtrReadTrans; /* 0x0C10 */
-       volatile unsigned long _3DParamReadTrans;       /* 0x0C14 */
-       volatile unsigned long _3DRegionReadThresh;     /* 0x0C18 */
-       volatile unsigned long _3DPtrReadThresh;        /* 0x0C1C */
-       volatile unsigned long _3DParamReadThresh;      /* 0x0C20 */
-       volatile unsigned long _3DRegionReadAGPRemap;   /* 0x0C24 */
-       volatile unsigned long _3DPtrReadAGPRemap;      /* 0x0C28 */
-       volatile unsigned long _3DParamReadAGPRemap;    /* 0x0C2C */
-       volatile unsigned long ZBufferAGPRemap; /* 0x0C30 */
-       volatile unsigned long TAIndexAGPRemap; /* 0x0C34 */
-       volatile unsigned long TAVertexAGPRemap;        /* 0x0C38 */
-       volatile unsigned long TAUVAddrTrans;   /* 0x0C3C */
-       volatile unsigned long TATailPtrCacheTrans;     /* 0x0C40 */
-       volatile unsigned long TAParamWriteTrans;       /* 0x0C44 */
-       volatile unsigned long TAPtrWriteTrans; /* 0x0C48 */
-       volatile unsigned long TAParamWriteThresh;      /* 0x0C4C */
-       volatile unsigned long TAPtrWriteThresh;        /* 0x0C50 */
-       volatile unsigned long TATailPtrCacheAGPRe;     /* 0x0C54 */
-       volatile unsigned long TAParamWriteAGPRe;       /* 0x0C58 */
-       volatile unsigned long TAPtrWriteAGPRe; /* 0x0C5C */
-       volatile unsigned long SDRAMArbiterConf;        /* 0x0C60 */
-       volatile unsigned long SDRAMConf0;      /* 0x0C64 */
-       volatile unsigned long SDRAMConf1;      /* 0x0C68 */
-       volatile unsigned long SDRAMConf2;      /* 0x0C6C */
-       volatile unsigned long SDRAMRefresh;    /* 0x0C70 */
-       volatile unsigned long SDRAMPowerStat;  /* 0x0C74 */
-
-       volatile unsigned long Fill6[2];        /* GAP 0x0C78 - 0x0C7C */
-
-       volatile unsigned long RAMBistData;     /* 0x0C80 */
-       volatile unsigned long RAMBistCtrl;     /* 0x0C84 */
-       volatile unsigned long FIFOBistKey;     /* 0x0C88 */
-       volatile unsigned long RAMBistResult;   /* 0x0C8C */
-       volatile unsigned long FIFOBistResult;  /* 0x0C90 */
+       volatile u32 Fill4[412];        /* 0x0190 - 0x07FC */
+
+       volatile u32 TACtrlStreamBase;  /* 0x0800 */
+       volatile u32 TAObjDataBase;     /* 0x0804 */
+       volatile u32 TAPtrDataBase;     /* 0x0808 */
+       volatile u32 TARegionDataBase;  /* 0x080C */
+       volatile u32 TATailPtrBase;     /* 0x0810 */
+       volatile u32 TAPtrRegionSize;   /* 0x0814 */
+       volatile u32 TAConfiguration;   /* 0x0818 */
+       volatile u32 TAObjDataStartAddr;        /* 0x081C */
+       volatile u32 TAObjDataEndAddr;  /* 0x0820 */
+       volatile u32 TAXScreenClip;     /* 0x0824 */
+       volatile u32 TAYScreenClip;     /* 0x0828 */
+       volatile u32 TARHWClamp;        /* 0x082C */
+       volatile u32 TARHWCompare;      /* 0x0830 */
+       volatile u32 TAStart;   /* 0x0834 */
+       volatile u32 TAObjReStart;      /* 0x0838 */
+       volatile u32 TAPtrReStart;      /* 0x083C */
+       volatile u32 TAStatus1; /* 0x0840 */
+       volatile u32 TAStatus2; /* 0x0844 */
+       volatile u32 TAIntStatus;       /* 0x0848 */
+       volatile u32 TAIntMask; /* 0x084C */
+
+       volatile u32 Fill5[235];        /* GAP 0x0850 - 0x0BF8 */
+
+       volatile u32 TextureAddrThresh; /* 0x0BFC */
+       volatile u32 Core1Translation;  /* 0x0C00 */
+       volatile u32 TextureAddrReMap;  /* 0x0C04 */
+       volatile u32 RenderOutAGPRemap; /* 0x0C08 */
+       volatile u32 _3DRegionReadTrans;        /* 0x0C0C */
+       volatile u32 _3DPtrReadTrans;   /* 0x0C10 */
+       volatile u32 _3DParamReadTrans; /* 0x0C14 */
+       volatile u32 _3DRegionReadThresh;       /* 0x0C18 */
+       volatile u32 _3DPtrReadThresh;  /* 0x0C1C */
+       volatile u32 _3DParamReadThresh;        /* 0x0C20 */
+       volatile u32 _3DRegionReadAGPRemap;     /* 0x0C24 */
+       volatile u32 _3DPtrReadAGPRemap;        /* 0x0C28 */
+       volatile u32 _3DParamReadAGPRemap;      /* 0x0C2C */
+       volatile u32 ZBufferAGPRemap;   /* 0x0C30 */
+       volatile u32 TAIndexAGPRemap;   /* 0x0C34 */
+       volatile u32 TAVertexAGPRemap;  /* 0x0C38 */
+       volatile u32 TAUVAddrTrans;     /* 0x0C3C */
+       volatile u32 TATailPtrCacheTrans;       /* 0x0C40 */
+       volatile u32 TAParamWriteTrans; /* 0x0C44 */
+       volatile u32 TAPtrWriteTrans;   /* 0x0C48 */
+       volatile u32 TAParamWriteThresh;        /* 0x0C4C */
+       volatile u32 TAPtrWriteThresh;  /* 0x0C50 */
+       volatile u32 TATailPtrCacheAGPRe;       /* 0x0C54 */
+       volatile u32 TAParamWriteAGPRe; /* 0x0C58 */
+       volatile u32 TAPtrWriteAGPRe;   /* 0x0C5C */
+       volatile u32 SDRAMArbiterConf;  /* 0x0C60 */
+       volatile u32 SDRAMConf0;        /* 0x0C64 */
+       volatile u32 SDRAMConf1;        /* 0x0C68 */
+       volatile u32 SDRAMConf2;        /* 0x0C6C */
+       volatile u32 SDRAMRefresh;      /* 0x0C70 */
+       volatile u32 SDRAMPowerStat;    /* 0x0C74 */
+
+       volatile u32 Fill6[2];  /* GAP 0x0C78 - 0x0C7C */
+
+       volatile u32 RAMBistData;       /* 0x0C80 */
+       volatile u32 RAMBistCtrl;       /* 0x0C84 */
+       volatile u32 FIFOBistKey;       /* 0x0C88 */
+       volatile u32 RAMBistResult;     /* 0x0C8C */
+       volatile u32 FIFOBistResult;    /* 0x0C90 */
 
        /*
-          volatile unsigned long Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC
-          volatile unsigned long Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters
+          volatile u32 Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC
+          volatile u32 Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters
         */
 
-       volatile unsigned long Fill7[16];       /* 0x0c94 - 0x0cd0 */
+       volatile u32 Fill7[16]; /* 0x0c94 - 0x0cd0 */
 
-       volatile unsigned long SDRAMAddrSign;   /* 0x0CD4 */
-       volatile unsigned long SDRAMDataSign;   /* 0x0CD8 */
-       volatile unsigned long SDRAMSignConf;   /* 0x0CDC */
+       volatile u32 SDRAMAddrSign;     /* 0x0CD4 */
+       volatile u32 SDRAMDataSign;     /* 0x0CD8 */
+       volatile u32 SDRAMSignConf;     /* 0x0CDC */
 
        /* DWFILL; //GAP 0x0CE0 */
-       volatile unsigned long dwFill_2;
-
-       volatile unsigned long ISPSignature;    /* 0x0CE4 */
-
-       volatile unsigned long Fill8[454];      /*GAP 0x0CE8 - 0x13FC */
-
-       volatile unsigned long DACPrimAddress;  /* 0x1400 */
-       volatile unsigned long DACPrimSize;     /* 0x1404 */
-       volatile unsigned long DACCursorAddr;   /* 0x1408 */
-       volatile unsigned long DACCursorCtrl;   /* 0x140C */
-       volatile unsigned long DACOverlayAddr;  /* 0x1410 */
-       volatile unsigned long DACOverlayUAddr; /* 0x1414 */
-       volatile unsigned long DACOverlayVAddr; /* 0x1418 */
-       volatile unsigned long DACOverlaySize;  /* 0x141C */
-       volatile unsigned long DACOverlayVtDec; /* 0x1420 */
-
-       volatile unsigned long Fill9[9];        /* GAP 0x1424 - 0x1444 */
-
-       volatile unsigned long DACVerticalScal; /* 0x1448 */
-       volatile unsigned long DACPixelFormat;  /* 0x144C */
-       volatile unsigned long DACHorizontalScal;       /* 0x1450 */
-       volatile unsigned long DACVidWinStart;  /* 0x1454 */
-       volatile unsigned long DACVidWinEnd;    /* 0x1458 */
-       volatile unsigned long DACBlendCtrl;    /* 0x145C */
-       volatile unsigned long DACHorTim1;      /* 0x1460 */
-       volatile unsigned long DACHorTim2;      /* 0x1464 */
-       volatile unsigned long DACHorTim3;      /* 0x1468 */
-       volatile unsigned long DACVerTim1;      /* 0x146C */
-       volatile unsigned long DACVerTim2;      /* 0x1470 */
-       volatile unsigned long DACVerTim3;      /* 0x1474 */
-       volatile unsigned long DACBorderColor;  /* 0x1478 */
-       volatile unsigned long DACSyncCtrl;     /* 0x147C */
-       volatile unsigned long DACStreamCtrl;   /* 0x1480 */
-       volatile unsigned long DACLUTAddress;   /* 0x1484 */
-       volatile unsigned long DACLUTData;      /* 0x1488 */
-       volatile unsigned long DACBurstCtrl;    /* 0x148C */
-       volatile unsigned long DACCrcTrigger;   /* 0x1490 */
-       volatile unsigned long DACCrcDone;      /* 0x1494 */
-       volatile unsigned long DACCrcResult1;   /* 0x1498 */
-       volatile unsigned long DACCrcResult2;   /* 0x149C */
-       volatile unsigned long DACLinecount;    /* 0x14A0 */
-
-       volatile unsigned long Fill10[151];     /*GAP 0x14A4 - 0x16FC */
-
-       volatile unsigned long DigVidPortCtrl;  /* 0x1700 */
-       volatile unsigned long DigVidPortStat;  /* 0x1704 */
+       volatile u32 dwFill_2;
+
+       volatile u32 ISPSignature;      /* 0x0CE4 */
+
+       volatile u32 Fill8[454];        /*GAP 0x0CE8 - 0x13FC */
+
+       volatile u32 DACPrimAddress;    /* 0x1400 */
+       volatile u32 DACPrimSize;       /* 0x1404 */
+       volatile u32 DACCursorAddr;     /* 0x1408 */
+       volatile u32 DACCursorCtrl;     /* 0x140C */
+       volatile u32 DACOverlayAddr;    /* 0x1410 */
+       volatile u32 DACOverlayUAddr;   /* 0x1414 */
+       volatile u32 DACOverlayVAddr;   /* 0x1418 */
+       volatile u32 DACOverlaySize;    /* 0x141C */
+       volatile u32 DACOverlayVtDec;   /* 0x1420 */
+
+       volatile u32 Fill9[9];  /* GAP 0x1424 - 0x1444 */
+
+       volatile u32 DACVerticalScal;   /* 0x1448 */
+       volatile u32 DACPixelFormat;    /* 0x144C */
+       volatile u32 DACHorizontalScal; /* 0x1450 */
+       volatile u32 DACVidWinStart;    /* 0x1454 */
+       volatile u32 DACVidWinEnd;      /* 0x1458 */
+       volatile u32 DACBlendCtrl;      /* 0x145C */
+       volatile u32 DACHorTim1;        /* 0x1460 */
+       volatile u32 DACHorTim2;        /* 0x1464 */
+       volatile u32 DACHorTim3;        /* 0x1468 */
+       volatile u32 DACVerTim1;        /* 0x146C */
+       volatile u32 DACVerTim2;        /* 0x1470 */
+       volatile u32 DACVerTim3;        /* 0x1474 */
+       volatile u32 DACBorderColor;    /* 0x1478 */
+       volatile u32 DACSyncCtrl;       /* 0x147C */
+       volatile u32 DACStreamCtrl;     /* 0x1480 */
+       volatile u32 DACLUTAddress;     /* 0x1484 */
+       volatile u32 DACLUTData;        /* 0x1488 */
+       volatile u32 DACBurstCtrl;      /* 0x148C */
+       volatile u32 DACCrcTrigger;     /* 0x1490 */
+       volatile u32 DACCrcDone;        /* 0x1494 */
+       volatile u32 DACCrcResult1;     /* 0x1498 */
+       volatile u32 DACCrcResult2;     /* 0x149C */
+       volatile u32 DACLinecount;      /* 0x14A0 */
+
+       volatile u32 Fill10[151];       /*GAP 0x14A4 - 0x16FC */
+
+       volatile u32 DigVidPortCtrl;    /* 0x1700 */
+       volatile u32 DigVidPortStat;    /* 0x1704 */
 
        /*
-          volatile unsigned long Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC
-          volatile unsigned long Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT
+          volatile u32 Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC
+          volatile u32 Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT
         */
 
-       volatile unsigned long Fill11[1598];
+       volatile u32 Fill11[1598];
 
        /* DWFILL; //GAP 0x3000          ALUT 256MB offset */
-       volatile unsigned long Fill_3;
+       volatile u32 Fill_3;
 
 } STG4000REG;
 
index 4527cbf0a4ec61c4aca6956bbce7be89aea202e7..b061d709bc44ce78e114908f3e17e2eff54583d4 100644 (file)
@@ -420,7 +420,7 @@ static void mddi_resume(struct msm_mddi_client_data *cdata)
        mddi_set_auto_hibernate(&mddi->client_data, 1);
 }
 
-static int __init mddi_get_client_caps(struct mddi_info *mddi)
+static int __devinit mddi_get_client_caps(struct mddi_info *mddi)
 {
        int i, j;
 
@@ -622,9 +622,9 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
 
 static struct mddi_info mddi_info[2];
 
-static int __init mddi_clk_setup(struct platform_device *pdev,
-                                struct mddi_info *mddi,
-                                unsigned long clk_rate)
+static int __devinit mddi_clk_setup(struct platform_device *pdev,
+                                   struct mddi_info *mddi,
+                                   unsigned long clk_rate)
 {
        int ret;
 
index 260cca7ddb41c4da56b9009decb75052e973fbda..26e83d7fdd6feaaaaffacf3b637f34720465355c 100644 (file)
@@ -815,8 +815,15 @@ static int __devinit uvesafb_vbe_init(struct fb_info *info)
        par->pmi_setpal = pmi_setpal;
        par->ypan = ypan;
 
-       if (par->pmi_setpal || par->ypan)
-               uvesafb_vbe_getpmi(task, par);
+       if (par->pmi_setpal || par->ypan) {
+               if (__supported_pte_mask & _PAGE_NX) {
+                       par->pmi_setpal = par->ypan = 0;
+                       printk(KERN_WARNING "uvesafb: NX protection is actively."
+                               "We have better not to use the PMI.\n");
+               } else {
+                       uvesafb_vbe_getpmi(task, par);
+               }
+       }
 #else
        /* The protected mode interface is not available on non-x86. */
        par->pmi_setpal = par->ypan = 0;
index 05f0a80818a2b1c202e2d5104ced13b9802287d0..c2d05a8279fd25c3ca988d354b7335e4102780c0 100644 (file)
 #include <linux/slab.h>
 #include <linux/module.h>
 
+/*
+ * Balloon device works in 4K page units.  So each page is pointed to by
+ * multiple balloon pages.  All memory counters in this driver are in balloon
+ * page units.
+ */
+#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
+
 struct virtio_balloon
 {
        struct virtio_device *vdev;
@@ -42,8 +49,13 @@ struct virtio_balloon
        /* Waiting for host to ack the pages we released. */
        struct completion acked;
 
-       /* The pages we've told the Host we're not using. */
+       /* Number of balloon pages we've told the Host we're not using. */
        unsigned int num_pages;
+       /*
+        * The pages we've told the Host we're not using.
+        * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE
+        * to num_pages above.
+        */
        struct list_head pages;
 
        /* The array of pfns we tell the Host about. */
@@ -66,7 +78,13 @@ static u32 page_to_balloon_pfn(struct page *page)
 
        BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT);
        /* Convert pfn from Linux page size to balloon page size. */
-       return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT);
+       return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE;
+}
+
+static struct page *balloon_pfn_to_page(u32 pfn)
+{
+       BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE);
+       return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE);
 }
 
 static void balloon_ack(struct virtqueue *vq)
@@ -96,12 +114,23 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
        wait_for_completion(&vb->acked);
 }
 
+static void set_page_pfns(u32 pfns[], struct page *page)
+{
+       unsigned int i;
+
+       /* Set balloon pfns pointing at this page.
+        * Note that the first pfn points at start of the page. */
+       for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++)
+               pfns[i] = page_to_balloon_pfn(page) + i;
+}
+
 static void fill_balloon(struct virtio_balloon *vb, size_t num)
 {
        /* We can only do one array worth at a time. */
        num = min(num, ARRAY_SIZE(vb->pfns));
 
-       for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
+       for (vb->num_pfns = 0; vb->num_pfns < num;
+            vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
                struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
                                        __GFP_NOMEMALLOC | __GFP_NOWARN);
                if (!page) {
@@ -113,9 +142,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)
                        msleep(200);
                        break;
                }
-               vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page);
+               set_page_pfns(vb->pfns + vb->num_pfns, page);
+               vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
                totalram_pages--;
-               vb->num_pages++;
                list_add(&page->lru, &vb->pages);
        }
 
@@ -130,8 +159,9 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num)
 {
        unsigned int i;
 
-       for (i = 0; i < num; i++) {
-               __free_page(pfn_to_page(pfns[i]));
+       /* Find pfns pointing at start of each page, get pages and free them. */
+       for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
+               __free_page(balloon_pfn_to_page(pfns[i]));
                totalram_pages++;
        }
 }
@@ -143,11 +173,12 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
        /* We can only do one array worth at a time. */
        num = min(num, ARRAY_SIZE(vb->pfns));
 
-       for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
+       for (vb->num_pfns = 0; vb->num_pfns < num;
+            vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
                page = list_first_entry(&vb->pages, struct page, lru);
                list_del(&page->lru);
-               vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page);
-               vb->num_pages--;
+               set_page_pfns(vb->pfns + vb->num_pfns, page);
+               vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
        }
 
        /*
@@ -234,11 +265,14 @@ static void virtballoon_changed(struct virtio_device *vdev)
 
 static inline s64 towards_target(struct virtio_balloon *vb)
 {
-       u32 v;
+       __le32 v;
+       s64 target;
+
        vb->vdev->config->get(vb->vdev,
                              offsetof(struct virtio_balloon_config, num_pages),
                              &v, sizeof(v));
-       return (s64)v - vb->num_pages;
+       target = le32_to_cpu(v);
+       return target - vb->num_pages;
 }
 
 static void update_balloon_size(struct virtio_balloon *vb)
index 99d8151c824adbff0611a16f493dde6e6927de4c..1ffd03bf8e10dcb6b015e3e0b94a2a460f0d0dcd 100644 (file)
@@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
        vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
 
        if (use_ptemod)
-               vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP;
+               vma->vm_flags |= VM_DONTCOPY;
 
        vma->vm_private_data = map;
 
index b4d4eac761db6241042e60db3b604caa9150e91e..f100ce20b16b428880863ab768bf952ed84c43a9 100644 (file)
@@ -1029,6 +1029,7 @@ int gnttab_init(void)
        int i;
        unsigned int max_nr_glist_frames, nr_glist_frames;
        unsigned int nr_init_grefs;
+       int ret;
 
        nr_grant_frames = 1;
        boot_max_nr_grant_frames = __max_nr_grant_frames();
@@ -1047,12 +1048,16 @@ int gnttab_init(void)
        nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
        for (i = 0; i < nr_glist_frames; i++) {
                gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
-               if (gnttab_list[i] == NULL)
+               if (gnttab_list[i] == NULL) {
+                       ret = -ENOMEM;
                        goto ini_nomem;
+               }
        }
 
-       if (gnttab_resume() < 0)
-               return -ENODEV;
+       if (gnttab_resume() < 0) {
+               ret = -ENODEV;
+               goto ini_nomem;
+       }
 
        nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
 
@@ -1070,7 +1075,7 @@ int gnttab_init(void)
        for (i--; i >= 0; i--)
                free_page((unsigned long)gnttab_list[i]);
        kfree(gnttab_list);
-       return -ENOMEM;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(gnttab_init);
 
index 9e14ae6cd49c018bf45156d58c1ff4af7411fdc3..412b96cc5305746c20d554b1a6d2c7e55ab09686 100644 (file)
@@ -132,6 +132,7 @@ static void do_suspend(void)
        err = dpm_suspend_end(PMSG_FREEZE);
        if (err) {
                printk(KERN_ERR "dpm_suspend_end failed: %d\n", err);
+               si.cancelled = 0;
                goto out_resume;
        }
 
index 63616d7453e6d51989babcfaa643b807edbb1fc4..97f5d264c31ee6f464b92e5b6a2656bff6f00b7f 100644 (file)
@@ -234,7 +234,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
        if (dev_data)
                dev_data->ack_intr = 0;
 
-       return result;
+       return result > 0 ? 0 : result;
 }
 
 static
index f20c5f178b40e27f8d2e9a4fbdf6e2b05dbe9320..a31b54d488398675fc01eaa2878f0a21ec49fe46 100644 (file)
@@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev)
        return xenbus_read_otherend_details(xendev, "backend-id", "backend");
 }
 
-static int is_device_connecting(struct device *dev, void *data)
+static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential)
 {
        struct xenbus_device *xendev = to_xenbus_device(dev);
        struct device_driver *drv = data;
@@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data)
        if (drv && (dev->driver != drv))
                return 0;
 
+       if (ignore_nonessential) {
+               /* With older QEMU, for PVonHVM guests the guest config files
+                * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0']
+                * which is nonsensical as there is no PV FB (there can be
+                * a PVKB) running as HVM guest. */
+
+               if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0))
+                       return 0;
+
+               if ((strncmp(xendev->nodename, "device/vfb", 10) == 0))
+                       return 0;
+       }
        xendrv = to_xenbus_driver(dev->driver);
        return (xendev->state < XenbusStateConnected ||
                (xendev->state == XenbusStateConnected &&
                 xendrv->is_ready && !xendrv->is_ready(xendev)));
 }
+static int essential_device_connecting(struct device *dev, void *data)
+{
+       return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */);
+}
+static int non_essential_device_connecting(struct device *dev, void *data)
+{
+       return is_device_connecting(dev, data, false);
+}
 
-static int exists_connecting_device(struct device_driver *drv)
+static int exists_essential_connecting_device(struct device_driver *drv)
 {
        return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
-                               is_device_connecting);
+                               essential_device_connecting);
+}
+static int exists_non_essential_connecting_device(struct device_driver *drv)
+{
+       return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+                               non_essential_device_connecting);
 }
 
 static int print_device_status(struct device *dev, void *data)
@@ -192,6 +217,23 @@ static int print_device_status(struct device *dev, void *data)
 /* We only wait for device setup after most initcalls have run. */
 static int ready_to_wait_for_devices;
 
+static bool wait_loop(unsigned long start, unsigned int max_delay,
+                    unsigned int *seconds_waited)
+{
+       if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) {
+               if (!*seconds_waited)
+                       printk(KERN_WARNING "XENBUS: Waiting for "
+                              "devices to initialise: ");
+               *seconds_waited += 5;
+               printk("%us...", max_delay - *seconds_waited);
+               if (*seconds_waited == max_delay)
+                       return true;
+       }
+
+       schedule_timeout_interruptible(HZ/10);
+
+       return false;
+}
 /*
  * On a 5-minute timeout, wait for all devices currently configured.  We need
  * to do this to guarantee that the filesystems and / or network devices
@@ -215,19 +257,14 @@ static void wait_for_devices(struct xenbus_driver *xendrv)
        if (!ready_to_wait_for_devices || !xen_domain())
                return;
 
-       while (exists_connecting_device(drv)) {
-               if (time_after(jiffies, start + (seconds_waited+5)*HZ)) {
-                       if (!seconds_waited)
-                               printk(KERN_WARNING "XENBUS: Waiting for "
-                                      "devices to initialise: ");
-                       seconds_waited += 5;
-                       printk("%us...", 300 - seconds_waited);
-                       if (seconds_waited == 300)
-                               break;
-               }
-
-               schedule_timeout_interruptible(HZ/10);
-       }
+       while (exists_non_essential_connecting_device(drv))
+               if (wait_loop(start, 30, &seconds_waited))
+                       break;
+
+       /* Skips PVKB and PVFB check.*/
+       while (exists_essential_connecting_device(drv))
+               if (wait_loop(start, 270, &seconds_waited))
+                       break;
 
        if (seconds_waited)
                printk("\n");
index da887604dfc51929cd4cc17b10a943645b4618ef..67a6db3e1b6f83677009d2323c54dccd38dea63d 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -93,9 +93,8 @@ static void aio_free_ring(struct kioctx *ctx)
                put_page(info->ring_pages[i]);
 
        if (info->mmap_size) {
-               down_write(&ctx->mm->mmap_sem);
-               do_munmap(ctx->mm, info->mmap_base, info->mmap_size);
-               up_write(&ctx->mm->mmap_sem);
+               BUG_ON(ctx->mm != current->mm);
+               vm_munmap(info->mmap_base, info->mmap_size);
        }
 
        if (info->ring_pages && info->ring_pages != info->internal_pages)
@@ -389,6 +388,17 @@ void exit_aio(struct mm_struct *mm)
                                "exit_aio:ioctx still alive: %d %d %d\n",
                                atomic_read(&ctx->users), ctx->dead,
                                ctx->reqs_active);
+               /*
+                * We don't need to bother with munmap() here -
+                * exit_mmap(mm) is coming and it'll unmap everything.
+                * Since aio_free_ring() uses non-zero ->mmap_size
+                * as indicator that it needs to unmap the area,
+                * just set it to 0; aio_free_ring() is the only
+                * place that uses ->mmap_size, so it's safe.
+                * That way we get all munmap done to current->mm -
+                * all other callers have ctx->mm == current->mm.
+                */
+               ctx->ring_info.mmap_size = 0;
                put_ioctx(ctx);
        }
 }
index 2eb12f13593db771987c9c4e7cd30c16515fcf11..d146e181d10df8611050c16745195b9efca62c93 100644 (file)
@@ -50,9 +50,7 @@ static int set_brk(unsigned long start, unsigned long end)
        end = PAGE_ALIGN(end);
        if (end > start) {
                unsigned long addr;
-               down_write(&current->mm->mmap_sem);
-               addr = do_brk(start, end - start);
-               up_write(&current->mm->mmap_sem);
+               addr = vm_brk(start, end - start);
                if (BAD_ADDR(addr))
                        return addr;
        }
@@ -280,9 +278,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                pos = 32;
                map_size = ex.a_text+ex.a_data;
 #endif
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(text_addr & PAGE_MASK, map_size);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(text_addr & PAGE_MASK, map_size);
                if (error != (text_addr & PAGE_MASK)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
@@ -313,9 +309,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
 
                if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
                        loff_t pos = fd_offset;
-                       down_write(&current->mm->mmap_sem);
-                       do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
-                       up_write(&current->mm->mmap_sem);
+                       vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
                        bprm->file->f_op->read(bprm->file,
                                        (char __user *)N_TXTADDR(ex),
                                        ex.a_text+ex.a_data, &pos);
@@ -325,24 +319,20 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                        goto beyond_if;
                }
 
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
+               error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
                        PROT_READ | PROT_EXEC,
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
                        fd_offset);
-               up_write(&current->mm->mmap_sem);
 
                if (error != N_TXTADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
                }
 
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
+               error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
                                PROT_READ | PROT_WRITE | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
                                fd_offset + ex.a_text);
-               up_write(&current->mm->mmap_sem);
                if (error != N_DATADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
@@ -412,9 +402,7 @@ static int load_aout_library(struct file *file)
                               "N_TXTOFF is not page aligned. Please convert library: %s\n",
                               file->f_path.dentry->d_name.name);
                }
-               down_write(&current->mm->mmap_sem);
-               do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
-               up_write(&current->mm->mmap_sem);
+               vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
                
                file->f_op->read(file, (char __user *)start_addr,
                        ex.a_text + ex.a_data, &pos);
@@ -425,12 +413,10 @@ static int load_aout_library(struct file *file)
                goto out;
        }
        /* Now use mmap to map the library into memory. */
-       down_write(&current->mm->mmap_sem);
-       error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
+       error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
                        N_TXTOFF(ex));
-       up_write(&current->mm->mmap_sem);
        retval = error;
        if (error != start_addr)
                goto out;
@@ -438,9 +424,7 @@ static int load_aout_library(struct file *file)
        len = PAGE_ALIGN(ex.a_text + ex.a_data);
        bss = ex.a_text + ex.a_data + ex.a_bss;
        if (bss > len) {
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(start_addr + len, bss - len);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(start_addr + len, bss - len);
                retval = error;
                if (error != start_addr + len)
                        goto out;
index 48ffb3dc610a7c9d6ea4428dd441666b4605b2c4..16f7354170725e050e69bf971aeb63eb57598c3e 100644 (file)
@@ -82,9 +82,7 @@ static int set_brk(unsigned long start, unsigned long end)
        end = ELF_PAGEALIGN(end);
        if (end > start) {
                unsigned long addr;
-               down_write(&current->mm->mmap_sem);
-               addr = do_brk(start, end - start);
-               up_write(&current->mm->mmap_sem);
+               addr = vm_brk(start, end - start);
                if (BAD_ADDR(addr))
                        return addr;
        }
@@ -514,9 +512,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
                elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);
 
                /* Map the last of the bss segment */
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(elf_bss, last_bss - elf_bss);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(elf_bss, last_bss - elf_bss);
                if (BAD_ADDR(error))
                        goto out_close;
        }
@@ -962,10 +958,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                   and some applications "depend" upon this behavior.
                   Since we do not have the power to recompile these, we
                   emulate the SVr4 behavior. Sigh. */
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
+               error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE, 0);
-               up_write(&current->mm->mmap_sem);
        }
 
 #ifdef ELF_PLAT_INIT
@@ -1050,8 +1044,7 @@ static int load_elf_library(struct file *file)
                eppnt++;
 
        /* Now use mmap to map the library into memory. */
-       down_write(&current->mm->mmap_sem);
-       error = do_mmap(file,
+       error = vm_mmap(file,
                        ELF_PAGESTART(eppnt->p_vaddr),
                        (eppnt->p_filesz +
                         ELF_PAGEOFFSET(eppnt->p_vaddr)),
@@ -1059,7 +1052,6 @@ static int load_elf_library(struct file *file)
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
                        (eppnt->p_offset -
                         ELF_PAGEOFFSET(eppnt->p_vaddr)));
-       up_write(&current->mm->mmap_sem);
        if (error != ELF_PAGESTART(eppnt->p_vaddr))
                goto out_free_ph;
 
@@ -1072,11 +1064,8 @@ static int load_elf_library(struct file *file)
        len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
                            ELF_MIN_ALIGN - 1);
        bss = eppnt->p_memsz + eppnt->p_vaddr;
-       if (bss > len) {
-               down_write(&current->mm->mmap_sem);
-               do_brk(len, bss - len);
-               up_write(&current->mm->mmap_sem);
-       }
+       if (bss > len)
+               vm_brk(len, bss - len);
        error = 0;
 
 out_free_ph:
index 9bd5612a8224fc5c6374d4dcc27ff99a58ee76e5..d390a0fffc65e1794c1985a2a626a87ed16c124b 100644 (file)
@@ -390,21 +390,17 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
            (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))
                stack_prot |= PROT_EXEC;
 
-       down_write(&current->mm->mmap_sem);
-       current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot,
+       current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot,
                                         MAP_PRIVATE | MAP_ANONYMOUS |
                                         MAP_UNINITIALIZED | MAP_GROWSDOWN,
                                         0);
 
        if (IS_ERR_VALUE(current->mm->start_brk)) {
-               up_write(&current->mm->mmap_sem);
                retval = current->mm->start_brk;
                current->mm->start_brk = 0;
                goto error_kill;
        }
 
-       up_write(&current->mm->mmap_sem);
-
        current->mm->brk = current->mm->start_brk;
        current->mm->context.end_brk = current->mm->start_brk;
        current->mm->context.end_brk +=
@@ -955,10 +951,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
        if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
                mflags |= MAP_EXECUTABLE;
 
-       down_write(&mm->mmap_sem);
-       maddr = do_mmap(NULL, load_addr, top - base,
+       maddr = vm_mmap(NULL, load_addr, top - base,
                        PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
-       up_write(&mm->mmap_sem);
        if (IS_ERR_VALUE(maddr))
                return (int) maddr;
 
@@ -1096,10 +1090,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
 
                /* create the mapping */
                disp = phdr->p_vaddr & ~PAGE_MASK;
-               down_write(&mm->mmap_sem);
-               maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
+               maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
                                phdr->p_offset - disp);
-               up_write(&mm->mmap_sem);
 
                kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
                       loop, phdr->p_memsz + disp, prot, flags,
@@ -1143,10 +1135,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
                        unsigned long xmaddr;
 
                        flags |= MAP_FIXED | MAP_ANONYMOUS;
-                       down_write(&mm->mmap_sem);
-                       xmaddr = do_mmap(NULL, xaddr, excess - excess1,
+                       xmaddr = vm_mmap(NULL, xaddr, excess - excess1,
                                         prot, flags, 0);
-                       up_write(&mm->mmap_sem);
 
                        kdebug("mmap[%d] <anon>"
                               " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
index 024d20ee3ca3a617e377045fa7cf6d0706a4ed43..6b2daf99fab8bcd91d314f0abd951b8472a092d2 100644 (file)
@@ -542,10 +542,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                 */
                DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
 
-               down_write(&current->mm->mmap_sem);
-               textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
+               textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
                                  MAP_PRIVATE|MAP_EXECUTABLE, 0);
-               up_write(&current->mm->mmap_sem);
                if (!textpos || IS_ERR_VALUE(textpos)) {
                        if (!textpos)
                                textpos = (unsigned long) -ENOMEM;
@@ -556,10 +554,8 @@ static int load_flat_file(struct linux_binprm * bprm,
 
                len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
                len = PAGE_ALIGN(len);
-               down_write(&current->mm->mmap_sem);
-               realdatastart = do_mmap(0, 0, len,
+               realdatastart = vm_mmap(0, 0, len,
                        PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
-               up_write(&current->mm->mmap_sem);
 
                if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) {
                        if (!realdatastart)
@@ -603,10 +599,8 @@ static int load_flat_file(struct linux_binprm * bprm,
 
                len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
                len = PAGE_ALIGN(len);
-               down_write(&current->mm->mmap_sem);
-               textpos = do_mmap(0, 0, len,
+               textpos = vm_mmap(0, 0, len,
                        PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
-               up_write(&current->mm->mmap_sem);
 
                if (!textpos || IS_ERR_VALUE(textpos)) {
                        if (!textpos)
index e4fc746629a70000dc2ace0aac62038717add3f1..4517aaff61b4b874df51113698524fc20d44578c 100644 (file)
@@ -147,10 +147,8 @@ static int map_som_binary(struct file *file,
        code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);
        current->mm->start_code = code_start;
        current->mm->end_code = code_start + code_size;
-       down_write(&current->mm->mmap_sem);
-       retval = do_mmap(file, code_start, code_size, prot,
+       retval = vm_mmap(file, code_start, code_size, prot,
                        flags, SOM_PAGESTART(hpuxhdr->exec_tfile));
-       up_write(&current->mm->mmap_sem);
        if (retval < 0 && retval > -1024)
                goto out;
 
@@ -158,20 +156,16 @@ static int map_som_binary(struct file *file,
        data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);
        current->mm->start_data = data_start;
        current->mm->end_data = bss_start = data_start + data_size;
-       down_write(&current->mm->mmap_sem);
-       retval = do_mmap(file, data_start, data_size,
+       retval = vm_mmap(file, data_start, data_size,
                        prot | PROT_WRITE, flags,
                        SOM_PAGESTART(hpuxhdr->exec_dfile));
-       up_write(&current->mm->mmap_sem);
        if (retval < 0 && retval > -1024)
                goto out;
 
        som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);
        current->mm->start_brk = current->mm->brk = som_brk;
-       down_write(&current->mm->mmap_sem);
-       retval = do_mmap(NULL, bss_start, som_brk - bss_start,
+       retval = vm_mmap(NULL, bss_start, som_brk - bss_start,
                        prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0);
-       up_write(&current->mm->mmap_sem);
        if (retval > 0 || retval < -1024)
                retval = 0;
 out:
index d286b40a56715edbddb68c3ba1e5d4403ab94153..86eff48dab786d525d3395d31dcf3f45a11dafc1 100644 (file)
@@ -405,6 +405,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
                        bio_put(bio);
 
                        bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS);
+                       BUG_ON(!bio);
                        bio->bi_private = cb;
                        bio->bi_end_io = end_compressed_bio_write;
                        bio_add_page(bio, page, PAGE_CACHE_SIZE, 0);
@@ -687,6 +688,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 
                        comp_bio = compressed_bio_alloc(bdev, cur_disk_byte,
                                                        GFP_NOFS);
+                       BUG_ON(!comp_bio);
                        comp_bio->bi_private = cb;
                        comp_bio->bi_end_io = end_compressed_bio_read;
 
index 5b8ef8eb35218e0f595ee93069fc1ccab49c6b1e..3f65a812e282d00744e9de5b89acc09ead08acb8 100644 (file)
@@ -2166,7 +2166,7 @@ BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item,
 
 static inline bool btrfs_root_readonly(struct btrfs_root *root)
 {
-       return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY;
+       return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0;
 }
 
 /* struct btrfs_root_backup */
index a84420491c11075093cc2d76f4c080953f9fc55b..2b35f8d14bb9a14c7f1539268dce04973413512f 100644 (file)
@@ -529,9 +529,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
         * allocate blocks for the tree root we can't do the fast caching since
         * we likely hold important locks.
         */
-       if (trans && (!trans->transaction->in_commit) &&
-           (root && root != root->fs_info->tree_root) &&
-           btrfs_test_opt(root, SPACE_CACHE)) {
+       if (fs_info->mount_opt & BTRFS_MOUNT_SPACE_CACHE) {
                ret = load_free_space_cache(fs_info, cache);
 
                spin_lock(&cache->lock);
@@ -3152,15 +3150,14 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
 /*
  * returns target flags in extended format or 0 if restripe for this
  * chunk_type is not in progress
+ *
+ * should be called with either volume_mutex or balance_lock held
  */
 static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags)
 {
        struct btrfs_balance_control *bctl = fs_info->balance_ctl;
        u64 target = 0;
 
-       BUG_ON(!mutex_is_locked(&fs_info->volume_mutex) &&
-              !spin_is_locked(&fs_info->balance_lock));
-
        if (!bctl)
                return 0;
 
@@ -4205,7 +4202,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info)
        num_bytes += div64_u64(data_used + meta_used, 50);
 
        if (num_bytes * 3 > meta_used)
-               num_bytes = div64_u64(meta_used, 3) * 2;
+               num_bytes = div64_u64(meta_used, 3);
 
        return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10);
 }
index 8d904dd7ea9f6175012d8abdcf810a7d8d200ae7..cd4b5e40022128894dacfa5d51e60b400a0793bc 100644 (file)
@@ -1937,7 +1937,7 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb,
        struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree;
        u64 start = eb->start;
        unsigned long i, num_pages = num_extent_pages(eb->start, eb->len);
-       int ret;
+       int ret = 0;
 
        for (i = 0; i < num_pages; i++) {
                struct page *p = extent_buffer_page(eb, i);
@@ -2180,6 +2180,10 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
        }
 
        bio = bio_alloc(GFP_NOFS, 1);
+       if (!bio) {
+               free_io_failure(inode, failrec, 0);
+               return -EIO;
+       }
        bio->bi_private = state;
        bio->bi_end_io = failed_bio->bi_end_io;
        bio->bi_sector = failrec->logical >> 9;
index e88330d3df52f259b42e3fc5e0f865befd172e20..202008ec367d4c4c2cfcf73f7289692dd910b25c 100644 (file)
@@ -747,13 +747,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
        bool matched;
        u64 used = btrfs_block_group_used(&block_group->item);
 
-       /*
-        * If we're unmounting then just return, since this does a search on the
-        * normal root and not the commit root and we could deadlock.
-        */
-       if (btrfs_fs_closing(fs_info))
-               return 0;
-
        /*
         * If this block group has been marked to be cleared for one reason or
         * another then we can't trust the on disk cache, so just return.
@@ -768,6 +761,8 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
        path = btrfs_alloc_path();
        if (!path)
                return 0;
+       path->search_commit_root = 1;
+       path->skip_locking = 1;
 
        inode = lookup_free_space_inode(root, block_group, path);
        if (IS_ERR(inode)) {
index 90acc82046c3ab80b459ff076ced3e97ea4b0e3c..bc015f77f3ea2e2c0500d4428ce2cbd54aa6834f 100644 (file)
@@ -1044,6 +1044,8 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
 
                BUG_ON(!page->page);
                bio = bio_alloc(GFP_NOFS, 1);
+               if (!bio)
+                       return -EIO;
                bio->bi_bdev = page->bdev;
                bio->bi_sector = page->physical >> 9;
                bio->bi_end_io = scrub_complete_bio_end_io;
@@ -1171,6 +1173,8 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
                DECLARE_COMPLETION_ONSTACK(complete);
 
                bio = bio_alloc(GFP_NOFS, 1);
+               if (!bio)
+                       return -EIO;
                bio->bi_bdev = page_bad->bdev;
                bio->bi_sector = page_bad->physical >> 9;
                bio->bi_end_io = scrub_complete_bio_end_io;
index 8da29e8e4de15999397f137825bb378c2e983ede..11b77a59db629923368f993b3a3b5f6e7a883f15 100644 (file)
@@ -480,6 +480,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
        struct btrfs_transaction *cur_trans = trans->transaction;
        struct btrfs_fs_info *info = root->fs_info;
        int count = 0;
+       int err = 0;
 
        if (--trans->use_count) {
                trans->block_rsv = trans->orig_rsv;
@@ -532,18 +533,18 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
 
        if (current->journal_info == trans)
                current->journal_info = NULL;
-       memset(trans, 0, sizeof(*trans));
-       kmem_cache_free(btrfs_trans_handle_cachep, trans);
 
        if (throttle)
                btrfs_run_delayed_iputs(root);
 
        if (trans->aborted ||
            root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
-               return -EIO;
+               err = -EIO;
        }
 
-       return 0;
+       memset(trans, 0, sizeof(*trans));
+       kmem_cache_free(btrfs_trans_handle_cachep, trans);
+       return err;
 }
 
 int btrfs_end_transaction(struct btrfs_trans_handle *trans,
index a872b48be0ae15fd77eff56e2c529470ddde0b7f..759d02486d7ccb2dcb2ff1b1334396cc219880ca 100644 (file)
@@ -3833,6 +3833,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
                int sub_stripes = 0;
                u64 stripes_per_dev = 0;
                u32 remaining_stripes = 0;
+               u32 last_stripe = 0;
 
                if (map->type &
                    (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) {
@@ -3846,6 +3847,8 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
                                                      stripe_nr_orig,
                                                      factor,
                                                      &remaining_stripes);
+                       div_u64_rem(stripe_nr_end - 1, factor, &last_stripe);
+                       last_stripe *= sub_stripes;
                }
 
                for (i = 0; i < num_stripes; i++) {
@@ -3858,16 +3861,29 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
                                         BTRFS_BLOCK_GROUP_RAID10)) {
                                bbio->stripes[i].length = stripes_per_dev *
                                                          map->stripe_len;
+
                                if (i / sub_stripes < remaining_stripes)
                                        bbio->stripes[i].length +=
                                                map->stripe_len;
+
+                               /*
+                                * Special for the first stripe and
+                                * the last stripe:
+                                *
+                                * |-------|...|-------|
+                                *     |----------|
+                                *    off     end_off
+                                */
                                if (i < sub_stripes)
                                        bbio->stripes[i].length -=
                                                stripe_offset;
-                               if ((i / sub_stripes + 1) %
-                                   sub_stripes == remaining_stripes)
+
+                               if (stripe_index >= last_stripe &&
+                                   stripe_index <= (last_stripe +
+                                                    sub_stripes - 1))
                                        bbio->stripes[i].length -=
                                                stripe_end_offset;
+
                                if (i == sub_stripes - 1)
                                        stripe_offset = 0;
                        } else
index d81e933a796b1a07aa41ad6987f6f8d328594746..f31dc9ac37b76f0014fe5584c88d35d836bb1659 100644 (file)
@@ -109,6 +109,8 @@ enum {
 
        /* Options which could be blank */
        Opt_blank_pass,
+       Opt_blank_user,
+       Opt_blank_ip,
 
        Opt_err
 };
@@ -183,11 +185,15 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_wsize, "wsize=%s" },
        { Opt_actimeo, "actimeo=%s" },
 
+       { Opt_blank_user, "user=" },
+       { Opt_blank_user, "username=" },
        { Opt_user, "user=%s" },
        { Opt_user, "username=%s" },
        { Opt_blank_pass, "pass=" },
        { Opt_pass, "pass=%s" },
        { Opt_pass, "password=%s" },
+       { Opt_blank_ip, "ip=" },
+       { Opt_blank_ip, "addr=" },
        { Opt_ip, "ip=%s" },
        { Opt_ip, "addr=%s" },
        { Opt_unc, "unc=%s" },
@@ -1117,7 +1123,7 @@ static int get_option_ul(substring_t args[], unsigned long *option)
        string = match_strdup(args);
        if (string == NULL)
                return -ENOMEM;
-       rc = kstrtoul(string, 10, option);
+       rc = kstrtoul(string, 0, option);
        kfree(string);
 
        return rc;
@@ -1534,15 +1540,17 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
 
                /* String Arguments */
 
+               case Opt_blank_user:
+                       /* null user, ie. anonymous authentication */
+                       vol->nullauth = 1;
+                       vol->username = NULL;
+                       break;
                case Opt_user:
                        string = match_strdup(args);
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               /* null user, ie. anonymous authentication */
-                               vol->nullauth = 1;
-                       } else if (strnlen(string, MAX_USERNAME_SIZE) >
+                       if (strnlen(string, MAX_USERNAME_SIZE) >
                                                        MAX_USERNAME_SIZE) {
                                printk(KERN_WARNING "CIFS: username too long\n");
                                goto cifs_parse_mount_err;
@@ -1611,14 +1619,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        }
                        vol->password[j] = '\0';
                        break;
+               case Opt_blank_ip:
+                       vol->UNCip = NULL;
+                       break;
                case Opt_ip:
                        string = match_strdup(args);
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               vol->UNCip = NULL;
-                       } else if (strnlen(string, INET6_ADDRSTRLEN) >
+                       if (strnlen(string, INET6_ADDRSTRLEN) >
                                                INET6_ADDRSTRLEN) {
                                printk(KERN_WARNING "CIFS: ip address "
                                                    "too long\n");
@@ -1636,12 +1645,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: invalid path to "
-                                                   "network resource\n");
-                               goto cifs_parse_mount_err;
-                       }
-
                        temp_len = strnlen(string, 300);
                        if (temp_len  == 300) {
                                printk(KERN_WARNING "CIFS: UNC name too long\n");
@@ -1670,11 +1673,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: invalid domain"
-                                                   " name\n");
-                               goto cifs_parse_mount_err;
-                       } else if (strnlen(string, 256) == 256) {
+                       if (strnlen(string, 256) == 256) {
                                printk(KERN_WARNING "CIFS: domain name too"
                                                    " long\n");
                                goto cifs_parse_mount_err;
@@ -1693,11 +1692,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: srcaddr value not"
-                                                   " specified\n");
-                               goto cifs_parse_mount_err;
-                       } else if (!cifs_convert_address(
+                       if (!cifs_convert_address(
                                        (struct sockaddr *)&vol->srcaddr,
                                        string, strlen(string))) {
                                printk(KERN_WARNING "CIFS:  Could not parse"
@@ -1710,11 +1705,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: Invalid path"
-                                                   " prefix\n");
-                               goto cifs_parse_mount_err;
-                       }
                        temp_len = strnlen(string, 1024);
                        if (string[0] != '/')
                                temp_len++; /* missing leading slash */
@@ -1742,11 +1732,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: Invalid iocharset"
-                                                   " specified\n");
-                               goto cifs_parse_mount_err;
-                       } else if (strnlen(string, 1024) >= 65) {
+                       if (strnlen(string, 1024) >= 65) {
                                printk(KERN_WARNING "CIFS: iocharset name "
                                                    "too long.\n");
                                goto cifs_parse_mount_err;
@@ -1771,11 +1757,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: No socket option"
-                                                   " specified\n");
-                               goto cifs_parse_mount_err;
-                       }
                        if (strnicmp(string, "TCP_NODELAY", 11) == 0)
                                vol->sockopt_tcp_nodelay = 1;
                        break;
@@ -1784,12 +1765,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: Invalid (empty)"
-                                                   " netbiosname\n");
-                               break;
-                       }
-
                        memset(vol->source_rfc1001_name, 0x20,
                                RFC1001_NAME_LEN);
                        /*
@@ -1817,11 +1792,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: Empty server"
-                                       " netbiosname specified\n");
-                               break;
-                       }
                        /* last byte, type, is 0x20 for servr type */
                        memset(vol->target_rfc1001_name, 0x20,
                                RFC1001_NAME_LEN_WITH_NULL);
@@ -1848,12 +1818,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               cERROR(1, "no protocol version specified"
-                                         " after vers= mount option");
-                               goto cifs_parse_mount_err;
-                       }
-
                        if (strnicmp(string, "cifs", 4) == 0 ||
                            strnicmp(string, "1", 1) == 0) {
                                /* This is the default */
@@ -1868,12 +1832,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: no security flavor"
-                                                   " specified\n");
-                               break;
-                       }
-
                        if (cifs_parse_security_flavors(string, vol) != 0)
                                goto cifs_parse_mount_err;
                        break;
index fa5c07d51dccf2cb1b66d4b2d04a4eec8a92e7da..4c58d4a3adc4f29c6a2829bc54ac4be122c77ae7 100644 (file)
@@ -1736,6 +1736,18 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
        if (now && conv && !(lkb->lkb_exflags & DLM_LKF_QUECVT))
                return 1;
 
+       /*
+        * Even if the convert is compat with all granted locks,
+        * QUECVT forces it behind other locks on the convert queue.
+        */
+
+       if (now && conv && (lkb->lkb_exflags & DLM_LKF_QUECVT)) {
+               if (list_empty(&r->res_convertqueue))
+                       return 1;
+               else
+                       goto out;
+       }
+
        /*
         * The NOORDER flag is set to avoid the standard vms rules on grant
         * order.
index ab2594a30f86f8a39a0fc918a0bdc69e1d7c9e0f..0e01e90add8bc42f1492a73a2e1e78331b8ae134 100644 (file)
@@ -1203,9 +1203,6 @@ struct ext4_sb_info {
        unsigned long s_ext_blocks;
        unsigned long s_ext_extents;
 #endif
-       /* ext4 extent cache stats */
-       unsigned long extent_cache_hits;
-       unsigned long extent_cache_misses;
 
        /* for buddy allocator */
        struct ext4_group_info ***s_group_info;
index 1421938e6792a4f5426cbd8f4d218eea4f2192f9..abcdeab67f5232b66d4aa5a6cbb88838094f6247 100644 (file)
@@ -2066,10 +2066,6 @@ static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block,
                ret = 1;
        }
 errout:
-       if (!ret)
-               sbi->extent_cache_misses++;
-       else
-               sbi->extent_cache_hits++;
        trace_ext4_ext_in_cache(inode, block, ret);
        spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
        return ret;
@@ -2882,7 +2878,7 @@ static int ext4_split_extent_at(handle_t *handle,
                if (err)
                        goto fix_extent_len;
                /* update the extent length and mark as initialized */
-               ex->ee_len = cpu_to_le32(ee_len);
+               ex->ee_len = cpu_to_le16(ee_len);
                ext4_ext_try_to_merge(inode, path, ex);
                err = ext4_ext_dirty(handle, inode, path + depth);
                goto out;
index ceebaf853beb74c7e139e63f46bf44975696566b..6da193564e43b2dc6862dcca4c4aa52689479939 100644 (file)
@@ -1305,20 +1305,20 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
                ext4_msg(sb, KERN_ERR,
                        "Cannot change journaled "
                        "quota options when quota turned on");
-               return 0;
+               return -1;
        }
        qname = match_strdup(args);
        if (!qname) {
                ext4_msg(sb, KERN_ERR,
                        "Not enough memory for storing quotafile name");
-               return 0;
+               return -1;
        }
        if (sbi->s_qf_names[qtype] &&
                strcmp(sbi->s_qf_names[qtype], qname)) {
                ext4_msg(sb, KERN_ERR,
                        "%s quota file already specified", QTYPE2NAME(qtype));
                kfree(qname);
-               return 0;
+               return -1;
        }
        sbi->s_qf_names[qtype] = qname;
        if (strchr(sbi->s_qf_names[qtype], '/')) {
@@ -1326,7 +1326,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
                        "quotafile must be on filesystem root");
                kfree(sbi->s_qf_names[qtype]);
                sbi->s_qf_names[qtype] = NULL;
-               return 0;
+               return -1;
        }
        set_opt(sb, QUOTA);
        return 1;
@@ -1341,7 +1341,7 @@ static int clear_qf_name(struct super_block *sb, int qtype)
                sbi->s_qf_names[qtype]) {
                ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options"
                        " when quota turned on");
-               return 0;
+               return -1;
        }
        /*
         * The space will be released later when all options are confirmed
@@ -1450,6 +1450,16 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
        const struct mount_opts *m;
        int arg = 0;
 
+#ifdef CONFIG_QUOTA
+       if (token == Opt_usrjquota)
+               return set_qf_name(sb, USRQUOTA, &args[0]);
+       else if (token == Opt_grpjquota)
+               return set_qf_name(sb, GRPQUOTA, &args[0]);
+       else if (token == Opt_offusrjquota)
+               return clear_qf_name(sb, USRQUOTA);
+       else if (token == Opt_offgrpjquota)
+               return clear_qf_name(sb, GRPQUOTA);
+#endif
        if (args->from && match_int(args, &arg))
                return -1;
        switch (token) {
@@ -1549,18 +1559,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
                                sbi->s_mount_opt |= m->mount_opt;
                        }
 #ifdef CONFIG_QUOTA
-               } else if (token == Opt_usrjquota) {
-                       if (!set_qf_name(sb, USRQUOTA, &args[0]))
-                               return -1;
-               } else if (token == Opt_grpjquota) {
-                       if (!set_qf_name(sb, GRPQUOTA, &args[0]))
-                               return -1;
-               } else if (token == Opt_offusrjquota) {
-                       if (!clear_qf_name(sb, USRQUOTA))
-                               return -1;
-               } else if (token == Opt_offgrpjquota) {
-                       if (!clear_qf_name(sb, GRPQUOTA))
-                               return -1;
                } else if (m->flags & MOPT_QFMT) {
                        if (sb_any_quota_loaded(sb) &&
                            sbi->s_jquota_fmt != m->mount_opt) {
@@ -2366,18 +2364,6 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a,
                          EXT4_SB(sb)->s_sectors_written_start) >> 1)));
 }
 
-static ssize_t extent_cache_hits_show(struct ext4_attr *a,
-                                     struct ext4_sb_info *sbi, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_hits);
-}
-
-static ssize_t extent_cache_misses_show(struct ext4_attr *a,
-                                       struct ext4_sb_info *sbi, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_misses);
-}
-
 static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
                                          struct ext4_sb_info *sbi,
                                          const char *buf, size_t count)
@@ -2435,8 +2421,6 @@ static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store)
 EXT4_RO_ATTR(delayed_allocation_blocks);
 EXT4_RO_ATTR(session_write_kbytes);
 EXT4_RO_ATTR(lifetime_write_kbytes);
-EXT4_RO_ATTR(extent_cache_hits);
-EXT4_RO_ATTR(extent_cache_misses);
 EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show,
                 inode_readahead_blks_store, s_inode_readahead_blks);
 EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
@@ -2452,8 +2436,6 @@ static struct attribute *ext4_attrs[] = {
        ATTR_LIST(delayed_allocation_blocks),
        ATTR_LIST(session_write_kbytes),
        ATTR_LIST(lifetime_write_kbytes),
-       ATTR_LIST(extent_cache_hits),
-       ATTR_LIST(extent_cache_misses),
        ATTR_LIST(inode_readahead_blks),
        ATTR_LIST(inode_goal),
        ATTR_LIST(mb_stats),
index 206632887bb40ccf48bb80b96e497c2107c172d9..df5ac048dc74e6b33174a69dc36b3a5b6084fd74 100644 (file)
@@ -387,9 +387,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
        if (fc->no_create)
                return -ENOSYS;
 
-       if (flags & O_DIRECT)
-               return -EINVAL;
-
        forget = fuse_alloc_forget();
        if (!forget)
                return -ENOMEM;
@@ -644,13 +641,12 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
        fuse_put_request(fc, req);
        if (!err) {
                struct inode *inode = entry->d_inode;
+               struct fuse_inode *fi = get_fuse_inode(inode);
 
-               /*
-                * Set nlink to zero so the inode can be cleared, if the inode
-                * does have more links this will be discovered at the next
-                * lookup/getattr.
-                */
-               clear_nlink(inode);
+               spin_lock(&fc->lock);
+               fi->attr_version = ++fc->attr_version;
+               drop_nlink(inode);
+               spin_unlock(&fc->lock);
                fuse_invalidate_attr(inode);
                fuse_invalidate_attr(dir);
                fuse_invalidate_entry_cache(entry);
@@ -762,8 +758,17 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
           will reflect changes in the backing inode (link count,
           etc.)
        */
-       if (!err || err == -EINTR)
+       if (!err) {
+               struct fuse_inode *fi = get_fuse_inode(inode);
+
+               spin_lock(&fc->lock);
+               fi->attr_version = ++fc->attr_version;
+               inc_nlink(inode);
+               spin_unlock(&fc->lock);
+               fuse_invalidate_attr(inode);
+       } else if (err == -EINTR) {
                fuse_invalidate_attr(inode);
+       }
        return err;
 }
 
index a841868bf9ce363cb9705f3a5ba978a39c682df7..504e61b7fd7515f8aafe7e3b9edd2c9fa42fd91d 100644 (file)
@@ -194,10 +194,6 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
        struct fuse_conn *fc = get_fuse_conn(inode);
        int err;
 
-       /* VFS checks this, but only _after_ ->open() */
-       if (file->f_flags & O_DIRECT)
-               return -EINVAL;
-
        err = generic_file_open(inode, file);
        if (err)
                return err;
@@ -932,17 +928,23 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        struct file *file = iocb->ki_filp;
        struct address_space *mapping = file->f_mapping;
        size_t count = 0;
+       size_t ocount = 0;
        ssize_t written = 0;
+       ssize_t written_buffered = 0;
        struct inode *inode = mapping->host;
        ssize_t err;
        struct iov_iter i;
+       loff_t endbyte = 0;
 
        WARN_ON(iocb->ki_pos != pos);
 
-       err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ);
+       ocount = 0;
+       err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
        if (err)
                return err;
 
+       count = ocount;
+
        mutex_lock(&inode->i_mutex);
        vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
 
@@ -962,11 +964,41 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
        file_update_time(file);
 
-       iov_iter_init(&i, iov, nr_segs, count, 0);
-       written = fuse_perform_write(file, mapping, &i, pos);
-       if (written >= 0)
-               iocb->ki_pos = pos + written;
+       if (file->f_flags & O_DIRECT) {
+               written = generic_file_direct_write(iocb, iov, &nr_segs,
+                                                   pos, &iocb->ki_pos,
+                                                   count, ocount);
+               if (written < 0 || written == count)
+                       goto out;
+
+               pos += written;
+               count -= written;
 
+               iov_iter_init(&i, iov, nr_segs, count, written);
+               written_buffered = fuse_perform_write(file, mapping, &i, pos);
+               if (written_buffered < 0) {
+                       err = written_buffered;
+                       goto out;
+               }
+               endbyte = pos + written_buffered - 1;
+
+               err = filemap_write_and_wait_range(file->f_mapping, pos,
+                                                  endbyte);
+               if (err)
+                       goto out;
+
+               invalidate_mapping_pages(file->f_mapping,
+                                        pos >> PAGE_CACHE_SHIFT,
+                                        endbyte >> PAGE_CACHE_SHIFT);
+
+               written += written_buffered;
+               iocb->ki_pos = pos + written_buffered;
+       } else {
+               iov_iter_init(&i, iov, nr_segs, count, 0);
+               written = fuse_perform_write(file, mapping, &i, pos);
+               if (written >= 0)
+                       iocb->ki_pos = pos + written;
+       }
 out:
        current->backing_dev_info = NULL;
        mutex_unlock(&inode->i_mutex);
@@ -1101,30 +1133,41 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf,
        return res;
 }
 
-static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
-                                size_t count, loff_t *ppos)
+static ssize_t __fuse_direct_write(struct file *file, const char __user *buf,
+                                  size_t count, loff_t *ppos)
 {
        struct inode *inode = file->f_path.dentry->d_inode;
        ssize_t res;
 
-       if (is_bad_inode(inode))
-               return -EIO;
-
-       /* Don't allow parallel writes to the same file */
-       mutex_lock(&inode->i_mutex);
        res = generic_write_checks(file, ppos, &count, 0);
        if (!res) {
                res = fuse_direct_io(file, buf, count, ppos, 1);
                if (res > 0)
                        fuse_write_update_size(inode, *ppos);
        }
-       mutex_unlock(&inode->i_mutex);
 
        fuse_invalidate_attr(inode);
 
        return res;
 }
 
+static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
+                                size_t count, loff_t *ppos)
+{
+       struct inode *inode = file->f_path.dentry->d_inode;
+       ssize_t res;
+
+       if (is_bad_inode(inode))
+               return -EIO;
+
+       /* Don't allow parallel writes to the same file */
+       mutex_lock(&inode->i_mutex);
+       res = __fuse_direct_write(file, buf, count, ppos);
+       mutex_unlock(&inode->i_mutex);
+
+       return res;
+}
+
 static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req)
 {
        __free_page(req->pages[0]);
@@ -2077,6 +2120,57 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc,
        return 0;
 }
 
+static ssize_t fuse_loop_dio(struct file *filp, const struct iovec *iov,
+                            unsigned long nr_segs, loff_t *ppos, int rw)
+{
+       const struct iovec *vector = iov;
+       ssize_t ret = 0;
+
+       while (nr_segs > 0) {
+               void __user *base;
+               size_t len;
+               ssize_t nr;
+
+               base = vector->iov_base;
+               len = vector->iov_len;
+               vector++;
+               nr_segs--;
+
+               if (rw == WRITE)
+                       nr = __fuse_direct_write(filp, base, len, ppos);
+               else
+                       nr = fuse_direct_read(filp, base, len, ppos);
+
+               if (nr < 0) {
+                       if (!ret)
+                               ret = nr;
+                       break;
+               }
+               ret += nr;
+               if (nr != len)
+                       break;
+       }
+
+       return ret;
+}
+
+
+static ssize_t
+fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+                       loff_t offset, unsigned long nr_segs)
+{
+       ssize_t ret = 0;
+       struct file *file = NULL;
+       loff_t pos = 0;
+
+       file = iocb->ki_filp;
+       pos = offset;
+
+       ret = fuse_loop_dio(file, iov, nr_segs, &pos, rw);
+
+       return ret;
+}
+
 static const struct file_operations fuse_file_operations = {
        .llseek         = fuse_file_llseek,
        .read           = do_sync_read,
@@ -2120,6 +2214,7 @@ static const struct address_space_operations fuse_file_aops  = {
        .readpages      = fuse_readpages,
        .set_page_dirty = __set_page_dirty_nobuffers,
        .bmap           = fuse_bmap,
+       .direct_IO      = fuse_direct_IO,
 };
 
 void fuse_init_file_inode(struct inode *inode)
index 4aec5995867e95c8c0df3e00d93b1e5ae39d25c0..26783eb2b1fc9465602cc0f452c49aa3e72d32b5 100644 (file)
@@ -947,6 +947,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_magic = FUSE_SUPER_MAGIC;
        sb->s_op = &fuse_super_operations;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
+       sb->s_time_gran = 1;
        sb->s_export_op = &fuse_export_operations;
 
        file = fget(d.fd);
index c465ae066c62c6392ee22047d2be0ec650b89c98..eb08c9e43c2afb13947ca557f1a62da4626c5071 100644 (file)
@@ -1,10 +1,6 @@
 config GFS2_FS
        tristate "GFS2 file system support"
        depends on (64BIT || LBDAF)
-       select DLM if GFS2_FS_LOCKING_DLM
-       select CONFIGFS_FS if GFS2_FS_LOCKING_DLM
-       select SYSFS if GFS2_FS_LOCKING_DLM
-       select IP_SCTP if DLM_SCTP
        select FS_POSIX_ACL
        select CRC32
        select QUOTACTL
@@ -29,7 +25,8 @@ config GFS2_FS
 
 config GFS2_FS_LOCKING_DLM
        bool "GFS2 DLM locking"
-       depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && HOTPLUG
+       depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && \
+               HOTPLUG && DLM && CONFIGFS_FS && SYSFS
        help
          Multiple node locking module for GFS2
 
index 38b7a74a0f913392f1c05bcd567a82e2792d6cdb..9b2ff0e851b13ad824f1a1a06addd3bbd04763e6 100644 (file)
@@ -807,7 +807,7 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
 
        if (inode == sdp->sd_rindex) {
                adjust_fs_space(inode);
-               ip->i_gh.gh_flags |= GL_NOCACHE;
+               sdp->sd_rindex_uptodate = 0;
        }
 
        brelse(dibh);
@@ -873,7 +873,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
 
        if (inode == sdp->sd_rindex) {
                adjust_fs_space(inode);
-               ip->i_gh.gh_flags |= GL_NOCACHE;
+               sdp->sd_rindex_uptodate = 0;
        }
 
        brelse(dibh);
index 197c5c47e57763c7f8c926be7e8c527463107c0e..03c04febe26f095e58d36504e7fb4400c30be6ca 100644 (file)
@@ -724,7 +724,11 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
        int metadata;
        unsigned int revokes = 0;
        int x;
-       int error = 0;
+       int error;
+
+       error = gfs2_rindex_update(sdp);
+       if (error)
+               return error;
 
        if (!*top)
                sm->sm_first = 0;
index c35573abd3710a123112edcdf30c29c5e9f41023..a836056343f077bee81a6f54c7a1e5b0f86cf604 100644 (file)
@@ -1844,6 +1844,10 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
        unsigned int x, size = len * sizeof(u64);
        int error;
 
+       error = gfs2_rindex_update(sdp);
+       if (error)
+               return error;
+
        memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
 
        ht = kzalloc(size, GFP_NOFS);
index c98a60ee6dfd5bf84921e1fd8ad626c4922ca86c..a9ba2444e077ac145f23c25161038a0f8ac2f468 100644 (file)
@@ -1031,7 +1031,13 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
        struct buffer_head *bh;
        struct gfs2_holder ghs[3];
        struct gfs2_rgrpd *rgd;
-       int error = -EROFS;
+       int error;
+
+       error = gfs2_rindex_update(sdp);
+       if (error)
+               return error;
+
+       error = -EROFS;
 
        gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
        gfs2_holder_init(ip->i_gl,  LM_ST_EXCLUSIVE, 0, ghs + 1);
@@ -1224,6 +1230,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                        return 0;
        }
 
+       error = gfs2_rindex_update(sdp);
+       if (error)
+               return error;
+
        if (odip != ndip) {
                error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE,
                                           0, &r_gh);
@@ -1345,7 +1355,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
        error = alloc_required;
        if (error < 0)
                goto out_gunlock;
-       error = 0;
 
        if (alloc_required) {
                struct gfs2_qadata *qa = gfs2_qadata_get(ndip);
index 19bde40b4864c6d3faccc0ea513e830dc75f288f..3df65c9ab73b3ff3b56b338f37100d1f404ab594 100644 (file)
@@ -332,9 +332,6 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk, bool exact)
        struct rb_node *n, *next;
        struct gfs2_rgrpd *cur;
 
-       if (gfs2_rindex_update(sdp))
-               return NULL;
-
        spin_lock(&sdp->sd_rindex_spin);
        n = sdp->sd_rindex_tree.rb_node;
        while (n) {
@@ -640,6 +637,7 @@ static int read_rindex_entry(struct gfs2_inode *ip,
                return 0;
 
        error = 0; /* someone else read in the rgrp; free it and ignore it */
+       gfs2_glock_put(rgd->rd_gl);
 
 fail:
        kfree(rgd->rd_bits);
@@ -927,6 +925,10 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
        } else if (copy_from_user(&r, argp, sizeof(r)))
                return -EFAULT;
 
+       ret = gfs2_rindex_update(sdp);
+       if (ret)
+               return ret;
+
        rgd = gfs2_blk2rgrpd(sdp, r.start, 0);
        rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0);
 
index 2e5ba425cae743f006b938a39b8e70469c9f471a..927f4df874ae788c744e1e7e51edb19d92b60e36 100644 (file)
@@ -238,6 +238,10 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
        unsigned int x;
        int error;
 
+       error = gfs2_rindex_update(sdp);
+       if (error)
+               return error;
+
        if (GFS2_EA_IS_STUFFED(ea))
                return 0;
 
@@ -1330,6 +1334,10 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
        unsigned int x;
        int error;
 
+       error = gfs2_rindex_update(sdp);
+       if (error)
+               return error;
+
        memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
 
        error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh);
@@ -1439,6 +1447,10 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
        struct gfs2_holder gh;
        int error;
 
+       error = gfs2_rindex_update(sdp);
+       if (error)
+               return error;
+
        rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr, 1);
        if (!rgd) {
                gfs2_consist_inode(ip);
index 358094f0433d41c0fbe21360a24e9a475d95e3da..18d08f5db53adb46d832222357df9d81d5058f11 100644 (file)
@@ -529,6 +529,7 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
        return 0;
 out:
        d_genocide(root);
+       shrink_dcache_parent(root);
        dput(root);
        return -ENOMEM;
 }
index 3ddcbb1c0a432728f626986b1d057d11aafdce84..13ad1539fbf2479cd7f69a45611cd3d6a460688f 100644 (file)
@@ -241,7 +241,7 @@ static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat)
        p = xdr_inline_decode(xdr, 4);
        if (unlikely(p == NULL))
                goto out_overflow;
-       if (unlikely(*p > nlm4_failed))
+       if (unlikely(ntohl(*p) > ntohl(nlm4_failed)))
                goto out_bad_xdr;
        *stat = *p;
        return 0;
index 3d35e3e80c1ccfac1367647b6ac417ba3f5bd1b2..d269ada7670e155c7544a2aa01ea0697e98f3991 100644 (file)
@@ -236,7 +236,7 @@ static int decode_nlm_stat(struct xdr_stream *xdr,
        p = xdr_inline_decode(xdr, 4);
        if (unlikely(p == NULL))
                goto out_overflow;
-       if (unlikely(*p > nlm_lck_denied_grace_period))
+       if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period)))
                goto out_enum;
        *stat = *p;
        return 0;
index 08c6e36ab2eb05d8c28f68394a326573a7f52658..43f46cd9edea84e18040381a2647a54ca59debb0 100644 (file)
@@ -803,13 +803,13 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,
        return p;
 }
 
-static int
+static __be32
 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
                const char *name, int namlen)
 {
        struct svc_export       *exp;
        struct dentry           *dparent, *dchild;
-       int rv = 0;
+       __be32 rv = nfserr_noent;
 
        dparent = cd->fh.fh_dentry;
        exp  = cd->fh.fh_export;
@@ -817,26 +817,20 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
        if (isdotent(name, namlen)) {
                if (namlen == 2) {
                        dchild = dget_parent(dparent);
-                       if (dchild == dparent) {
-                               /* filesystem root - cannot return filehandle for ".." */
-                               dput(dchild);
-                               return -ENOENT;
-                       }
+                       /* filesystem root - cannot return filehandle for ".." */
+                       if (dchild == dparent)
+                               goto out;
                } else
                        dchild = dget(dparent);
        } else
                dchild = lookup_one_len(name, dparent, namlen);
        if (IS_ERR(dchild))
-               return -ENOENT;
-       rv = -ENOENT;
+               return rv;
        if (d_mountpoint(dchild))
                goto out;
-       rv = fh_compose(fhp, exp, dchild, &cd->fh);
-       if (rv)
-               goto out;
        if (!dchild->d_inode)
                goto out;
-       rv = 0;
+       rv = fh_compose(fhp, exp, dchild, &cd->fh);
 out:
        dput(dchild);
        return rv;
@@ -845,7 +839,7 @@ out:
 static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen)
 {
        struct svc_fh   fh;
-       int err;
+       __be32 err;
 
        fh_init(&fh, NFS3_FHSIZE);
        err = compose_entry_fh(cd, &fh, name, namlen);
index 2ed14dfd00a231e9c813b78b3d728bcdfb849b06..987e719fbae8c64f2776f914e7f4104ee04be492 100644 (file)
@@ -235,15 +235,15 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
                 */
                if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
                        open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
-                                               FATTR4_WORD1_TIME_MODIFY);
+                                                       FATTR4_WORD1_TIME_MODIFY);
        } else {
                status = nfsd_lookup(rqstp, current_fh,
                                     open->op_fname.data, open->op_fname.len, resfh);
                fh_unlock(current_fh);
-               if (status)
-                       goto out;
-               status = nfsd_check_obj_isreg(resfh);
        }
+       if (status)
+               goto out;
+       status = nfsd_check_obj_isreg(resfh);
        if (status)
                goto out;
 
@@ -841,6 +841,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
              struct nfsd4_setattr *setattr)
 {
        __be32 status = nfs_ok;
+       int err;
 
        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
                nfs4_lock_state();
@@ -852,9 +853,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                        return status;
                }
        }
-       status = fh_want_write(&cstate->current_fh);
-       if (status)
-               return status;
+       err = fh_want_write(&cstate->current_fh);
+       if (err)
+               return nfserrno(err);
        status = nfs_ok;
 
        status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
index 1841f8bf845e7440bba605f25357a512a8a5b0b0..7f71c69cdcdfdcbd7245a71820b9f13e1a0bb135 100644 (file)
@@ -4211,16 +4211,14 @@ out:
  * vfs_test_lock.  (Arguably perhaps test_lock should be done with an
  * inode operation.)
  */
-static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
+static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
 {
        struct file *file;
-       int err;
-
-       err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
-       if (err)
-               return err;
-       err = vfs_test_lock(file, lock);
-       nfsd_close(file);
+       __be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
+       if (!err) {
+               err = nfserrno(vfs_test_lock(file, lock));
+               nfsd_close(file);
+       }
        return err;
 }
 
@@ -4234,7 +4232,6 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        struct inode *inode;
        struct file_lock file_lock;
        struct nfs4_lockowner *lo;
-       int error;
        __be32 status;
 
        if (locks_in_grace())
@@ -4280,12 +4277,10 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        nfs4_transform_lock_offset(&file_lock);
 
-       status = nfs_ok;
-       error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
-       if (error) {
-               status = nfserrno(error);
+       status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
+       if (status)
                goto out;
-       }
+
        if (file_lock.fl_type != F_UNLCK) {
                status = nfserr_denied;
                nfs4_set_lock_denied(&file_lock, &lockt->lt_denied);
index bcd8904ab1e36dd807f26379392000fb114f9bc6..74c00bc92b9af6b01e95e55c119b90d61fbf9d34 100644 (file)
@@ -1392,7 +1392,7 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta
        for (i = 0; i < test_stateid->ts_num_ids; i++) {
                stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
                if (!stateid) {
-                       status = PTR_ERR(stateid);
+                       status = nfserrno(-ENOMEM);
                        goto out;
                }
 
@@ -3410,7 +3410,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
        *p++ = htonl(test_stateid->ts_num_ids);
 
        list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
-               *p++ = htonl(stateid->ts_id_status);
+               *p++ = stateid->ts_id_status;
        }
 
        ADJUST_ARGS();
index 296d671654d6a12fbb89567ea6b80cfd26a1829f..568666156ea4f59525d67207551ee8c45a3b730e 100644 (file)
@@ -1458,7 +1458,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                switch (createmode) {
                case NFS3_CREATE_UNCHECKED:
                        if (! S_ISREG(dchild->d_inode->i_mode))
-                               err = nfserr_exist;
+                               goto out;
                        else if (truncp) {
                                /* in nfsv4, we need to treat this case a little
                                 * differently.  we don't want to truncate the
index 3165aebb43c87934b743ecf08e5f02cef586d771..31b9463fba1fb19259da764d94372ffffc0f6008 100644 (file)
@@ -1134,7 +1134,7 @@ static int ocfs2_adjust_rightmost_branch(handle_t *handle,
        }
 
        el = path_leaf_el(path);
-       rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1];
+       rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1];
 
        ocfs2_adjust_rightmost_records(handle, et, path, rec);
 
index cf782338266421779e5ba8fa165786b006f4c2aa..9f32d7cbb7a3701f1f28d938b17ae4d057dc4e84 100644 (file)
@@ -1036,14 +1036,14 @@ static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci,
 
        tmp_el = left_path->p_node[subtree_root].el;
        blkno = left_path->p_node[subtree_root+1].bh->b_blocknr;
-       for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) {
+       for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) {
                if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) {
                        *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos);
                        break;
                }
        }
 
-       BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec));
+       BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec));
 
 out:
        ocfs2_free_path(left_path);
@@ -1468,7 +1468,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh,
 
        trace_ocfs2_divide_leaf_refcount_block(
                (unsigned long long)ref_leaf_bh->b_blocknr,
-               le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used));
+               le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used));
 
        /*
         * XXX: Improvement later.
@@ -2411,7 +2411,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
                                rb = (struct ocfs2_refcount_block *)
                                                        prev_bh->b_data;
 
-                               if (le64_to_cpu(rb->rf_records.rl_used) +
+                               if (le16_to_cpu(rb->rf_records.rl_used) +
                                    recs_add >
                                    le16_to_cpu(rb->rf_records.rl_count))
                                        ref_blocks++;
@@ -2476,7 +2476,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
        if (prev_bh) {
                rb = (struct ocfs2_refcount_block *)prev_bh->b_data;
 
-               if (le64_to_cpu(rb->rf_records.rl_used) + recs_add >
+               if (le16_to_cpu(rb->rf_records.rl_used) + recs_add >
                    le16_to_cpu(rb->rf_records.rl_count))
                        ref_blocks++;
 
@@ -3629,7 +3629,7 @@ int ocfs2_refcounted_xattr_delete_need(struct inode *inode,
                         * one will split a refcount rec, so totally we need
                         * clusters * 2 new refcount rec.
                         */
-                       if (le64_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
+                       if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
                            le16_to_cpu(rb->rf_records.rl_count))
                                ref_blocks++;
 
index ba5d97e4a73e8a43e64fc3cfa55fb9b97d4ec6a5..f169da4624fd07c5964c3d24d3b65e8a0dcd5ed7 100644 (file)
@@ -600,7 +600,7 @@ static void ocfs2_bg_alloc_cleanup(handle_t *handle,
                ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode,
                                          cluster_ac->ac_bh,
                                          le64_to_cpu(rec->e_blkno),
-                                         le32_to_cpu(rec->e_leaf_clusters));
+                                         le16_to_cpu(rec->e_leaf_clusters));
                if (ret)
                        mlog_errno(ret);
                /* Try all the clusters to free */
@@ -1628,7 +1628,7 @@ static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res,
 {
        unsigned int bpc = le16_to_cpu(cl->cl_bpc);
        unsigned int bitoff = le32_to_cpu(rec->e_cpos) * bpc;
-       unsigned int bitcount = le32_to_cpu(rec->e_leaf_clusters) * bpc;
+       unsigned int bitcount = le16_to_cpu(rec->e_leaf_clusters) * bpc;
 
        if (res->sr_bit_offset < bitoff)
                return 0;
index 6a0c62d6e4428bf38711d0afcd4d860061f0feb6..64c3b3172367abbd1c1464b9372f33ee4efa7acb 100644 (file)
 #ifndef arch_irq_stat
 #define arch_irq_stat() 0
 #endif
-#ifndef arch_idle_time
-#define arch_idle_time(cpu) 0
-#endif
+
+#ifdef arch_idle_time
+
+static cputime64_t get_idle_time(int cpu)
+{
+       cputime64_t idle;
+
+       idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
+       if (cpu_online(cpu) && !nr_iowait_cpu(cpu))
+               idle += arch_idle_time(cpu);
+       return idle;
+}
+
+static cputime64_t get_iowait_time(int cpu)
+{
+       cputime64_t iowait;
+
+       iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
+       if (cpu_online(cpu) && nr_iowait_cpu(cpu))
+               iowait += arch_idle_time(cpu);
+       return iowait;
+}
+
+#else
 
 static u64 get_idle_time(int cpu)
 {
        u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL);
 
-       if (idle_time == -1ULL) {
+       if (idle_time == -1ULL)
                /* !NO_HZ so we can rely on cpustat.idle */
                idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
-               idle += arch_idle_time(cpu);
-       } else
+       else
                idle = usecs_to_cputime64(idle_time);
 
        return idle;
@@ -49,6 +69,8 @@ static u64 get_iowait_time(int cpu)
        return iowait;
 }
 
+#endif
+
 static int show_stat(struct seq_file *p, void *v)
 {
        int i, j;
index 2a7a3f5d1ca6d69ac5508fa85310867e339615c0..35a36d39fa2cb2af62616918872706794a20d8e1 100644 (file)
@@ -729,6 +729,9 @@ int sysfs_create_dir(struct kobject * kobj)
        else
                parent_sd = &sysfs_root;
 
+       if (!parent_sd)
+               return -ENOENT;
+
        if (sysfs_ns_type(parent_sd))
                ns = kobj->ktype->namespace(kobj);
        type = sysfs_read_ns_type(kobj);
@@ -878,7 +881,6 @@ int sysfs_rename(struct sysfs_dirent *sd,
 
                dup_name = sd->s_name;
                sd->s_name = new_name;
-               sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);
        }
 
        /* Move to the appropriate place in the appropriate directories rbtree. */
@@ -886,6 +888,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
        sysfs_get(new_parent_sd);
        sysfs_put(sd->s_parent);
        sd->s_ns = new_ns;
+       sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);
        sd->s_parent = new_parent_sd;
        sysfs_link_sibling(sd);
 
index dd1701caecc94bcfe38625052dd7564ded19c379..2df555c66d57d463381042632ae124ad53aecb42 100644 (file)
@@ -67,7 +67,11 @@ static int internal_create_group(struct kobject *kobj, int update,
        /* Updates may happen before the object has been instantiated */
        if (unlikely(update && !kobj->sd))
                return -EINVAL;
-
+       if (!grp->attrs) {
+               WARN(1, "sysfs: attrs not set by subsystem for group: %s/%s\n",
+                       kobj->name, grp->name ? "" : grp->name);
+               return -EINVAL;
+       }
        if (grp->name) {
                error = sysfs_create_subdir(kobj, grp->name, &sd);
                if (error)
index 3963116083aeae56fdb3aa9056e86daf8200ed9c..e478de4e5d564e936302d753e65ac4e52768b3a7 100644 (file)
@@ -85,7 +85,7 @@ struct drm_exynos_gem_mmap {
 struct drm_exynos_vidi_connection {
        unsigned int connection;
        unsigned int extensions;
-       uint64_t *edid;
+       uint64_t edid;
 };
 
 struct drm_exynos_plane_set_zpos {
@@ -96,7 +96,8 @@ struct drm_exynos_plane_set_zpos {
 /* memory type definitions. */
 enum e_drm_exynos_gem_mem_type {
        /* Physically Non-Continuous memory. */
-       EXYNOS_BO_NONCONTIG     = 1 << 0
+       EXYNOS_BO_NONCONTIG     = 1 << 0,
+       EXYNOS_BO_MASK          = EXYNOS_BO_NONCONTIG
 };
 
 #define DRM_EXYNOS_GEM_CREATE          0x00
index 7847e197730ac86cc480092d5dd525499d106716..8d54f79457ba54ae2c85ce1a0e03c0ca5a34e8fc 100644 (file)
@@ -30,7 +30,6 @@ struct amba_device {
        struct device           dev;
        struct resource         res;
        struct clk              *pclk;
-       struct regulator        *vcore;
        u64                     dma_mask;
        unsigned int            periphid;
        unsigned int            irq[AMBA_NR_IRQS];
@@ -75,12 +74,6 @@ void amba_release_regions(struct amba_device *);
 #define amba_pclk_disable(d)   \
        do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0)
 
-#define amba_vcore_enable(d)   \
-       (IS_ERR((d)->vcore) ? 0 : regulator_enable((d)->vcore))
-
-#define amba_vcore_disable(d)  \
-       do { if (!IS_ERR((d)->vcore)) regulator_disable((d)->vcore); } while (0)
-
 /* Some drivers don't use the struct amba_device */
 #define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff)
 #define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f)
index b8c51124ed19b9b8368ebeb631c543b51029d31a..76dd1b199a1b0e55a39e34d34f6f228ea30a0016 100644 (file)
@@ -25,6 +25,8 @@
 #ifndef _SSP_PL022_H
 #define _SSP_PL022_H
 
+#include <linux/types.h>
+
 /**
  * whether SSP is in loopback mode or not
  */
index 606cf339bb561f6b526c2a58ddcf1378c8376bf1..2aa24664a5b53a2b178d1ee52fd3c2731b18aaf0 100644 (file)
@@ -426,14 +426,10 @@ struct request_queue {
                                 (1 << QUEUE_FLAG_SAME_COMP)    |       \
                                 (1 << QUEUE_FLAG_ADD_RANDOM))
 
-static inline int queue_is_locked(struct request_queue *q)
+static inline void queue_lockdep_assert_held(struct request_queue *q)
 {
-#ifdef CONFIG_SMP
-       spinlock_t *lock = q->queue_lock;
-       return lock && spin_is_locked(lock);
-#else
-       return 1;
-#endif
+       if (q->queue_lock)
+               lockdep_assert_held(q->queue_lock);
 }
 
 static inline void queue_flag_set_unlocked(unsigned int flag,
@@ -445,7 +441,7 @@ static inline void queue_flag_set_unlocked(unsigned int flag,
 static inline int queue_flag_test_and_clear(unsigned int flag,
                                            struct request_queue *q)
 {
-       WARN_ON_ONCE(!queue_is_locked(q));
+       queue_lockdep_assert_held(q);
 
        if (test_bit(flag, &q->queue_flags)) {
                __clear_bit(flag, &q->queue_flags);
@@ -458,7 +454,7 @@ static inline int queue_flag_test_and_clear(unsigned int flag,
 static inline int queue_flag_test_and_set(unsigned int flag,
                                          struct request_queue *q)
 {
-       WARN_ON_ONCE(!queue_is_locked(q));
+       queue_lockdep_assert_held(q);
 
        if (!test_bit(flag, &q->queue_flags)) {
                __set_bit(flag, &q->queue_flags);
@@ -470,7 +466,7 @@ static inline int queue_flag_test_and_set(unsigned int flag,
 
 static inline void queue_flag_set(unsigned int flag, struct request_queue *q)
 {
-       WARN_ON_ONCE(!queue_is_locked(q));
+       queue_lockdep_assert_held(q);
        __set_bit(flag, &q->queue_flags);
 }
 
@@ -487,7 +483,7 @@ static inline int queue_in_flight(struct request_queue *q)
 
 static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
 {
-       WARN_ON_ONCE(!queue_is_locked(q));
+       queue_lockdep_assert_held(q);
        __clear_bit(flag, &q->queue_flags);
 }
 
index 676f967390aeb8ccfe4983a9fab04285d62ce58d..f9a2e5e67a5423e204389b8d01e0f83d41df1a30 100644 (file)
@@ -974,6 +974,7 @@ int dma_async_device_register(struct dma_device *device);
 void dma_async_device_unregister(struct dma_device *device);
 void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
 struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
+struct dma_chan *net_dma_find_channel(void);
 #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
 
 /* --- Helper iov-locking functions --- */
index 8ba2c9460b28fb90bfee024aa8f73601f6c4cf68..8f2ab8fef929f42b81f3d9a75c564b42455dc06e 100644 (file)
@@ -593,7 +593,7 @@ struct fuse_dirent {
        __u64   off;
        __u32   namelen;
        __u32   type;
-       char name[0];
+       char name[];
 };
 
 #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
index 2463b61003336b0f176b5ed851aa8776a5202697..1f90de0cfdbe7ed344fccdf9eb04e774c5493adc 100644 (file)
@@ -666,23 +666,11 @@ struct twl4030_codec_data {
        unsigned int check_defaults:1;
        unsigned int reset_registers:1;
        unsigned int hs_extmute:1;
-       u16 hs_left_step;
-       u16 hs_right_step;
-       u16 hf_left_step;
-       u16 hf_right_step;
        void (*set_hs_extmute)(int mute);
 };
 
 struct twl4030_vibra_data {
        unsigned int    coexist;
-
-       /* twl6040 */
-       unsigned int vibldrv_res;       /* left driver resistance */
-       unsigned int vibrdrv_res;       /* right driver resistance */
-       unsigned int viblmotor_res;     /* left motor resistance */
-       unsigned int vibrmotor_res;     /* right motor resistance */
-       int vddvibl_uV;                 /* VDDVIBL volt, set 0 for fixed reg */
-       int vddvibr_uV;                 /* VDDVIBR volt, set 0 for fixed reg */
 };
 
 struct twl4030_audio_data {
index bff29c58da23013e5e1e19f0cdeaf2ad45d602fc..b27cfcfd3a59c15319488580a14de42c18174744 100644 (file)
@@ -49,6 +49,12 @@ typedef      void (*irq_preflow_handler_t)(struct irq_data *data);
  * IRQ_TYPE_LEVEL_LOW          - low level triggered
  * IRQ_TYPE_LEVEL_MASK         - Mask to filter out the level bits
  * IRQ_TYPE_SENSE_MASK         - Mask for all the above bits
+ * IRQ_TYPE_DEFAULT            - For use by some PICs to ask irq_set_type
+ *                               to setup the HW to a sane default (used
+ *                                by irqdomain map() callbacks to synchronize
+ *                                the HW state and SW flags for a newly
+ *                                allocated descriptor).
+ *
  * IRQ_TYPE_PROBE              - Special flag for probing in progress
  *
  * Bits which can be modified via irq_set/clear/modify_status_flags()
@@ -77,6 +83,7 @@ enum {
        IRQ_TYPE_LEVEL_LOW      = 0x00000008,
        IRQ_TYPE_LEVEL_MASK     = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH),
        IRQ_TYPE_SENSE_MASK     = 0x0000000f,
+       IRQ_TYPE_DEFAULT        = IRQ_TYPE_SENSE_MASK,
 
        IRQ_TYPE_PROBE          = 0x00000010,
 
@@ -263,6 +270,11 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
        d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS;
 }
 
+static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
+{
+       return d->hwirq;
+}
+
 /**
  * struct irq_chip - hardware interrupt chip descriptor
  *
index ead4a4215797b81c7a35baed6b428026d2039e00..c65740d76e663a35da56f3e680835d8349e8f9dd 100644 (file)
@@ -42,12 +42,6 @@ struct of_device_id;
 /* Number of irqs reserved for a legacy isa controller */
 #define NUM_ISA_INTERRUPTS     16
 
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
 /**
  * struct irq_domain_ops - Methods for irq_domain objects
  * @match: Match an interrupt controller device node to a host, returns
@@ -104,6 +98,9 @@ struct irq_domain {
                        unsigned int size;
                        unsigned int *revmap;
                } linear;
+               struct {
+                       unsigned int max_irq;
+               } nomap;
                struct radix_tree_root tree;
        } revmap_data;
        const struct irq_domain_ops *ops;
@@ -126,6 +123,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
                                         const struct irq_domain_ops *ops,
                                         void *host_data);
 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+                                        unsigned int max_irq,
                                         const struct irq_domain_ops *ops,
                                         void *host_data);
 struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
@@ -134,7 +132,6 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
 
 extern struct irq_domain *irq_find_host(struct device_node *node);
 extern void irq_set_default_host(struct irq_domain *host);
-extern void irq_set_virq_count(unsigned int count);
 
 static inline struct irq_domain *irq_domain_add_legacy_isa(
                                struct device_node *of_node,
@@ -146,7 +143,6 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
 }
 extern struct irq_domain *irq_find_host(struct device_node *node);
 extern void irq_set_default_host(struct irq_domain *host);
-extern void irq_set_virq_count(unsigned int count);
 
 
 extern unsigned int irq_create_mapping(struct irq_domain *host,
index 067eda0e4b329cfbfbfcd0e1bb2e88a550c242d8..be342b94c640849f18e669b73f6f418092dc860f 100644 (file)
@@ -4,29 +4,43 @@
 #include <generated/autoconf.h>
 
 /*
- * Helper macros to use CONFIG_ options in C expressions. Note that
+ * Helper macros to use CONFIG_ options in C/CPP expressions. Note that
  * these only work with boolean and tristate options.
  */
 
+/*
+ * Getting something that works in C and CPP for an arg that may or may
+ * not be defined is tricky.  Here, if we have "#define CONFIG_BOOGER 1"
+ * we match on the placeholder define, insert the "0," for arg1 and generate
+ * the triplet (0, 1, 0).  Then the last step cherry picks the 2nd arg (a one).
+ * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when
+ * the last step cherry picks the 2nd arg, we get a zero.
+ */
+#define __ARG_PLACEHOLDER_1 0,
+#define config_enabled(cfg) _config_enabled(cfg)
+#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value)
+#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0)
+#define ___config_enabled(__ignored, val, ...) val
+
 /*
  * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm',
  * 0 otherwise.
  *
  */
 #define IS_ENABLED(option) \
-       (__enabled_ ## option || __enabled_ ## option ## _MODULE)
+       (config_enabled(option) || config_enabled(option##_MODULE))
 
 /*
  * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0
  * otherwise. For boolean options, this is equivalent to
  * IS_ENABLED(CONFIG_FOO).
  */
-#define IS_BUILTIN(option) __enabled_ ## option
+#define IS_BUILTIN(option) config_enabled(option)
 
 /*
  * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0
  * otherwise.
  */
-#define IS_MODULE(option) __enabled_ ## option ## _MODULE
+#define IS_MODULE(option) config_enabled(option##_MODULE)
 
 #endif /* __LINUX_KCONFIG_H */
index 665a260c7e09948fa3b5e3516efca2890edef840..72cbf08d45fbc878d5198eda807b12dbdffa6268 100644 (file)
@@ -596,6 +596,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
 
 #ifdef CONFIG_IOMMU_API
 int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
 int kvm_iommu_map_guest(struct kvm *kvm);
 int kvm_iommu_unmap_guest(struct kvm *kvm);
 int kvm_assign_device(struct kvm *kvm,
@@ -609,6 +610,11 @@ static inline int kvm_iommu_map_pages(struct kvm *kvm,
        return 0;
 }
 
+static inline void kvm_iommu_unmap_pages(struct kvm *kvm,
+                                        struct kvm_memory_slot *slot)
+{
+}
+
 static inline int kvm_iommu_map_guest(struct kvm *kvm)
 {
        return -ENODEV;
index 9890687f582de0c36cdbcc56cf252a381e82e8ee..5a049dfaf1533174d7293810b132128c5e3f2121 100644 (file)
@@ -8,41 +8,14 @@
 #ifndef __MFD_DB5500_PRCMU_H
 #define __MFD_DB5500_PRCMU_H
 
-#ifdef CONFIG_MFD_DB5500_PRCMU
-
-void db5500_prcmu_early_init(void);
-int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state);
-int db5500_prcmu_set_display_clocks(void);
-int db5500_prcmu_disable_dsipll(void);
-int db5500_prcmu_enable_dsipll(void);
-int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
-int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
-void db5500_prcmu_enable_wakeups(u32 wakeups);
-int db5500_prcmu_request_clock(u8 clock, bool enable);
-void db5500_prcmu_config_abb_event_readout(u32 abb_events);
-void db5500_prcmu_get_abb_event_buffer(void __iomem **buf);
-int prcmu_resetout(u8 resoutn, u8 state);
-int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
-       bool keep_ap_pll);
-int db5500_prcmu_config_esram0_deep_sleep(u8 state);
-void db5500_prcmu_system_reset(u16 reset_code);
-u16 db5500_prcmu_get_reset_code(void);
-bool db5500_prcmu_is_ac_wake_requested(void);
-int db5500_prcmu_set_arm_opp(u8 opp);
-int db5500_prcmu_get_arm_opp(void);
-
-#else /* !CONFIG_UX500_SOC_DB5500 */
-
-static inline void db5500_prcmu_early_init(void) {}
-
-static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
+static inline int prcmu_resetout(u8 resoutn, u8 state)
 {
-       return -ENOSYS;
+       return 0;
 }
 
-static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
+static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state)
 {
-       return -ENOSYS;
+       return 0;
 }
 
 static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
@@ -50,69 +23,82 @@ static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
        return 0;
 }
 
-static inline int db5500_prcmu_set_display_clocks(void)
+static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
+       bool keep_ap_pll)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_disable_dsipll(void)
+static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_enable_dsipll(void)
+static inline u16 db5500_prcmu_get_reset_code(void)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
+static inline bool db5500_prcmu_is_ac_wake_requested(void)
 {
        return 0;
 }
 
-static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
-
-static inline int prcmu_resetout(u8 resoutn, u8 state)
+static inline int db5500_prcmu_set_arm_opp(u8 opp)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state)
+static inline int db5500_prcmu_get_arm_opp(void)
 {
        return 0;
 }
 
-static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
 static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {}
 
-static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
-       bool keep_ap_pll)
-{
-       return 0;
-}
+static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
 
 static inline void db5500_prcmu_system_reset(u16 reset_code) {}
 
-static inline u16 db5500_prcmu_get_reset_code(void)
+static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
+
+#ifdef CONFIG_MFD_DB5500_PRCMU
+
+void db5500_prcmu_early_init(void);
+int db5500_prcmu_set_display_clocks(void);
+int db5500_prcmu_disable_dsipll(void);
+int db5500_prcmu_enable_dsipll(void);
+int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
+int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
+
+#else /* !CONFIG_UX500_SOC_DB5500 */
+
+static inline void db5500_prcmu_early_init(void) {}
+
+static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
 {
-       return 0;
+       return -ENOSYS;
 }
 
-static inline bool db5500_prcmu_is_ac_wake_requested(void)
+static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
 {
-       return 0;
+       return -ENOSYS;
 }
 
-static inline int db5500_prcmu_set_arm_opp(u8 opp)
+static inline int db5500_prcmu_set_display_clocks(void)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_get_arm_opp(void)
+static inline int db5500_prcmu_disable_dsipll(void)
 {
        return 0;
 }
 
+static inline int db5500_prcmu_enable_dsipll(void)
+{
+       return 0;
+}
 
 #endif /* CONFIG_MFD_DB5500_PRCMU */
 
index a2c61609d21dbf6ab5ffe386e2721e58ac388ffe..0b64b19d81abf9e89e3d609f020e10e2ac9952b6 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/mutex.h>
 #include <linux/types.h>
+#include <linux/regmap.h>
 
 #define RC5T583_MAX_REGS               0xF8
 
@@ -279,14 +280,44 @@ struct rc5t583_platform_data {
        bool            enable_shutdown;
 };
 
-int rc5t583_write(struct device *dev, u8 reg, uint8_t val);
-int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val);
-int rc5t583_set_bits(struct device *dev, unsigned int reg,
-               unsigned int bit_mask);
-int rc5t583_clear_bits(struct device *dev, unsigned int reg,
-               unsigned int bit_mask);
-int rc5t583_update(struct device *dev, unsigned int reg,
-               unsigned int val, unsigned int mask);
+static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       return regmap_write(rc5t583->regmap, reg, val);
+}
+
+static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       unsigned int ival;
+       int ret;
+       ret = regmap_read(rc5t583->regmap, reg, &ival);
+       if (!ret)
+               *val = (uint8_t)ival;
+       return ret;
+}
+
+static inline int rc5t583_set_bits(struct device *dev, unsigned int reg,
+                       unsigned int bit_mask)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
+}
+
+static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg,
+                       unsigned int bit_mask)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
+}
+
+static inline int rc5t583_update(struct device *dev, unsigned int reg,
+               unsigned int val, unsigned int mask)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       return regmap_update_bits(rc5t583->regmap, reg, mask, val);
+}
+
 int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id,
        int ext_pwr_req, int deepsleep_slot_nr);
 int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base);
index 9bc9ac651dad9bf2be544961c18e06fd1bfbd119..b15b5f03f5c44c74473f30e46411876000bf5863 100644 (file)
 #define TWL6040_SYSCLK_SEL_LPPLL       0
 #define TWL6040_SYSCLK_SEL_HPPLL       1
 
+struct twl6040_codec_data {
+       u16 hs_left_step;
+       u16 hs_right_step;
+       u16 hf_left_step;
+       u16 hf_right_step;
+};
+
+struct twl6040_vibra_data {
+       unsigned int vibldrv_res;       /* left driver resistance */
+       unsigned int vibrdrv_res;       /* right driver resistance */
+       unsigned int viblmotor_res;     /* left motor resistance */
+       unsigned int vibrmotor_res;     /* right motor resistance */
+       int vddvibl_uV;                 /* VDDVIBL volt, set 0 for fixed reg */
+       int vddvibr_uV;                 /* VDDVIBR volt, set 0 for fixed reg */
+};
+
+struct twl6040_platform_data {
+       int audpwron_gpio;      /* audio power-on gpio */
+       unsigned int irq_base;
+
+       struct twl6040_codec_data *codec;
+       struct twl6040_vibra_data *vibra;
+};
+
+struct regmap;
+
 struct twl6040 {
        struct device *dev;
+       struct regmap *regmap;
        struct mutex mutex;
        struct mutex io_mutex;
        struct mutex irq_mutex;
index d8738a464b94a71822f191bdd45bcac29b01814c..74aa71bea1e4ff6bf0bd7a43dfdff37c870438ee 100644 (file)
@@ -1393,29 +1393,20 @@ extern int install_special_mapping(struct mm_struct *mm,
 
 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
 
-extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-       unsigned long len, unsigned long prot,
-       unsigned long flag, unsigned long pgoff);
 extern unsigned long mmap_region(struct file *file, unsigned long addr,
        unsigned long len, unsigned long flags,
        vm_flags_t vm_flags, unsigned long pgoff);
-
-static inline unsigned long do_mmap(struct file *file, unsigned long addr,
-       unsigned long len, unsigned long prot,
-       unsigned long flag, unsigned long offset)
-{
-       unsigned long ret = -EINVAL;
-       if ((offset + PAGE_ALIGN(len)) < offset)
-               goto out;
-       if (!(offset & ~PAGE_MASK))
-               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
-out:
-       return ret;
-}
-
+extern unsigned long do_mmap(struct file *, unsigned long,
+        unsigned long, unsigned long,
+        unsigned long, unsigned long);
 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
 
-extern unsigned long do_brk(unsigned long, unsigned long);
+/* These take the mm semaphore themselves */
+extern unsigned long vm_brk(unsigned long, unsigned long);
+extern int vm_munmap(unsigned long, size_t);
+extern unsigned long vm_mmap(struct file *, unsigned long,
+        unsigned long, unsigned long,
+        unsigned long, unsigned long);
 
 /* truncate.c */
 extern void truncate_inode_pages(struct address_space *, loff_t);
index 01beae78f07935e45d1a04ac544e8826ad90618a..629b823f88362b44001cf09dc1559d1e86780dad 100644 (file)
@@ -481,7 +481,7 @@ struct mmc_driver {
        struct device_driver drv;
        int (*probe)(struct mmc_card *);
        void (*remove)(struct mmc_card *);
-       int (*suspend)(struct mmc_card *, pm_message_t);
+       int (*suspend)(struct mmc_card *);
        int (*resume)(struct mmc_card *);
 };
 
index 0ddd161f3b060c2e2ec0d665c1ddc719213443f7..31d2844e6572be34ed104e1a92fafd48abc0bf76 100644 (file)
@@ -104,9 +104,18 @@ struct bridge_skb_cb {
        } daddr;
 };
 
+static inline void br_drop_fake_rtable(struct sk_buff *skb)
+{
+       struct dst_entry *dst = skb_dst(skb);
+
+       if (dst && (dst->flags & DST_FAKE_RTABLE))
+               skb_dst_drop(skb);
+}
+
 #else
 #define nf_bridge_maybe_copy_header(skb)       (0)
 #define nf_bridge_pad(skb)                     (0)
+#define br_drop_fake_rtable(skb)               do { } while (0)
 #endif /* CONFIG_BRIDGE_NETFILTER */
 
 #endif /* __KERNEL__ */
index f549adccc94c569801f4181bacd84e87f0743725..1bc898b14a8070ba0c8aab847157fbe90e8ca619 100644 (file)
@@ -287,7 +287,17 @@ extern unsigned int ip6t_do_table(struct sk_buff *skb,
                                  struct xt_table *table);
 
 /* Check for an extension */
-extern int ip6t_ext_hdr(u8 nexthdr);
+static inline int
+ip6t_ext_hdr(u8 nexthdr)
+{      return (nexthdr == IPPROTO_HOPOPTS) ||
+              (nexthdr == IPPROTO_ROUTING) ||
+              (nexthdr == IPPROTO_FRAGMENT) ||
+              (nexthdr == IPPROTO_ESP) ||
+              (nexthdr == IPPROTO_AH) ||
+              (nexthdr == IPPROTO_NONE) ||
+              (nexthdr == IPPROTO_DSTOPTS);
+}
+
 /* find specified header and get offset to it */
 extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
                         int target, unsigned short *fragoff);
index b8d4001212b30bbd94f7a8d47a3afe32e5dd229e..5b7d84ac954a2c7a5e0b7f19f3529bb01e1a981f 100644 (file)
@@ -1,3 +1,4 @@
+header-y += cld.h
 header-y += debug.h
 header-y += export.h
 header-y += nfsfh.h
index fee4349364f77ed971fac838bf95391e0097f585..e4d1de742502f6230fc9d9dd94c707949409cf45 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef __LINUX_PINCTRL_MACHINE_H
 #define __LINUX_PINCTRL_MACHINE_H
 
+#include <linux/bug.h>
+
 #include "pinctrl-state.h"
 
 enum pinctrl_map_type {
@@ -148,7 +150,7 @@ struct pinctrl_map {
 #define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs)              \
        PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs)
 
-#ifdef CONFIG_PINMUX
+#ifdef CONFIG_PINCTRL
 
 extern int pinctrl_register_mappings(struct pinctrl_map const *map,
                                unsigned num_maps);
index f51bf2e70c69605d8e298929a251490dbcf23bd2..2db407a400513efcc39ced42b6e94859fb7f417f 100644 (file)
@@ -357,7 +357,7 @@ struct uart_port {
 #define UPF_CONS_FLOW          ((__force upf_t) (1 << 23))
 #define UPF_SHARE_IRQ          ((__force upf_t) (1 << 24))
 #define UPF_EXAR_EFR           ((__force upf_t) (1 << 25))
-#define UPF_IIR_ONCE           ((__force upf_t) (1 << 26))
+#define UPF_BUG_THRE           ((__force upf_t) (1 << 26))
 /* The exact UART type is known and should not be probed.  */
 #define UPF_FIXED_TYPE         ((__force upf_t) (1 << 27))
 #define UPF_BOOT_AUTOCONF      ((__force upf_t) (1 << 28))
index 33370271b8b2c43ac65925619d15305d27a7018c..111f26b6e28b992bbebbe645819712bf8c07ab63 100644 (file)
@@ -238,11 +238,12 @@ enum {
 /*
  * The callback notifies userspace to release buffers when skb DMA is done in
  * lower device, the skb last reference should be 0 when calling this.
- * The desc is used to track userspace buffer index.
+ * The ctx field is used to track device context.
+ * The desc field is used to track userspace buffer index.
  */
 struct ubuf_info {
-       void (*callback)(void *);
-       void *arg;
+       void (*callback)(struct ubuf_info *);
+       void *ctx;
        unsigned long desc;
 };
 
@@ -481,6 +482,7 @@ struct sk_buff {
        union {
                __u32           mark;
                __u32           dropcount;
+               __u32           avail_size;
        };
 
        sk_buff_data_t          transport_header;
@@ -1018,7 +1020,7 @@ static inline void skb_queue_splice(const struct sk_buff_head *list,
 }
 
 /**
- *     skb_queue_splice - join two skb lists and reinitialise the emptied list
+ *     skb_queue_splice_init - join two skb lists and reinitialise the emptied list
  *     @list: the new list to add
  *     @head: the place to add it in the first list
  *
@@ -1049,7 +1051,7 @@ static inline void skb_queue_splice_tail(const struct sk_buff_head *list,
 }
 
 /**
- *     skb_queue_splice_tail - join two skb lists and reinitialise the emptied list
+ *     skb_queue_splice_tail_init - join two skb lists and reinitialise the emptied list
  *     @list: the new list to add
  *     @head: the place to add it in the first list
  *
@@ -1365,6 +1367,18 @@ static inline int skb_tailroom(const struct sk_buff *skb)
        return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail;
 }
 
+/**
+ *     skb_availroom - bytes at buffer end
+ *     @skb: buffer to check
+ *
+ *     Return the number of bytes of free space at the tail of an sk_buff
+ *     allocated by sk_stream_alloc()
+ */
+static inline int skb_availroom(const struct sk_buff *skb)
+{
+       return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len;
+}
+
 /**
  *     skb_reserve - adjust headroom
  *     @skb: buffer to alter
index 6a40c76bdcf1a7732d71675d888e722aa0dc578c..1747b6787b9e90375827a9af75148bf420caf386 100644 (file)
@@ -3,14 +3,10 @@
 
 #include <linux/compiler.h>
 
+#ifdef __KERNEL__
+
 #undef NULL
-#if defined(__cplusplus)
-#define NULL 0
-#else
 #define NULL ((void *)0)
-#endif
-
-#ifdef __KERNEL__
 
 enum {
        false   = 0,
index e5fa50345516837d035650183aebefc7f0633d8b..7f480db60231a714b9e520f3a16856c5d4e4a5e1 100644 (file)
@@ -210,6 +210,12 @@ typedef u32 phys_addr_t;
 
 typedef phys_addr_t resource_size_t;
 
+/*
+ * This type is the placeholder for a hardware interrupt number. It has to be
+ * big enough to enclose whatever representation is used by a given platform.
+ */
+typedef unsigned long irq_hw_number_t;
+
 typedef struct {
        int counter;
 } atomic_t;
index f67810f8f21b1e6468af6c61e044923c005e0da4..38ab3f46346ff4852eabc4e0bbfc3fc2d5e2e793 100644 (file)
@@ -94,6 +94,7 @@ struct usb_phy {
 
        struct usb_otg          *otg;
 
+       struct device           *io_dev;
        struct usb_phy_io_ops   *io_ops;
        void __iomem            *io_priv;
 
index fbb666b1b67008ef38d9f7c2b0e9682e924fbae7..4742838882332ac766a97ddc9c582afde6127457 100644 (file)
 /* parity check flag */
 #define RELEVANT_IFLAG(iflag)  (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
 
-enum port_dev_state {
-       PORT_UNREGISTERED,
-       PORT_REGISTERING,
-       PORT_REGISTERED,
-       PORT_UNREGISTERING,
-};
-
 /* USB serial flags */
 #define USB_SERIAL_WRITE_BUSY  0
 
@@ -124,7 +117,6 @@ struct usb_serial_port {
        char                    throttle_req;
        unsigned long           sysrq; /* sysrq timeout */
        struct device           dev;
-       enum port_dev_state     dev_state;
 };
 #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
 
index 9c3120dca294ddc41d2a131540d8135cf001de89..b572f80bdfd527d10a9793047c6d2f7c14f0d685 100644 (file)
@@ -47,6 +47,8 @@
  */
 #define VGA_DEFAULT_DEVICE     (NULL)
 
+struct pci_dev;
+
 /* For use by clients */
 
 /**
index 59c5d18cc3857da85690627b085e1065eeeb78ad..bed833d9796aed86bac5ca7d45ad53cde3447e52 100644 (file)
@@ -36,7 +36,11 @@ struct dst_entry {
        struct net_device       *dev;
        struct  dst_ops         *ops;
        unsigned long           _metrics;
-       unsigned long           expires;
+       union {
+               unsigned long           expires;
+               /* point to where the dst_entry copied from */
+               struct dst_entry        *from;
+       };
        struct dst_entry        *path;
        struct neighbour __rcu  *_neighbour;
 #ifdef CONFIG_XFRM
@@ -55,6 +59,7 @@ struct dst_entry {
 #define DST_NOCACHE            0x0010
 #define DST_NOCOUNT            0x0020
 #define DST_NOPEER             0x0040
+#define DST_FAKE_RTABLE                0x0080
 
        short                   error;
        short                   obsolete;
index b26bb810198169c9b0d10462c282d284a6ad1bca..0ae759a6c76ef7f2b58ba28588195223443ca352 100644 (file)
@@ -123,6 +123,54 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
        return ((struct rt6_info *)dst)->rt6i_idev;
 }
 
+static inline void rt6_clean_expires(struct rt6_info *rt)
+{
+       if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
+               dst_release(rt->dst.from);
+
+       rt->rt6i_flags &= ~RTF_EXPIRES;
+       rt->dst.from = NULL;
+}
+
+static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
+{
+       if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
+               dst_release(rt->dst.from);
+
+       rt->rt6i_flags |= RTF_EXPIRES;
+       rt->dst.expires = expires;
+}
+
+static inline void rt6_update_expires(struct rt6_info *rt, int timeout)
+{
+       if (!(rt->rt6i_flags & RTF_EXPIRES)) {
+               if (rt->dst.from)
+                       dst_release(rt->dst.from);
+               /* dst_set_expires relies on expires == 0 
+                * if it has not been set previously.
+                */
+               rt->dst.expires = 0;
+       }
+
+       dst_set_expires(&rt->dst, timeout);
+       rt->rt6i_flags |= RTF_EXPIRES;
+}
+
+static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
+{
+       struct dst_entry *new = (struct dst_entry *) from;
+
+       if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) {
+               if (new == rt->dst.from)
+                       return;
+               dst_release(rt->dst.from);
+       }
+
+       rt->rt6i_flags &= ~RTF_EXPIRES;
+       rt->dst.from = new;
+       dst_hold(new);
+}
+
 struct fib6_walker_t {
        struct list_head lh;
        struct fib6_node *root, *node;
index 2bdee51ba30d29f1ccd296fdbdcd06a709a5b4c4..72522f0873757ae08507671667cc7bc7cc849110 100644 (file)
@@ -393,7 +393,7 @@ struct ip_vs_protocol {
 
        void (*exit)(struct ip_vs_protocol *pp);
 
-       void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
+       int (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
 
        void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd);
 
@@ -1203,6 +1203,8 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol,
 
 extern int ip_vs_use_count_inc(void);
 extern void ip_vs_use_count_dec(void);
+extern int ip_vs_register_nl_ioctl(void);
+extern void ip_vs_unregister_nl_ioctl(void);
 extern int ip_vs_control_init(void);
 extern void ip_vs_control_cleanup(void);
 extern struct ip_vs_dest *
index 77d4c3745cb5be169f87507a34349cd853e8da10..ef46058d35bf0de1fdabf80915594f9d201a0a5c 100644 (file)
@@ -245,7 +245,7 @@ static inline unsigned long red_calc_qavg_from_idle_time(const struct red_parms
         *
         * dummy packets as a burst after idle time, i.e.
         *
-        *      p->qavg *= (1-W)^m
+        *      v->qavg *= (1-W)^m
         *
         * This is an apparently overcomplicated solution (f.e. we have to
         * precompute a table to make this calculation in reasonable time)
@@ -279,7 +279,7 @@ static inline unsigned long red_calc_qavg_no_idle_time(const struct red_parms *p
                                                       unsigned int backlog)
 {
        /*
-        * NOTE: p->qavg is fixed point number with point at Wlog.
+        * NOTE: v->qavg is fixed point number with point at Wlog.
         * The formula below is equvalent to floating point
         * version:
         *
@@ -390,7 +390,7 @@ static inline void red_adaptative_algo(struct red_parms *p, struct red_vars *v)
        if (red_is_idling(v))
                qavg = red_calc_qavg_from_idle_time(p, v);
 
-       /* p->qavg is fixed point number with point at Wlog */
+       /* v->qavg is fixed point number with point at Wlog */
        qavg >>= p->Wlog;
 
        if (qavg > p->target_max && p->max_P <= MAX_P_MAX)
index a6ba1f8871fda3077183717a1e099cd5161b555c..5a0a58ac4126c47517ea5a4da0fdb051cc88daba 100644 (file)
@@ -246,6 +246,7 @@ struct cg_proto;
   *    @sk_user_data: RPC layer private data
   *    @sk_sndmsg_page: cached page for sendmsg
   *    @sk_sndmsg_off: cached offset for sendmsg
+  *    @sk_peek_off: current peek_offset value
   *    @sk_send_head: front of stuff to transmit
   *    @sk_security: used by security modules
   *    @sk_mark: generic packet mark
@@ -1128,9 +1129,9 @@ sk_sockets_allocated_read_positive(struct sock *sk)
        struct proto *prot = sk->sk_prot;
 
        if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
-               return percpu_counter_sum_positive(sk->sk_cgrp->sockets_allocated);
+               return percpu_counter_read_positive(sk->sk_cgrp->sockets_allocated);
 
-       return percpu_counter_sum_positive(prot->sockets_allocated);
+       return percpu_counter_read_positive(prot->sockets_allocated);
 }
 
 static inline int
index 377df4a28512bd7d97aad68b9a72d1f449f2cba8..1e1198546c725d43a7ff6baa657c25ef364d73ee 100644 (file)
@@ -134,6 +134,9 @@ struct scsi_cmnd {
 
 static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
 {
+       if (!cmd->request->rq_disk)
+               return NULL;
+
        return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
 }
 
index b6e0f57d451d28fe27edb602ae02cba552d5709e..bc056687f647f7aa9965d5ec4b297bbe9459e557 100644 (file)
@@ -325,6 +325,13 @@ void release_and_free_resource(struct resource *res);
 
 /* --- */
 
+/* sound printk debug levels */
+enum {
+       SND_PR_ALWAYS,
+       SND_PR_DEBUG,
+       SND_PR_VERBOSE,
+};
+
 #if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
 __printf(4, 5)
 void __snd_printk(unsigned int level, const char *file, int line,
@@ -354,6 +361,8 @@ void __snd_printk(unsigned int level, const char *file, int line,
  */
 #define snd_printd(fmt, args...) \
        __snd_printk(1, __FILE__, __LINE__, fmt, ##args)
+#define _snd_printd(level, fmt, args...) \
+       __snd_printk(level, __FILE__, __LINE__, fmt, ##args)
 
 /**
  * snd_BUG - give a BUG warning message and stack trace
@@ -383,6 +392,7 @@ void __snd_printk(unsigned int level, const char *file, int line,
 #else /* !CONFIG_SND_DEBUG */
 
 #define snd_printd(fmt, args...)       do { } while (0)
+#define _snd_printd(level, fmt, args...) do { } while (0)
 #define snd_BUG()                      do { } while (0)
 static inline int __snd_bug_on(int cond)
 {
index 97b36eeca4c90b51cf9fa0abcd81af72e1dfb715..e70683d9ec32f00bf58a0ea2dc64be2d74fb8415 100644 (file)
@@ -386,6 +386,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
        struct cred *new;
        int ret;
 
+       p->replacement_session_keyring = NULL;
+
        if (
 #ifdef CONFIG_KEYS
                !p->cred->thread_keyring &&
index cf1a4a68ce444f03218ea0adbbd1f0ea178cc4d0..d1a758bc972afcb3f7c0103de781fa5720bea126 100644 (file)
@@ -62,7 +62,7 @@ config IRQ_DOMAIN_DEBUG
        help
          This option will show the mapping relationship between hardware irq
          numbers and Linux irq numbers. The mapping is exposed via debugfs
-         in the file "virq_mapping".
+         in the file "irq_domain_mapping".
 
          If you don't know what this means you don't need it.
 
index 3601f3fbf67c8808cb0223206713b1d1aeeb31bb..0e0ba5f840b26c84affc8fe813ce4a89b51753bf 100644 (file)
@@ -23,7 +23,6 @@ static LIST_HEAD(irq_domain_list);
 static DEFINE_MUTEX(irq_domain_mutex);
 
 static DEFINE_MUTEX(revmap_trees_mutex);
-static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_domain *irq_default_domain;
 
 /**
@@ -184,13 +183,16 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
 }
 
 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+                                        unsigned int max_irq,
                                         const struct irq_domain_ops *ops,
                                         void *host_data)
 {
        struct irq_domain *domain = irq_domain_alloc(of_node,
                                        IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
-       if (domain)
+       if (domain) {
+               domain->revmap_data.nomap.max_irq = max_irq ? max_irq : ~0;
                irq_domain_add(domain);
+       }
        return domain;
 }
 
@@ -262,22 +264,6 @@ void irq_set_default_host(struct irq_domain *domain)
        irq_default_domain = domain;
 }
 
-/**
- * irq_set_virq_count() - Set the maximum number of linux irqs
- * @count: number of linux irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-void irq_set_virq_count(unsigned int count)
-{
-       pr_debug("irq: Trying to set virq count to %d\n", count);
-
-       BUG_ON(count < NUM_ISA_INTERRUPTS);
-       if (count < NR_IRQS)
-               irq_virq_count = count;
-}
-
 static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
                            irq_hw_number_t hwirq)
 {
@@ -320,13 +306,12 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
                pr_debug("irq: create_direct virq allocation failed\n");
                return 0;
        }
-       if (virq >= irq_virq_count) {
+       if (virq >= domain->revmap_data.nomap.max_irq) {
                pr_err("ERROR: no free irqs available below %i maximum\n",
-                       irq_virq_count);
+                       domain->revmap_data.nomap.max_irq);
                irq_free_desc(virq);
                return 0;
        }
-
        pr_debug("irq: create_direct obtained virq %d\n", virq);
 
        if (irq_setup_virq(domain, virq, virq)) {
@@ -350,7 +335,8 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
 unsigned int irq_create_mapping(struct irq_domain *domain,
                                irq_hw_number_t hwirq)
 {
-       unsigned int virq, hint;
+       unsigned int hint;
+       int virq;
 
        pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
 
@@ -377,13 +363,13 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
                return irq_domain_legacy_revmap(domain, hwirq);
 
        /* Allocate a virtual interrupt number */
-       hint = hwirq % irq_virq_count;
+       hint = hwirq % nr_irqs;
        if (hint == 0)
                hint++;
        virq = irq_alloc_desc_from(hint, 0);
-       if (!virq)
+       if (virq <= 0)
                virq = irq_alloc_desc_from(1, 0);
-       if (!virq) {
+       if (virq <= 0) {
                pr_debug("irq: -> virq allocation failed\n");
                return 0;
        }
@@ -515,7 +501,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
                              irq_hw_number_t hwirq)
 {
        unsigned int i;
-       unsigned int hint = hwirq % irq_virq_count;
+       unsigned int hint = hwirq % nr_irqs;
 
        /* Look for default domain if nececssary */
        if (domain == NULL)
@@ -536,7 +522,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
                if (data && (data->domain == domain) && (data->hwirq == hwirq))
                        return i;
                i++;
-               if (i >= irq_virq_count)
+               if (i >= nr_irqs)
                        i = 1;
        } while(i != hint);
        return 0;
@@ -642,8 +628,9 @@ static int virq_debug_show(struct seq_file *m, void *private)
        void *data;
        int i;
 
-       seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
-                     "chip name", "chip data", "domain name");
+       seq_printf(m, "%-5s  %-7s  %-15s  %-*s  %s\n", "irq", "hwirq",
+                     "chip name", (int)(2 * sizeof(void *) + 2), "chip data",
+                     "domain name");
 
        for (i = 1; i < nr_irqs; i++) {
                desc = irq_to_desc(i);
@@ -666,7 +653,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
                        seq_printf(m, "%-15s  ", p);
 
                        data = irq_desc_get_chip_data(desc);
-                       seq_printf(m, "0x%16p  ", data);
+                       seq_printf(m, data ? "0x%p  " : "  %p  ", data);
 
                        if (desc->irq_data.domain && desc->irq_data.domain->of_node)
                                p = desc->irq_data.domain->of_node->full_name;
index 0c56d44b9fd5736f05498966b332fa97b30356ac..1588e3b2871b9e28a68316f91ca418d44a75cba2 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/irq_work.h>
 #include <linux/percpu.h>
 #include <linux/hardirq.h>
+#include <linux/irqflags.h>
 #include <asm/processor.h>
 
 /*
index 22000c3db0dd53e28b01fc05a302316e02d1d221..8d262b4675738d21bea752d65a47117c3d8ae514 100644 (file)
@@ -284,8 +284,12 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
        if (value) {
                if(copy_from_user(&set_buffer, value, sizeof(set_buffer)))
                        return -EFAULT;
-       } else
-               memset((char *) &set_buffer, 0, sizeof(set_buffer));
+       } else {
+               memset(&set_buffer, 0, sizeof(set_buffer));
+               printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer."
+                           " Misfeature support will be removed\n",
+                           current->comm);
+       }
 
        error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
        if (error || !ovalue)
index 80aed44e345abc648f7ac3d0e7560a05e453c7fd..8ed89a175d79376600dfbfd777f06ed3c24665a5 100644 (file)
@@ -97,7 +97,7 @@ void panic(const char *fmt, ...)
        /*
         * Avoid nested stack-dumping if a panic occurs during oops processing
         */
-       if (!oops_in_progress)
+       if (!test_taint(TAINT_DIE) && oops_in_progress <= 1)
                dump_stack();
 #endif
 
index 52b3a06a02f8406c4f78eb06cfaad89f51910a21..4ab11879aeb4d15baa3d8d25fa753725084ed809 100644 (file)
@@ -170,7 +170,7 @@ static int proc_taint(struct ctl_table *table, int write,
 #endif
 
 #ifdef CONFIG_PRINTK
-static int proc_dmesg_restrict(struct ctl_table *table, int write,
+static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
                                void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
@@ -703,7 +703,7 @@ static struct ctl_table kern_table[] = {
                .data           = &dmesg_restrict,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec_minmax,
+               .proc_handler   = proc_dointvec_minmax_sysadmin,
                .extra1         = &zero,
                .extra2         = &one,
        },
@@ -712,7 +712,7 @@ static struct ctl_table kern_table[] = {
                .data           = &kptr_restrict,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dmesg_restrict,
+               .proc_handler   = proc_dointvec_minmax_sysadmin,
                .extra1         = &zero,
                .extra2         = &two,
        },
@@ -1943,7 +1943,7 @@ static int proc_taint(struct ctl_table *table, int write,
 }
 
 #ifdef CONFIG_PRINTK
-static int proc_dmesg_restrict(struct ctl_table *table, int write,
+static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
                                void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        if (write && !capable(CAP_SYS_ADMIN))
index 2cf9cc7aa103bff9d40267eb862484ec3052e1de..a20dc8a3c9499e5631102ec869d67d6148c63ea6 100644 (file)
@@ -1,6 +1,10 @@
 #
 # Timer subsystem related configuration options
 #
+
+# Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is
+# only related to the tick functionality. Oneshot clockevent devices
+# are supported independ of this.
 config TICK_ONESHOT
        bool
 
index e883f57a3cd39f33796f5a91856d30d5573f0543..bf57abdc7bd04dbf2c8f16d5dbd3ee07e688383d 100644 (file)
@@ -575,10 +575,12 @@ void tick_broadcast_switch_to_oneshot(void)
        unsigned long flags;
 
        raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
+
+       tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT;
+
        if (cpumask_empty(tick_get_broadcast_mask()))
                goto end;
 
-       tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT;
        bc = tick_broadcast_device.evtdev;
        if (bc)
                tick_broadcast_setup_oneshot(bc);
index 3526038f28361b7e4241818cafb8a9a978310e0c..6a3a5b9ff56176c2951256edf7ef9601a0f49106 100644 (file)
@@ -534,9 +534,9 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
                                hrtimer_get_expires(&ts->sched_timer), 0))
                                break;
                }
-               /* Update jiffies and reread time */
-               tick_do_update_jiffies64(now);
+               /* Reread time and update jiffies */
                now = ktime_get();
+               tick_do_update_jiffies64(now);
        }
 }
 
index 21dee7c19afd8e9c493bec8585869f098545f4ff..aeefa8bc8b1c2dac1493703ff2f209ce894938f9 100644 (file)
@@ -192,14 +192,14 @@ static int kobject_add_internal(struct kobject *kobj)
 
                /* be noisy on error issues */
                if (error == -EEXIST)
-                       printk(KERN_ERR "%s failed for %s with "
-                              "-EEXIST, don't try to register things with "
-                              "the same name in the same directory.\n",
-                              __func__, kobject_name(kobj));
+                       WARN(1, "%s failed for %s with "
+                            "-EEXIST, don't try to register things with "
+                            "the same name in the same directory.\n",
+                            __func__, kobject_name(kobj));
                else
-                       printk(KERN_ERR "%s failed for %s (%d)\n",
-                              __func__, kobject_name(kobj), error);
-               dump_stack();
+                       WARN(1, "%s failed for %s (error: %d parent: %s)\n",
+                            __func__, kobject_name(kobj), error,
+                            parent ? kobject_name(parent) : "'none'");
        } else
                kobj->state_in_sysfs = 1;
 
index 2f526627e4f575c50468b51015270c35d2179721..0c505361da197a9a46c8b2665af7b5520ad11974 100644 (file)
@@ -177,8 +177,8 @@ int mpi_rshift(MPI x, MPI a, unsigned n)
  */
 int mpi_lshift_limbs(MPI a, unsigned int count)
 {
-       mpi_ptr_t ap = a->d;
-       int n = a->nlimbs;
+       const int n = a->nlimbs;
+       mpi_ptr_t ap;
        int i;
 
        if (!count || !n)
@@ -187,6 +187,7 @@ int mpi_lshift_limbs(MPI a, unsigned int count)
        if (RESIZE_IF_NEEDED(a, n + count) < 0)
                return -ENOMEM;
 
+       ap = a->d;
        for (i = n - 1; i >= 0; i--)
                ap[i + count] = ap[i];
        for (i = 0; i < count; i++)
index b8ce6f450956e6e3a9191cbf92afd1d490a32c9d..cd65cb19c941b2bf04cb86777cb8312ecad6c0ae 100644 (file)
@@ -2791,6 +2791,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
         * so no worry about deadlock.
         */
        page = pte_page(entry);
+       get_page(page);
        if (page != pagecache_page)
                lock_page(page);
 
@@ -2822,6 +2823,7 @@ out_page_table_lock:
        }
        if (page != pagecache_page)
                unlock_page(page);
+       put_page(page);
 
 out_mutex:
        mutex_unlock(&hugetlb_instantiation_mutex);
index 99f285599501482e8b48c77eb768a62981811cf6..a44eab3157f8dc4b25e686b643ccacbc8449e041 100644 (file)
@@ -330,6 +330,9 @@ static int __init_memblock memblock_add_region(struct memblock_type *type,
        phys_addr_t end = base + memblock_cap_size(base, &size);
        int i, nr_new;
 
+       if (!size)
+               return 0;
+
        /* special case for empty array */
        if (type->regions[0].size == 0) {
                WARN_ON(type->cnt != 1 || type->total_size);
@@ -430,6 +433,9 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type,
 
        *start_rgn = *end_rgn = 0;
 
+       if (!size)
+               return 0;
+
        /* we'll create at most two more regions */
        while (type->cnt + 2 > type->max)
                if (memblock_double_array(type) < 0)
@@ -514,7 +520,6 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
                     (unsigned long long)base,
                     (unsigned long long)base + size,
                     (void *)_RET_IP_);
-       BUG_ON(0 == size);
 
        return memblock_add_region(_rgn, base, size, MAX_NUMNODES);
 }
index 7d698df4a067ce591fd661f45e098610e1a027db..b868def9bcc1e1f20c05406b1e9b90e0eae5d182 100644 (file)
@@ -2165,7 +2165,7 @@ static int __cpuinit memcg_cpu_hotplug_callback(struct notifier_block *nb,
        if (action == CPU_ONLINE)
                return NOTIFY_OK;
 
-       if ((action != CPU_DEAD) || action != CPU_DEAD_FROZEN)
+       if (action != CPU_DEAD && action != CPU_DEAD_FROZEN)
                return NOTIFY_OK;
 
        for_each_mem_cgroup(iter)
@@ -3392,6 +3392,7 @@ void mem_cgroup_replace_page_cache(struct page *oldpage,
         * the newpage may be on LRU(or pagevec for LRU) already. We lock
         * LRU while we overwrite pc->mem_cgroup.
         */
+       pc = lookup_page_cgroup(newpage);
        __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true);
 }
 
@@ -3763,7 +3764,7 @@ move_account:
                        goto try_to_free;
                cond_resched();
        /* "ret" should also be checked to ensure all lists are empty. */
-       } while (memcg->res.usage > 0 || ret);
+       } while (res_counter_read_u64(&memcg->res, RES_USAGE) > 0 || ret);
 out:
        css_put(&memcg->css);
        return ret;
@@ -3778,7 +3779,7 @@ try_to_free:
        lru_add_drain_all();
        /* try to free all pages in this cgroup */
        shrink = 1;
-       while (nr_retries && memcg->res.usage > 0) {
+       while (nr_retries && res_counter_read_u64(&memcg->res, RES_USAGE) > 0) {
                int progress;
 
                if (signal_pending(current)) {
index a7bf6a31c9f62be11cb8e5819322565b7cf2c266..848ef52d96031f5061bc86582aa0120ccd0394e8 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -240,6 +240,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
        return next;
 }
 
+static unsigned long do_brk(unsigned long addr, unsigned long len);
+
 SYSCALL_DEFINE1(brk, unsigned long, brk)
 {
        unsigned long rlim, retval;
@@ -951,7 +953,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint)
  * The caller must hold down_write(&current->mm->mmap_sem).
  */
 
-unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
+static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
                        unsigned long len, unsigned long prot,
                        unsigned long flags, unsigned long pgoff)
 {
@@ -1087,7 +1089,32 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
 
        return mmap_region(file, addr, len, flags, vm_flags, pgoff);
 }
-EXPORT_SYMBOL(do_mmap_pgoff);
+
+unsigned long do_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+{
+       if (unlikely(offset + PAGE_ALIGN(len) < offset))
+               return -EINVAL;
+       if (unlikely(offset & ~PAGE_MASK))
+               return -EINVAL;
+       return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
+}
+EXPORT_SYMBOL(do_mmap);
+
+unsigned long vm_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+{
+       unsigned long ret;
+       struct mm_struct *mm = current->mm;
+
+       down_write(&mm->mmap_sem);
+       ret = do_mmap(file, addr, len, prot, flag, offset);
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+EXPORT_SYMBOL(vm_mmap);
 
 SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
                unsigned long, prot, unsigned long, flags,
@@ -2105,21 +2132,25 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
 
        return 0;
 }
-
 EXPORT_SYMBOL(do_munmap);
 
-SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+int vm_munmap(unsigned long start, size_t len)
 {
        int ret;
        struct mm_struct *mm = current->mm;
 
-       profile_munmap(addr);
-
        down_write(&mm->mmap_sem);
-       ret = do_munmap(mm, addr, len);
+       ret = do_munmap(mm, start, len);
        up_write(&mm->mmap_sem);
        return ret;
 }
+EXPORT_SYMBOL(vm_munmap);
+
+SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+{
+       profile_munmap(addr);
+       return vm_munmap(addr, len);
+}
 
 static inline void verify_mm_writelocked(struct mm_struct *mm)
 {
@@ -2136,7 +2167,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm)
  *  anonymous maps.  eventually we may be able to do some
  *  brk-specific accounting here.
  */
-unsigned long do_brk(unsigned long addr, unsigned long len)
+static unsigned long do_brk(unsigned long addr, unsigned long len)
 {
        struct mm_struct * mm = current->mm;
        struct vm_area_struct * vma, * prev;
@@ -2232,7 +2263,17 @@ out:
        return addr;
 }
 
-EXPORT_SYMBOL(do_brk);
+unsigned long vm_brk(unsigned long addr, unsigned long len)
+{
+       struct mm_struct *mm = current->mm;
+       unsigned long ret;
+
+       down_write(&mm->mmap_sem);
+       ret = do_brk(addr, len);
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+EXPORT_SYMBOL(vm_brk);
 
 /* Release all mmaps. */
 void exit_mmap(struct mm_struct *mm)
index f59e170fceb4e01046a339d8878f5030dea8a4f9..bb8f4f004a82ce57abb0653a9a8ed72d533f5c45 100644 (file)
@@ -1233,7 +1233,7 @@ enomem:
 /*
  * handle mapping creation for uClinux
  */
-unsigned long do_mmap_pgoff(struct file *file,
+static unsigned long do_mmap_pgoff(struct file *file,
                            unsigned long addr,
                            unsigned long len,
                            unsigned long prot,
@@ -1470,7 +1470,32 @@ error_getting_region:
        show_free_areas(0);
        return -ENOMEM;
 }
-EXPORT_SYMBOL(do_mmap_pgoff);
+
+unsigned long do_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+{
+       if (unlikely(offset + PAGE_ALIGN(len) < offset))
+               return -EINVAL;
+       if (unlikely(offset & ~PAGE_MASK))
+               return -EINVAL;
+       return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
+}
+EXPORT_SYMBOL(do_mmap);
+
+unsigned long vm_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+{
+       unsigned long ret;
+       struct mm_struct *mm = current->mm;
+
+       down_write(&mm->mmap_sem);
+       ret = do_mmap(file, addr, len, prot, flag, offset);
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+EXPORT_SYMBOL(vm_mmap);
 
 SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
                unsigned long, prot, unsigned long, flags,
@@ -1709,16 +1734,22 @@ erase_whole_vma:
 }
 EXPORT_SYMBOL(do_munmap);
 
-SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+int vm_munmap(unsigned long addr, size_t len)
 {
-       int ret;
        struct mm_struct *mm = current->mm;
+       int ret;
 
        down_write(&mm->mmap_sem);
        ret = do_munmap(mm, addr, len);
        up_write(&mm->mmap_sem);
        return ret;
 }
+EXPORT_SYMBOL(vm_munmap);
+
+SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+{
+       return vm_munmap(addr, len);
+}
 
 /*
  * release all the mappings made in a process's VM space
@@ -1744,7 +1775,7 @@ void exit_mmap(struct mm_struct *mm)
        kleave("");
 }
 
-unsigned long do_brk(unsigned long addr, unsigned long len)
+unsigned long vm_brk(unsigned long addr, unsigned long len)
 {
        return -ENOMEM;
 }
index 9d3dd3763cf763460b0f4f17b7ff630e5c8115c0..4c5ff7f284d9b299d7ea9cf3b7bfe374550ce5ca 100644 (file)
@@ -26,7 +26,7 @@
  */
 static const struct address_space_operations swap_aops = {
        .writepage      = swap_writepage,
-       .set_page_dirty = __set_page_dirty_nobuffers,
+       .set_page_dirty = __set_page_dirty_no_writeback,
        .migratepage    = migrate_page,
 };
 
index 33c332bbab738231105cc7c3cfacf80e5297ed6e..1a518684a32f0a55e516dc642c7284ee44ae803f 100644 (file)
@@ -2107,12 +2107,7 @@ restart:
                 * with multiple processes reclaiming pages, the total
                 * freeing target can get unreasonably large.
                 */
-               if (nr_reclaimed >= nr_to_reclaim)
-                       nr_to_reclaim = 0;
-               else
-                       nr_to_reclaim -= nr_reclaimed;
-
-               if (!nr_to_reclaim && priority < DEF_PRIORITY)
+               if (nr_reclaimed >= nr_to_reclaim && priority < DEF_PRIORITY)
                        break;
        }
        blk_finish_plug(&plug);
index 0906c194a4139b1cf56e368876c7ba463e911c5b..9d9a6a3edbd58584fdceffdf680de6e28dc72c90 100644 (file)
@@ -2011,16 +2011,17 @@ static void __exit ax25_exit(void)
        proc_net_remove(&init_net, "ax25_route");
        proc_net_remove(&init_net, "ax25");
        proc_net_remove(&init_net, "ax25_calls");
-       ax25_rt_free();
-       ax25_uid_free();
-       ax25_dev_free();
 
-       ax25_unregister_sysctl();
        unregister_netdevice_notifier(&ax25_dev_notifier);
+       ax25_unregister_sysctl();
 
        dev_remove_pack(&ax25_packet_type);
 
        sock_unregister(PF_AX25);
        proto_unregister(&ax25_proto);
+
+       ax25_rt_free();
+       ax25_uid_free();
+       ax25_dev_free();
 }
 module_exit(ax25_exit);
index 61f65344e711fc4b87856889c8d83e89d0d911d6..a2098e3de500d4ab34c3d3b14435eddb5089b354 100644 (file)
@@ -47,6 +47,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
                kfree_skb(skb);
        } else {
                skb_push(skb, ETH_HLEN);
+               br_drop_fake_rtable(skb);
                dev_queue_xmit(skb);
        }
 
index 702a1ae9220b79bd9e60cc25732201fe8750dcd2..27ca25ed70216979790ffd6c555baaf88bf4e7a4 100644 (file)
@@ -241,7 +241,6 @@ static void br_multicast_group_expired(unsigned long data)
        hlist_del_rcu(&mp->hlist[mdb->ver]);
        mdb->size--;
 
-       del_timer(&mp->query_timer);
        call_rcu_bh(&mp->rcu, br_multicast_free_group);
 
 out:
@@ -271,7 +270,6 @@ static void br_multicast_del_pg(struct net_bridge *br,
                rcu_assign_pointer(*pp, p->next);
                hlist_del_init(&p->mglist);
                del_timer(&p->timer);
-               del_timer(&p->query_timer);
                call_rcu_bh(&p->rcu, br_multicast_free_pg);
 
                if (!mp->ports && !mp->mglist &&
@@ -507,74 +505,6 @@ static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br,
        return NULL;
 }
 
-static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp)
-{
-       struct net_bridge *br = mp->br;
-       struct sk_buff *skb;
-
-       skb = br_multicast_alloc_query(br, &mp->addr);
-       if (!skb)
-               goto timer;
-
-       netif_rx(skb);
-
-timer:
-       if (++mp->queries_sent < br->multicast_last_member_count)
-               mod_timer(&mp->query_timer,
-                         jiffies + br->multicast_last_member_interval);
-}
-
-static void br_multicast_group_query_expired(unsigned long data)
-{
-       struct net_bridge_mdb_entry *mp = (void *)data;
-       struct net_bridge *br = mp->br;
-
-       spin_lock(&br->multicast_lock);
-       if (!netif_running(br->dev) || !mp->mglist ||
-           mp->queries_sent >= br->multicast_last_member_count)
-               goto out;
-
-       br_multicast_send_group_query(mp);
-
-out:
-       spin_unlock(&br->multicast_lock);
-}
-
-static void br_multicast_send_port_group_query(struct net_bridge_port_group *pg)
-{
-       struct net_bridge_port *port = pg->port;
-       struct net_bridge *br = port->br;
-       struct sk_buff *skb;
-
-       skb = br_multicast_alloc_query(br, &pg->addr);
-       if (!skb)
-               goto timer;
-
-       br_deliver(port, skb);
-
-timer:
-       if (++pg->queries_sent < br->multicast_last_member_count)
-               mod_timer(&pg->query_timer,
-                         jiffies + br->multicast_last_member_interval);
-}
-
-static void br_multicast_port_group_query_expired(unsigned long data)
-{
-       struct net_bridge_port_group *pg = (void *)data;
-       struct net_bridge_port *port = pg->port;
-       struct net_bridge *br = port->br;
-
-       spin_lock(&br->multicast_lock);
-       if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
-           pg->queries_sent >= br->multicast_last_member_count)
-               goto out;
-
-       br_multicast_send_port_group_query(pg);
-
-out:
-       spin_unlock(&br->multicast_lock);
-}
-
 static struct net_bridge_mdb_entry *br_multicast_get_group(
        struct net_bridge *br, struct net_bridge_port *port,
        struct br_ip *group, int hash)
@@ -690,8 +620,6 @@ rehash:
        mp->addr = *group;
        setup_timer(&mp->timer, br_multicast_group_expired,
                    (unsigned long)mp);
-       setup_timer(&mp->query_timer, br_multicast_group_query_expired,
-                   (unsigned long)mp);
 
        hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]);
        mdb->size++;
@@ -746,8 +674,6 @@ static int br_multicast_add_group(struct net_bridge *br,
        hlist_add_head(&p->mglist, &port->mglist);
        setup_timer(&p->timer, br_multicast_port_group_expired,
                    (unsigned long)p);
-       setup_timer(&p->query_timer, br_multicast_port_group_query_expired,
-                   (unsigned long)p);
 
        rcu_assign_pointer(*pp, p);
 
@@ -1291,9 +1217,6 @@ static void br_multicast_leave_group(struct net_bridge *br,
                     time_after(mp->timer.expires, time) :
                     try_to_del_timer_sync(&mp->timer) >= 0)) {
                        mod_timer(&mp->timer, time);
-
-                       mp->queries_sent = 0;
-                       mod_timer(&mp->query_timer, now);
                }
 
                goto out;
@@ -1310,9 +1233,6 @@ static void br_multicast_leave_group(struct net_bridge *br,
                     time_after(p->timer.expires, time) :
                     try_to_del_timer_sync(&p->timer) >= 0)) {
                        mod_timer(&p->timer, time);
-
-                       p->queries_sent = 0;
-                       mod_timer(&p->query_timer, now);
                }
 
                break;
@@ -1681,7 +1601,6 @@ void br_multicast_stop(struct net_bridge *br)
                hlist_for_each_entry_safe(mp, p, n, &mdb->mhash[i],
                                          hlist[ver]) {
                        del_timer(&mp->timer);
-                       del_timer(&mp->query_timer);
                        call_rcu_bh(&mp->rcu, br_multicast_free_group);
                }
        }
index dec4f3817133c879b524a65f0919b5dabcff46ea..d7f49b63ab0fd17b82828f60278b5f8a99664a1d 100644 (file)
@@ -156,7 +156,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
        rt->dst.dev = br->dev;
        rt->dst.path = &rt->dst;
        dst_init_metrics(&rt->dst, br_dst_default_metrics, true);
-       rt->dst.flags   = DST_NOXFRM | DST_NOPEER;
+       rt->dst.flags   = DST_NOXFRM | DST_NOPEER | DST_FAKE_RTABLE;
        rt->dst.ops = &fake_dst_ops;
 }
 
@@ -694,11 +694,7 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb,
                                   const struct net_device *out,
                                   int (*okfn)(struct sk_buff *))
 {
-       struct rtable *rt = skb_rtable(skb);
-
-       if (rt && rt == bridge_parent_rtable(in))
-               skb_dst_drop(skb);
-
+       br_drop_fake_rtable(skb);
        return NF_ACCEPT;
 }
 
index 0b67a63ad7a870e550c9d23d03ed7eb52ef854bf..e1d882257877374e21c7a314740a7ee7f76f4ccc 100644 (file)
@@ -82,9 +82,7 @@ struct net_bridge_port_group {
        struct hlist_node               mglist;
        struct rcu_head                 rcu;
        struct timer_list               timer;
-       struct timer_list               query_timer;
        struct br_ip                    addr;
-       u32                             queries_sent;
 };
 
 struct net_bridge_mdb_entry
@@ -94,10 +92,8 @@ struct net_bridge_mdb_entry
        struct net_bridge_port_group __rcu *ports;
        struct rcu_head                 rcu;
        struct timer_list               timer;
-       struct timer_list               query_timer;
        struct br_ip                    addr;
        bool                            mglist;
-       u32                             queries_sent;
 };
 
 struct net_bridge_mdb_htable
index 20618dd3088b79e0f1528436c7b1c9359f9c9cd6..d09340e1523f64d0aa1f7ba71cf0d0626c22036a 100644 (file)
@@ -103,6 +103,7 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
                skb->protocol = htons(ETH_P_IPV6);
                break;
        default:
+               kfree_skb(skb);
                priv->netdev->stats.rx_errors++;
                return -EINVAL;
        }
@@ -220,14 +221,16 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (skb->len > priv->netdev->mtu) {
                pr_warn("Size of skb exceeded MTU\n");
+               kfree_skb(skb);
                dev->stats.tx_errors++;
-               return -ENOSPC;
+               return NETDEV_TX_OK;
        }
 
        if (!priv->flowenabled) {
                pr_debug("dropping packets flow off\n");
+               kfree_skb(skb);
                dev->stats.tx_dropped++;
-               return NETDEV_TX_BUSY;
+               return NETDEV_TX_OK;
        }
 
        if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP)
@@ -242,7 +245,7 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
        result = priv->chnl.dn->transmit(priv->chnl.dn, pkt);
        if (result) {
                dev->stats.tx_dropped++;
-               return result;
+               return NETDEV_TX_OK;
        }
 
        /* Update statistics. */
index c25d453b2803be9a5ad1261fee7cd7120aa60fd5..9bb8f87c4cdad35481e6fc2389090d32a6d5b917 100644 (file)
@@ -1409,14 +1409,34 @@ EXPORT_SYMBOL(register_netdevice_notifier);
  *     register_netdevice_notifier(). The notifier is unlinked into the
  *     kernel structures and may then be reused. A negative errno code
  *     is returned on a failure.
+ *
+ *     After unregistering unregister and down device events are synthesized
+ *     for all devices on the device list to the removed notifier to remove
+ *     the need for special case cleanup code.
  */
 
 int unregister_netdevice_notifier(struct notifier_block *nb)
 {
+       struct net_device *dev;
+       struct net *net;
        int err;
 
        rtnl_lock();
        err = raw_notifier_chain_unregister(&netdev_chain, nb);
+       if (err)
+               goto unlock;
+
+       for_each_net(net) {
+               for_each_netdev(net, dev) {
+                       if (dev->flags & IFF_UP) {
+                               nb->notifier_call(nb, NETDEV_GOING_DOWN, dev);
+                               nb->notifier_call(nb, NETDEV_DOWN, dev);
+                       }
+                       nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
+                       nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev);
+               }
+       }
+unlock:
        rtnl_unlock();
        return err;
 }
index 7f36b38e060fcfbf98ed35cd1dff84067f75d11c..a7cad741df012a2b7790246d6c2d569bac38bda4 100644 (file)
@@ -42,13 +42,14 @@ static void send_dm_alert(struct work_struct *unused);
  * netlink alerts
  */
 static int trace_state = TRACE_OFF;
-static DEFINE_SPINLOCK(trace_state_lock);
+static DEFINE_MUTEX(trace_state_mutex);
 
 struct per_cpu_dm_data {
        struct work_struct dm_alert_work;
-       struct sk_buff *skb;
+       struct sk_buff __rcu *skb;
        atomic_t dm_hit_count;
        struct timer_list send_timer;
+       int cpu;
 };
 
 struct dm_hw_stat_delta {
@@ -79,29 +80,53 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data)
        size_t al;
        struct net_dm_alert_msg *msg;
        struct nlattr *nla;
+       struct sk_buff *skb;
+       struct sk_buff *oskb = rcu_dereference_protected(data->skb, 1);
 
        al = sizeof(struct net_dm_alert_msg);
        al += dm_hit_limit * sizeof(struct net_dm_drop_point);
        al += sizeof(struct nlattr);
 
-       data->skb = genlmsg_new(al, GFP_KERNEL);
-       genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
-                       0, NET_DM_CMD_ALERT);
-       nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
-       msg = nla_data(nla);
-       memset(msg, 0, al);
-       atomic_set(&data->dm_hit_count, dm_hit_limit);
+       skb = genlmsg_new(al, GFP_KERNEL);
+
+       if (skb) {
+               genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
+                               0, NET_DM_CMD_ALERT);
+               nla = nla_reserve(skb, NLA_UNSPEC,
+                                 sizeof(struct net_dm_alert_msg));
+               msg = nla_data(nla);
+               memset(msg, 0, al);
+       } else
+               schedule_work_on(data->cpu, &data->dm_alert_work);
+
+       /*
+        * Don't need to lock this, since we are guaranteed to only
+        * run this on a single cpu at a time.
+        * Note also that we only update data->skb if the old and new skb
+        * pointers don't match.  This ensures that we don't continually call
+        * synchornize_rcu if we repeatedly fail to alloc a new netlink message.
+        */
+       if (skb != oskb) {
+               rcu_assign_pointer(data->skb, skb);
+
+               synchronize_rcu();
+
+               atomic_set(&data->dm_hit_count, dm_hit_limit);
+       }
+
 }
 
 static void send_dm_alert(struct work_struct *unused)
 {
        struct sk_buff *skb;
-       struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
+       struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data);
+
+       WARN_ON_ONCE(data->cpu != smp_processor_id());
 
        /*
         * Grab the skb we're about to send
         */
-       skb = data->skb;
+       skb = rcu_dereference_protected(data->skb, 1);
 
        /*
         * Replace it with a new one
@@ -111,8 +136,10 @@ static void send_dm_alert(struct work_struct *unused)
        /*
         * Ship it!
         */
-       genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL);
+       if (skb)
+               genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL);
 
+       put_cpu_var(dm_cpu_data);
 }
 
 /*
@@ -123,9 +150,11 @@ static void send_dm_alert(struct work_struct *unused)
  */
 static void sched_send_work(unsigned long unused)
 {
-       struct per_cpu_dm_data *data =  &__get_cpu_var(dm_cpu_data);
+       struct per_cpu_dm_data *data =  &get_cpu_var(dm_cpu_data);
+
+       schedule_work_on(smp_processor_id(), &data->dm_alert_work);
 
-       schedule_work(&data->dm_alert_work);
+       put_cpu_var(dm_cpu_data);
 }
 
 static void trace_drop_common(struct sk_buff *skb, void *location)
@@ -134,8 +163,15 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
        struct nlmsghdr *nlh;
        struct nlattr *nla;
        int i;
-       struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
+       struct sk_buff *dskb;
+       struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data);
+
+
+       rcu_read_lock();
+       dskb = rcu_dereference(data->skb);
 
+       if (!dskb)
+               goto out;
 
        if (!atomic_add_unless(&data->dm_hit_count, -1, 0)) {
                /*
@@ -144,12 +180,13 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
                goto out;
        }
 
-       nlh = (struct nlmsghdr *)data->skb->data;
+       nlh = (struct nlmsghdr *)dskb->data;
        nla = genlmsg_data(nlmsg_data(nlh));
        msg = nla_data(nla);
        for (i = 0; i < msg->entries; i++) {
                if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) {
                        msg->points[i].count++;
+                       atomic_inc(&data->dm_hit_count);
                        goto out;
                }
        }
@@ -157,7 +194,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
        /*
         * We need to create a new entry
         */
-       __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
+       __nla_reserve_nohdr(dskb, sizeof(struct net_dm_drop_point));
        nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point));
        memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
        msg->points[msg->entries].count = 1;
@@ -169,6 +206,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
        }
 
 out:
+       rcu_read_unlock();
+       put_cpu_var(dm_cpu_data);
        return;
 }
 
@@ -213,7 +252,7 @@ static int set_all_monitor_traces(int state)
        struct dm_hw_stat_delta *new_stat = NULL;
        struct dm_hw_stat_delta *temp;
 
-       spin_lock(&trace_state_lock);
+       mutex_lock(&trace_state_mutex);
 
        if (state == trace_state) {
                rc = -EAGAIN;
@@ -252,7 +291,7 @@ static int set_all_monitor_traces(int state)
                rc = -EINPROGRESS;
 
 out_unlock:
-       spin_unlock(&trace_state_lock);
+       mutex_unlock(&trace_state_mutex);
 
        return rc;
 }
@@ -295,12 +334,12 @@ static int dropmon_net_event(struct notifier_block *ev_block,
 
                new_stat->dev = dev;
                new_stat->last_rx = jiffies;
-               spin_lock(&trace_state_lock);
+               mutex_lock(&trace_state_mutex);
                list_add_rcu(&new_stat->list, &hw_stats_list);
-               spin_unlock(&trace_state_lock);
+               mutex_unlock(&trace_state_mutex);
                break;
        case NETDEV_UNREGISTER:
-               spin_lock(&trace_state_lock);
+               mutex_lock(&trace_state_mutex);
                list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) {
                        if (new_stat->dev == dev) {
                                new_stat->dev = NULL;
@@ -311,7 +350,7 @@ static int dropmon_net_event(struct notifier_block *ev_block,
                                }
                        }
                }
-               spin_unlock(&trace_state_lock);
+               mutex_unlock(&trace_state_mutex);
                break;
        }
 out:
@@ -367,13 +406,15 @@ static int __init init_net_drop_monitor(void)
 
        for_each_present_cpu(cpu) {
                data = &per_cpu(dm_cpu_data, cpu);
-               reset_per_cpu_data(data);
+               data->cpu = cpu;
                INIT_WORK(&data->dm_alert_work, send_dm_alert);
                init_timer(&data->send_timer);
                data->send_timer.data = cpu;
                data->send_timer.function = sched_send_work;
+               reset_per_cpu_data(data);
        }
 
+
        goto out;
 
 out_unreg:
index 0e950fda9a0abc88ffaa9e3e62b2a11c023a7b8b..31a5ae51a45c8770136ac1b60b76da842d9803df 100644 (file)
@@ -83,21 +83,29 @@ assign:
 
 static int ops_init(const struct pernet_operations *ops, struct net *net)
 {
-       int err;
+       int err = -ENOMEM;
+       void *data = NULL;
+
        if (ops->id && ops->size) {
-               void *data = kzalloc(ops->size, GFP_KERNEL);
+               data = kzalloc(ops->size, GFP_KERNEL);
                if (!data)
-                       return -ENOMEM;
+                       goto out;
 
                err = net_assign_generic(net, *ops->id, data);
-               if (err) {
-                       kfree(data);
-                       return err;
-               }
+               if (err)
+                       goto cleanup;
        }
+       err = 0;
        if (ops->init)
-               return ops->init(net);
-       return 0;
+               err = ops->init(net);
+       if (!err)
+               return 0;
+
+cleanup:
+       kfree(data);
+
+out:
+       return err;
 }
 
 static void ops_free(const struct pernet_operations *ops, struct net *net)
@@ -448,12 +456,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops)
 static int __register_pernet_operations(struct list_head *list,
                                        struct pernet_operations *ops)
 {
-       int err = 0;
-       err = ops_init(ops, &init_net);
-       if (err)
-               ops_free(ops, &init_net);
-       return err;
-       
+       return ops_init(ops, &init_net);
 }
 
 static void __unregister_pernet_operations(struct pernet_operations *ops)
index baf8d281152cebc9e55ce8a7343d427b24b8b61e..e59840010d45c9bc25f521fe1ef0717d2de984af 100644 (file)
@@ -952,9 +952,11 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
                goto adjust_others;
        }
 
-       data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+       data = kmalloc(size + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
+                      gfp_mask);
        if (!data)
                goto nodata;
+       size = SKB_WITH_OVERHEAD(ksize(data));
 
        /* Copy only real data... and, alas, header. This should be
         * optimized for the cases when header is void.
index 36851588536861bb5fe67f61c69829807e599fb4..840821b90bcd7e11c79c14dd44bcc02aedcedf23 100644 (file)
@@ -1044,6 +1044,24 @@ static void lowpan_dev_free(struct net_device *dev)
        free_netdev(dev);
 }
 
+static struct wpan_phy *lowpan_get_phy(const struct net_device *dev)
+{
+       struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+       return ieee802154_mlme_ops(real_dev)->get_phy(real_dev);
+}
+
+static u16 lowpan_get_pan_id(const struct net_device *dev)
+{
+       struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+       return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev);
+}
+
+static u16 lowpan_get_short_addr(const struct net_device *dev)
+{
+       struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+       return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev);
+}
+
 static struct header_ops lowpan_header_ops = {
        .create = lowpan_header_create,
 };
@@ -1053,6 +1071,12 @@ static const struct net_device_ops lowpan_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
 };
 
+static struct ieee802154_mlme_ops lowpan_mlme = {
+       .get_pan_id = lowpan_get_pan_id,
+       .get_phy = lowpan_get_phy,
+       .get_short_addr = lowpan_get_short_addr,
+};
+
 static void lowpan_setup(struct net_device *dev)
 {
        pr_debug("(%s)\n", __func__);
@@ -1070,6 +1094,7 @@ static void lowpan_setup(struct net_device *dev)
 
        dev->netdev_ops         = &lowpan_netdev_ops;
        dev->header_ops         = &lowpan_header_ops;
+       dev->ml_priv            = &lowpan_mlme;
        dev->destructor         = lowpan_dev_free;
 }
 
@@ -1143,6 +1168,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
        list_add_tail(&entry->list, &lowpan_devices);
        mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx);
 
+       spin_lock_init(&flist_lock);
+
        register_netdevice(dev);
 
        return 0;
@@ -1152,11 +1179,20 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head)
 {
        struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev);
        struct net_device *real_dev = lowpan_dev->real_dev;
-       struct lowpan_dev_record *entry;
-       struct lowpan_dev_record *tmp;
+       struct lowpan_dev_record *entry, *tmp;
+       struct lowpan_fragment *frame, *tframe;
 
        ASSERT_RTNL();
 
+       spin_lock(&flist_lock);
+       list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) {
+               del_timer(&frame->timer);
+               list_del(&frame->list);
+               dev_kfree_skb(frame->skb);
+               kfree(frame);
+       }
+       spin_unlock(&flist_lock);
+
        mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx);
        list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) {
                if (entry->ldev == dev) {
index 8d25a1c557eb50f012761227634d0ae7155c7180..8f8db724bfafe5f744a8f956dc7e710a67dc7faa 100644 (file)
@@ -141,7 +141,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
                        goto rtattr_failure;
 
        if (icsk == NULL) {
-               r->idiag_rqueue = r->idiag_wqueue = 0;
+               handler->idiag_get_info(sk, r, NULL);
                goto out;
        }
 
index de9da21113a11be6c9f57b15a97b3936a574e512..cf73cc70ed2d2e1bfe1a5c837bc9993358e9904e 100644 (file)
@@ -74,16 +74,24 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
 
        iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
        if (iph == NULL)
-               return -NF_DROP;
+               return -NF_ACCEPT;
 
        /* Conntrack defragments packets, we might still see fragments
         * inside ICMP packets though. */
        if (iph->frag_off & htons(IP_OFFSET))
-               return -NF_DROP;
+               return -NF_ACCEPT;
 
        *dataoff = nhoff + (iph->ihl << 2);
        *protonum = iph->protocol;
 
+       /* Check bogus IP headers */
+       if (*dataoff > skb->len) {
+               pr_debug("nf_conntrack_ipv4: bogus IPv4 packet: "
+                        "nhoff %u, ihl %u, skblen %u\n",
+                        nhoff, iph->ihl << 2, skb->len);
+               return -NF_ACCEPT;
+       }
+
        return NF_ACCEPT;
 }
 
index 5d54ed30e821fc1744432178b33d0585831cd32f..1272a88c2a6331bb749d3a016710de649c1de057 100644 (file)
@@ -701,11 +701,12 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
        skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
        if (skb) {
                if (sk_wmem_schedule(sk, skb->truesize)) {
+                       skb_reserve(skb, sk->sk_prot->max_header);
                        /*
                         * Make sure that we have exactly size bytes
                         * available to the caller, no more, no less.
                         */
-                       skb_reserve(skb, skb_tailroom(skb) - size);
+                       skb->avail_size = size;
                        return skb;
                }
                __kfree_skb(skb);
@@ -995,10 +996,9 @@ new_segment:
                                copy = seglen;
 
                        /* Where to copy to? */
-                       if (skb_tailroom(skb) > 0) {
+                       if (skb_availroom(skb) > 0) {
                                /* We have some space in skb head. Superb! */
-                               if (copy > skb_tailroom(skb))
-                                       copy = skb_tailroom(skb);
+                               copy = min_t(int, copy, skb_availroom(skb));
                                err = skb_add_data_nocache(sk, skb, from, copy);
                                if (err)
                                        goto do_fault;
@@ -1452,7 +1452,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                if ((available < target) &&
                    (len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) &&
                    !sysctl_tcp_low_latency &&
-                   dma_find_channel(DMA_MEMCPY)) {
+                   net_dma_find_channel()) {
                        preempt_enable_no_resched();
                        tp->ucopy.pinned_list =
                                        dma_pin_iovec_pages(msg->msg_iov, len);
@@ -1667,7 +1667,7 @@ do_prequeue:
                if (!(flags & MSG_TRUNC)) {
 #ifdef CONFIG_NET_DMA
                        if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
-                               tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY);
+                               tp->ucopy.dma_chan = net_dma_find_channel();
 
                        if (tp->ucopy.dma_chan) {
                                tp->ucopy.dma_cookie = dma_skb_copy_datagram_iovec(
@@ -3243,7 +3243,7 @@ void __init tcp_init(void)
 {
        struct sk_buff *skb = NULL;
        unsigned long limit;
-       int max_share, cnt;
+       int max_rshare, max_wshare, cnt;
        unsigned int i;
        unsigned long jiffy = jiffies;
 
@@ -3302,17 +3302,17 @@ void __init tcp_init(void)
 
        tcp_init_mem(&init_net);
        /* Set per-socket limits to no more than 1/128 the pressure threshold */
-       limit = nr_free_buffer_pages() << (PAGE_SHIFT - 10);
-       limit = max(limit, 128UL);
-       max_share = min(4UL*1024*1024, limit);
+       limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
+       max_wshare = min(4UL*1024*1024, limit);
+       max_rshare = min(6UL*1024*1024, limit);
 
        sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
        sysctl_tcp_wmem[1] = 16*1024;
-       sysctl_tcp_wmem[2] = max(64*1024, max_share);
+       sysctl_tcp_wmem[2] = max(64*1024, max_wshare);
 
        sysctl_tcp_rmem[0] = SK_MEM_QUANTUM;
        sysctl_tcp_rmem[1] = 87380;
-       sysctl_tcp_rmem[2] = max(87380, max_share);
+       sysctl_tcp_rmem[2] = max(87380, max_rshare);
 
        pr_info("Hash tables configured (established %u bind %u)\n",
                tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size);
index e886e2f7fa8d03edc8644179a6f1ef7ca6a374f6..257b61789eeba9fd064470c91e3a8bffb8d1812d 100644 (file)
@@ -85,7 +85,7 @@ int sysctl_tcp_ecn __read_mostly = 2;
 EXPORT_SYMBOL(sysctl_tcp_ecn);
 int sysctl_tcp_dsack __read_mostly = 1;
 int sysctl_tcp_app_win __read_mostly = 31;
-int sysctl_tcp_adv_win_scale __read_mostly = 2;
+int sysctl_tcp_adv_win_scale __read_mostly = 1;
 EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
 
 int sysctl_tcp_stdurg __read_mostly;
@@ -335,6 +335,7 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb)
                        incr = __tcp_grow_window(sk, skb);
 
                if (incr) {
+                       incr = max_t(int, incr, 2 * skb->len);
                        tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr,
                                               tp->window_clamp);
                        inet_csk(sk)->icsk_ack.quick |= 1;
@@ -474,8 +475,11 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
                if (!win_dep) {
                        m -= (new_sample >> 3);
                        new_sample += m;
-               } else if (m < new_sample)
-                       new_sample = m << 3;
+               } else {
+                       m <<= 3;
+                       if (m < new_sample)
+                               new_sample = m;
+               }
        } else {
                /* No previous measure. */
                new_sample = m << 3;
@@ -491,7 +495,7 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp)
                goto new_measure;
        if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq))
                return;
-       tcp_rcv_rtt_update(tp, jiffies - tp->rcv_rtt_est.time, 1);
+       tcp_rcv_rtt_update(tp, tcp_time_stamp - tp->rcv_rtt_est.time, 1);
 
 new_measure:
        tp->rcv_rtt_est.seq = tp->rcv_nxt + tp->rcv_wnd;
@@ -2864,11 +2868,14 @@ static inline void tcp_complete_cwr(struct sock *sk)
 
        /* Do not moderate cwnd if it's already undone in cwr or recovery. */
        if (tp->undo_marker) {
-               if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR)
+               if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) {
                        tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
-               else /* PRR */
+                       tp->snd_cwnd_stamp = tcp_time_stamp;
+               } else if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH) {
+                       /* PRR algorithm. */
                        tp->snd_cwnd = tp->snd_ssthresh;
-               tp->snd_cwnd_stamp = tcp_time_stamp;
+                       tp->snd_cwnd_stamp = tcp_time_stamp;
+               }
        }
        tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR);
 }
@@ -5225,7 +5232,7 @@ static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb,
                return 0;
 
        if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
-               tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY);
+               tp->ucopy.dma_chan = net_dma_find_channel();
 
        if (tp->ucopy.dma_chan && skb_csum_unnecessary(skb)) {
 
index 3a25cf743f8ba5a70d72dd9b068e42fe52675026..0cb86ceb652ff66432ba584fedef8231d94decc6 100644 (file)
@@ -1730,7 +1730,7 @@ process:
 #ifdef CONFIG_NET_DMA
                struct tcp_sock *tp = tcp_sk(sk);
                if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
-                       tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY);
+                       tp->ucopy.dma_chan = net_dma_find_channel();
                if (tp->ucopy.dma_chan)
                        ret = tcp_v4_do_rcv(sk, skb);
                else
index 364784a91939c50eff90f8d8f29a174e1f63bafe..7ac6423117adfb333f433cc1b86356d38cb995ea 100644 (file)
@@ -1096,6 +1096,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
        eat = min_t(int, len, skb_headlen(skb));
        if (eat) {
                __skb_pull(skb, eat);
+               skb->avail_size -= eat;
                len -= eat;
                if (!len)
                        return;
@@ -2060,7 +2061,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
                /* Punt if not enough space exists in the first SKB for
                 * the data in the second
                 */
-               if (skb->len > skb_tailroom(to))
+               if (skb->len > skb_availroom(to))
                        break;
 
                if (after(TCP_SKB_CB(skb)->end_seq, tcp_wnd_end(tp)))
index 8a949f19deb6dc93542396138004a5a6b2bfeeab..a7f86a3cd5023e2a7489167fcdd84df0d75a26a0 100644 (file)
@@ -146,9 +146,17 @@ static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh,
        return udp_dump_one(&udp_table, in_skb, nlh, req);
 }
 
+static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
+               void *info)
+{
+       r->idiag_rqueue = sk_rmem_alloc_get(sk);
+       r->idiag_wqueue = sk_wmem_alloc_get(sk);
+}
+
 static const struct inet_diag_handler udp_diag_handler = {
        .dump            = udp_diag_dump,
        .dump_one        = udp_diag_dump_one,
+       .idiag_get_info  = udp_diag_get_info,
        .idiag_type      = IPPROTO_UDP,
 };
 
@@ -167,6 +175,7 @@ static int udplite_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *
 static const struct inet_diag_handler udplite_diag_handler = {
        .dump            = udplite_diag_dump,
        .dump_one        = udplite_diag_dump_one,
+       .idiag_get_info  = udp_diag_get_info,
        .idiag_type      = IPPROTO_UDPLITE,
 };
 
index 6a3bb6077e19715bf2732bbce3d1c09d06aed104..7d5cb975cc6f8e6c22581daaa638b6b3df5a52d2 100644 (file)
@@ -803,8 +803,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
                                ip6_del_rt(rt);
                                rt = NULL;
                        } else if (!(rt->rt6i_flags & RTF_EXPIRES)) {
-                               rt->dst.expires = expires;
-                               rt->rt6i_flags |= RTF_EXPIRES;
+                               rt6_set_expires(rt, expires);
                        }
                }
                dst_release(&rt->dst);
@@ -1887,11 +1886,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
                                rt = NULL;
                        } else if (addrconf_finite_timeout(rt_expires)) {
                                /* not infinity */
-                               rt->dst.expires = jiffies + rt_expires;
-                               rt->rt6i_flags |= RTF_EXPIRES;
+                               rt6_set_expires(rt, jiffies + rt_expires);
                        } else {
-                               rt->rt6i_flags &= ~RTF_EXPIRES;
-                               rt->dst.expires = 0;
+                               rt6_clean_expires(rt);
                        }
                } else if (valid_lft) {
                        clock_t expires = 0;
index 5b27fbcae346677a28db262c5ffc1a272e1b1cd5..93717435013e0a146c10bc8cf3ea4cbddb627f9b 100644 (file)
@@ -673,11 +673,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
                                            &rt->rt6i_gateway)) {
                                if (!(iter->rt6i_flags & RTF_EXPIRES))
                                        return -EEXIST;
-                               iter->dst.expires = rt->dst.expires;
-                               if (!(rt->rt6i_flags & RTF_EXPIRES)) {
-                                       iter->rt6i_flags &= ~RTF_EXPIRES;
-                                       iter->dst.expires = 0;
-                               }
+                               if (!(rt->rt6i_flags & RTF_EXPIRES))
+                                       rt6_clean_expires(iter);
+                               else
+                                       rt6_set_expires(iter, rt->dst.expires);
                                return -EEXIST;
                        }
                }
index 3dcdb81ec3e8abdb934627cd243aed0e5ce3b5a3..176b469322acd0b63b6e8d7ad0f095129b165868 100644 (file)
@@ -1264,8 +1264,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
        }
 
        if (rt)
-               rt->dst.expires = jiffies + (HZ * lifetime);
-
+               rt6_set_expires(rt, jiffies + (HZ * lifetime));
        if (ra_msg->icmph.icmp6_hop_limit) {
                in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
                if (rt)
index 94874b0bdcdcf9835fe0b0b53fd088c12db93305..9d4e155593190d81b99af8988899a0204a73ec80 100644 (file)
@@ -78,19 +78,6 @@ EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table);
 
    Hence the start of any table is given by get_table() below.  */
 
-/* Check for an extension */
-int
-ip6t_ext_hdr(u8 nexthdr)
-{
-       return  (nexthdr == IPPROTO_HOPOPTS)   ||
-               (nexthdr == IPPROTO_ROUTING)   ||
-               (nexthdr == IPPROTO_FRAGMENT)  ||
-               (nexthdr == IPPROTO_ESP)       ||
-               (nexthdr == IPPROTO_AH)        ||
-               (nexthdr == IPPROTO_NONE)      ||
-               (nexthdr == IPPROTO_DSTOPTS);
-}
-
 /* Returns whether matches rule or not. */
 /* Performance critical - called for every packet */
 static inline bool
@@ -2366,7 +2353,6 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
 EXPORT_SYMBOL(ip6t_register_table);
 EXPORT_SYMBOL(ip6t_unregister_table);
 EXPORT_SYMBOL(ip6t_do_table);
-EXPORT_SYMBOL(ip6t_ext_hdr);
 EXPORT_SYMBOL(ipv6_find_hdr);
 
 module_init(ip6_tables_init);
index 3992e26a603987cf8bba458dd4f687af5c900a2f..bc4888d902b2ed904f0ca767ac3e4d9cd35c252c 100644 (file)
@@ -62,7 +62,7 @@
 #include <linux/sysctl.h>
 #endif
 
-static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
+static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
                                    const struct in6_addr *dest);
 static struct dst_entry        *ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static unsigned int     ip6_default_advmss(const struct dst_entry *dst);
@@ -285,6 +285,10 @@ static void ip6_dst_destroy(struct dst_entry *dst)
                rt->rt6i_idev = NULL;
                in6_dev_put(idev);
        }
+
+       if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from)
+               dst_release(dst->from);
+
        if (peer) {
                rt->rt6i_peer = NULL;
                inet_putpeer(peer);
@@ -329,8 +333,17 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
 
 static __inline__ int rt6_check_expired(const struct rt6_info *rt)
 {
-       return (rt->rt6i_flags & RTF_EXPIRES) &&
-               time_after(jiffies, rt->dst.expires);
+       struct rt6_info *ort = NULL;
+
+       if (rt->rt6i_flags & RTF_EXPIRES) {
+               if (time_after(jiffies, rt->dst.expires))
+                       return 1;
+       } else if (rt->dst.from) {
+               ort = (struct rt6_info *) rt->dst.from;
+               return (ort->rt6i_flags & RTF_EXPIRES) &&
+                       time_after(jiffies, ort->dst.expires);
+       }
+       return 0;
 }
 
 static inline int rt6_need_strict(const struct in6_addr *daddr)
@@ -620,12 +633,11 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
                                 (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
 
        if (rt) {
-               if (!addrconf_finite_timeout(lifetime)) {
-                       rt->rt6i_flags &= ~RTF_EXPIRES;
-               } else {
-                       rt->dst.expires = jiffies + HZ * lifetime;
-                       rt->rt6i_flags |= RTF_EXPIRES;
-               }
+               if (!addrconf_finite_timeout(lifetime))
+                       rt6_clean_expires(rt);
+               else
+                       rt6_set_expires(rt, jiffies + HZ * lifetime);
+
                dst_release(&rt->dst);
        }
        return 0;
@@ -730,7 +742,7 @@ int ip6_ins_rt(struct rt6_info *rt)
        return __ip6_ins_rt(rt, &info);
 }
 
-static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort,
+static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort,
                                      const struct in6_addr *daddr,
                                      const struct in6_addr *saddr)
 {
@@ -954,10 +966,10 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
                rt->rt6i_idev = ort->rt6i_idev;
                if (rt->rt6i_idev)
                        in6_dev_hold(rt->rt6i_idev);
-               rt->dst.expires = 0;
 
                rt->rt6i_gateway = ort->rt6i_gateway;
-               rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
+               rt->rt6i_flags = ort->rt6i_flags;
+               rt6_clean_expires(rt);
                rt->rt6i_metric = 0;
 
                memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
@@ -1019,10 +1031,9 @@ static void ip6_link_failure(struct sk_buff *skb)
 
        rt = (struct rt6_info *) skb_dst(skb);
        if (rt) {
-               if (rt->rt6i_flags & RTF_CACHE) {
-                       dst_set_expires(&rt->dst, 0);
-                       rt->rt6i_flags |= RTF_EXPIRES;
-               } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT))
+               if (rt->rt6i_flags & RTF_CACHE)
+                       rt6_update_expires(rt, 0);
+               else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT))
                        rt->rt6i_node->fn_sernum = -1;
        }
 }
@@ -1289,9 +1300,12 @@ int ip6_route_add(struct fib6_config *cfg)
        }
 
        rt->dst.obsolete = -1;
-       rt->dst.expires = (cfg->fc_flags & RTF_EXPIRES) ?
-                               jiffies + clock_t_to_jiffies(cfg->fc_expires) :
-                               0;
+
+       if (cfg->fc_flags & RTF_EXPIRES)
+               rt6_set_expires(rt, jiffies +
+                               clock_t_to_jiffies(cfg->fc_expires));
+       else
+               rt6_clean_expires(rt);
 
        if (cfg->fc_protocol == RTPROT_UNSPEC)
                cfg->fc_protocol = RTPROT_BOOT;
@@ -1736,8 +1750,8 @@ again:
                        features |= RTAX_FEATURE_ALLFRAG;
                        dst_metric_set(&rt->dst, RTAX_FEATURES, features);
                }
-               dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires);
-               rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
+               rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires);
+               rt->rt6i_flags |= RTF_MODIFIED;
                goto out;
        }
 
@@ -1765,9 +1779,8 @@ again:
                 * which is 10 mins. After 10 mins the decreased pmtu is expired
                 * and detecting PMTU increase will be automatically happened.
                 */
-               dst_set_expires(&nrt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires);
-               nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
-
+               rt6_update_expires(nrt, net->ipv6.sysctl.ip6_rt_mtu_expires);
+               nrt->rt6i_flags |= RTF_DYNAMIC;
                ip6_ins_rt(nrt);
        }
 out:
@@ -1799,7 +1812,7 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad
  *     Misc support functions
  */
 
-static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
+static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
                                    const struct in6_addr *dest)
 {
        struct net *net = dev_net(ort->dst.dev);
@@ -1819,10 +1832,14 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
                if (rt->rt6i_idev)
                        in6_dev_hold(rt->rt6i_idev);
                rt->dst.lastuse = jiffies;
-               rt->dst.expires = 0;
 
                rt->rt6i_gateway = ort->rt6i_gateway;
-               rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
+               rt->rt6i_flags = ort->rt6i_flags;
+               if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ==
+                   (RTF_DEFAULT | RTF_ADDRCONF))
+                       rt6_set_from(rt, ort);
+               else
+                       rt6_clean_expires(rt);
                rt->rt6i_metric = 0;
 
 #ifdef CONFIG_IPV6_SUBTREES
index 12c6ece67f396a2d01f641b7a0e0d728fcab3337..98256cf72f9dbca22dc80b3405ac80ec4fdb158f 100644 (file)
@@ -1383,6 +1383,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        tcp_mtup_init(newsk);
        tcp_sync_mss(newsk, dst_mtu(dst));
        newtp->advmss = dst_metric_advmss(dst);
+       if (tcp_sk(sk)->rx_opt.user_mss &&
+           tcp_sk(sk)->rx_opt.user_mss < newtp->advmss)
+               newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
+
        tcp_initialize_rcv_mss(newsk);
        if (tcp_rsk(req)->snt_synack)
                tcp_valid_rtt_meas(newsk,
@@ -1645,7 +1649,7 @@ process:
 #ifdef CONFIG_NET_DMA
                struct tcp_sock *tp = tcp_sk(sk);
                if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
-                       tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY);
+                       tp->ucopy.dma_chan = net_dma_find_channel();
                if (tp->ucopy.dma_chan)
                        ret = tcp_v6_do_rcv(sk, skb);
                else
index 11dbb2255ccbce3f1e34c34f35a56a9ebd9428c1..7e5d927b576f79b8163b765ff5dcb6f6e0c4be43 100644 (file)
@@ -3480,7 +3480,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 
        /* Addresses to be used by KM for negotiation, if ext is available */
        if (k != NULL && (set_sadb_kmaddress(skb, k) < 0))
-               return -EINVAL;
+               goto err;
 
        /* selector src */
        set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel);
index 55670ec3cd0f916143759cbc73320cf85b7ef196..6274f0be82b0c3445f6288f7fb8c7612d5325d69 100644 (file)
@@ -232,7 +232,7 @@ static void l2tp_ip_close(struct sock *sk, long timeout)
 {
        write_lock_bh(&l2tp_ip_lock);
        hlist_del_init(&sk->sk_bind_node);
-       hlist_del_init(&sk->sk_node);
+       sk_del_node_init(sk);
        write_unlock_bh(&l2tp_ip_lock);
        sk_common_release(sk);
 }
@@ -271,7 +271,8 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
            chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
                goto out;
 
-       inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr;
+       if (addr->l2tp_addr.s_addr)
+               inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr;
        if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
                inet->inet_saddr = 0;  /* Use device */
        sk_dst_reset(sk);
@@ -441,8 +442,9 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
 
                daddr = lip->l2tp_addr.s_addr;
        } else {
+               rc = -EDESTADDRREQ;
                if (sk->sk_state != TCP_ESTABLISHED)
-                       return -EDESTADDRREQ;
+                       goto out;
 
                daddr = inet->inet_daddr;
                connected = 1;
index 2555816e778827250e5aec0d33eaa2fa9512addc..00bdb1d9d690b5acb100fe38c2e455a110d8f09b 100644 (file)
@@ -1924,6 +1924,7 @@ protocol_fail:
 control_fail:
        ip_vs_estimator_net_cleanup(net);
 estimator_fail:
+       net->ipvs = NULL;
        return -ENOMEM;
 }
 
@@ -1936,6 +1937,7 @@ static void __net_exit __ip_vs_cleanup(struct net *net)
        ip_vs_control_net_cleanup(net);
        ip_vs_estimator_net_cleanup(net);
        IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen);
+       net->ipvs = NULL;
 }
 
 static void __net_exit __ip_vs_dev_cleanup(struct net *net)
@@ -1993,10 +1995,18 @@ static int __init ip_vs_init(void)
                goto cleanup_dev;
        }
 
+       ret = ip_vs_register_nl_ioctl();
+       if (ret < 0) {
+               pr_err("can't register netlink/ioctl.\n");
+               goto cleanup_hooks;
+       }
+
        pr_info("ipvs loaded.\n");
 
        return ret;
 
+cleanup_hooks:
+       nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
 cleanup_dev:
        unregister_pernet_device(&ipvs_core_dev_ops);
 cleanup_sub:
@@ -2012,6 +2022,7 @@ exit:
 
 static void __exit ip_vs_cleanup(void)
 {
+       ip_vs_unregister_nl_ioctl();
        nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
        unregister_pernet_device(&ipvs_core_dev_ops);
        unregister_pernet_subsys(&ipvs_core_ops);       /* free ip_vs struct */
index b3afe189af61880464ef6562c568016509957293..f5589987fc80d59a8d1fc5ec1e546d72562521fa 100644 (file)
@@ -3680,7 +3680,7 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net)
        return 0;
 }
 
-void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net)
+void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -3692,7 +3692,7 @@ void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net)
 #else
 
 int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; }
-void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { }
+void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) { }
 
 #endif
 
@@ -3750,21 +3750,10 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net)
        free_percpu(ipvs->tot_stats.cpustats);
 }
 
-int __init ip_vs_control_init(void)
+int __init ip_vs_register_nl_ioctl(void)
 {
-       int idx;
        int ret;
 
-       EnterFunction(2);
-
-       /* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */
-       for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++)  {
-               INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
-               INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
-       }
-
-       smp_wmb();      /* Do we really need it now ? */
-
        ret = nf_register_sockopt(&ip_vs_sockopts);
        if (ret) {
                pr_err("cannot register sockopt.\n");
@@ -3776,28 +3765,47 @@ int __init ip_vs_control_init(void)
                pr_err("cannot register Generic Netlink interface.\n");
                goto err_genl;
        }
-
-       ret = register_netdevice_notifier(&ip_vs_dst_notifier);
-       if (ret < 0)
-               goto err_notf;
-
-       LeaveFunction(2);
        return 0;
 
-err_notf:
-       ip_vs_genl_unregister();
 err_genl:
        nf_unregister_sockopt(&ip_vs_sockopts);
 err_sock:
        return ret;
 }
 
+void ip_vs_unregister_nl_ioctl(void)
+{
+       ip_vs_genl_unregister();
+       nf_unregister_sockopt(&ip_vs_sockopts);
+}
+
+int __init ip_vs_control_init(void)
+{
+       int idx;
+       int ret;
+
+       EnterFunction(2);
+
+       /* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */
+       for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+               INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
+               INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
+       }
+
+       smp_wmb();      /* Do we really need it now ? */
+
+       ret = register_netdevice_notifier(&ip_vs_dst_notifier);
+       if (ret < 0)
+               return ret;
+
+       LeaveFunction(2);
+       return 0;
+}
+
 
 void ip_vs_control_cleanup(void)
 {
        EnterFunction(2);
        unregister_netdevice_notifier(&ip_vs_dst_notifier);
-       ip_vs_genl_unregister();
-       nf_unregister_sockopt(&ip_vs_sockopts);
        LeaveFunction(2);
 }
index 538d74ee4f68bc18e7bb379d7432388aba305425..e39f693dd3e49b9595ced939bd0531c07acdd159 100644 (file)
@@ -439,6 +439,8 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
        struct ip_vs_app *app;
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return -ENOENT;
        app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL);
        if (!app)
                return -ENOMEM;
index 0f16283fd05854fccc68fad349c7f29509926252..caa43704e55ead5f5c6c2287e78c818cacb038e4 100644 (file)
@@ -551,6 +551,9 @@ static int __net_init __ip_vs_lblc_init(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return -ENOENT;
+
        if (!net_eq(net, &init_net)) {
                ipvs->lblc_ctl_table = kmemdup(vs_vars_table,
                                                sizeof(vs_vars_table),
index eec797f8cce705a1676caeb3c3078053ddcdf523..548bf37aa29e07ebd53eaa760dbcadf844edfa13 100644 (file)
@@ -745,6 +745,9 @@ static int __net_init __ip_vs_lblcr_init(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return -ENOENT;
+
        if (!net_eq(net, &init_net)) {
                ipvs->lblcr_ctl_table = kmemdup(vs_vars_table,
                                                sizeof(vs_vars_table),
index f843a88332509edc9ac7ed509cba6d679685664f..ed835e67a07e07598408b130f64fbafd85a33679 100644 (file)
@@ -59,9 +59,6 @@ static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp)
        return 0;
 }
 
-#if defined(CONFIG_IP_VS_PROTO_TCP) || defined(CONFIG_IP_VS_PROTO_UDP) || \
-    defined(CONFIG_IP_VS_PROTO_SCTP) || defined(CONFIG_IP_VS_PROTO_AH) || \
-    defined(CONFIG_IP_VS_PROTO_ESP)
 /*
  *     register an ipvs protocols netns related data
  */
@@ -81,12 +78,18 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
        ipvs->proto_data_table[hash] = pd;
        atomic_set(&pd->appcnt, 0);     /* Init app counter */
 
-       if (pp->init_netns != NULL)
-               pp->init_netns(net, pd);
+       if (pp->init_netns != NULL) {
+               int ret = pp->init_netns(net, pd);
+               if (ret) {
+                       /* unlink an free proto data */
+                       ipvs->proto_data_table[hash] = pd->next;
+                       kfree(pd);
+                       return ret;
+               }
+       }
 
        return 0;
 }
-#endif
 
 /*
  *     unregister an ipvs protocol
@@ -316,22 +319,35 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
  */
 int __net_init ip_vs_protocol_net_init(struct net *net)
 {
+       int i, ret;
+       static struct ip_vs_protocol *protos[] = {
 #ifdef CONFIG_IP_VS_PROTO_TCP
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp);
+        &ip_vs_protocol_tcp,
 #endif
 #ifdef CONFIG_IP_VS_PROTO_UDP
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_udp);
+       &ip_vs_protocol_udp,
 #endif
 #ifdef CONFIG_IP_VS_PROTO_SCTP
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_sctp);
+       &ip_vs_protocol_sctp,
 #endif
 #ifdef CONFIG_IP_VS_PROTO_AH
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_ah);
+       &ip_vs_protocol_ah,
 #endif
 #ifdef CONFIG_IP_VS_PROTO_ESP
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_esp);
+       &ip_vs_protocol_esp,
 #endif
+       };
+
+       for (i = 0; i < ARRAY_SIZE(protos); i++) {
+               ret = register_ip_vs_proto_netns(net, protos[i]);
+               if (ret < 0)
+                       goto cleanup;
+       }
        return 0;
+
+cleanup:
+       ip_vs_protocol_net_cleanup(net);
+       return ret;
 }
 
 void __net_exit ip_vs_protocol_net_cleanup(struct net *net)
index 1fbf7a2816f5ade317a747737840588d41621bf0..9f3fb751c49154bac37fa4baa84853a2c0dd0c06 100644 (file)
@@ -1090,7 +1090,7 @@ out:
  *   timeouts is netns related now.
  * ---------------------------------------------
  */
-static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -1098,6 +1098,9 @@ static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
        spin_lock_init(&ipvs->sctp_app_lock);
        pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
                                                        sizeof(sctp_timeouts));
+       if (!pd->timeout_table)
+               return -ENOMEM;
+       return 0;
 }
 
 static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
index ef8641f7af8300efae329a3a74cb4325eba1761f..cd609cc62721095baf50475d14e80384089f280a 100644 (file)
@@ -677,7 +677,7 @@ void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp)
  *   timeouts is netns related now.
  * ---------------------------------------------
  */
-static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -685,7 +685,10 @@ static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
        spin_lock_init(&ipvs->tcp_app_lock);
        pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts,
                                                        sizeof(tcp_timeouts));
+       if (!pd->timeout_table)
+               return -ENOMEM;
        pd->tcp_state_table =  tcp_states;
+       return 0;
 }
 
 static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd)
index f4b7262896bbd272fb8d3cff5298455b1deff703..2fedb2dcb3d1f5e831546b59480eceee14e59a84 100644 (file)
@@ -467,7 +467,7 @@ udp_state_transition(struct ip_vs_conn *cp, int direction,
        cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL];
 }
 
-static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __udp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -475,6 +475,9 @@ static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
        spin_lock_init(&ipvs->udp_app_lock);
        pd->timeout_table = ip_vs_create_timeout_table((int *)udp_timeouts,
                                                        sizeof(udp_timeouts));
+       if (!pd->timeout_table)
+               return -ENOMEM;
+       return 0;
 }
 
 static void __udp_exit(struct net *net, struct ip_vs_proto_data *pd)
index 3cc4487ac349997850940c6cbd274c196863f6aa..729f157a0efa690cf877dbd9dbb94dd1b09f1be6 100644 (file)
@@ -1592,7 +1592,7 @@ static int nf_conntrack_init_net(struct net *net)
        return 0;
 
 err_timeout:
-       nf_conntrack_timeout_fini(net);
+       nf_conntrack_ecache_fini(net);
 err_ecache:
        nf_conntrack_tstamp_fini(net);
 err_tstamp:
index 361eade62a09e58e06194fb78d8c6b07333f015a..0d07a1dcf60504758aace258dd0347f06f305797 100644 (file)
@@ -584,8 +584,8 @@ static bool tcp_in_window(const struct nf_conn *ct,
                         * Let's try to use the data from the packet.
                         */
                        sender->td_end = end;
-                       win <<= sender->td_scale;
-                       sender->td_maxwin = (win == 0 ? 1 : win);
+                       swin = win << sender->td_scale;
+                       sender->td_maxwin = (swin == 0 ? 1 : swin);
                        sender->td_maxend = end + sender->td_maxwin;
                        /*
                         * We haven't seen traffic in the other direction yet
index 59530e93fa58f7abdaa4a0734ad2fd1e5241c040..3746d8b9a47868694be0848fc0d09013a0a5b282 100644 (file)
@@ -227,7 +227,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
        }
 
 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
-       if (info->timeout) {
+       if (info->timeout[0]) {
                typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
                struct nf_conn_timeout *timeout_ext;
 
index 9b9a85ecc4c79d70c88db78a12e5d54309e28d43..bf5cf69c820a285be318ecb3dab044530f2c8bc2 100644 (file)
@@ -331,23 +331,6 @@ static int __net_init phonet_init_net(struct net *net)
 
 static void __net_exit phonet_exit_net(struct net *net)
 {
-       struct phonet_net *pnn = phonet_pernet(net);
-       struct net_device *dev;
-       unsigned i;
-
-       rtnl_lock();
-       for_each_netdev(net, dev)
-               phonet_device_destroy(dev);
-
-       for (i = 0; i < 64; i++) {
-               dev = pnn->routes.table[i];
-               if (dev) {
-                       rtm_phonet_notify(RTM_DELROUTE, dev, i);
-                       dev_put(dev);
-               }
-       }
-       rtnl_unlock();
-
        proc_net_remove(net, "phonet");
 }
 
@@ -361,7 +344,7 @@ static struct pernet_operations phonet_net_ops = {
 /* Initialize Phonet devices list */
 int __init phonet_device_init(void)
 {
-       int err = register_pernet_device(&phonet_net_ops);
+       int err = register_pernet_subsys(&phonet_net_ops);
        if (err)
                return err;
 
@@ -377,7 +360,7 @@ void phonet_device_exit(void)
 {
        rtnl_unregister_all(PF_PHONET);
        unregister_netdevice_notifier(&phonet_device_notifier);
-       unregister_pernet_device(&phonet_net_ops);
+       unregister_pernet_subsys(&phonet_net_ops);
        proc_net_remove(&init_net, "pnresource");
 }
 
index 0b15236be7b609251199a36b5fdd0f9b6075b18f..8179494c269a205467da62e5c97c125a1a6b09c6 100644 (file)
@@ -565,11 +565,8 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
                opt.packets     = q->packetsin;
                opt.bytesin     = q->bytesin;
 
-               if (gred_wred_mode(table)) {
-                       q->vars.qidlestart =
-                               table->tab[table->def]->vars.qidlestart;
-                       q->vars.qavg = table->tab[table->def]->vars.qavg;
-               }
+               if (gred_wred_mode(table))
+                       gred_load_wred_set(table, q);
 
                opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg);
 
index 5da548fa7ae9d46de78f5b75152e1a84b99ca9a7..ebd22966f7480aaacb49ca892c774ac23c477acb 100644 (file)
@@ -408,10 +408,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
                if (!(skb = skb_unshare(skb, GFP_ATOMIC)) ||
                    (skb->ip_summed == CHECKSUM_PARTIAL &&
-                    skb_checksum_help(skb))) {
-                       sch->qstats.drops++;
-                       return NET_XMIT_DROP;
-               }
+                    skb_checksum_help(skb)))
+                       return qdisc_drop(skb, sch);
 
                skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
        }
index de639eeeed506b76b54220e7e7f86ed879af02a1..faea0ec612bfed2932ca5dc25868fe00888a5afc 100755 (executable)
@@ -1869,12 +1869,6 @@ sub process {
                            "No space is necessary after a cast\n" . $hereprev);
                }
 
-               if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
-                   $prevrawline =~ /^\+[ \t]*$/) {
-                       CHK("BLOCK_COMMENT_STYLE",
-                           "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev);
-               }
-
 # check for spaces at the beginning of a line.
 # Exceptions:
 #  1) within comments
index 0586085136d1304eebaa43142be468e4a7f40c8c..52577f052bc12d06503aa9d6459eaa578fb0fd4b 100644 (file)
@@ -539,35 +539,6 @@ static struct conf_printer header_printer_cb =
        .print_comment = header_print_comment,
 };
 
-/*
- * Generate the __enabled_CONFIG_* and __enabled_CONFIG_*_MODULE macros for
- * use by the IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is
- * generated even for booleans so that the IS_ENABLED() macro works.
- */
-static void
-header_print__enabled_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
-{
-
-       switch (sym->type) {
-       case S_BOOLEAN:
-       case S_TRISTATE: {
-               fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n",
-                   sym->name, (*value == 'y'));
-               fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n",
-                   sym->name, (*value == 'm'));
-               break;
-       }
-       default:
-               break;
-       }
-}
-
-static struct conf_printer header__enabled_printer_cb =
-{
-       .print_symbol = header_print__enabled_symbol,
-       .print_comment = header_print_comment,
-};
-
 /*
  * Tristate printer
  *
@@ -949,16 +920,11 @@ int conf_write_autoconf(void)
        conf_write_heading(out_h, &header_printer_cb, NULL);
 
        for_all_symbols(i, sym) {
-               if (!sym->name)
-                       continue;
-
                sym_calc_value(sym);
-
-               conf_write_symbol(out_h, sym, &header__enabled_printer_cb, NULL);
-
-               if (!(sym->flags & SYMBOL_WRITE))
+               if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
                        continue;
 
+               /* write symbol to auto.conf, tristate and header files */
                conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
 
                conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
index 8e730ccc3f2b22d55e7b716cf20298da4e9b7475..44ddaa542db6fbb6612560ac312b65ffca330b4c 100644 (file)
@@ -1100,6 +1100,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
        if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
                return;
 
+       /* We're looking for an object */
+       if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
+               return;
+
        /* All our symbols are of form <prefix>__mod_XXX_device_table. */
        name = strstr(symname, "__mod_");
        if (!name)
index 3f01fd9087308bb84564358101c5761b38368e1c..c4e7d1510f9dfd3136d80e63684b8dc764794950 100644 (file)
@@ -132,8 +132,10 @@ static struct module *new_module(char *modname)
        /* strip trailing .o */
        s = strrchr(p, '.');
        if (s != NULL)
-               if (strcmp(s, ".o") == 0)
+               if (strcmp(s, ".o") == 0) {
                        *s = '\0';
+                       mod->is_dot_o = 1;
+               }
 
        /* add to list */
        mod->name = p;
@@ -587,7 +589,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
        unsigned int crc;
        enum export export;
 
-       if (!is_vmlinux(mod->name) && strncmp(symname, "__ksymtab", 9) == 0)
+       if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
+           strncmp(symname, "__ksymtab", 9) == 0)
                export = export_from_secname(info, get_secindex(info, sym));
        else
                export = export_from_sec(info, get_secindex(info, sym));
index 2031119080dce2ac5d8ca63aeb967f0505cc5f74..51207e4d5f8bcae0add675e31cf579f28763d1d4 100644 (file)
@@ -113,6 +113,7 @@ struct module {
        int has_cleanup;
        struct buffer dev_table_buf;
        char         srcversion[25];
+       int is_dot_o;
 };
 
 struct elf_info {
index 17a5798c29dae96a19a5804b90512390c1df332c..7a2d372f4885a479bff7c97140b45124950c9e19 100644 (file)
@@ -12,8 +12,8 @@
 BCJ=
 LZMA2OPTS=
 
-case $ARCH in
-       x86|x86_64)     BCJ=--x86 ;;
+case $SRCARCH in
+       x86)            BCJ=--x86 ;;
        powerpc)        BCJ=--powerpc ;;
        ia64)           BCJ=--ia64; LZMA2OPTS=pb=4 ;;
        arm)            BCJ=--arm ;;
index 0cf4b53480a778ffeacd46149aa785c63db81c07..71a166a05975bfef1ea92f68473dc147063b4a7b 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/securebits.h>
 #include <linux/user_namespace.h>
 #include <linux/binfmts.h>
+#include <linux/personality.h>
 
 /*
  * If a non-root user executes a setuid-root binary in
@@ -505,6 +506,11 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
        }
 skip:
 
+       /* if we have fs caps, clear dangerous personality flags */
+       if (!cap_issubset(new->cap_permitted, old->cap_permitted))
+               bprm->per_clear |= PER_CLEAR_ON_SETID;
+
+
        /* Don't let someone trace a set[ug]id/setpcap binary with the revised
         * credentials unless they have the appropriate permit
         */
index 81c03a597112f15e49ad6e77f162be3c0e0f1f6c..45c32f074166b270fe5434cfcc24ffa076f8b7a3 100644 (file)
@@ -1939,18 +1939,19 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
        char *hostsp;
        struct socket_smack *ssp = sk->sk_security;
        struct smk_audit_info ad;
-       struct lsm_network_audit net;
 
        rcu_read_lock();
        hostsp = smack_host_label(sap);
        if (hostsp != NULL) {
-               sk_lbl = SMACK_UNLABELED_SOCKET;
 #ifdef CONFIG_AUDIT
+               struct lsm_network_audit net;
+
                smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
                ad.a.u.net->family = sap->sin_family;
                ad.a.u.net->dport = sap->sin_port;
                ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
 #endif
+               sk_lbl = SMACK_UNLABELED_SOCKET;
                rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
        } else {
                sk_lbl = SMACK_CIPSO_SOCKET;
@@ -2809,11 +2810,14 @@ static int smack_unix_stream_connect(struct sock *sock,
        struct socket_smack *osp = other->sk_security;
        struct socket_smack *nsp = newsk->sk_security;
        struct smk_audit_info ad;
-       struct lsm_network_audit net;
        int rc = 0;
 
+#ifdef CONFIG_AUDIT
+       struct lsm_network_audit net;
+
        smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
        smk_ad_setfield_u_net_sk(&ad, other);
+#endif
 
        if (!capable(CAP_MAC_OVERRIDE))
                rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
@@ -2842,11 +2846,14 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
        struct socket_smack *ssp = sock->sk->sk_security;
        struct socket_smack *osp = other->sk->sk_security;
        struct smk_audit_info ad;
-       struct lsm_network_audit net;
        int rc = 0;
 
+#ifdef CONFIG_AUDIT
+       struct lsm_network_audit net;
+
        smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
        smk_ad_setfield_u_net_sk(&ad, other->sk);
+#endif
 
        if (!capable(CAP_MAC_OVERRIDE))
                rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
@@ -2993,7 +3000,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
        char *csp;
        int rc;
        struct smk_audit_info ad;
+#ifdef CONFIG_AUDIT
        struct lsm_network_audit net;
+#endif
        if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
                return 0;
 
@@ -3156,7 +3165,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
        char *sp;
        int rc;
        struct smk_audit_info ad;
+#ifdef CONFIG_AUDIT
        struct lsm_network_audit net;
+#endif
 
        /* handle mapped IPv4 packets arriving via IPv6 sockets */
        if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
@@ -3629,8 +3640,38 @@ struct security_operations smack_ops = {
 };
 
 
-static __init void init_smack_know_list(void)
+static __init void init_smack_known_list(void)
 {
+       /*
+        * Initialize CIPSO locks
+        */
+       spin_lock_init(&smack_known_huh.smk_cipsolock);
+       spin_lock_init(&smack_known_hat.smk_cipsolock);
+       spin_lock_init(&smack_known_star.smk_cipsolock);
+       spin_lock_init(&smack_known_floor.smk_cipsolock);
+       spin_lock_init(&smack_known_invalid.smk_cipsolock);
+       spin_lock_init(&smack_known_web.smk_cipsolock);
+       /*
+        * Initialize rule list locks
+        */
+       mutex_init(&smack_known_huh.smk_rules_lock);
+       mutex_init(&smack_known_hat.smk_rules_lock);
+       mutex_init(&smack_known_floor.smk_rules_lock);
+       mutex_init(&smack_known_star.smk_rules_lock);
+       mutex_init(&smack_known_invalid.smk_rules_lock);
+       mutex_init(&smack_known_web.smk_rules_lock);
+       /*
+        * Initialize rule lists
+        */
+       INIT_LIST_HEAD(&smack_known_huh.smk_rules);
+       INIT_LIST_HEAD(&smack_known_hat.smk_rules);
+       INIT_LIST_HEAD(&smack_known_star.smk_rules);
+       INIT_LIST_HEAD(&smack_known_floor.smk_rules);
+       INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
+       INIT_LIST_HEAD(&smack_known_web.smk_rules);
+       /*
+        * Create the known labels list
+        */
        list_add(&smack_known_huh.list, &smack_known_list);
        list_add(&smack_known_hat.list, &smack_known_list);
        list_add(&smack_known_star.list, &smack_known_list);
@@ -3665,16 +3706,8 @@ static __init int smack_init(void)
        cred = (struct cred *) current->cred;
        cred->security = tsp;
 
-       /* initialize the smack_know_list */
-       init_smack_know_list();
-       /*
-        * Initialize locks
-        */
-       spin_lock_init(&smack_known_huh.smk_cipsolock);
-       spin_lock_init(&smack_known_hat.smk_cipsolock);
-       spin_lock_init(&smack_known_star.smk_cipsolock);
-       spin_lock_init(&smack_known_floor.smk_cipsolock);
-       spin_lock_init(&smack_known_invalid.smk_cipsolock);
+       /* initialize the smack_known_list */
+       init_smack_known_list();
 
        /*
         * Register with LSM
index 5c32f36ff70618dfb08e3040c94060238dfa44da..038811cb7e625eb48e331c351d079232248dfb83 100644 (file)
@@ -1614,20 +1614,6 @@ static int __init init_smk_fs(void)
        smk_cipso_doi();
        smk_unlbl_ambient(NULL);
 
-       mutex_init(&smack_known_floor.smk_rules_lock);
-       mutex_init(&smack_known_hat.smk_rules_lock);
-       mutex_init(&smack_known_huh.smk_rules_lock);
-       mutex_init(&smack_known_invalid.smk_rules_lock);
-       mutex_init(&smack_known_star.smk_rules_lock);
-       mutex_init(&smack_known_web.smk_rules_lock);
-
-       INIT_LIST_HEAD(&smack_known_floor.smk_rules);
-       INIT_LIST_HEAD(&smack_known_hat.smk_rules);
-       INIT_LIST_HEAD(&smack_known_huh.smk_rules);
-       INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
-       INIT_LIST_HEAD(&smack_known_star.smk_rules);
-       INIT_LIST_HEAD(&smack_known_web.smk_rules);
-
        return err;
 }
 
index 14a286a7bf2b01686e450b2a3bc258df59f24e21..857586135d1820ee9310b2794716f4aef2c903eb 100644 (file)
@@ -419,6 +419,7 @@ EXPORT_SYMBOL(snd_ctl_make_virtual_master);
  * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control
  * @kcontrol: vmaster kctl element
  * @hook: the hook function
+ * @private_data: the private_data pointer to be saved
  *
  * Adds the given hook to the vmaster control element so that it's called
  * at each time when the value is changed.
index b4a6aa960f4b6718d70dacdbdb1a745589564d1b..8490f59709bbf5721786bf89da622caac9f8cdc8 100644 (file)
@@ -1019,13 +1019,15 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
        irq_cfg = get_irq_config(sscape->type, irq[dev]);
        if (irq_cfg == INVALID_IRQ) {
                snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
-               return -ENXIO;
+               err = -ENXIO;
+               goto _release_dma;
        }
 
        mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]);
        if (mpu_irq_cfg == INVALID_IRQ) {
                snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
-               return -ENXIO;
+               err = -ENXIO;
+               goto _release_dma;
        }
 
        /*
index bdd0857b88710bb4fb2489766bcb4ea3fa26b79e..7ffc182e084478fac3e7ca4cf98523d4e68867d5 100644 (file)
@@ -38,4 +38,4 @@ static int __init alsa_sound_last_init(void)
        return 0;
 }
 
-__initcall(alsa_sound_last_init);
+late_initcall_sync(alsa_sound_last_init);
index 2c79d60a725f45dd83f31edf6187204ed8c4db1d..536c4c0514d32a2713b5abee58a55baf4b66fdfc 100644 (file)
@@ -1294,6 +1294,8 @@ static int __init calibrate_adc(WORD srate)
 
 static int upload_dsp_code(void)
 {
+       int ret = 0;
+
        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
 #ifndef HAVE_DSPCODEH
        INITCODESIZE = mod_firmware_load(INITCODEFILE, &INITCODE);
@@ -1312,7 +1314,8 @@ static int upload_dsp_code(void)
        memcpy_toio(dev.base, PERMCODE, PERMCODESIZE);
        if (msnd_upload_host(&dev, INITCODE, INITCODESIZE) < 0) {
                printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out;
        }
 #ifdef HAVE_DSPCODEH
        printk(KERN_INFO LOGNAME ": DSP firmware uploaded (resident)\n");
@@ -1320,12 +1323,13 @@ static int upload_dsp_code(void)
        printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n");
 #endif
 
+out:
 #ifndef HAVE_DSPCODEH
        vfree(INITCODE);
        vfree(PERMCODE);
 #endif
 
-       return 0;
+       return ret;
 }
 
 #ifdef MSND_CLASSIC
index 88168044375f9d7fba0b41d7567ee30c263e698e..5ca0939e4223b6104893fd77ccb3e1f5f982bd6c 100644 (file)
@@ -2,8 +2,8 @@
 
 config SND_TEA575X
        tristate
-       depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2
-       default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2
+       depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO
+       default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO
 
 menuconfig SND_PCI
        bool "PCI sound devices"
index 8c63200cf339631d9c18649c4a9f5195f650e9c9..bc86cb726d795175361c05c685a0004b37dade18 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************
 
     AudioScience HPI driver
-    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
+    Copyright (C) 1997-2012  AudioScience Inc. <support@audioscience.com>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of version 2 of the GNU General Public License as
@@ -42,7 +42,7 @@ On error *pLockedMemHandle marked invalid, non-zero returned.
 If this function succeeds, then HpiOs_LockedMem_GetVirtAddr() and
 HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle.
 */
-int hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
+u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
                                                           /**< memory handle */
        u32 size, /**< Size in bytes to allocate */
        struct pci_dev *p_os_reference
index 87f4385fe8c7f1a6b976734f0b56b19706d4d67b..5ef4fe964366e6e1c69d9cc71b7794e866ca0a6a 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************
 
     AudioScience HPI driver
-    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
+    Copyright (C) 1997-2012  AudioScience Inc. <support@audioscience.com>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of version 2 of the GNU General Public License as
@@ -39,11 +39,11 @@ void hpios_delay_micro_seconds(u32 num_micro_sec)
 
 }
 
-/** Allocated an area of locked memory for bus master DMA operations.
+/** Allocate an area of locked memory for bus master DMA operations.
 
-On error, return -ENOMEM, and *pMemArea.size = 0
+If allocation fails, return 1, and *pMemArea.size = 0
 */
-int hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
+u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
        struct pci_dev *pdev)
 {
        /*?? any benefit in using managed dmam_alloc_coherent? */
@@ -62,7 +62,7 @@ int hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
                HPI_DEBUG_LOG(WARNING,
                        "failed to allocate %d bytes locked memory\n", size);
                p_mem_area->size = 0;
-               return -ENOMEM;
+               return 1;
        }
 }
 
index 9a9f372e1be4f50070e818116dd7786156fb089c..56b4f74c0b13a101e16e9433f76341ef7a5a7c0e 100644 (file)
@@ -851,6 +851,9 @@ struct hda_codec {
        unsigned int pin_amp_workaround:1; /* pin out-amp takes index
                                            * (e.g. Conexant codecs)
                                            */
+       unsigned int single_adc_amp:1; /* adc in-amp takes no index
+                                       * (e.g. CX20549 codec)
+                                       */
        unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
        unsigned int pins_shutup:1;     /* pins are shut up */
        unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
index b58b4b1687fa674243be3a167d20e64d8e90cbfe..4c054f4486b943b58ffae9ba51f4c40b98c99d19 100644 (file)
@@ -418,7 +418,7 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a)
        else
                buf2[0] = '\0';
 
-       printk(KERN_INFO "HDMI: supports coding type %s:"
+       _snd_printd(SND_PR_VERBOSE, "HDMI: supports coding type %s:"
                        " channels = %d, rates =%s%s\n",
                        cea_audio_coding_type_names[a->format],
                        a->channels,
@@ -442,14 +442,14 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
 {
        int i;
 
-       printk(KERN_INFO "HDMI: detected monitor %s at connection type %s\n",
+       _snd_printd(SND_PR_VERBOSE, "HDMI: detected monitor %s at connection type %s\n",
                        e->monitor_name,
                        eld_connection_type_names[e->conn_type]);
 
        if (e->spk_alloc) {
                char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
                snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
-               printk(KERN_INFO "HDMI: available speakers:%s\n", buf);
+               _snd_printd(SND_PR_VERBOSE, "HDMI: available speakers:%s\n", buf);
        }
 
        for (i = 0; i < e->sad_count; i++)
index 254ab5204603767c54f44f25b5d94df624bb89d3..e59e2f059b6ede9a21bc4d92ecf4f92a668f5ae3 100644 (file)
@@ -651,9 +651,16 @@ static void print_codec_info(struct snd_info_entry *entry,
                        snd_iprintf(buffer, "  Amp-In caps: ");
                        print_amp_caps(buffer, codec, nid, HDA_INPUT);
                        snd_iprintf(buffer, "  Amp-In vals: ");
-                       print_amp_vals(buffer, codec, nid, HDA_INPUT,
-                                      wid_caps & AC_WCAP_STEREO,
-                                      wid_type == AC_WID_PIN ? 1 : conn_len);
+                       if (wid_type == AC_WID_PIN ||
+                           (codec->single_adc_amp &&
+                            wid_type == AC_WID_AUD_IN))
+                               print_amp_vals(buffer, codec, nid, HDA_INPUT,
+                                              wid_caps & AC_WCAP_STEREO,
+                                              1);
+                       else
+                               print_amp_vals(buffer, codec, nid, HDA_INPUT,
+                                              wid_caps & AC_WCAP_STEREO,
+                                              conn_len);
                }
                if (wid_caps & AC_WCAP_OUT_AMP) {
                        snd_iprintf(buffer, "  Amp-Out caps: ");
index 8c6523bbc797f8c3a22bbbeedc4a19194e26027e..d906c5b74cf0e7b047a4e702c71ba8b6d0e5d5de 100644 (file)
@@ -141,7 +141,6 @@ struct conexant_spec {
        unsigned int hp_laptop:1;
        unsigned int asus:1;
        unsigned int pin_eapd_ctrls:1;
-       unsigned int single_adc_amp:1;
 
        unsigned int adc_switching:1;
 
@@ -687,27 +686,26 @@ static const struct hda_channel_mode cxt5045_modes[1] = {
 static const struct hda_input_mux cxt5045_capture_source = {
        .num_items = 2,
        .items = {
-               { "IntMic", 0x1 },
-               { "ExtMic", 0x2 },
+               { "Internal Mic", 0x1 },
+               { "Mic",          0x2 },
        }
 };
 
 static const struct hda_input_mux cxt5045_capture_source_benq = {
-       .num_items = 5,
+       .num_items = 4,
        .items = {
-               { "IntMic", 0x1 },
-               { "ExtMic", 0x2 },
-               { "LineIn", 0x3 },
-               { "CD",     0x4 },
-               { "Mixer",  0x0 },
+               { "Internal Mic", 0x1 },
+               { "Mic",          0x2 },
+               { "Line",         0x3 },
+               { "Mixer",        0x0 },
        }
 };
 
 static const struct hda_input_mux cxt5045_capture_source_hp530 = {
        .num_items = 2,
        .items = {
-               { "ExtMic", 0x1 },
-               { "IntMic", 0x2 },
+               { "Mic",          0x1 },
+               { "Internal Mic", 0x2 },
        }
 };
 
@@ -798,10 +796,8 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
 }
 
 static const struct snd_kcontrol_new cxt5045_mixers[] = {
-       HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
@@ -822,27 +818,15 @@ static const struct snd_kcontrol_new cxt5045_mixers[] = {
 };
 
 static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
-       HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
-       HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x3, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x3, HDA_INPUT),
 
        {}
 };
 
 static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
-       HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
@@ -946,10 +930,10 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
        /* Output controls */
        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("HP-OUT Playback Volume", 0x11, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("HP-OUT Playback Switch", 0x11, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("LINE1 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
        
        /* Modes for retasking pin widgets */
        CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
@@ -960,16 +944,16 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
 
        /* Loopback mixer controls */
 
-       HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
-       HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
-       HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
-       HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
+       HDA_CODEC_VOLUME("PCM Volume", 0x17, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("PCM Switch", 0x17, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("MIC1 pin Volume", 0x17, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("MIC1 pin Switch", 0x17, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("LINE1 pin Volume", 0x17, 0x2, HDA_INPUT),
+       HDA_CODEC_MUTE("LINE1 pin Switch", 0x17, 0x2, HDA_INPUT),
+       HDA_CODEC_VOLUME("HP-OUT pin Volume", 0x17, 0x3, HDA_INPUT),
+       HDA_CODEC_MUTE("HP-OUT pin Switch", 0x17, 0x3, HDA_INPUT),
+       HDA_CODEC_VOLUME("CD pin Volume", 0x17, 0x4, HDA_INPUT),
+       HDA_CODEC_MUTE("CD pin Switch", 0x17, 0x4, HDA_INPUT),
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Input Source",
@@ -978,16 +962,8 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
                .put = conexant_mux_enum_put,
        },
        /* Audio input controls */
-       HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
-       HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
-       HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
-       HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
-       HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
-       HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
        { } /* end */
 };
 
@@ -1009,10 +985,6 @@ static const struct hda_verb cxt5045_test_init_verbs[] = {
        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
        {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
 
-       /* Start with output sum widgets muted and their output gains at min */
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
        /* Unmute retasking pin widget output buffers since the default
         * state appears to be output.  As the pin mode is changed by the
         * user the pin mode control will take care of enabling the pin's
@@ -1027,11 +999,11 @@ static const struct hda_verb cxt5045_test_init_verbs[] = {
        /* Set ADC connection select to match default mixer setting (mic1
         * pin)
         */
-       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
+       {0x17, AC_VERB_SET_CONNECT_SEL, 0x01},
 
        /* Mute all inputs to mixer widget (even unconnected ones) */
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer */
        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
@@ -1110,7 +1082,7 @@ static int patch_cxt5045(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
        codec->spec = spec;
-       codec->pin_amp_workaround = 1;
+       codec->single_adc_amp = 1;
 
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
@@ -3999,9 +3971,14 @@ static void cx_auto_init_output(struct hda_codec *codec)
        int i;
 
        mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
-       for (i = 0; i < cfg->hp_outs; i++)
+       for (i = 0; i < cfg->hp_outs; i++) {
+               unsigned int val = PIN_OUT;
+               if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) &
+                   AC_PINCAP_HP_DRV)
+                       val |= AC_PINCTL_HP_EN;
                snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
-                                   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+       }
        mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
        mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
        mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
@@ -4220,7 +4197,7 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
                int idx = get_input_connection(codec, adc_nid, nid);
                if (idx < 0)
                        continue;
-               if (spec->single_adc_amp)
+               if (codec->single_adc_amp)
                        idx = 0;
                return cx_auto_add_volume_idx(codec, label, pfx,
                                              cidx, adc_nid, HDA_INPUT, idx);
@@ -4275,7 +4252,7 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
                if (cidx < 0)
                        continue;
                input_conn[i] = spec->imux_info[i].adc;
-               if (!spec->single_adc_amp)
+               if (!codec->single_adc_amp)
                        input_conn[i] |= cidx << 8;
                if (i > 0 && input_conn[i] != input_conn[0])
                        multi_connection = 1;
@@ -4419,8 +4396,10 @@ static void apply_pin_fixup(struct hda_codec *codec,
 
 enum {
        CXT_PINCFG_LENOVO_X200,
+       CXT_PINCFG_LENOVO_TP410,
 };
 
+/* ThinkPad X200 & co with cxt5051 */
 static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
        { 0x16, 0x042140ff }, /* HP (seq# overridden) */
        { 0x17, 0x21a11000 }, /* dock-mic */
@@ -4429,15 +4408,33 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
        {}
 };
 
+/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */
+static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = {
+       { 0x19, 0x042110ff }, /* HP (seq# overridden) */
+       { 0x1a, 0x21a190f0 }, /* dock-mic */
+       { 0x1c, 0x212140ff }, /* dock-HP */
+       {}
+};
+
 static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
        [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
+       [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,
 };
 
-static const struct snd_pci_quirk cxt_fixups[] = {
+static const struct snd_pci_quirk cxt5051_fixups[] = {
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
        {}
 };
 
+static const struct snd_pci_quirk cxt5066_fixups[] = {
+       SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
+       SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
+       SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
+       SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
+       SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
+       {}
+};
+
 /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
  * can be created (bko#42825)
  */
@@ -4466,19 +4463,21 @@ static int patch_conexant_auto(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
        codec->spec = spec;
-       codec->pin_amp_workaround = 1;
 
        switch (codec->vendor_id) {
        case 0x14f15045:
-               spec->single_adc_amp = 1;
+               codec->single_adc_amp = 1;
                break;
        case 0x14f15051:
                add_cx5051_fake_mutes(codec);
+               codec->pin_amp_workaround = 1;
+               apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
                break;
+       default:
+               codec->pin_amp_workaround = 1;
+               apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
        }
 
-       apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
-
        /* Show mute-led control only on HP laptops
         * This is a sort of white-list: on HP laptops, EAPD corresponds
         * only to the mute-LED without actualy amp function.  Meanwhile,
index 540cd13f7f15e4fd4ecd3a0ae3a114a16683b76d..83f345f3c961b05313a17e10d9c46d53ace138c7 100644 (file)
@@ -757,8 +757,6 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
        struct hdmi_spec *spec = codec->spec;
        int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
        int pin_nid;
-       int pd = !!(res & AC_UNSOL_RES_PD);
-       int eldv = !!(res & AC_UNSOL_RES_ELDV);
        int pin_idx;
        struct hda_jack_tbl *jack;
 
@@ -768,9 +766,10 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
        pin_nid = jack->nid;
        jack->jack_dirty = 1;
 
-       printk(KERN_INFO
+       _snd_printd(SND_PR_VERBOSE,
                "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
-               codec->addr, pin_nid, pd, eldv);
+               codec->addr, pin_nid,
+               !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
 
        pin_idx = pin_nid_to_pin_index(spec, pin_nid);
        if (pin_idx < 0)
@@ -992,7 +991,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
        if (eld->monitor_present)
                eld_valid       = !!(present & AC_PINSENSE_ELDV);
 
-       printk(KERN_INFO
+       _snd_printd(SND_PR_VERBOSE,
                "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
                codec->addr, pin_nid, eld->monitor_present, eld_valid);
 
index 9917e55d6f11f8bbe9c0e8c7827febaf6c6ba6f7..e65e3543305568a9ab910057502ba583f656e724 100644 (file)
@@ -1445,6 +1445,13 @@ enum {
        ALC_FIXUP_ACT_BUILD,
 };
 
+static void alc_apply_pincfgs(struct hda_codec *codec,
+                             const struct alc_pincfg *cfg)
+{
+       for (; cfg->nid; cfg++)
+               snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+}
+
 static void alc_apply_fixup(struct hda_codec *codec, int action)
 {
        struct alc_spec *spec = codec->spec;
@@ -1478,9 +1485,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action)
                        snd_printdd(KERN_INFO "hda_codec: %s: "
                                    "Apply pincfg for %s\n",
                                    codec->chip_name, modelname);
-                       for (; cfg->nid; cfg++)
-                               snd_hda_codec_set_pincfg(codec, cfg->nid,
-                                                        cfg->val);
+                       alc_apply_pincfgs(codec, cfg);
                        break;
                case ALC_FIXUP_VERBS:
                        if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
@@ -3398,8 +3403,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
        for (;;) {
                badness = fill_and_eval_dacs(codec, fill_hardwired,
                                             fill_mio_first);
-               if (badness < 0)
+               if (badness < 0) {
+                       kfree(best_cfg);
                        return badness;
+               }
                debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
                              cfg->line_out_type, fill_hardwired, fill_mio_first,
                              badness);
@@ -3434,7 +3441,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
                        cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
                        fill_hardwired = true;
                        continue;
-               } 
+               }
                if (cfg->hp_outs > 0 &&
                    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
                        cfg->speaker_outs = cfg->line_outs;
@@ -3448,7 +3455,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
                        cfg->line_out_type = AUTO_PIN_HP_OUT;
                        fill_hardwired = true;
                        continue;
-               } 
+               }
                break;
        }
 
@@ -4423,7 +4430,7 @@ static int alc_parse_auto_config(struct hda_codec *codec,
 static int alc880_parse_auto_config(struct hda_codec *codec)
 {
        static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
-       static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 
+       static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
        return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
 }
 
@@ -4859,6 +4866,7 @@ enum {
        ALC260_FIXUP_GPIO1_TOGGLE,
        ALC260_FIXUP_REPLACER,
        ALC260_FIXUP_HP_B1900,
+       ALC260_FIXUP_KN1,
 };
 
 static void alc260_gpio1_automute(struct hda_codec *codec)
@@ -4886,6 +4894,36 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
        }
 }
 
+static void alc260_fixup_kn1(struct hda_codec *codec,
+                            const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       static const struct alc_pincfg pincfgs[] = {
+               { 0x0f, 0x02214000 }, /* HP/speaker */
+               { 0x12, 0x90a60160 }, /* int mic */
+               { 0x13, 0x02a19000 }, /* ext mic */
+               { 0x18, 0x01446000 }, /* SPDIF out */
+               /* disable bogus I/O pins */
+               { 0x10, 0x411111f0 },
+               { 0x11, 0x411111f0 },
+               { 0x14, 0x411111f0 },
+               { 0x15, 0x411111f0 },
+               { 0x16, 0x411111f0 },
+               { 0x17, 0x411111f0 },
+               { 0x19, 0x411111f0 },
+               { }
+       };
+
+       switch (action) {
+       case ALC_FIXUP_ACT_PRE_PROBE:
+               alc_apply_pincfgs(codec, pincfgs);
+               break;
+       case ALC_FIXUP_ACT_PROBE:
+               spec->init_amp = ALC_INIT_NONE;
+               break;
+       }
+}
+
 static const struct alc_fixup alc260_fixups[] = {
        [ALC260_FIXUP_HP_DC5750] = {
                .type = ALC_FIXUP_PINS,
@@ -4936,7 +4974,11 @@ static const struct alc_fixup alc260_fixups[] = {
                .v.func = alc260_fixup_gpio1_toggle,
                .chained = true,
                .chain_id = ALC260_FIXUP_COEF,
-       }
+       },
+       [ALC260_FIXUP_KN1] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc260_fixup_kn1,
+       },
 };
 
 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
@@ -4946,6 +4988,7 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
        SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
        SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
+       SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
        SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
        SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
        {}
@@ -5269,7 +5312,9 @@ static const struct alc_fixup alc882_fixups[] = {
                        { 0x16, 0x99130111 }, /* CLFE speaker */
                        { 0x17, 0x99130112 }, /* surround speaker */
                        { }
-               }
+               },
+               .chained = true,
+               .chain_id = ALC882_FIXUP_GPIO1,
        },
        [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
                .type = ALC_FIXUP_PINS,
@@ -5312,7 +5357,9 @@ static const struct alc_fixup alc882_fixups[] = {
                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
                        { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
                        { }
-               }
+               },
+               .chained = true,
+               .chain_id = ALC882_FIXUP_GPIO1,
        },
        [ALC885_FIXUP_MACPRO_GPIO] = {
                .type = ALC_FIXUP_FUNC,
@@ -5359,6 +5406,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
                      ALC882_FIXUP_ACER_ASPIRE_4930G),
        SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
        SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
+       SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
        SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
        SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
        SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
@@ -5384,6 +5432,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
+       SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
        SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
        SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
@@ -5399,6 +5448,13 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        {}
 };
 
+static const struct alc_model_fixup alc882_fixup_models[] = {
+       {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
+       {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
+       {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
+       {}
+};
+
 /*
  * BIOS auto configuration
  */
@@ -5439,7 +5495,8 @@ static int patch_alc882(struct hda_codec *codec)
        if (err < 0)
                goto error;
 
-       alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
+       alc_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
+                      alc882_fixups);
        alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
        alc_auto_parse_customize_define(codec);
@@ -6079,7 +6136,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
         * Basically the device should work as is without the fixup table.
         * If BIOS doesn't give a proper info, enable the corresponding
         * fixup entry.
-        */ 
+        */
        SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
                      ALC269_FIXUP_AMIC),
        SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
@@ -6296,7 +6353,7 @@ static void alc_fixup_no_jack_detect(struct hda_codec *codec,
 {
        if (action == ALC_FIXUP_ACT_PRE_PROBE)
                codec->no_jack_detect = 1;
-}      
+}
 
 static const struct alc_fixup alc861_fixups[] = {
        [ALC861_FIXUP_FSC_AMILO_PI1505] = {
@@ -6714,7 +6771,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
         * Basically the device should work as is without the fixup table.
         * If BIOS doesn't give a proper info, enable the corresponding
         * fixup entry.
-        */ 
+        */
        SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
        SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
        SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
index 33a9946b492cb333184b1a9405c11f553fc55566..4742cac26aa9b4058a58220897e45c2e826dc47d 100644 (file)
@@ -5063,12 +5063,11 @@ static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
        if (spec->gpio_led_polarity)
                muted = !muted;
 
-       /*polarity defines *not* muted state level*/
        if (!spec->vref_mute_led_nid) {
                if (muted)
-                       spec->gpio_data &= ~spec->gpio_led; /* orange */
+                       spec->gpio_data |= spec->gpio_led;
                else
-                       spec->gpio_data |= spec->gpio_led; /* white */
+                       spec->gpio_data &= ~spec->gpio_led;
                stac_gpio_set(codec, spec->gpio_mask,
                                spec->gpio_dir, spec->gpio_data);
        } else {
index 6508e8b790bb16076d3539261db7df43032438e4..59d8efaa17e96eec921774fad61fd149884f2241 100644 (file)
@@ -57,7 +57,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_TPA6130A2 if I2C
        select SND_SOC_TLV320DAC33 if I2C
        select SND_SOC_TWL4030 if TWL4030_CORE
-       select SND_SOC_TWL6040 if TWL4030_CORE
+       select SND_SOC_TWL6040 if TWL6040_CORE
        select SND_SOC_UDA134X
        select SND_SOC_UDA1380 if I2C
        select SND_SOC_WL1273 if MFD_WL1273_CORE
@@ -276,7 +276,6 @@ config SND_SOC_TWL4030
        tristate
 
 config SND_SOC_TWL6040
-       select TWL6040_CORE
        tristate
 
 config SND_SOC_UDA134X
index f8e10ced244a6d4f36b6ab964bf39f54579da91e..b3e24f289421a7fda3dda11043039179c4777535 100644 (file)
  * min : 0xFE : -115.0 dB
  * mute: 0xFF
  */
-static const DECLARE_TLV_DB_SCALE(out_tlv, -11500, 50, 1);
+static const DECLARE_TLV_DB_SCALE(out_tlv, -11550, 50, 1);
 
 static const struct snd_kcontrol_new ak4642_snd_controls[] = {
 
index d1926266fe00f4ae10003d9c632a07e4dcd68862..8e92fb88ed090e594002407850e1275df4078577 100644 (file)
@@ -143,11 +143,11 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
 }
 
 /*
- * using codec assist to small pop, hp_powerup or lineout_powerup
- * should stay setting until vag_powerup is fully ramped down,
- * vag fully ramped down require 400ms.
+ * As manual described, ADC/DAC only works when VAG powerup,
+ * So enabled VAG before ADC/DAC up.
+ * In power down case, we need wait 400ms when vag fully ramped down.
  */
-static int small_pop_event(struct snd_soc_dapm_widget *w,
+static int power_vag_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
        switch (event) {
@@ -156,7 +156,7 @@ static int small_pop_event(struct snd_soc_dapm_widget *w,
                        SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
                break;
 
-       case SND_SOC_DAPM_PRE_PMD:
+       case SND_SOC_DAPM_POST_PMD:
                snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
                        SGTL5000_VAG_POWERUP, 0);
                msleep(400);
@@ -201,12 +201,8 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
                                mic_bias_event,
                                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
-       SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0,
-                       small_pop_event,
-                       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-       SND_SOC_DAPM_PGA_E("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0,
-                       small_pop_event,
-                       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+       SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0),
 
        SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
        SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
@@ -221,8 +217,11 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
                                0, SGTL5000_CHIP_DIG_POWER,
                                1, 0),
 
-       SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
+       SND_SOC_DAPM_SUPPLY("VAG_POWER", SGTL5000_CHIP_ANA_POWER, 7, 0,
+                           power_vag_event,
+                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
+       SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
        SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
 };
 
@@ -231,9 +230,11 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
        {"Capture Mux", "LINE_IN", "LINE_IN"},  /* line_in --> adc_mux */
        {"Capture Mux", "MIC_IN", "MIC_IN"},    /* mic_in --> adc_mux */
 
+       {"ADC", NULL, "VAG_POWER"},
        {"ADC", NULL, "Capture Mux"},           /* adc_mux --> adc */
        {"AIFOUT", NULL, "ADC"},                /* adc --> i2s_out */
 
+       {"DAC", NULL, "VAG_POWER"},
        {"DAC", NULL, "AIFIN"},                 /* i2s-->dac,skip audio mux */
        {"Headphone Mux", "DAC", "DAC"},        /* dac --> hp_mux */
        {"LO", NULL, "DAC"},                    /* dac --> line_out */
index 2d8c6b825e57b9ecd17253c5de57432260ecdaab..dc7509b9d53aa27f4580c923bfe81b2baa7fbff6 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/i2c/twl.h>
 #include <linux/mfd/twl6040.h>
 
 #include <sound/core.h>
@@ -1528,7 +1527,7 @@ static int twl6040_resume(struct snd_soc_codec *codec)
 static int twl6040_probe(struct snd_soc_codec *codec)
 {
        struct twl6040_data *priv;
-       struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+       struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);
        struct platform_device *pdev = container_of(codec->dev,
                                                   struct platform_device, dev);
        int ret = 0;
index 1765a197acb0ab14d0a54cda8751dd45fa7b71fb..f23700359c672372f84a58df8701176b57e6d475 100644 (file)
@@ -73,6 +73,9 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
        if (!buf)
                return -ENOMEM;
 
+       if (!audmux_base)
+               return -ENOSYS;
+
        if (audmux_clk)
                clk_prepare_enable(audmux_clk);
 
@@ -152,7 +155,7 @@ static void __init audmux_debugfs_init(void)
                return;
        }
 
-       for (i = 1; i < 8; i++) {
+       for (i = 0; i < MX31_AUDMUX_PORT6_SSI_PINS_6 + 1; i++) {
                snprintf(buf, sizeof(buf), "ssi%d", i);
                if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
                                         (void *)i, &audmux_debugfs_fops))
index e00dd0b1139ca17144048a41148fb2a656b2db7c..deafbfaacdbf13644d72009ddeadd18c5eb81eea 100644 (file)
@@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430
 
 config SND_OMAP_SOC_OMAP_ABE_TWL6040
        tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
-       depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4
+       depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4
        select SND_OMAP_SOC_DMIC
        select SND_OMAP_SOC_MCPDM
        select SND_SOC_TWL6040
index 609abd51e55fef65ed8ec34157165b3e1a55b700..d08583790d231192fd2b11ac4cfcf8a50477b042 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
index e19c24ade414a3eef34073f6f98da139c8ff8b5a..accdcb7d4d9dafbf5397cc33bc199fa2c86bbb03 100644 (file)
@@ -1081,6 +1081,8 @@ static int soc_probe_platform(struct snd_soc_card *card,
                snd_soc_dapm_new_controls(&platform->dapm,
                        driver->dapm_widgets, driver->num_dapm_widgets);
 
+       platform->dapm.idle_bias_off = 1;
+
        if (driver->probe) {
                ret = driver->probe(platform);
                if (ret < 0) {
index 33509de52540bd8c38aea1bbfb121fe20fe238d5..e53349912b2e1b7c5f8a462018ed0cfecd8fc8b5 100644 (file)
@@ -79,11 +79,15 @@ static int tegra_i2s_show(struct seq_file *s, void *unused)
        struct tegra_i2s *i2s = s->private;
        int i;
 
+       clk_enable(i2s->clk_i2s);
+
        for (i = 0; i < ARRAY_SIZE(regs); i++) {
                u32 val = tegra_i2s_read(i2s, regs[i].offset);
                seq_printf(s, "%s = %08x\n", regs[i].name, val);
        }
 
+       clk_disable(i2s->clk_i2s);
+
        return 0;
 }
 
@@ -112,7 +116,7 @@ static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
                debugfs_remove(i2s->debug);
 }
 #else
-static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id)
+static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s)
 {
 }
 
index 475428cf270e01eba85cff0a042c2d358669e7aa..9ff2c601445f439f734b097b82967c6abad1fd65 100644 (file)
@@ -79,11 +79,15 @@ static int tegra_spdif_show(struct seq_file *s, void *unused)
        struct tegra_spdif *spdif = s->private;
        int i;
 
+       clk_enable(spdif->clk_spdif_out);
+
        for (i = 0; i < ARRAY_SIZE(regs); i++) {
                u32 val = tegra_spdif_read(spdif, regs[i].offset);
                seq_printf(s, "%s = %08x\n", regs[i].name, val);
        }
 
+       clk_disable(spdif->clk_spdif_out);
+
        return 0;
 }
 
index 416684be0ad308a6df2a69d22f41409de05f7466..26b823b61aa175f2f0d8a475e6574a8615ae0e32 100644 (file)
@@ -19,3 +19,5 @@ TAGS
 cscope*
 config.mak
 config.mak.autogen
+*-bison.*
+*-flex.*
index 820371f10d1b1b96e1be9332d454f6ee053aaf34..03059e75665a267b39baa45b5f7e107557b96542 100644 (file)
@@ -237,21 +237,20 @@ export PERL_PATH
 FLEX = $(CROSS_COMPILE)flex
 BISON= $(CROSS_COMPILE)bison
 
-event-parser:
-       $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/parse-events-flex.c: util/parse-events.l
        $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
 
-$(OUTPUT)util/parse-events-flex.c: event-parser
-$(OUTPUT)util/parse-events-bison.c: event-parser
+$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
+       $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
 
-pmu-parser:
-       $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
+$(OUTPUT)util/pmu-flex.c: util/pmu.l
        $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
 
-$(OUTPUT)util/pmu-flex.c: pmu-parser
-$(OUTPUT)util/pmu-bison.c: pmu-parser
+$(OUTPUT)util/pmu-bison.c: util/pmu.y
+       $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
 
-$(OUTPUT)util/parse-events.o: event-parser pmu-parser
+$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
 
 LIB_FILE=$(OUTPUT)libperf.a
 
@@ -527,7 +526,7 @@ else
 endif
 
 ifdef NO_GTK2
-       BASIC_CFLAGS += -DNO_GTK2
+       BASIC_CFLAGS += -DNO_GTK2_SUPPORT
 else
        FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0)
        ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y)
@@ -852,8 +851,6 @@ help:
        @echo '  html           - make html documentation'
        @echo '  info           - make GNU info documentation (access with info <foo>)'
        @echo '  pdf            - make pdf documentation'
-       @echo '  event-parser   - make event parser code'
-       @echo '  pmu-parser     - make pmu format parser code'
        @echo '  TAGS           - use etags to make tag information for source browsing'
        @echo '  tags           - use ctags to make tag information for source browsing'
        @echo '  cscope - use cscope to make interactive browsing database'
index fb8b5f83b4a0ae77736fbffe6a6736d56813eed6..1cad3af4bf4c9ff0f1813ba1cb826f18d3993a42 100644 (file)
@@ -17,6 +17,7 @@
 #include "util/debug.h"
 
 #include <sys/prctl.h>
+#include <sys/resource.h>
 
 #include <semaphore.h>
 #include <pthread.h>
index e3c63aef8efc6a334728ee9864c8243415c478be..8ef59f8262bb37a28c2e83724dbe62b88df349e7 100644 (file)
@@ -42,6 +42,7 @@
 #include "util/debug.h"
 
 #include <assert.h>
+#include <elf.h>
 #include <fcntl.h>
 
 #include <stdio.h>
@@ -59,6 +60,7 @@
 #include <sys/prctl.h>
 #include <sys/wait.h>
 #include <sys/uio.h>
+#include <sys/utsname.h>
 #include <sys/mman.h>
 
 #include <linux/unistd.h>
@@ -162,12 +164,40 @@ static void __zero_source_counters(struct hist_entry *he)
        symbol__annotate_zero_histograms(sym);
 }
 
+static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
+{
+       struct utsname uts;
+       int err = uname(&uts);
+
+       ui__warning("Out of bounds address found:\n\n"
+                   "Addr:   %" PRIx64 "\n"
+                   "DSO:    %s %c\n"
+                   "Map:    %" PRIx64 "-%" PRIx64 "\n"
+                   "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n"
+                   "Arch:   %s\n"
+                   "Kernel: %s\n"
+                   "Tools:  %s\n\n"
+                   "Not all samples will be on the annotation output.\n\n"
+                   "Please report to linux-kernel@vger.kernel.org\n",
+                   ip, map->dso->long_name, dso__symtab_origin(map->dso),
+                   map->start, map->end, sym->start, sym->end,
+                   sym->binding == STB_GLOBAL ? 'g' :
+                   sym->binding == STB_LOCAL  ? 'l' : 'w', sym->name,
+                   err ? "[unknown]" : uts.machine,
+                   err ? "[unknown]" : uts.release, perf_version_string);
+       if (use_browser <= 0)
+               sleep(5);
+       
+       map->erange_warned = true;
+}
+
 static void perf_top__record_precise_ip(struct perf_top *top,
                                        struct hist_entry *he,
                                        int counter, u64 ip)
 {
        struct annotation *notes;
        struct symbol *sym;
+       int err;
 
        if (he == NULL || he->ms.sym == NULL ||
            ((top->sym_filter_entry == NULL ||
@@ -189,9 +219,12 @@ static void perf_top__record_precise_ip(struct perf_top *top,
        }
 
        ip = he->ms.map->map_ip(he->ms.map, ip);
-       symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
+       err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
 
        pthread_mutex_unlock(&notes->lock);
+
+       if (err == -ERANGE && !he->ms.map->erange_warned)
+               ui__warn_map_erange(he->ms.map, sym, ip);
 }
 
 static void perf_top__show_details(struct perf_top *top)
@@ -615,6 +648,7 @@ process_hotkey:
 
 /* Tag samples to be skipped. */
 static const char *skip_symbols[] = {
+       "intel_idle",
        "default_idle",
        "native_safe_halt",
        "cpu_idle",
index 677e59d62a8dc3ae0475ab31d8c78acaeca50e51..95b6f8b6177a98e45bc295bf4096b753aab70696 100644 (file)
@@ -29,13 +29,14 @@ if [ ! -s $BUILDIDS ] ; then
 fi
 
 MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX)
+PERF_BUILDID_LINKDIR=$(readlink -f $PERF_BUILDID_DIR)/
 
 cut -d ' ' -f 1 $BUILDIDS | \
 while read build_id ; do
        linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2}
        filename=$(readlink -f $linkname)
        echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST
-       echo ${filename#$PERF_BUILDID_DIR} >> $MANIFEST
+       echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST
 done
 
 tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST
index 199f69ec656f7a77c5c490e2f1195c9e09226e98..08c6d138a655c09398f05c6b1c4affdf1cb0ec56 100644 (file)
@@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
 
        pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
 
-       if (addr > sym->end)
-               return 0;
+       if (addr < sym->start || addr > sym->end)
+               return -ERANGE;
 
        offset = addr - sym->start;
        h = annotation__histogram(notes, evidx);
@@ -561,16 +561,12 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
 {
        struct annotation *notes = symbol__annotation(sym);
        struct sym_hist *h = annotation__histogram(notes, evidx);
-       struct objdump_line *pos;
-       int len = sym->end - sym->start;
+       int len = sym->end - sym->start, offset;
 
        h->sum = 0;
-
-       list_for_each_entry(pos, &notes->src->source, node) {
-               if (pos->offset != -1 && pos->offset < len) {
-                       h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8;
-                       h->sum += h->addr[pos->offset];
-               }
+       for (offset = 0; offset < len; ++offset) {
+               h->addr[offset] = h->addr[offset] * 7 / 8;
+               h->sum += h->addr[offset];
        }
 }
 
index 2ec4b60aff6c1efa5929c53e3c572b1d6504cfbd..9f6d630d53161e6f314e2efd51a90c3cb329521e 100644 (file)
@@ -256,6 +256,18 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
                if (!cmp) {
                        he->period += period;
                        ++he->nr_events;
+
+                       /* If the map of an existing hist_entry has
+                        * become out-of-date due to an exec() or
+                        * similar, update it.  Otherwise we will
+                        * mis-adjust symbol addresses when computing
+                        * the history counter to increment.
+                        */
+                       if (he->ms.map != entry->ms.map) {
+                               he->ms.map = entry->ms.map;
+                               if (he->ms.map)
+                                       he->ms.map->referenced = true;
+                       }
                        goto out;
                }
 
index dea6d1c1a95471018cdde36d0a4c23e20c8f64a1..35ae56864e4f59625369941886b196438f107c99 100644 (file)
@@ -38,6 +38,7 @@ void map__init(struct map *self, enum map_type type,
        RB_CLEAR_NODE(&self->rb_node);
        self->groups   = NULL;
        self->referenced = false;
+       self->erange_warned = false;
 }
 
 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
index b100c20b7f94f653448eaafcfb70e61e314f9e22..81371bad4ef0e43e1121b5b8c4367fe4d6b212d8 100644 (file)
@@ -33,6 +33,7 @@ struct map {
        u64                     end;
        u8 /* enum map_type */  type;
        bool                    referenced;
+       bool                    erange_warned;
        u32                     priv;
        u64                     pgoff;
 
index 9412e3b05f6888c9504c7ab6b3dd0effe73de627..1efd3bee6336bd6f1052ee76684e25cd489fa163 100644 (file)
@@ -826,8 +826,16 @@ static struct machine *
 {
        const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
-       if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest)
-               return perf_session__find_machine(session, event->ip.pid);
+       if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
+               u32 pid;
+
+               if (event->header.type == PERF_RECORD_MMAP)
+                       pid = event->mmap.pid;
+               else
+                       pid = event->ip.pid;
+
+               return perf_session__find_machine(session, pid);
+       }
 
        return perf_session__find_host_machine(session);
 }
@@ -868,11 +876,11 @@ static int perf_session_deliver_event(struct perf_session *session,
                dump_sample(session, event, sample);
                if (evsel == NULL) {
                        ++session->hists.stats.nr_unknown_id;
-                       return -1;
+                       return 0;
                }
                if (machine == NULL) {
                        ++session->hists.stats.nr_unprocessable_samples;
-                       return -1;
+                       return 0;
                }
                return tool->sample(tool, event, sample, evsel, machine);
        case PERF_RECORD_MMAP:
index d7a1c4afe28b9089ab09bbf5b7abce623e46a544..2f83e5dc996706a005dcdc9c1cac3cb88d38b94d 100644 (file)
@@ -125,6 +125,9 @@ static int callchain__count_rows(struct rb_root *chain)
 
 static bool map_symbol__toggle_fold(struct map_symbol *self)
 {
+       if (!self)
+               return false;
+
        if (!self->has_children)
                return false;
 
index a457d2138f49ac8ed860507de8c9068566368889..e9fff9830bf0bf6f2229603516ebdd633996fd20 100644 (file)
@@ -240,9 +240,13 @@ int kvm_iommu_map_guest(struct kvm *kvm)
                return -ENODEV;
        }
 
+       mutex_lock(&kvm->slots_lock);
+
        kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
-       if (!kvm->arch.iommu_domain)
-               return -ENOMEM;
+       if (!kvm->arch.iommu_domain) {
+               r = -ENOMEM;
+               goto out_unlock;
+       }
 
        if (!allow_unsafe_assigned_interrupts &&
            !iommu_domain_has_cap(kvm->arch.iommu_domain,
@@ -253,17 +257,16 @@ int kvm_iommu_map_guest(struct kvm *kvm)
                       " module option.\n", __func__);
                iommu_domain_free(kvm->arch.iommu_domain);
                kvm->arch.iommu_domain = NULL;
-               return -EPERM;
+               r = -EPERM;
+               goto out_unlock;
        }
 
        r = kvm_iommu_map_memslots(kvm);
        if (r)
-               goto out_unmap;
-
-       return 0;
+               kvm_iommu_unmap_memslots(kvm);
 
-out_unmap:
-       kvm_iommu_unmap_memslots(kvm);
+out_unlock:
+       mutex_unlock(&kvm->slots_lock);
        return r;
 }
 
@@ -310,6 +313,11 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
        }
 }
 
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+       kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages);
+}
+
 static int kvm_iommu_unmap_memslots(struct kvm *kvm)
 {
        int idx;
@@ -320,7 +328,7 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm)
        slots = kvm_memslots(kvm);
 
        kvm_for_each_memslot(memslot, slots)
-               kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages);
+               kvm_iommu_unmap_pages(kvm, memslot);
 
        srcu_read_unlock(&kvm->srcu, idx);
 
@@ -335,7 +343,11 @@ int kvm_iommu_unmap_guest(struct kvm *kvm)
        if (!domain)
                return 0;
 
+       mutex_lock(&kvm->slots_lock);
        kvm_iommu_unmap_memslots(kvm);
+       kvm->arch.iommu_domain = NULL;
+       mutex_unlock(&kvm->slots_lock);
+
        iommu_domain_free(domain);
        return 0;
 }
index 42b73930a6de6b2210708aca55903f87a9bab459..9739b533ca2e6954f75c98fc1bb307e641aedf94 100644 (file)
@@ -808,12 +808,13 @@ int __kvm_set_memory_region(struct kvm *kvm,
        if (r)
                goto out_free;
 
-       /* map the pages in iommu page table */
+       /* map/unmap the pages in iommu page table */
        if (npages) {
                r = kvm_iommu_map_pages(kvm, &new);
                if (r)
                        goto out_free;
-       }
+       } else
+               kvm_iommu_unmap_pages(kvm, &old);
 
        r = -ENOMEM;
        slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),