From 2cd9fb3bbc2e757b631c0221a437cf6a1ad1e5ca Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Jan 2012 11:39:22 +0300 Subject: [PATCH] --- yaml --- r: 287286 b: refs/heads/master c: 803ab977618eae2b292cda0a97eed75f42250ddf h: refs/heads/master v: v3 --- [refs] | 2 +- .../Documentation/DocBook/device-drivers.tmpl | 12 +- trunk/Documentation/driver-model/devres.txt | 4 - .../feature-removal-schedule.txt | 14 - trunk/Documentation/input/event-codes.txt | 72 +- trunk/Documentation/pinctrl.txt | 17 +- trunk/Documentation/stable_kernel_rules.txt | 3 +- trunk/Documentation/sysctl/kernel.txt | 2 - trunk/Documentation/thermal/sysfs-api.txt | 2 +- trunk/Documentation/virtual/00-INDEX | 2 + trunk/MAINTAINERS | 66 +- trunk/Makefile | 2 +- trunk/arch/arm/Kconfig | 4 +- trunk/arch/arm/common/gic.c | 7 +- trunk/arch/arm/include/asm/assembler.h | 4 +- trunk/arch/arm/include/asm/domain.h | 8 +- trunk/arch/arm/include/asm/futex.h | 8 +- trunk/arch/arm/include/asm/smp.h | 6 + trunk/arch/arm/include/asm/smp_plat.h | 6 - trunk/arch/arm/include/asm/tlb.h | 10 +- trunk/arch/arm/include/asm/uaccess.h | 16 +- trunk/arch/arm/kernel/entry-armv.S | 2 +- trunk/arch/arm/kernel/entry-common.S | 15 +- trunk/arch/arm/kernel/perf_event_v7.c | 28 - trunk/arch/arm/kernel/ptrace.c | 8 +- trunk/arch/arm/kernel/setup.c | 17 +- trunk/arch/arm/kernel/signal.c | 5 +- trunk/arch/arm/kernel/smp.c | 24 +- trunk/arch/arm/kernel/smp_twd.c | 2 - trunk/arch/arm/kernel/vmlinux.lds.S | 9 +- trunk/arch/arm/lib/getuser.S | 12 +- trunk/arch/arm/lib/putuser.S | 28 +- trunk/arch/arm/lib/uaccess.S | 82 +- trunk/arch/arm/mach-at91/Kconfig | 14 - trunk/arch/arm/mach-at91/Makefile | 14 +- trunk/arch/arm/mach-at91/at91cap9.c | 9 +- trunk/arch/arm/mach-at91/at91sam9260.c | 1 - trunk/arch/arm/mach-at91/at91sam9261.c | 1 - trunk/arch/arm/mach-at91/at91sam9263.c | 1 - trunk/arch/arm/mach-at91/at91sam9_alt_reset.S | 7 +- trunk/arch/arm/mach-at91/at91sam9g45.c | 7 +- trunk/arch/arm/mach-at91/at91sam9g45_reset.S | 40 - trunk/arch/arm/mach-at91/at91sam9rl.c | 1 - trunk/arch/arm/mach-at91/generic.h | 2 - .../arm/mach-at91/include/mach/at91_rstc.h | 18 +- .../arm/mach-at91/include/mach/at91cap9.h | 2 +- .../mach-at91/include/mach/at91cap9_ddrsdr.h | 108 + .../arm/mach-at91/include/mach/at91sam9260.h | 2 +- .../arm/mach-at91/include/mach/at91sam9261.h | 2 +- .../arm/mach-at91/include/mach/at91sam9263.h | 2 +- .../mach-at91/include/mach/at91sam9_ddrsdr.h | 30 +- .../arm/mach-at91/include/mach/at91sam9g45.h | 2 +- .../arm/mach-at91/include/mach/at91sam9rl.h | 2 +- trunk/arch/arm/mach-at91/include/mach/board.h | 2 +- trunk/arch/arm/mach-at91/pm.c | 9 +- trunk/arch/arm/mach-at91/pm.h | 8 +- trunk/arch/arm/mach-at91/pm_slowclock.S | 5 +- trunk/arch/arm/mach-at91/setup.c | 16 +- trunk/arch/arm/mach-bcmring/arch.c | 2 +- trunk/arch/arm/mach-bcmring/dma.c | 812 ++++++ .../arch/arm/mach-bcmring/include/mach/dma.h | 196 ++ trunk/arch/arm/mach-davinci/board-da850-evm.c | 2 +- trunk/arch/arm/mach-davinci/board-dm365-evm.c | 2 +- .../arch/arm/mach-davinci/board-dm644x-evm.c | 2 +- .../arch/arm/mach-davinci/board-dm646x-evm.c | 2 +- .../arch/arm/mach-davinci/board-neuros-osd2.c | 2 +- .../arm/mach-davinci/board-omapl138-hawk.c | 2 +- trunk/arch/arm/mach-davinci/board-sffsdr.c | 2 +- trunk/arch/arm/mach-davinci/da850.c | 32 + trunk/arch/arm/mach-exynos/hotplug.c | 1 - trunk/arch/arm/mach-exynos/platsmp.c | 1 - trunk/arch/arm/mach-highbank/highbank.c | 3 +- trunk/arch/arm/mach-imx/Kconfig | 1 + trunk/arch/arm/mach-imx/clock-imx6q.c | 11 - trunk/arch/arm/mach-imx/mach-mx53_ard.c | 4 +- trunk/arch/arm/mach-imx/src.c | 5 +- trunk/arch/arm/mach-msm/hotplug.c | 1 - trunk/arch/arm/mach-msm/platsmp.c | 1 - trunk/arch/arm/mach-omap2/Kconfig | 12 +- trunk/arch/arm/mach-omap2/devices.c | 1 - trunk/arch/arm/mach-omap2/gpmc.c | 6 - trunk/arch/arm/mach-omap2/hsmmc.c | 16 +- trunk/arch/arm/mach-omap2/io.c | 4 +- .../omap_hwmod_2xxx_3xxx_ipblock_data.c | 21 + .../mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 22 - .../arm/mach-omap2/omap_hwmod_3xxx_data.c | 54 +- .../arm/mach-omap2/omap_hwmod_44xx_data.c | 2 - trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c | 1 - trunk/arch/arm/mach-omap2/smartreflex.c | 2 +- trunk/arch/arm/mach-omap2/timer.c | 2 +- trunk/arch/arm/mach-pxa/devices.c | 20 + trunk/arch/arm/mach-pxa/pxa25x.c | 2 + trunk/arch/arm/mach-pxa/pxa27x.c | 2 + trunk/arch/arm/mach-pxa/pxa300.c | 1 + trunk/arch/arm/mach-pxa/pxa320.c | 1 + trunk/arch/arm/mach-pxa/pxa3xx.c | 1 + trunk/arch/arm/mach-pxa/pxa95x.c | 1 + trunk/arch/arm/mach-realview/hotplug.c | 1 - .../arm/mach-realview/include/mach/board-eb.h | 18 +- .../mach-realview/include/mach/board-pb11mp.h | 2 - trunk/arch/arm/mach-realview/realview_eb.c | 11 +- .../arch/arm/mach-realview/realview_pb11mp.c | 13 +- trunk/arch/arm/mach-sa1100/assabet.c | 12 + trunk/arch/arm/mach-sa1100/cerf.c | 11 + trunk/arch/arm/mach-sa1100/clock.c | 91 +- trunk/arch/arm/mach-sa1100/collie.c | 23 +- trunk/arch/arm/mach-sa1100/cpu-sa1100.c | 2 +- trunk/arch/arm/mach-sa1100/generic.c | 27 +- trunk/arch/arm/mach-sa1100/include/mach/mcp.h | 2 + trunk/arch/arm/mach-sa1100/jornada720_ssp.c | 2 - trunk/arch/arm/mach-sa1100/lart.c | 10 + trunk/arch/arm/mach-sa1100/shannon.c | 11 + trunk/arch/arm/mach-sa1100/simpad.c | 18 +- trunk/arch/arm/mach-shmobile/setup-sh7372.c | 2 - trunk/arch/arm/mach-shmobile/smp-r8a7779.c | 1 - trunk/arch/arm/mach-shmobile/smp-sh73a0.c | 1 - trunk/arch/arm/mach-ux500/Kconfig | 1 - trunk/arch/arm/mach-ux500/board-mop500-sdi.c | 2 - trunk/arch/arm/mach-ux500/cache-l2x0.c | 48 +- trunk/arch/arm/mach-ux500/hotplug.c | 1 - trunk/arch/arm/mach-ux500/platsmp.c | 1 - trunk/arch/arm/mach-ux500/usb.c | 6 + trunk/arch/arm/mach-vexpress/ct-ca9x4.c | 4 +- trunk/arch/arm/mach-vexpress/hotplug.c | 1 - trunk/arch/arm/mm/Kconfig | 1 - trunk/arch/arm/mm/init.c | 2 +- trunk/arch/arm/mm/proc-v7.S | 26 +- .../arch/arm/plat-mxc/include/mach/iomux-v1.h | 2 +- trunk/arch/arm/plat-versatile/platsmp.c | 1 - trunk/arch/avr32/Kconfig | 1 - trunk/arch/m68k/atari/config.c | 8 +- trunk/arch/m68k/include/asm/irq.h | 13 + trunk/arch/m68k/kernel/process_mm.c | 2 +- trunk/arch/m68k/kernel/process_no.c | 4 +- trunk/arch/m68k/kernel/traps.c | 36 +- trunk/arch/m68k/mm/cache.c | 6 +- trunk/arch/microblaze/Kconfig | 1 - trunk/arch/microblaze/include/asm/atomic.h | 1 - trunk/arch/microblaze/kernel/setup.c | 21 +- .../powerpc/boot/dts/fsl/mpc8536si-post.dtsi | 4 - .../powerpc/boot/dts/fsl/p1010si-post.dtsi | 3 +- .../powerpc/boot/dts/fsl/p1020si-post.dtsi | 4 - .../powerpc/boot/dts/fsl/p1022si-post.dtsi | 3 +- .../powerpc/boot/dts/fsl/p2020si-post.dtsi | 4 - trunk/arch/powerpc/boot/dts/p1020rdb.dtsi | 13 +- trunk/arch/powerpc/boot/dts/p1021mds.dts | 3 +- trunk/arch/powerpc/boot/dts/p2020ds.dtsi | 3 +- trunk/arch/powerpc/boot/dts/p2020rdb.dts | 3 +- trunk/arch/powerpc/kernel/crash.c | 2 +- trunk/arch/powerpc/kernel/legacy_serial.c | 2 - trunk/arch/powerpc/platforms/85xx/p1022_ds.c | 1 - .../arch/powerpc/platforms/powernv/pci-ioda.c | 43 +- trunk/arch/powerpc/platforms/pseries/Kconfig | 2 +- trunk/arch/powerpc/sysdev/fsl_pci.c | 5 +- trunk/arch/s390/Makefile | 1 + trunk/arch/s390/kernel/vmlinux.lds.S | 4 +- trunk/arch/sparc/Kconfig | 1 - trunk/arch/sparc/kernel/sun4m_irq.c | 3 - trunk/arch/sparc/lib/divdi3.S | 16 +- trunk/arch/x86/Kconfig | 1 + trunk/arch/x86/boot/compressed/misc.c | 2 - trunk/arch/x86/include/asm/cmpxchg.h | 6 +- trunk/arch/x86/include/asm/cpufeature.h | 1 - trunk/arch/x86/include/asm/kvm_emulate.h | 16 - trunk/arch/x86/include/asm/uv/uv_hub.h | 4 +- trunk/arch/x86/kernel/dumpstack.c | 3 +- trunk/arch/x86/kernel/dumpstack_64.c | 8 +- trunk/arch/x86/kernel/microcode_amd.c | 24 +- trunk/arch/x86/kernel/reboot.c | 36 +- trunk/arch/x86/kvm/emulate.c | 51 - trunk/arch/x86/kvm/x86.c | 45 - trunk/arch/x86/mm/fault.c | 4 +- trunk/arch/x86/net/bpf_jit_comp.c | 36 +- trunk/arch/x86/platform/uv/tlb_uv.c | 2 - trunk/arch/x86/platform/uv/uv_irq.c | 2 +- trunk/arch/x86/xen/spinlock.c | 27 +- trunk/arch/xtensa/include/asm/string.h | 3 + trunk/crypto/sha512_generic.c | 62 +- trunk/drivers/acpi/Makefile | 1 + trunk/drivers/acpi/apei/apei-base.c | 35 +- trunk/drivers/acpi/apei/einj.c | 95 +- trunk/drivers/acpi/atomicio.c | 422 +++ trunk/drivers/acpi/osl.c | 152 +- trunk/drivers/acpi/processor_driver.c | 154 +- trunk/drivers/acpi/sleep.c | 8 - trunk/drivers/base/Makefile | 2 +- trunk/drivers/base/core.c | 17 +- trunk/drivers/base/regmap/regmap.c | 3 - trunk/drivers/base/sys.c | 383 +++ trunk/drivers/block/rbd.c | 7 +- trunk/drivers/char/agp/backend.c | 12 +- trunk/drivers/dma/at_hdmac.c | 4 +- trunk/drivers/dma/at_hdmac_regs.h | 17 +- trunk/drivers/dma/dmatest.c | 2 +- trunk/drivers/dma/imx-sdma.c | 6 +- trunk/drivers/dma/shdma.c | 3 +- trunk/drivers/firewire/ohci.c | 6 +- trunk/drivers/gpio/gpio-lpc32xx.c | 2 +- trunk/drivers/gpio/gpio-ml-ioh.c | 1 - trunk/drivers/gpio/gpio-pch.c | 1 - trunk/drivers/gpio/gpio-samsung.c | 23 +- trunk/drivers/gpu/drm/drm_auth.c | 6 +- trunk/drivers/gpu/drm/drm_fops.c | 5 - trunk/drivers/gpu/drm/drm_gem.c | 2 +- trunk/drivers/gpu/drm/exynos/Kconfig | 4 +- .../drivers/gpu/drm/exynos/exynos_drm_fimd.c | 109 +- trunk/drivers/gpu/drm/exynos/exynos_hdmi.c | 8 +- trunk/drivers/gpu/drm/gma500/framebuffer.c | 8 +- trunk/drivers/gpu/drm/gma500/gtt.c | 5 +- trunk/drivers/gpu/drm/i810/i810_dma.c | 17 +- trunk/drivers/gpu/drm/i810/i810_drv.c | 1 - trunk/drivers/gpu/drm/i810/i810_drv.h | 6 +- trunk/drivers/gpu/drm/i915/i915_debugfs.c | 31 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 1 - trunk/drivers/gpu/drm/i915/i915_drv.c | 56 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 10 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 3 +- trunk/drivers/gpu/drm/i915/i915_suspend.c | 11 +- trunk/drivers/gpu/drm/i915/intel_bios.h | 6 +- trunk/drivers/gpu/drm/i915/intel_crt.c | 23 - trunk/drivers/gpu/drm/i915/intel_display.c | 22 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 8 - trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 41 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 8 +- trunk/drivers/gpu/drm/i915/intel_sprite.c | 8 +- trunk/drivers/gpu/drm/i915/intel_tv.c | 138 +- trunk/drivers/gpu/drm/nouveau/nouveau_bios.h | 5 +- trunk/drivers/gpu/drm/nouveau/nouveau_bo.c | 4 - .../drivers/gpu/drm/nouveau/nouveau_display.c | 10 - trunk/drivers/gpu/drm/nouveau/nouveau_drv.c | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_gem.c | 23 +- trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c | 9 - trunk/drivers/gpu/drm/nouveau/nv50_pm.c | 4 +- trunk/drivers/gpu/drm/radeon/atombios_crtc.c | 64 +- trunk/drivers/gpu/drm/radeon/atombios_dp.c | 40 +- .../gpu/drm/radeon/atombios_encoders.c | 89 +- trunk/drivers/gpu/drm/radeon/evergreen.c | 1 - trunk/drivers/gpu/drm/radeon/evergreend.h | 1 - trunk/drivers/gpu/drm/radeon/ni.c | 1 - trunk/drivers/gpu/drm/radeon/nid.h | 1 - trunk/drivers/gpu/drm/radeon/r600_blit_kms.c | 35 +- trunk/drivers/gpu/drm/radeon/radeon.h | 84 +- .../gpu/drm/radeon/radeon_atpx_handler.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_bios.c | 2 +- trunk/drivers/gpu/drm/radeon/radeon_device.c | 12 +- trunk/drivers/gpu/drm/radeon/radeon_display.c | 6 +- .../drivers/gpu/drm/radeon/radeon_encoders.c | 77 - trunk/drivers/gpu/drm/radeon/radeon_i2c.c | 2 - trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c | 6 - trunk/drivers/gpu/drm/radeon/radeon_mode.h | 8 - trunk/drivers/gpu/drm/radeon/radeon_ring.c | 37 +- trunk/drivers/gpu/drm/sis/sis_drv.c | 3 +- trunk/drivers/gpu/drm/ttm/ttm_bo.c | 17 +- trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- trunk/drivers/hid/hid-hyperv.c | 1 - trunk/drivers/hid/hid-wacom.c | 7 +- trunk/drivers/hid/hid-wiimote-core.c | 4 +- trunk/drivers/hid/usbhid/hiddev.c | 4 +- trunk/drivers/hwmon/f71805f.c | 10 +- trunk/drivers/hwmon/sht15.c | 3 +- trunk/drivers/hwmon/w83627ehf.c | 29 +- trunk/drivers/i2c/busses/i2c-omap.c | 2 +- trunk/drivers/idle/intel_idle.c | 2 +- trunk/drivers/infiniband/core/ucma.c | 5 +- trunk/drivers/infiniband/core/uverbs_cmd.c | 1 - trunk/drivers/infiniband/core/verbs.c | 2 +- trunk/drivers/infiniband/hw/ipath/ipath_fs.c | 2 +- trunk/drivers/infiniband/hw/mlx4/mad.c | 7 +- trunk/drivers/infiniband/hw/nes/nes.c | 2 +- trunk/drivers/infiniband/hw/nes/nes.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_cm.c | 10 +- trunk/drivers/infiniband/hw/nes/nes_cm.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_context.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_hw.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_hw.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_mgt.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_mgt.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_nic.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_user.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_utils.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_verbs.c | 6 +- trunk/drivers/infiniband/hw/nes/nes_verbs.h | 2 +- trunk/drivers/infiniband/hw/qib/qib_iba6120.c | 2 +- trunk/drivers/infiniband/hw/qib/qib_pcie.c | 2 +- trunk/drivers/input/evdev.c | 2 +- trunk/drivers/input/keyboard/twl4030_keypad.c | 4 +- trunk/drivers/input/serio/i8042-x86ia64io.h | 7 - trunk/drivers/input/serio/serio_raw.c | 15 +- trunk/drivers/media/dvb/dvb-usb/anysee.c | 11 +- .../drivers/media/dvb/dvb-usb/cinergyT2-fe.c | 7 +- trunk/drivers/media/dvb/frontends/cxd2820r.h | 6 +- .../media/dvb/frontends/cxd2820r_core.c | 20 +- trunk/drivers/media/video/atmel-isi.c | 14 - trunk/drivers/media/video/em28xx/em28xx-dvb.c | 3 +- trunk/drivers/mfd/mcp-core.c | 61 +- trunk/drivers/mfd/mcp-sa11x0.c | 169 +- trunk/drivers/mfd/twl6040-core.c | 128 +- trunk/drivers/mfd/ucb1x00-core.c | 67 +- trunk/drivers/mfd/ucb1x00-ts.c | 34 +- trunk/drivers/misc/lkdtm.c | 6 +- trunk/drivers/mtd/mtdcore.c | 2 +- trunk/drivers/mtd/nand/atmel_nand.c | 45 +- trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 18 +- trunk/drivers/mtd/nand/nand_base.c | 2 +- trunk/drivers/net/bonding/bond_alb.c | 27 +- trunk/drivers/net/dsa/mv88e6060.c | 1 - trunk/drivers/net/dsa/mv88e6123_61_65.c | 22 +- trunk/drivers/net/dsa/mv88e6131.c | 1 - trunk/drivers/net/dsa/mv88e6xxx.c | 1 - .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 111 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 11 +- .../net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 44 +- .../net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 11 - trunk/drivers/net/ethernet/broadcom/tg3.c | 9 +- trunk/drivers/net/ethernet/cisco/enic/enic.h | 2 +- .../net/ethernet/cisco/enic/enic_main.c | 38 +- .../net/ethernet/emulex/benet/be_main.c | 3 +- .../drivers/net/ethernet/faraday/ftgmac100.c | 1 - trunk/drivers/net/ethernet/faraday/ftmac100.c | 1 - trunk/drivers/net/ethernet/intel/igb/Makefile | 2 +- .../net/ethernet/intel/igb/e1000_82575.c | 2 +- .../net/ethernet/intel/igb/e1000_82575.h | 2 +- .../net/ethernet/intel/igb/e1000_defines.h | 2 +- .../drivers/net/ethernet/intel/igb/e1000_hw.h | 2 +- .../net/ethernet/intel/igb/e1000_mac.c | 4 +- .../net/ethernet/intel/igb/e1000_mac.h | 2 +- .../net/ethernet/intel/igb/e1000_mbx.c | 2 +- .../net/ethernet/intel/igb/e1000_mbx.h | 2 +- .../net/ethernet/intel/igb/e1000_nvm.c | 2 +- .../net/ethernet/intel/igb/e1000_nvm.h | 2 +- .../net/ethernet/intel/igb/e1000_phy.c | 2 +- .../net/ethernet/intel/igb/e1000_phy.h | 2 +- .../net/ethernet/intel/igb/e1000_regs.h | 2 +- trunk/drivers/net/ethernet/intel/igb/igb.h | 2 +- .../net/ethernet/intel/igb/igb_ethtool.c | 2 +- .../drivers/net/ethernet/intel/igb/igb_main.c | 10 +- .../net/ethernet/intel/igbvf/ethtool.c | 3 +- .../drivers/net/ethernet/intel/igbvf/netdev.c | 5 + .../net/ethernet/intel/ixgbe/ixgbe_type.h | 32 +- .../net/ethernet/intel/ixgbevf/ethtool.c | 5 +- .../net/ethernet/intel/ixgbevf/ixgbevf.h | 8 +- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 41 +- .../drivers/net/ethernet/intel/ixgbevf/mbx.c | 3 +- trunk/drivers/net/ethernet/intel/ixgbevf/vf.c | 7 +- trunk/drivers/net/ethernet/intel/ixgbevf/vf.h | 2 +- .../net/ethernet/marvell/mv643xx_eth.c | 14 - trunk/drivers/net/ethernet/marvell/skge.c | 109 +- .../drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 +- trunk/drivers/net/ethernet/mellanox/mlx4/cq.c | 4 +- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 159 +- .../net/ethernet/mellanox/mlx4/en_main.c | 6 +- .../net/ethernet/mellanox/mlx4/en_netdev.c | 38 +- .../net/ethernet/mellanox/mlx4/en_rx.c | 8 +- trunk/drivers/net/ethernet/mellanox/mlx4/eq.c | 21 +- trunk/drivers/net/ethernet/mellanox/mlx4/fw.c | 7 + trunk/drivers/net/ethernet/mellanox/mlx4/fw.h | 1 + .../drivers/net/ethernet/mellanox/mlx4/main.c | 3 +- .../drivers/net/ethernet/mellanox/mlx4/mlx4.h | 8 +- .../net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +- trunk/drivers/net/ethernet/mellanox/mlx4/mr.c | 2 +- trunk/drivers/net/ethernet/mellanox/mlx4/pd.c | 3 +- .../drivers/net/ethernet/mellanox/mlx4/port.c | 23 - .../net/ethernet/mellanox/mlx4/profile.c | 2 +- trunk/drivers/net/ethernet/mellanox/mlx4/qp.c | 2 +- .../ethernet/mellanox/mlx4/resource_tracker.c | 39 +- .../drivers/net/ethernet/mellanox/mlx4/srq.c | 2 +- .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 17 +- .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 2 +- .../net/ethernet/stmicro/stmmac/stmmac_pci.c | 6 +- trunk/drivers/net/hyperv/netvsc_drv.c | 5 +- trunk/drivers/net/macvlan.c | 1 - trunk/drivers/net/phy/mdio_bus.c | 5 +- trunk/drivers/net/team/team.c | 136 +- trunk/drivers/net/wireless/b43/Kconfig | 6 - trunk/drivers/net/wireless/b43/main.c | 2 - .../net/wireless/brcm80211/brcmsmac/main.c | 10 +- .../net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 4 +- trunk/drivers/net/xen-netfront.c | 2 +- trunk/drivers/pcmcia/sa1111_generic.c | 3 +- trunk/drivers/pinctrl/core.c | 50 +- trunk/drivers/pinctrl/core.h | 3 - trunk/drivers/pinctrl/pinconf.c | 6 +- trunk/drivers/pinctrl/pinconf.h | 4 +- trunk/drivers/pinctrl/pinmux.c | 81 +- trunk/drivers/pinctrl/pinmux.h | 4 +- trunk/drivers/regulator/core.c | 3 +- trunk/drivers/regulator/of_regulator.c | 2 +- trunk/drivers/rtc/Kconfig | 2 +- trunk/drivers/rtc/rtc-sa1100.c | 295 ++- trunk/drivers/s390/block/dasd.c | 6 - trunk/drivers/s390/block/dasd_alias.c | 64 +- trunk/drivers/s390/block/dasd_eckd.c | 63 +- trunk/drivers/s390/block/dasd_int.h | 2 - trunk/drivers/scsi/mac_esp.c | 3 +- trunk/drivers/scsi/mac_scsi.c | 6 + .../drivers/staging/media/go7007/go7007-usb.c | 1 - trunk/drivers/thermal/thermal_sys.c | 4 +- trunk/drivers/tty/serial/{8250 => }/8250.c | 0 trunk/drivers/tty/serial/{8250 => }/8250.h | 0 trunk/drivers/tty/serial/8250/Kconfig | 280 -- trunk/drivers/tty/serial/8250/Makefile | 20 - .../tty/serial/{8250 => }/8250_accent.c | 0 .../tty/serial/{8250 => }/8250_acorn.c | 0 .../drivers/tty/serial/{8250 => }/8250_boca.c | 0 trunk/drivers/tty/serial/{8250 => }/8250_dw.c | 0 .../tty/serial/{8250 => }/8250_early.c | 0 .../serial/{8250 => }/8250_exar_st16c554.c | 0 .../tty/serial/{8250 => }/8250_fourport.c | 0 .../drivers/tty/serial/{8250 => }/8250_fsl.c | 0 .../drivers/tty/serial/{8250 => }/8250_gsc.c | 0 .../tty/serial/{8250 => }/8250_hp300.c | 0 .../drivers/tty/serial/{8250 => }/8250_hub6.c | 0 .../drivers/tty/serial/{8250 => }/8250_mca.c | 0 .../drivers/tty/serial/{8250 => }/8250_pci.c | 0 .../drivers/tty/serial/{8250 => }/8250_pnp.c | 0 trunk/drivers/tty/serial/Kconfig | 283 +- trunk/drivers/tty/serial/Makefile | 20 +- trunk/drivers/tty/serial/amba-pl011.c | 30 +- trunk/drivers/tty/serial/jsm/jsm_driver.c | 1 - .../drivers/tty/serial/{8250 => }/m32r_sio.c | 0 .../drivers/tty/serial/{8250 => }/m32r_sio.h | 0 .../tty/serial/{8250 => }/m32r_sio_reg.h | 0 trunk/drivers/tty/serial/max3107-aava.c | 344 +++ trunk/drivers/tty/serial/omap-serial.c | 4 +- trunk/drivers/tty/serial/serial_core.c | 6 +- .../drivers/tty/serial/{8250 => }/serial_cs.c | 0 trunk/drivers/tty/tty_port.c | 12 +- trunk/drivers/tty/vt/vt_ioctl.c | 1 + trunk/drivers/usb/class/cdc-wdm.c | 59 +- trunk/drivers/usb/dwc3/ep0.c | 15 +- trunk/drivers/usb/dwc3/gadget.c | 2 +- trunk/drivers/usb/gadget/composite.c | 7 +- trunk/drivers/usb/gadget/epautoconf.c | 2 +- trunk/drivers/usb/gadget/f_mass_storage.c | 10 +- trunk/drivers/usb/gadget/fsl_udc_core.c | 4 +- trunk/drivers/usb/gadget/langwell_udc.c | 107 +- trunk/drivers/usb/gadget/langwell_udc.h | 1 + trunk/drivers/usb/gadget/storage_common.c | 6 +- trunk/drivers/usb/host/ehci-fsl.c | 2 +- trunk/drivers/usb/host/ehci-pci.c | 6 - trunk/drivers/usb/host/ohci-at91.c | 24 +- trunk/drivers/usb/host/ohci-dbg.c | 12 +- trunk/drivers/usb/host/ohci-pci.c | 4 - trunk/drivers/usb/host/xhci-ring.c | 6 +- trunk/drivers/usb/misc/emi26.c | 3 + trunk/drivers/usb/misc/emi62.c | 3 + trunk/drivers/usb/misc/usbsevseg.c | 2 +- trunk/drivers/usb/musb/davinci.c | 3 + trunk/drivers/usb/musb/musb_core.c | 5 +- trunk/drivers/usb/musb/omap2430.c | 4 +- trunk/drivers/usb/otg/Kconfig | 18 +- trunk/drivers/usb/otg/Makefile | 1 + trunk/drivers/usb/otg/langwell_otg.c | 2347 +++++++++++++++++ trunk/drivers/usb/otg/mv_otg.c | 2 - trunk/drivers/usb/renesas_usbhs/mod_gadget.c | 2 +- trunk/drivers/usb/serial/cp210x.c | 105 +- trunk/drivers/usb/serial/ftdi_sio.c | 14 +- trunk/drivers/usb/serial/ftdi_sio_ids.h | 19 - trunk/drivers/usb/serial/io_ti.c | 10 +- trunk/drivers/usb/serial/kobil_sct.c | 2 +- trunk/drivers/usb/serial/option.c | 5 - trunk/drivers/usb/serial/qcaux.c | 7 +- trunk/drivers/usb/storage/realtek_cr.c | 2 +- trunk/drivers/usb/usb-skeleton.c | 18 +- trunk/drivers/usb/wusbcore/Kconfig | 2 +- trunk/drivers/video/macfb.c | 60 +- trunk/drivers/virtio/virtio_ring.c | 8 +- trunk/drivers/watchdog/dw_wdt.c | 6 +- trunk/drivers/watchdog/iTCO_wdt.c | 35 - trunk/drivers/watchdog/imx2_wdt.c | 11 +- trunk/drivers/watchdog/nuc900_wdt.c | 5 +- trunk/drivers/watchdog/omap_wdt.c | 2 - trunk/drivers/watchdog/pnx4008_wdt.c | 2 +- trunk/drivers/watchdog/stmp3xxx_wdt.c | 2 +- trunk/drivers/watchdog/via_wdt.c | 6 +- trunk/drivers/watchdog/wafer5823wdt.c | 4 +- trunk/drivers/watchdog/wm8350_wdt.c | 4 +- trunk/drivers/xen/grant-table.c | 7 +- trunk/fs/btrfs/backref.c | 4 +- trunk/fs/btrfs/check-integrity.c | 11 +- trunk/fs/btrfs/disk-io.c | 7 - trunk/fs/btrfs/extent-tree.c | 49 +- trunk/fs/btrfs/extent_io.c | 2 - trunk/fs/btrfs/free-space-cache.c | 5 +- trunk/fs/btrfs/inode.c | 10 +- trunk/fs/btrfs/ioctl.c | 2 +- trunk/fs/btrfs/tree-log.c | 6 +- trunk/fs/ceph/caps.c | 4 +- trunk/fs/ceph/dir.c | 4 +- trunk/fs/ceph/mds_client.c | 10 +- trunk/fs/ceph/mds_client.h | 7 +- trunk/fs/ceph/xattr.c | 4 +- trunk/fs/cifs/connect.c | 6 +- trunk/fs/ecryptfs/crypto.c | 54 +- trunk/fs/ecryptfs/ecryptfs_kernel.h | 5 - trunk/fs/ecryptfs/inode.c | 48 +- trunk/fs/ecryptfs/keystore.c | 5 +- trunk/fs/ecryptfs/miscdev.c | 140 +- trunk/fs/ecryptfs/mmap.c | 8 +- trunk/fs/ecryptfs/read_write.c | 96 +- trunk/fs/exec.c | 33 +- trunk/fs/ext2/ioctl.c | 22 +- trunk/fs/jbd/checkpoint.c | 27 +- trunk/fs/jbd/recovery.c | 4 - trunk/fs/jffs2/erase.c | 2 +- trunk/fs/logfs/dev_mtd.c | 6 + trunk/fs/logfs/dir.c | 2 +- trunk/fs/logfs/file.c | 2 - trunk/fs/logfs/gc.c | 2 +- trunk/fs/logfs/inode.c | 4 +- trunk/fs/logfs/journal.c | 1 + trunk/fs/logfs/logfs.h | 5 +- trunk/fs/logfs/readwrite.c | 51 +- trunk/fs/logfs/segment.c | 51 +- trunk/fs/logfs/super.c | 3 +- trunk/fs/proc/base.c | 126 +- trunk/fs/quota/dquot.c | 8 +- trunk/fs/sysfs/file.c | 6 - trunk/fs/sysfs/inode.c | 5 +- trunk/fs/xfs/xfs_vnodeops.c | 3 +- trunk/include/acpi/acpiosxf.h | 4 - trunk/include/acpi/atomicio.h | 10 + trunk/include/acpi/processor.h | 1 - trunk/include/drm/drmP.h | 1 - trunk/include/linux/binfmts.h | 3 +- trunk/include/linux/freezer.h | 2 - trunk/include/linux/gpio_keys.h | 2 - trunk/include/linux/if_team.h | 10 - trunk/include/linux/lp8727.h | 0 trunk/include/linux/mfd/mcp.h | 12 +- trunk/include/linux/mfd/twl6040.h | 2 - trunk/include/linux/mfd/ucb1x00.h | 5 +- trunk/include/linux/mlx4/device.h | 1 - trunk/include/linux/mod_devicetable.h | 11 + trunk/include/linux/mpi.h | 2 + trunk/include/linux/mtd/mtd.h | 6 +- trunk/include/linux/perf_event.h | 1 - trunk/include/linux/pm_qos.h | 14 +- trunk/include/linux/quota.h | 6 +- trunk/include/linux/res_counter.h | 11 +- trunk/include/linux/sched.h | 8 +- trunk/include/linux/sh_dma.h | 1 - trunk/include/linux/snmp.h | 1 + trunk/include/linux/sysdev.h | 164 ++ trunk/include/linux/thermal.h | 4 +- trunk/include/linux/usb/langwell_otg.h | 139 + trunk/include/net/bluetooth/hci.h | 2 +- trunk/include/net/netns/generic.h | 1 - trunk/include/net/netprio_cgroup.h | 1 + trunk/include/net/sock.h | 14 +- trunk/include/net/tcp.h | 2 - trunk/include/sound/core.h | 2 - trunk/kernel/events/callchain.c | 2 + trunk/kernel/events/core.c | 106 +- trunk/kernel/exit.c | 16 - trunk/kernel/fork.c | 20 - trunk/kernel/kprobes.c | 6 +- trunk/kernel/power/power.h | 24 +- trunk/kernel/power/process.c | 26 +- trunk/kernel/power/user.c | 15 +- trunk/kernel/rcutorture.c | 8 +- trunk/kernel/res_counter.c | 25 - trunk/kernel/sched/core.c | 19 +- trunk/kernel/sched/fair.c | 34 +- trunk/kernel/sched/rt.c | 5 - trunk/kernel/watchdog.c | 2 +- trunk/lib/Kconfig | 4 - trunk/lib/Makefile | 2 - trunk/lib/bug.c | 2 +- trunk/lib/clz_tab.c | 18 - trunk/lib/digsig.c | 52 +- trunk/lib/mpi/longlong.h | 44 +- trunk/lib/mpi/mpi-bit.c | 19 + trunk/lib/mpi/mpi-div.c | 5 - trunk/lib/mpi/mpi-pow.c | 2 +- trunk/lib/mpi/mpicoder.c | 91 +- trunk/lib/mpi/mpih-div.c | 4 - trunk/lib/mpi/mpiutil.c | 5 +- trunk/mm/compaction.c | 13 - trunk/mm/filemap.c | 8 +- trunk/mm/filemap_xip.c | 7 +- trunk/mm/kmemleak.c | 3 +- trunk/mm/memblock.c | 7 +- trunk/mm/memcontrol.c | 7 +- trunk/mm/migrate.c | 2 +- trunk/mm/process_vm_access.c | 23 +- trunk/net/bluetooth/hci_core.c | 2 +- trunk/net/caif/caif_dev.c | 22 +- trunk/net/caif/cfcnfg.c | 1 + trunk/net/ceph/ceph_common.c | 2 + trunk/net/ceph/mon_client.c | 13 +- trunk/net/core/ethtool.c | 1 - trunk/net/core/flow_dissector.c | 1 - trunk/net/core/net_namespace.c | 31 +- trunk/net/core/pktgen.c | 4 +- trunk/net/core/rtnetlink.c | 3 - trunk/net/core/sock.c | 4 +- trunk/net/ipv4/inet_connection_sock.c | 7 +- trunk/net/ipv4/ip_gre.c | 4 - trunk/net/ipv4/proc.c | 1 + trunk/net/ipv4/sysctl_net_ipv4.c | 1 - trunk/net/ipv4/tcp.c | 16 +- trunk/net/ipv4/tcp_bic.c | 11 +- trunk/net/ipv4/tcp_cubic.c | 10 +- trunk/net/ipv4/tcp_input.c | 41 +- trunk/net/ipv4/tcp_ipv4.c | 2 +- trunk/net/ipv4/tcp_output.c | 6 +- trunk/net/ipv6/addrconf.c | 61 +- trunk/net/ipv6/tcp_ipv6.c | 2 +- trunk/net/l2tp/l2tp_ip.c | 5 + trunk/net/llc/af_llc.c | 5 - trunk/net/mac80211/debugfs_key.c | 7 +- trunk/net/mac80211/ibss.c | 1 - trunk/net/mac80211/iface.c | 1 - trunk/net/mac80211/mesh_hwmp.c | 8 +- trunk/net/mac80211/mesh_plink.c | 4 +- trunk/net/mac80211/mlme.c | 38 +- trunk/net/rds/af_rds.c | 20 +- trunk/net/sched/sch_netem.c | 2 +- trunk/net/sunrpc/auth_generic.c | 17 +- trunk/net/unix/af_unix.c | 19 +- trunk/scripts/mod/file2alias.c | 10 + trunk/sound/core/compress_offload.c | 13 +- trunk/sound/pci/hda/alc880_quirks.c | 17 +- trunk/sound/pci/hda/alc882_quirks.c | 15 +- trunk/sound/pci/hda/hda_codec.c | 2 +- trunk/sound/pci/hda/hda_intel.c | 6 +- trunk/sound/pci/hda/hda_jack.c | 24 +- trunk/sound/pci/hda/patch_cirrus.c | 6 +- trunk/sound/pci/hda/patch_conexant.c | 2 +- trunk/sound/pci/hda/patch_realtek.c | 101 +- trunk/sound/pci/hda/patch_sigmatel.c | 19 +- trunk/sound/pci/hda/patch_via.c | 284 +- trunk/sound/pci/ymfpci/ymfpci.c | 21 +- trunk/sound/pci/ymfpci/ymfpci_main.c | 21 +- trunk/sound/soc/codecs/sgtl5000.c | 17 +- trunk/sound/soc/codecs/tlv320aic32x4.c | 110 +- trunk/sound/soc/codecs/wm2000.c | 31 +- trunk/sound/soc/codecs/wm5100.c | 15 +- trunk/sound/soc/codecs/wm8958-dsp2.c | 2 +- trunk/sound/soc/codecs/wm8962.c | 2 +- trunk/sound/soc/codecs/wm8996.c | 9 +- trunk/sound/soc/codecs/wm8996.h | 4 - trunk/sound/soc/codecs/wm_hubs.c | 10 +- trunk/sound/soc/mxs/mxs-saif.c | 5 - trunk/sound/soc/samsung/neo1973_wm8753.c | 65 +- trunk/tools/perf/Makefile | 7 +- trunk/tools/perf/builtin-probe.c | 2 + trunk/tools/perf/builtin-top.c | 13 +- trunk/tools/perf/util/header.c | 2 +- trunk/tools/perf/util/probe-event.c | 2 + trunk/tools/perf/util/symbol.c | 1 + trunk/tools/perf/util/trace-event-parse.c | 3 +- trunk/tools/perf/util/ui/browsers/hists.c | 2 + trunk/tools/perf/util/ui/helpline.c | 1 + trunk/tools/perf/util/util.h | 1 + trunk/virt/kvm/kvm_main.c | 2 +- 658 files changed, 9380 insertions(+), 5593 deletions(-) delete mode 100644 trunk/arch/arm/mach-at91/at91sam9g45_reset.S create mode 100644 trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h create mode 100644 trunk/drivers/acpi/atomicio.c create mode 100644 trunk/drivers/base/sys.c rename trunk/drivers/tty/serial/{8250 => }/8250.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250.h (100%) delete mode 100644 trunk/drivers/tty/serial/8250/Kconfig delete mode 100644 trunk/drivers/tty/serial/8250/Makefile rename trunk/drivers/tty/serial/{8250 => }/8250_accent.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_acorn.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_boca.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_dw.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_early.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_exar_st16c554.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_fourport.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_fsl.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_gsc.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_hp300.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_hub6.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_mca.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_pci.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_pnp.c (100%) rename trunk/drivers/tty/serial/{8250 => }/m32r_sio.c (100%) rename trunk/drivers/tty/serial/{8250 => }/m32r_sio.h (100%) rename trunk/drivers/tty/serial/{8250 => }/m32r_sio_reg.h (100%) create mode 100644 trunk/drivers/tty/serial/max3107-aava.c rename trunk/drivers/tty/serial/{8250 => }/serial_cs.c (100%) create mode 100644 trunk/drivers/usb/otg/langwell_otg.c create mode 100644 trunk/include/acpi/atomicio.h mode change 100644 => 100755 trunk/include/linux/lp8727.h create mode 100644 trunk/include/linux/sysdev.h create mode 100644 trunk/include/linux/usb/langwell_otg.h delete mode 100644 trunk/lib/clz_tab.c diff --git a/[refs] b/[refs] index 6ad14685f2b9..938830a2ce64 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e25c173379d1053f0851fa924cd608fc0b16252f +refs/heads/master: 803ab977618eae2b292cda0a97eed75f42250ddf diff --git a/trunk/Documentation/DocBook/device-drivers.tmpl b/trunk/Documentation/DocBook/device-drivers.tmpl index 9c27e5125dd2..2f7fd4360848 100644 --- a/trunk/Documentation/DocBook/device-drivers.tmpl +++ b/trunk/Documentation/DocBook/device-drivers.tmpl @@ -102,12 +102,9 @@ X!Iinclude/linux/kobject.h !Iinclude/linux/device.h Device Drivers Base -!Idrivers/base/init.c !Edrivers/base/driver.c !Edrivers/base/core.c -!Edrivers/base/syscore.c !Edrivers/base/class.c -!Idrivers/base/node.c !Edrivers/base/firmware_class.c !Edrivers/base/transport_class.c -!Edrivers/base/dd.c +!Edrivers/base/sys.c !Iinclude/linux/platform_device.h !Edrivers/base/platform.c !Edrivers/base/bus.c - - Device Drivers DMA Management -!Edrivers/base/dma-buf.c -!Edrivers/base/dma-coherent.c -!Edrivers/base/dma-mapping.c Device Drivers Power Management !Edrivers/base/power/main.c @@ -227,7 +219,7 @@ X!Isound/sound_firmware.c 16x50 UART Driver !Edrivers/tty/serial/serial_core.c -!Edrivers/tty/serial/8250/8250.c +!Edrivers/tty/serial/8250.c diff --git a/trunk/Documentation/driver-model/devres.txt b/trunk/Documentation/driver-model/devres.txt index 41c0c5d1ba14..10c64c8a13d4 100644 --- a/trunk/Documentation/driver-model/devres.txt +++ b/trunk/Documentation/driver-model/devres.txt @@ -233,10 +233,6 @@ certainly invest a bit more effort into libata core layer). 6. List of managed interfaces ----------------------------- -MEM - devm_kzalloc() - devm_kfree() - IO region devm_request_region() devm_request_mem_region() diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index a0ffac029a0d..1bea46a54b1c 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -510,17 +510,3 @@ Why: The pci_scan_bus_parented() interface creates a new root bus. The convert to using pci_scan_root_bus() so they can supply a list of bus resources when the bus is created. Who: Bjorn Helgaas - ----------------------------- - -What: The CAP9 SoC family will be removed -When: 3.4 -Files: arch/arm/mach-at91/at91cap9.c - arch/arm/mach-at91/at91cap9_devices.c - arch/arm/mach-at91/include/mach/at91cap9.h - arch/arm/mach-at91/include/mach/at91cap9_matrix.h - arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h - arch/arm/mach-at91/board-cap9adk.c -Why: The code is not actively maintained and platforms are now hard to find. -Who: Nicolas Ferre - Jean-Christophe PLAGNIOL-VILLARD diff --git a/trunk/Documentation/input/event-codes.txt b/trunk/Documentation/input/event-codes.txt index 53305bd08182..23fcb05175be 100644 --- a/trunk/Documentation/input/event-codes.txt +++ b/trunk/Documentation/input/event-codes.txt @@ -17,11 +17,11 @@ reports supported by a device are also provided by sysfs in class/input/event*/device/capabilities/, and the properties of a device are provided in class/input/event*/device/properties. -Event types: -=========== -Event types are groupings of codes under a logical input construct. Each -type has a set of applicable codes to be used in generating events. See the -Codes section for details on valid codes for each type. +Types: +========== +Types are groupings of codes under a logical input construct. Each type has a +set of applicable codes to be used in generating events. See the Codes section +for details on valid codes for each type. * EV_SYN: - Used as markers to separate events. Events may be separated in time or in @@ -63,9 +63,9 @@ Codes section for details on valid codes for each type. * EV_FF_STATUS: - Used to receive force feedback device status. -Event codes: -=========== -Event codes define the precise type of event. +Codes: +========== +Codes define the precise type of event. EV_SYN: ---------- @@ -220,56 +220,6 @@ EV_PWR: EV_PWR events are a special type of event used specifically for power mangement. Its usage is not well defined. To be addressed later. -Device properties: -================= -Normally, userspace sets up an input device based on the data it emits, -i.e., the event types. In the case of two devices emitting the same event -types, additional information can be provided in the form of device -properties. - -INPUT_PROP_DIRECT + INPUT_PROP_POINTER: --------------------------------------- -The INPUT_PROP_DIRECT property indicates that device coordinates should be -directly mapped to screen coordinates (not taking into account trivial -transformations, such as scaling, flipping and rotating). Non-direct input -devices require non-trivial transformation, such as absolute to relative -transformation for touchpads. Typical direct input devices: touchscreens, -drawing tablets; non-direct devices: touchpads, mice. - -The INPUT_PROP_POINTER property indicates that the device is not transposed -on the screen and thus requires use of an on-screen pointer to trace user's -movements. Typical pointer devices: touchpads, tablets, mice; non-pointer -device: touchscreen. - -If neither INPUT_PROP_DIRECT or INPUT_PROP_POINTER are set, the property is -considered undefined and the device type should be deduced in the -traditional way, using emitted event types. - -INPUT_PROP_BUTTONPAD: --------------------- -For touchpads where the button is placed beneath the surface, such that -pressing down on the pad causes a button click, this property should be -set. Common in clickpad notebooks and macbooks from 2009 and onwards. - -Originally, the buttonpad property was coded into the bcm5974 driver -version field under the name integrated button. For backwards -compatibility, both methods need to be checked in userspace. - -INPUT_PROP_SEMI_MT: ------------------- -Some touchpads, most common between 2008 and 2011, can detect the presence -of multiple contacts without resolving the individual positions; only the -number of contacts and a rectangular shape is known. For such -touchpads, the semi-mt property should be set. - -Depending on the device, the rectangle may enclose all touches, like a -bounding box, or just some of them, for instance the two most recent -touches. The diversity makes the rectangle of limited use, but some -gestures can normally be extracted from it. - -If INPUT_PROP_SEMI_MT is not set, the device is assumed to be a true MT -device. - Guidelines: ========== The guidelines below ensure proper single-touch and multi-finger functionality. @@ -290,8 +240,6 @@ used to report when a touch is active on the screen. BTN_{MOUSE,LEFT,MIDDLE,RIGHT} must not be reported as the result of touch contact. BTN_TOOL_ events should be reported where possible. -For new hardware, INPUT_PROP_DIRECT should be set. - Trackpads: ---------- Legacy trackpads that only provide relative position information must report @@ -302,8 +250,6 @@ location of the touch. BTN_TOUCH should be used to report when a touch is active on the trackpad. Where multi-finger support is available, BTN_TOOL_ should be used to report the number of touches active on the trackpad. -For new hardware, INPUT_PROP_POINTER should be set. - Tablets: ---------- BTN_TOOL_ events must be reported when a stylus or other tool is active on @@ -314,5 +260,3 @@ button may be used for buttons on the tablet except BTN_{MOUSE,LEFT}. BTN_{0,1,2,etc} are good generic codes for unlabeled buttons. Do not use meaningful buttons, like BTN_FORWARD, unless the button is labeled for that purpose on the device. - -For new hardware, both INPUT_PROP_DIRECT and INPUT_PROP_POINTER should be set. diff --git a/trunk/Documentation/pinctrl.txt b/trunk/Documentation/pinctrl.txt index 150fd3833d0b..6727b92bc2fb 100644 --- a/trunk/Documentation/pinctrl.txt +++ b/trunk/Documentation/pinctrl.txt @@ -857,41 +857,42 @@ case), we define a mapping like this: ... { - .name = "2bit" + .name "2bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_1_grp", .dev_name = "foo-mmc.0", }, { - .name = "4bit" + .name "4bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_1_grp", .dev_name = "foo-mmc.0", }, { - .name = "4bit" + .name "4bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_2_grp", .dev_name = "foo-mmc.0", }, { - .name = "8bit" + .name "8bit" .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", .group = "mmc0_1_grp", .dev_name = "foo-mmc.0", }, { - .name = "8bit" + .name "8bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_2_grp", .dev_name = "foo-mmc.0", }, { - .name = "8bit" + .name "8bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_3_grp", @@ -994,7 +995,7 @@ This is enabled by simply setting the .hog_on_boot field in the map to true, like this: { - .name = "POWERMAP" + .name "POWERMAP" .ctrl_dev_name = "pinctrl-foo", .function = "power_func", .hog_on_boot = true, @@ -1024,7 +1025,7 @@ it, disables and releases it, and muxes it in on the pins defined by group B: foo_switch() { - struct pinmux *pmx; + struct pinmux pmx; /* Enable on position A */ pmx = pinmux_get(&device, "spi0-pos-A"); diff --git a/trunk/Documentation/stable_kernel_rules.txt b/trunk/Documentation/stable_kernel_rules.txt index f0ab5cf28fca..21fd05c28e73 100644 --- a/trunk/Documentation/stable_kernel_rules.txt +++ b/trunk/Documentation/stable_kernel_rules.txt @@ -25,8 +25,7 @@ Procedure for submitting patches to the -stable tree: - Send the patch, after verifying that it follows the above rules, to stable@vger.kernel.org. You must note the upstream commit ID in the - changelog of your submission, as well as the kernel version you wish - it to be applied to. + changelog of your submission. - To have the patch automatically included in the stable tree, add the tag Cc: stable@vger.kernel.org in the sign-off area. Once the patch is merged it will be applied to diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt index 6d78841fd416..8c20fbd8b42d 100644 --- a/trunk/Documentation/sysctl/kernel.txt +++ b/trunk/Documentation/sysctl/kernel.txt @@ -601,8 +601,6 @@ can be ORed together: instead of using the one provided by the hardware. 512 - A kernel warning has occurred. 1024 - A module from drivers/staging was loaded. -2048 - The system is working around a severe firmware bug. -4096 - An out-of-tree module has been loaded. ============================================================== diff --git a/trunk/Documentation/thermal/sysfs-api.txt b/trunk/Documentation/thermal/sysfs-api.txt index 1733ab947a95..b61e46f449aa 100644 --- a/trunk/Documentation/thermal/sysfs-api.txt +++ b/trunk/Documentation/thermal/sysfs-api.txt @@ -284,7 +284,7 @@ method, the sys I/F structure will be built like this: The framework includes a simple notification mechanism, in the form of a netlink event. Netlink socket initialization is done during the _init_ of the framework. Drivers which intend to use the notification mechanism -just need to call thermal_generate_netlink_event() with two arguments viz +just need to call generate_netlink_event() with two arguments viz (originator, event). Typically the originator will be an integer assigned to a thermal_zone_device when it registers itself with the framework. The event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL, diff --git a/trunk/Documentation/virtual/00-INDEX b/trunk/Documentation/virtual/00-INDEX index 924bd462675e..8e601991d91c 100644 --- a/trunk/Documentation/virtual/00-INDEX +++ b/trunk/Documentation/virtual/00-INDEX @@ -4,6 +4,8 @@ Virtualization support in the Linux kernel. - this file. kvm/ - Kernel Virtual Machine. See also http://linux-kvm.org +lguest/ + - Extremely simple hypervisor for experimental/educational use. uml/ - User Mode Linux, builds/runs Linux kernel as a userspace program. virtio.txt diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 55ca0bea142c..93c68d5f1cf4 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -159,7 +159,7 @@ S: Maintained F: drivers/net/ethernet/realtek/r8169.c 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: linux-serial@vger.kernel.org W: http://serial.sourceforge.net S: Maintained @@ -789,6 +789,12 @@ F: arch/arm/mach-mx*/ F: arch/arm/mach-imx/ F: arch/arm/plat-mxc/ +ARM/FREESCALE IMX51 +M: Amit Kucheria +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-mx5/ + ARM/FREESCALE IMX6 M: Shawn Guo L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -1777,9 +1783,9 @@ X: net/wireless/wext* CHAR and MISC DRIVERS M: Arnd Bergmann -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git -S: Supported +S: Maintained F: drivers/char/* F: drivers/misc/* @@ -2281,7 +2287,7 @@ F: drivers/acpi/dock.c DOCUMENTATION M: Randy Dunlap L: linux-doc@vger.kernel.org -T: quilt http://xenotime.net/kernel-doc-patches/current/ +T: quilt http://userweb.kernel.org/~rdunlap/kernel-doc-patches/current/ S: Maintained F: Documentation/ @@ -2314,7 +2320,7 @@ F: lib/lru_cache.c F: Documentation/blockdev/drbd/ DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git S: Supported F: Documentation/kobject.txt @@ -2344,9 +2350,6 @@ F: include/drm/i915* DRM DRIVERS FOR EXYNOS M: Inki Dae -M: Joonyoung Shim -M: Seung-Woo Kim -M: Kyungmin Park L: dri-devel@lists.freedesktop.org S: Supported F: drivers/gpu/drm/exynos @@ -2399,7 +2402,7 @@ F: net/bridge/netfilter/ebt*.c ECRYPT FILE SYSTEM M: Tyler Hicks -M: Dustin Kirkland +M: Dustin Kirkland L: ecryptfs@vger.kernel.org W: https://launchpad.net/ecryptfs S: Supported @@ -3986,11 +3989,11 @@ M: Rusty Russell L: lguest@lists.ozlabs.org W: http://lguest.ozlabs.org/ S: Odd Fixes -F: arch/x86/include/asm/lguest*.h +F: Documentation/virtual/lguest/ F: arch/x86/lguest/ F: drivers/lguest/ F: include/linux/lguest*.h -F: tools/lguest/ +F: arch/x86/include/asm/lguest*.h LINUX FOR IBM pSERIES (RS/6000) M: Paul Mackerras @@ -4130,11 +4133,10 @@ L: linux-ntfs-dev@lists.sourceforge.net W: http://www.linux-ntfs.org/content/view/19/37/ S: Maintained F: Documentation/ldm.txt -F: block/partitions/ldm.* +F: fs/partitions/ldm.* LogFS M: Joern Engel -M: Prasad Joshi L: logfs@logfs.org W: logfs.org S: Maintained @@ -4276,6 +4278,13 @@ S: Orphan F: drivers/video/matrox/matroxfb_* F: include/linux/matroxfb.h +MAX1668 TEMPERATURE SENSOR DRIVER +M: "David George" +L: lm-sensors@lm-sensors.org +S: Maintained +F: Documentation/hwmon/max1668 +F: drivers/hwmon/max1668.c + MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: "Hans J. Koch" L: lm-sensors@lm-sensors.org @@ -5627,7 +5636,7 @@ W: http://www.ibm.com/developerworks/linux/linux390/ S: Supported F: arch/s390/ F: drivers/s390/ -F: block/partitions/ibm.c +F: fs/partitions/ibm.c F: Documentation/s390/ F: Documentation/DocBook/s390* @@ -6270,15 +6279,15 @@ S: Maintained F: arch/alpha/kernel/srm_env.c STABLE BRANCH -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: stable@vger.kernel.org -S: Supported +S: Maintained STAGING SUBSYSTEM -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git L: devel@driverdev.osuosl.org -S: Supported +S: Maintained F: drivers/staging/ STAGING - AGERE HERMES II and II.5 WIRELESS DRIVERS @@ -6390,6 +6399,11 @@ M: Omar Ramirez Luna S: Odd Fixes F: drivers/staging/tidspbridge/ +STAGING - TRIDENT TVMASTER TMxxxx USB VIDEO CAPTURE DRIVERS +L: linux-media@vger.kernel.org +S: Odd Fixes +F: drivers/staging/tm6000/ + STAGING - USB ENE SM/MS CARD READER DRIVER M: Al Cho S: Odd Fixes @@ -6658,10 +6672,10 @@ S: Maintained K: ^Subject:.*(?i)trivial TTY LAYER -M: Greg Kroah-Hartman -S: Supported +M: Greg Kroah-Hartman +S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git -F: drivers/tty/ +F: drivers/tty/* F: drivers/tty/serial/serial_core.c F: include/linux/serial_core.h F: include/linux/serial.h @@ -6947,7 +6961,7 @@ S: Maintained F: drivers/usb/serial/digi_acceleport.c USB SERIAL DRIVER -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: linux-usb@vger.kernel.org S: Supported F: Documentation/usb/usb-serial.txt @@ -6962,8 +6976,9 @@ S: Maintained F: drivers/usb/serial/empeg.c USB SERIAL KEYSPAN DRIVER -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: linux-usb@vger.kernel.org +W: http://www.kroah.com/linux/ S: Maintained F: drivers/usb/serial/*keyspan* @@ -6991,7 +7006,7 @@ F: Documentation/video4linux/sn9c102.txt F: drivers/media/video/sn9c102/ USB SUBSYSTEM -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: linux-usb@vger.kernel.org W: http://www.linux-usb.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git @@ -7078,7 +7093,7 @@ F: fs/hppfs/ USERSPACE I/O (UIO) M: "Hans J. Koch" -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman S: Maintained F: Documentation/DocBook/uio-howto.tmpl F: drivers/uio/ @@ -7353,7 +7368,6 @@ S: Supported F: Documentation/hwmon/wm83?? F: arch/arm/mach-s3c64xx/mach-crag6410* F: drivers/leds/leds-wm83*.c -F: drivers/hwmon/wm83??-hwmon.c F: drivers/input/misc/wm831x-on.c F: drivers/input/touchscreen/wm831x-ts.c F: drivers/input/touchscreen/wm97*.c diff --git a/trunk/Makefile b/trunk/Makefile index e3b23e864a53..71e6ed21dd15 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 3 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc1 NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index a48aecc17eac..24626b0419ee 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -754,7 +754,7 @@ config ARCH_SA1100 select ARCH_HAS_CPUFREQ select CPU_FREQ select GENERIC_CLOCKEVENTS - select HAVE_CLK + select CLKDEV_LOOKUP select HAVE_SCHED_CLOCK select TICK_ONESHOT select ARCH_REQUIRE_GPIOLIB @@ -825,6 +825,7 @@ config ARCH_S5PC100 select HAVE_CLK select CLKDEV_LOOKUP select CPU_V7 + select ARM_L1_CACHE_SHIFT_6 select ARCH_USES_GETTIMEOFFSET select HAVE_S3C2410_I2C if I2C select HAVE_S3C_RTC if RTC_CLASS @@ -841,6 +842,7 @@ config ARCH_S5PV210 select HAVE_CLK select CLKDEV_LOOKUP select CLKSRC_MMIO + select ARM_L1_CACHE_SHIFT_6 select ARCH_HAS_CPUFREQ select GENERIC_CLOCKEVENTS select HAVE_SCHED_CLOCK diff --git a/trunk/arch/arm/common/gic.c b/trunk/arch/arm/common/gic.c index c47d6199b784..b2dc2dd7f1df 100644 --- a/trunk/arch/arm/common/gic.c +++ b/trunk/arch/arm/common/gic.c @@ -41,7 +41,6 @@ #include #include -#include #include #include @@ -353,7 +352,11 @@ static void __init gic_dist_init(struct gic_chip_data *gic) unsigned int gic_irqs = gic->gic_irqs; struct irq_domain *domain = &gic->domain; void __iomem *base = gic_data_dist_base(gic); - u32 cpu = cpu_logical_map(smp_processor_id()); + u32 cpu = 0; + +#ifdef CONFIG_SMP + cpu = cpu_logical_map(smp_processor_id()); +#endif cpumask = 1 << cpu; cpumask |= cpumask << 8; diff --git a/trunk/arch/arm/include/asm/assembler.h b/trunk/arch/arm/include/asm/assembler.h index 62f8095d46de..b6e65dedfd71 100644 --- a/trunk/arch/arm/include/asm/assembler.h +++ b/trunk/arch/arm/include/asm/assembler.h @@ -237,7 +237,7 @@ */ #ifdef CONFIG_THUMB2_KERNEL - .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER() + .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T() 9999: .if \inc == 1 \instr\cond\()b\()\t\().w \reg, [\ptr, #\off] @@ -277,7 +277,7 @@ #else /* !CONFIG_THUMB2_KERNEL */ - .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER() + .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T() .rept \rept 9999: .if \inc == 1 diff --git a/trunk/arch/arm/include/asm/domain.h b/trunk/arch/arm/include/asm/domain.h index b5dc173d336f..af18ceaacf5d 100644 --- a/trunk/arch/arm/include/asm/domain.h +++ b/trunk/arch/arm/include/asm/domain.h @@ -83,9 +83,9 @@ * instructions (inline assembly) */ #ifdef CONFIG_CPU_USE_DOMAINS -#define TUSER(instr) #instr "t" +#define T(instr) #instr "t" #else -#define TUSER(instr) #instr +#define T(instr) #instr #endif #else /* __ASSEMBLY__ */ @@ -95,9 +95,9 @@ * instructions */ #ifdef CONFIG_CPU_USE_DOMAINS -#define TUSER(instr) instr ## t +#define T(instr) instr ## t #else -#define TUSER(instr) instr +#define T(instr) instr #endif #endif /* __ASSEMBLY__ */ diff --git a/trunk/arch/arm/include/asm/futex.h b/trunk/arch/arm/include/asm/futex.h index 7be54690aeec..253cc86318bf 100644 --- a/trunk/arch/arm/include/asm/futex.h +++ b/trunk/arch/arm/include/asm/futex.h @@ -75,9 +75,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \ __asm__ __volatile__( \ - "1: " TUSER(ldr) " %1, [%3]\n" \ + "1: " T(ldr) " %1, [%3]\n" \ " " insn "\n" \ - "2: " TUSER(str) " %0, [%3]\n" \ + "2: " T(str) " %0, [%3]\n" \ " mov %0, #0\n" \ __futex_atomic_ex_table("%5") \ : "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \ @@ -95,10 +95,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" - "1: " TUSER(ldr) " %1, [%4]\n" + "1: " T(ldr) " %1, [%4]\n" " teq %1, %2\n" " it eq @ explicit IT needed for the 2b label\n" - "2: " TUSER(streq) " %3, [%4]\n" + "2: " T(streq) " %3, [%4]\n" __futex_atomic_ex_table("%5") : "+r" (ret), "=&r" (val) : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) diff --git a/trunk/arch/arm/include/asm/smp.h b/trunk/arch/arm/include/asm/smp.h index ae29293270a3..1e5717afc4ac 100644 --- a/trunk/arch/arm/include/asm/smp.h +++ b/trunk/arch/arm/include/asm/smp.h @@ -70,6 +70,12 @@ extern void platform_secondary_init(unsigned int cpu); */ extern void platform_smp_prepare_cpus(unsigned int); +/* + * Logical CPU mapping. + */ +extern int __cpu_logical_map[NR_CPUS]; +#define cpu_logical_map(cpu) __cpu_logical_map[cpu] + /* * Initial data for bringing up a secondary CPU. */ diff --git a/trunk/arch/arm/include/asm/smp_plat.h b/trunk/arch/arm/include/asm/smp_plat.h index 558d6c80aca9..f24c1b9e211d 100644 --- a/trunk/arch/arm/include/asm/smp_plat.h +++ b/trunk/arch/arm/include/asm/smp_plat.h @@ -43,10 +43,4 @@ static inline int cache_ops_need_broadcast(void) } #endif -/* - * Logical CPU mapping. - */ -extern int __cpu_logical_map[]; -#define cpu_logical_map(cpu) __cpu_logical_map[cpu] - #endif diff --git a/trunk/arch/arm/include/asm/tlb.h b/trunk/arch/arm/include/asm/tlb.h index 314d4664eae7..5d3ed7e38561 100644 --- a/trunk/arch/arm/include/asm/tlb.h +++ b/trunk/arch/arm/include/asm/tlb.h @@ -198,15 +198,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long addr) { pgtable_page_dtor(pte); - - /* - * With the classic ARM MMU, a pte page has two corresponding pmd - * entries, each covering 1MB. - */ - addr &= PMD_MASK; - tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE); - tlb_add_flush(tlb, addr + SZ_1M); - + tlb_add_flush(tlb, addr); tlb_remove_page(tlb, pte); } diff --git a/trunk/arch/arm/include/asm/uaccess.h b/trunk/arch/arm/include/asm/uaccess.h index 2958976d867b..b293616a1a1a 100644 --- a/trunk/arch/arm/include/asm/uaccess.h +++ b/trunk/arch/arm/include/asm/uaccess.h @@ -227,7 +227,7 @@ do { \ #define __get_user_asm_byte(x,addr,err) \ __asm__ __volatile__( \ - "1: " TUSER(ldrb) " %1,[%2],#0\n" \ + "1: " T(ldrb) " %1,[%2],#0\n" \ "2:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ @@ -263,7 +263,7 @@ do { \ #define __get_user_asm_word(x,addr,err) \ __asm__ __volatile__( \ - "1: " TUSER(ldr) " %1,[%2],#0\n" \ + "1: " T(ldr) " %1,[%2],#0\n" \ "2:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ @@ -308,7 +308,7 @@ do { \ #define __put_user_asm_byte(x,__pu_addr,err) \ __asm__ __volatile__( \ - "1: " TUSER(strb) " %1,[%2],#0\n" \ + "1: " T(strb) " %1,[%2],#0\n" \ "2:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ @@ -341,7 +341,7 @@ do { \ #define __put_user_asm_word(x,__pu_addr,err) \ __asm__ __volatile__( \ - "1: " TUSER(str) " %1,[%2],#0\n" \ + "1: " T(str) " %1,[%2],#0\n" \ "2:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ @@ -366,10 +366,10 @@ do { \ #define __put_user_asm_dword(x,__pu_addr,err) \ __asm__ __volatile__( \ - ARM( "1: " TUSER(str) " " __reg_oper1 ", [%1], #4\n" ) \ - ARM( "2: " TUSER(str) " " __reg_oper0 ", [%1]\n" ) \ - THUMB( "1: " TUSER(str) " " __reg_oper1 ", [%1]\n" ) \ - THUMB( "2: " TUSER(str) " " __reg_oper0 ", [%1, #4]\n" ) \ + ARM( "1: " T(str) " " __reg_oper1 ", [%1], #4\n" ) \ + ARM( "2: " T(str) " " __reg_oper0 ", [%1]\n" ) \ + THUMB( "1: " T(str) " " __reg_oper1 ", [%1]\n" ) \ + THUMB( "2: " T(str) " " __reg_oper0 ", [%1, #4]\n" ) \ "3:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index be16a48007b4..3a456c6c7005 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -790,7 +790,7 @@ __kuser_cmpxchg64: @ 0xffff0f60 smp_dmb arm rsbs r0, r3, #0 @ set returned val and C flag ldmfd sp!, {r4, r5, r6, r7} - usr_ret lr + bx lr #elif !defined(CONFIG_SMP) diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index 9fd0ba90c1d2..520889cf1b5b 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -149,11 +149,6 @@ ENDPROC(ret_from_fork) #endif #endif -.macro mcount_adjust_addr rd, rn - bic \rd, \rn, #1 @ clear the Thumb bit if present - sub \rd, \rd, #MCOUNT_INSN_SIZE -.endm - .macro __mcount suffix mcount_enter ldr r0, =ftrace_trace_function @@ -178,7 +173,8 @@ ENDPROC(ret_from_fork) mcount_exit 1: mcount_get_lr r1 @ lr of instrumented func - mcount_adjust_addr r0, lr @ instrumented function + mov r0, lr @ instrumented function + sub r0, r0, #MCOUNT_INSN_SIZE adr lr, BSYM(2f) mov pc, r2 2: mcount_exit @@ -188,7 +184,8 @@ ENDPROC(ret_from_fork) mcount_enter mcount_get_lr r1 @ lr of instrumented func - mcount_adjust_addr r0, lr @ instrumented function + mov r0, lr @ instrumented function + sub r0, r0, #MCOUNT_INSN_SIZE .globl ftrace_call\suffix ftrace_call\suffix: @@ -208,11 +205,11 @@ ftrace_graph_call\suffix: #ifdef CONFIG_DYNAMIC_FTRACE @ called from __ftrace_caller, saved in mcount_enter ldr r1, [sp, #16] @ instrumented routine (func) - mcount_adjust_addr r1, r1 #else @ called from __mcount, untouched in lr - mcount_adjust_addr r1, lr @ instrumented routine (func) + mov r1, lr @ instrumented routine (func) #endif + sub r1, r1, #MCOUNT_INSN_SIZE mov r2, fp @ frame pointer bl prepare_ftrace_return mcount_exit diff --git a/trunk/arch/arm/kernel/perf_event_v7.c b/trunk/arch/arm/kernel/perf_event_v7.c index 6933244c68f9..460bbbb6b885 100644 --- a/trunk/arch/arm/kernel/perf_event_v7.c +++ b/trunk/arch/arm/kernel/perf_event_v7.c @@ -469,20 +469,6 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, }, }, - [C(NODE)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - }, }; /* @@ -593,20 +579,6 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, }, }, - [C(NODE)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - }, }; /* diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index e33870ff0ac0..e1d5e1929fbd 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -699,13 +699,10 @@ static int vfp_set(struct task_struct *target, { int ret; struct thread_info *thread = task_thread_info(target); - struct vfp_hard_struct new_vfp; + struct vfp_hard_struct new_vfp = thread->vfpstate.hard; const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs); const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr); - vfp_sync_hwstate(thread); - new_vfp = thread->vfpstate.hard; - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &new_vfp.fpregs, user_fpregs_offset, @@ -726,8 +723,9 @@ static int vfp_set(struct task_struct *target, if (ret) return ret; - vfp_flush_hwstate(thread); + vfp_sync_hwstate(thread); thread->vfpstate.hard = new_vfp; + vfp_flush_hwstate(thread); return 0; } diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index a255c39612ca..129fbd55bde8 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -159,7 +160,7 @@ static struct resource mem_res[] = { .flags = IORESOURCE_MEM }, { - .name = "Kernel code", + .name = "Kernel text", .start = 0, .end = 0, .flags = IORESOURCE_MEM @@ -426,20 +427,6 @@ void cpu_init(void) : "r14"); } -int __cpu_logical_map[NR_CPUS]; - -void __init smp_setup_processor_id(void) -{ - int i; - u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; - - cpu_logical_map(0) = cpu; - for (i = 1; i < NR_CPUS; ++i) - cpu_logical_map(i) = i == cpu ? 0 : i; - - printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); -} - static void __init setup_processor(void) { struct proc_info_list *list; diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 9e617bd4a146..0340224cf73c 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -227,8 +227,6 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame) if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) return -EINVAL; - vfp_flush_hwstate(thread); - /* * Copy the floating point registers. There can be unused * registers see asm/hwcap.h for details. @@ -253,6 +251,9 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame) __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + if (!err) + vfp_flush_hwstate(thread); + return err ? -EFAULT : 0; } diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index cdeb727527d3..57db122a4f62 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -233,6 +233,20 @@ void __ref cpu_die(void) } #endif /* CONFIG_HOTPLUG_CPU */ +int __cpu_logical_map[NR_CPUS]; + +void __init smp_setup_processor_id(void) +{ + int i; + u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; + + cpu_logical_map(0) = cpu; + for (i = 1; i < NR_CPUS; ++i) + cpu_logical_map(i) = i == cpu ? 0 : i; + + printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); +} + /* * Called by both boot and secondaries to move global data into * per-processor storage. @@ -429,7 +443,9 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent); static void ipi_timer(void) { struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); + irq_enter(); evt->event_handler(evt); + irq_exit(); } #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST @@ -532,9 +548,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) switch (ipinr) { case IPI_TIMER: - irq_enter(); ipi_timer(); - irq_exit(); break; case IPI_RESCHEDULE: @@ -542,21 +556,15 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; case IPI_CALL_FUNC: - irq_enter(); generic_smp_call_function_interrupt(); - irq_exit(); break; case IPI_CALL_FUNC_SINGLE: - irq_enter(); generic_smp_call_function_single_interrupt(); - irq_exit(); break; case IPI_CPU_STOP: - irq_enter(); ipi_cpu_stop(cpu); - irq_exit(); break; default: diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c index 4285daa077b0..c8e938553d47 100644 --- a/trunk/arch/arm/kernel/smp_twd.c +++ b/trunk/arch/arm/kernel/smp_twd.c @@ -252,8 +252,6 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) else twd_calibrate_rate(); - __raw_writel(0, twd_base + TWD_TIMER_CONTROL); - clk->name = "local_timer"; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 1e19691e0406..f76e75548670 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -4,7 +4,6 @@ */ #include -#include #include #include #include @@ -182,7 +181,7 @@ SECTIONS } #endif - PERCPU_SECTION(L1_CACHE_BYTES) + PERCPU_SECTION(32) #ifdef CONFIG_XIP_KERNEL __data_loc = ALIGN(4); /* location in binary */ @@ -213,13 +212,13 @@ SECTIONS #endif NOSAVE_DATA - CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) - READ_MOSTLY_DATA(L1_CACHE_BYTES) + CACHELINE_ALIGNED_DATA(32) + READ_MOSTLY_DATA(32) /* * The exception fixup table (might need resorting at runtime) */ - . = ALIGN(4); + . = ALIGN(32); __start___ex_table = .; #ifdef CONFIG_MMU *(__ex_table) diff --git a/trunk/arch/arm/lib/getuser.S b/trunk/arch/arm/lib/getuser.S index 11093a7c3e32..1b049cd7a49a 100644 --- a/trunk/arch/arm/lib/getuser.S +++ b/trunk/arch/arm/lib/getuser.S @@ -31,18 +31,18 @@ #include ENTRY(__get_user_1) -1: TUSER(ldrb) r2, [r0] +1: T(ldrb) r2, [r0] mov r0, #0 mov pc, lr ENDPROC(__get_user_1) ENTRY(__get_user_2) #ifdef CONFIG_THUMB2_KERNEL -2: TUSER(ldrb) r2, [r0] -3: TUSER(ldrb) r3, [r0, #1] +2: T(ldrb) r2, [r0] +3: T(ldrb) r3, [r0, #1] #else -2: TUSER(ldrb) r2, [r0], #1 -3: TUSER(ldrb) r3, [r0] +2: T(ldrb) r2, [r0], #1 +3: T(ldrb) r3, [r0] #endif #ifndef __ARMEB__ orr r2, r2, r3, lsl #8 @@ -54,7 +54,7 @@ ENTRY(__get_user_2) ENDPROC(__get_user_2) ENTRY(__get_user_4) -4: TUSER(ldr) r2, [r0] +4: T(ldr) r2, [r0] mov r0, #0 mov pc, lr ENDPROC(__get_user_4) diff --git a/trunk/arch/arm/lib/putuser.S b/trunk/arch/arm/lib/putuser.S index 7db25990c589..c023fc11e86c 100644 --- a/trunk/arch/arm/lib/putuser.S +++ b/trunk/arch/arm/lib/putuser.S @@ -31,7 +31,7 @@ #include ENTRY(__put_user_1) -1: TUSER(strb) r2, [r0] +1: T(strb) r2, [r0] mov r0, #0 mov pc, lr ENDPROC(__put_user_1) @@ -40,19 +40,19 @@ ENTRY(__put_user_2) mov ip, r2, lsr #8 #ifdef CONFIG_THUMB2_KERNEL #ifndef __ARMEB__ -2: TUSER(strb) r2, [r0] -3: TUSER(strb) ip, [r0, #1] +2: T(strb) r2, [r0] +3: T(strb) ip, [r0, #1] #else -2: TUSER(strb) ip, [r0] -3: TUSER(strb) r2, [r0, #1] +2: T(strb) ip, [r0] +3: T(strb) r2, [r0, #1] #endif #else /* !CONFIG_THUMB2_KERNEL */ #ifndef __ARMEB__ -2: TUSER(strb) r2, [r0], #1 -3: TUSER(strb) ip, [r0] +2: T(strb) r2, [r0], #1 +3: T(strb) ip, [r0] #else -2: TUSER(strb) ip, [r0], #1 -3: TUSER(strb) r2, [r0] +2: T(strb) ip, [r0], #1 +3: T(strb) r2, [r0] #endif #endif /* CONFIG_THUMB2_KERNEL */ mov r0, #0 @@ -60,18 +60,18 @@ ENTRY(__put_user_2) ENDPROC(__put_user_2) ENTRY(__put_user_4) -4: TUSER(str) r2, [r0] +4: T(str) r2, [r0] mov r0, #0 mov pc, lr ENDPROC(__put_user_4) ENTRY(__put_user_8) #ifdef CONFIG_THUMB2_KERNEL -5: TUSER(str) r2, [r0] -6: TUSER(str) r3, [r0, #4] +5: T(str) r2, [r0] +6: T(str) r3, [r0, #4] #else -5: TUSER(str) r2, [r0], #4 -6: TUSER(str) r3, [r0] +5: T(str) r2, [r0], #4 +6: T(str) r3, [r0] #endif mov r0, #0 mov pc, lr diff --git a/trunk/arch/arm/lib/uaccess.S b/trunk/arch/arm/lib/uaccess.S index 5c908b1cb8ed..d0ece2aeb70d 100644 --- a/trunk/arch/arm/lib/uaccess.S +++ b/trunk/arch/arm/lib/uaccess.S @@ -32,11 +32,11 @@ rsb ip, ip, #4 cmp ip, #2 ldrb r3, [r1], #1 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault ldrgeb r3, [r1], #1 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault ldrgtb r3, [r1], #1 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault sub r2, r2, ip b .Lc2u_dest_aligned @@ -59,7 +59,7 @@ ENTRY(__copy_to_user) addmi ip, r2, #4 bmi .Lc2u_0nowords ldr r3, [r1], #4 -USER( TUSER( str) r3, [r0], #4) @ May fault +USER( T(str) r3, [r0], #4) @ May fault mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction rsb ip, ip, #0 movs ip, ip, lsr #32 - PAGE_SHIFT @@ -88,18 +88,18 @@ USER( TUSER( str) r3, [r0], #4) @ May fault stmneia r0!, {r3 - r4} @ Shouldnt fault tst ip, #4 ldrne r3, [r1], #4 - TUSER( strne) r3, [r0], #4 @ Shouldnt fault + T(strne) r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .Lc2u_0fupi .Lc2u_0nowords: teq ip, #0 beq .Lc2u_finished .Lc2u_nowords: cmp ip, #2 ldrb r3, [r1], #1 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault ldrgeb r3, [r1], #1 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault ldrgtb r3, [r1], #1 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault b .Lc2u_finished .Lc2u_not_enough: @@ -120,7 +120,7 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault mov r3, r7, pull #8 ldr r7, [r1], #4 orr r3, r3, r7, push #24 -USER( TUSER( str) r3, [r0], #4) @ May fault +USER( T(str) r3, [r0], #4) @ May fault mov ip, r0, lsl #32 - PAGE_SHIFT rsb ip, ip, #0 movs ip, ip, lsr #32 - PAGE_SHIFT @@ -155,18 +155,18 @@ USER( TUSER( str) r3, [r0], #4) @ May fault movne r3, r7, pull #8 ldrne r7, [r1], #4 orrne r3, r3, r7, push #24 - TUSER( strne) r3, [r0], #4 @ Shouldnt fault + T(strne) r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .Lc2u_1fupi .Lc2u_1nowords: mov r3, r7, get_byte_1 teq ip, #0 beq .Lc2u_finished cmp ip, #2 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault movge r3, r7, get_byte_2 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault movgt r3, r7, get_byte_3 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault b .Lc2u_finished .Lc2u_2fupi: subs r2, r2, #4 @@ -175,7 +175,7 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault mov r3, r7, pull #16 ldr r7, [r1], #4 orr r3, r3, r7, push #16 -USER( TUSER( str) r3, [r0], #4) @ May fault +USER( T(str) r3, [r0], #4) @ May fault mov ip, r0, lsl #32 - PAGE_SHIFT rsb ip, ip, #0 movs ip, ip, lsr #32 - PAGE_SHIFT @@ -210,18 +210,18 @@ USER( TUSER( str) r3, [r0], #4) @ May fault movne r3, r7, pull #16 ldrne r7, [r1], #4 orrne r3, r3, r7, push #16 - TUSER( strne) r3, [r0], #4 @ Shouldnt fault + T(strne) r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .Lc2u_2fupi .Lc2u_2nowords: mov r3, r7, get_byte_2 teq ip, #0 beq .Lc2u_finished cmp ip, #2 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault movge r3, r7, get_byte_3 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault ldrgtb r3, [r1], #0 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault b .Lc2u_finished .Lc2u_3fupi: subs r2, r2, #4 @@ -230,7 +230,7 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault mov r3, r7, pull #24 ldr r7, [r1], #4 orr r3, r3, r7, push #8 -USER( TUSER( str) r3, [r0], #4) @ May fault +USER( T(str) r3, [r0], #4) @ May fault mov ip, r0, lsl #32 - PAGE_SHIFT rsb ip, ip, #0 movs ip, ip, lsr #32 - PAGE_SHIFT @@ -265,18 +265,18 @@ USER( TUSER( str) r3, [r0], #4) @ May fault movne r3, r7, pull #24 ldrne r7, [r1], #4 orrne r3, r3, r7, push #8 - TUSER( strne) r3, [r0], #4 @ Shouldnt fault + T(strne) r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .Lc2u_3fupi .Lc2u_3nowords: mov r3, r7, get_byte_3 teq ip, #0 beq .Lc2u_finished cmp ip, #2 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault ldrgeb r3, [r1], #1 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault ldrgtb r3, [r1], #0 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault b .Lc2u_finished ENDPROC(__copy_to_user) @@ -295,11 +295,11 @@ ENDPROC(__copy_to_user) .Lcfu_dest_not_aligned: rsb ip, ip, #4 cmp ip, #2 -USER( TUSER( ldrb) r3, [r1], #1) @ May fault +USER( T(ldrb) r3, [r1], #1) @ May fault strb r3, [r0], #1 -USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault +USER( T(ldrgeb) r3, [r1], #1) @ May fault strgeb r3, [r0], #1 -USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault +USER( T(ldrgtb) r3, [r1], #1) @ May fault strgtb r3, [r0], #1 sub r2, r2, ip b .Lcfu_dest_aligned @@ -322,7 +322,7 @@ ENTRY(__copy_from_user) .Lcfu_0fupi: subs r2, r2, #4 addmi ip, r2, #4 bmi .Lcfu_0nowords -USER( TUSER( ldr) r3, [r1], #4) +USER( T(ldr) r3, [r1], #4) str r3, [r0], #4 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction rsb ip, ip, #0 @@ -351,18 +351,18 @@ USER( TUSER( ldr) r3, [r1], #4) ldmneia r1!, {r3 - r4} @ Shouldnt fault stmneia r0!, {r3 - r4} tst ip, #4 - TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault + T(ldrne) r3, [r1], #4 @ Shouldnt fault strne r3, [r0], #4 ands ip, ip, #3 beq .Lcfu_0fupi .Lcfu_0nowords: teq ip, #0 beq .Lcfu_finished .Lcfu_nowords: cmp ip, #2 -USER( TUSER( ldrb) r3, [r1], #1) @ May fault +USER( T(ldrb) r3, [r1], #1) @ May fault strb r3, [r0], #1 -USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault +USER( T(ldrgeb) r3, [r1], #1) @ May fault strgeb r3, [r0], #1 -USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault +USER( T(ldrgtb) r3, [r1], #1) @ May fault strgtb r3, [r0], #1 b .Lcfu_finished @@ -375,7 +375,7 @@ USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault .Lcfu_src_not_aligned: bic r1, r1, #3 -USER( TUSER( ldr) r7, [r1], #4) @ May fault +USER( T(ldr) r7, [r1], #4) @ May fault cmp ip, #2 bgt .Lcfu_3fupi beq .Lcfu_2fupi @@ -383,7 +383,7 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault addmi ip, r2, #4 bmi .Lcfu_1nowords mov r3, r7, pull #8 -USER( TUSER( ldr) r7, [r1], #4) @ May fault +USER( T(ldr) r7, [r1], #4) @ May fault orr r3, r3, r7, push #24 str r3, [r0], #4 mov ip, r1, lsl #32 - PAGE_SHIFT @@ -418,7 +418,7 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault stmneia r0!, {r3 - r4} tst ip, #4 movne r3, r7, pull #8 -USER( TUSER( ldrne) r7, [r1], #4) @ May fault +USER( T(ldrne) r7, [r1], #4) @ May fault orrne r3, r3, r7, push #24 strne r3, [r0], #4 ands ip, ip, #3 @@ -438,7 +438,7 @@ USER( TUSER( ldrne) r7, [r1], #4) @ May fault addmi ip, r2, #4 bmi .Lcfu_2nowords mov r3, r7, pull #16 -USER( TUSER( ldr) r7, [r1], #4) @ May fault +USER( T(ldr) r7, [r1], #4) @ May fault orr r3, r3, r7, push #16 str r3, [r0], #4 mov ip, r1, lsl #32 - PAGE_SHIFT @@ -474,7 +474,7 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault stmneia r0!, {r3 - r4} tst ip, #4 movne r3, r7, pull #16 -USER( TUSER( ldrne) r7, [r1], #4) @ May fault +USER( T(ldrne) r7, [r1], #4) @ May fault orrne r3, r3, r7, push #16 strne r3, [r0], #4 ands ip, ip, #3 @@ -486,7 +486,7 @@ USER( TUSER( ldrne) r7, [r1], #4) @ May fault strb r3, [r0], #1 movge r3, r7, get_byte_3 strgeb r3, [r0], #1 -USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault +USER( T(ldrgtb) r3, [r1], #0) @ May fault strgtb r3, [r0], #1 b .Lcfu_finished @@ -494,7 +494,7 @@ USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault addmi ip, r2, #4 bmi .Lcfu_3nowords mov r3, r7, pull #24 -USER( TUSER( ldr) r7, [r1], #4) @ May fault +USER( T(ldr) r7, [r1], #4) @ May fault orr r3, r3, r7, push #8 str r3, [r0], #4 mov ip, r1, lsl #32 - PAGE_SHIFT @@ -529,7 +529,7 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault stmneia r0!, {r3 - r4} tst ip, #4 movne r3, r7, pull #24 -USER( TUSER( ldrne) r7, [r1], #4) @ May fault +USER( T(ldrne) r7, [r1], #4) @ May fault orrne r3, r3, r7, push #8 strne r3, [r0], #4 ands ip, ip, #3 @@ -539,9 +539,9 @@ USER( TUSER( ldrne) r7, [r1], #4) @ May fault beq .Lcfu_finished cmp ip, #2 strb r3, [r0], #1 -USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault +USER( T(ldrgeb) r3, [r1], #1) @ May fault strgeb r3, [r0], #1 -USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault +USER( T(ldrgtb) r3, [r1], #1) @ May fault strgtb r3, [r0], #1 b .Lcfu_finished ENDPROC(__copy_from_user) diff --git a/trunk/arch/arm/mach-at91/Kconfig b/trunk/arch/arm/mach-at91/Kconfig index 71feb00a1e99..4f991f295284 100644 --- a/trunk/arch/arm/mach-at91/Kconfig +++ b/trunk/arch/arm/mach-at91/Kconfig @@ -18,12 +18,6 @@ config HAVE_AT91_USART4 config HAVE_AT91_USART5 bool -config AT91_SAM9_ALT_RESET - bool - -config AT91_SAM9G45_RESET - bool - menu "Atmel AT91 System-on-Chip" choice @@ -45,7 +39,6 @@ config ARCH_AT91SAM9260 select HAVE_AT91_USART4 select HAVE_AT91_USART5 select HAVE_NET_MACB - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9261 bool "AT91SAM9261" @@ -53,7 +46,6 @@ config ARCH_AT91SAM9261 select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_AT91_DBGU0 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G10 bool "AT91SAM9G10" @@ -61,7 +53,6 @@ config ARCH_AT91SAM9G10 select GENERIC_CLOCKEVENTS select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9263 bool "AT91SAM9263" @@ -70,7 +61,6 @@ config ARCH_AT91SAM9263 select HAVE_FB_ATMEL select HAVE_NET_MACB select HAVE_AT91_DBGU1 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9RL bool "AT91SAM9RL" @@ -79,7 +69,6 @@ config ARCH_AT91SAM9RL select HAVE_AT91_USART3 select HAVE_FB_ATMEL select HAVE_AT91_DBGU0 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G20 bool "AT91SAM9G20" @@ -90,7 +79,6 @@ config ARCH_AT91SAM9G20 select HAVE_AT91_USART4 select HAVE_AT91_USART5 select HAVE_NET_MACB - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G45 bool "AT91SAM9G45" @@ -100,7 +88,6 @@ config ARCH_AT91SAM9G45 select HAVE_FB_ATMEL select HAVE_NET_MACB select HAVE_AT91_DBGU1 - select AT91_SAM9G45_RESET config ARCH_AT91CAP9 bool "AT91CAP9" @@ -109,7 +96,6 @@ config ARCH_AT91CAP9 select HAVE_FB_ATMEL select HAVE_NET_MACB select HAVE_AT91_DBGU1 - select AT91_SAM9G45_RESET config ARCH_AT91X40 bool "AT91x40" diff --git a/trunk/arch/arm/mach-at91/Makefile b/trunk/arch/arm/mach-at91/Makefile index 705e1fbded39..242174f9f355 100644 --- a/trunk/arch/arm/mach-at91/Makefile +++ b/trunk/arch/arm/mach-at91/Makefile @@ -8,17 +8,15 @@ obj-n := obj- := obj-$(CONFIG_AT91_PMC_UNIT) += clock.o -obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o -obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o diff --git a/trunk/arch/arm/mach-at91/at91cap9.c b/trunk/arch/arm/mach-at91/at91cap9.c index a42edc25a87e..edb879ac04c8 100644 --- a/trunk/arch/arm/mach-at91/at91cap9.c +++ b/trunk/arch/arm/mach-at91/at91cap9.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "soc.h" #include "generic.h" @@ -313,6 +314,11 @@ static struct at91_gpio_bank at91cap9_gpio[] __initdata = { } }; +static void at91cap9_restart(char mode, const char *cmd) +{ + at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); +} + /* -------------------------------------------------------------------- * AT91CAP9 processor initialization * -------------------------------------------------------------------- */ @@ -325,14 +331,13 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_ioremap_registers(void) { at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC); - at91_ioremap_rstc(AT91CAP9_BASE_RSTC); at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); } static void __init at91cap9_initialize(void) { - arm_pm_restart = at91sam9g45_restart; + arm_pm_restart = at91cap9_restart; at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); /* Register GPIO subsystem */ diff --git a/trunk/arch/arm/mach-at91/at91sam9260.c b/trunk/arch/arm/mach-at91/at91sam9260.c index d4036ba43612..5e46e4a96430 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260.c +++ b/trunk/arch/arm/mach-at91/at91sam9260.c @@ -323,7 +323,6 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9260_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); } diff --git a/trunk/arch/arm/mach-at91/at91sam9261.c b/trunk/arch/arm/mach-at91/at91sam9261.c index 023c2ff138df..b85b9ea60170 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261.c +++ b/trunk/arch/arm/mach-at91/at91sam9261.c @@ -281,7 +281,6 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9261_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); } diff --git a/trunk/arch/arm/mach-at91/at91sam9263.c b/trunk/arch/arm/mach-at91/at91sam9263.c index 75e876c258af..79e3669b1117 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263.c +++ b/trunk/arch/arm/mach-at91/at91sam9263.c @@ -301,7 +301,6 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9263_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); diff --git a/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S b/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S index 518e42377171..d3f931c5942e 100644 --- a/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S +++ b/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S @@ -23,8 +23,7 @@ .globl at91sam9_alt_restart at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants - ldr r1, =at91_rstc_base - ldr r1, [r1] + ldr r1, .at91_va_base_rstc_cr mov r2, #1 mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN @@ -34,9 +33,11 @@ at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM - str r4, [r1, #AT91_RSTC_CR] @ reset processor + str r4, [r1] @ reset processor b . .at91_va_base_sdramc: .word AT91_VA_BASE_SYS + AT91_SDRAMC0 +.at91_va_base_rstc_cr: + .word AT91_VA_BASE_SYS + AT91_RSTC_CR diff --git a/trunk/arch/arm/mach-at91/at91sam9g45.c b/trunk/arch/arm/mach-at91/at91sam9g45.c index 1cb6a96b1c1e..7032dd32cdf0 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "soc.h" @@ -317,6 +318,11 @@ static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = { } }; +static void at91sam9g45_restart(char mode, const char *cmd) +{ + at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); +} + /* -------------------------------------------------------------------- * AT91SAM9G45 processor initialization * -------------------------------------------------------------------- */ @@ -330,7 +336,6 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); } diff --git a/trunk/arch/arm/mach-at91/at91sam9g45_reset.S b/trunk/arch/arm/mach-at91/at91sam9g45_reset.S deleted file mode 100644 index 0468be10980b..000000000000 --- a/trunk/arch/arm/mach-at91/at91sam9g45_reset.S +++ /dev/null @@ -1,40 +0,0 @@ -/* - * reset AT91SAM9G45 as per errata - * - * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD - * - * unless the SDRAM is cleanly shutdown before we hit the - * reset register it can be left driving the data bus and - * killing the chance of a subsequent boot from NAND - * - * GPLv2 Only - */ - -#include -#include -#include -#include - - .arm - - .globl at91sam9g45_restart - -at91sam9g45_restart: - ldr r0, .at91_va_base_sdramc0 @ preload constants - ldr r1, =at91_rstc_base - ldr r1, [r1] - - mov r2, #1 - mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN - ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST - - .balign 32 @ align to cache line - - str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access - str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0 - str r4, [r1, #AT91_RSTC_CR] @ reset processor - - b . - -.at91_va_base_sdramc0: - .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 diff --git a/trunk/arch/arm/mach-at91/at91sam9rl.c b/trunk/arch/arm/mach-at91/at91sam9rl.c index d2c91a841cb8..d6bcb1da11df 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl.c @@ -286,7 +286,6 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); } diff --git a/trunk/arch/arm/mach-at91/generic.h b/trunk/arch/arm/mach-at91/generic.h index 594133451c0c..4866b8180d66 100644 --- a/trunk/arch/arm/mach-at91/generic.h +++ b/trunk/arch/arm/mach-at91/generic.h @@ -58,9 +58,7 @@ extern void at91_irq_suspend(void); extern void at91_irq_resume(void); /* reset */ -extern void at91_ioremap_rstc(u32 base_addr); extern void at91sam9_alt_restart(char, const char *); -extern void at91sam9g45_restart(char, const char *); /* shutdown */ extern void at91_ioremap_shdwc(u32 base_addr); diff --git a/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h b/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h index 875fa336800b..cbd2bf052c1f 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h @@ -16,25 +16,13 @@ #ifndef AT91_RSTC_H #define AT91_RSTC_H -#ifndef __ASSEMBLY__ -extern void __iomem *at91_rstc_base; - -#define at91_rstc_read(field) \ - __raw_readl(at91_rstc_base + field) - -#define at91_rstc_write(field, value) \ - __raw_writel(value, at91_rstc_base + field); -#else -.extern at91_rstc_base -#endif - -#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */ +#define AT91_RSTC_CR (AT91_RSTC + 0x00) /* Reset Controller Control Register */ #define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */ #define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */ #define AT91_RSTC_EXTRST (1 << 3) /* External Reset */ #define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */ -#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */ +#define AT91_RSTC_SR (AT91_RSTC + 0x04) /* Reset Controller Status Register */ #define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */ #define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */ #define AT91_RSTC_RSTTYP_GENERAL (0 << 8) @@ -45,7 +33,7 @@ extern void __iomem *at91_rstc_base; #define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */ #define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */ -#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */ +#define AT91_RSTC_MR (AT91_RSTC + 0x08) /* Reset Controller Mode Register */ #define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */ #define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */ #define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */ diff --git a/trunk/arch/arm/mach-at91/include/mach/at91cap9.h b/trunk/arch/arm/mach-at91/include/mach/at91cap9.h index 61d952902f2b..4c0e2f6011d7 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91cap9.h @@ -83,6 +83,7 @@ #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ (0xfffffd50 - AT91_BASE_SYS) : \ (0xfffffd60 - AT91_BASE_SYS)) @@ -95,7 +96,6 @@ #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 #define AT91CAP9_BASE_PIOD 0xfffff800 -#define AT91CAP9_BASE_RSTC 0xfffffd00 #define AT91CAP9_BASE_SHDWC 0xfffffd10 #define AT91CAP9_BASE_RTT 0xfffffd20 #define AT91CAP9_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h new file mode 100644 index 000000000000..976f4a6c3353 --- /dev/null +++ b/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h @@ -0,0 +1,108 @@ +/* + * arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h + * + * (C) 2008 Andrew Victor + * + * DDR/SDR Controller (DDRSDRC) - System peripherals registers. + * Based on AT91CAP9 datasheet revision B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91CAP9_DDRSDR_H +#define AT91CAP9_DDRSDR_H + +#define AT91_DDRSDRC_MR 0x00 /* Mode Register */ +#define AT91_DDRSDRC_MODE (0xf << 0) /* Command Mode */ +#define AT91_DDRSDRC_MODE_NORMAL 0 +#define AT91_DDRSDRC_MODE_NOP 1 +#define AT91_DDRSDRC_MODE_PRECHARGE 2 +#define AT91_DDRSDRC_MODE_LMR 3 +#define AT91_DDRSDRC_MODE_REFRESH 4 +#define AT91_DDRSDRC_MODE_EXT_LMR 5 +#define AT91_DDRSDRC_MODE_DEEP 6 + +#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */ +#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */ + +#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */ +#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */ +#define AT91_DDRSDRC_NC_SDR8 (0 << 0) +#define AT91_DDRSDRC_NC_SDR9 (1 << 0) +#define AT91_DDRSDRC_NC_SDR10 (2 << 0) +#define AT91_DDRSDRC_NC_SDR11 (3 << 0) +#define AT91_DDRSDRC_NC_DDR9 (0 << 0) +#define AT91_DDRSDRC_NC_DDR10 (1 << 0) +#define AT91_DDRSDRC_NC_DDR11 (2 << 0) +#define AT91_DDRSDRC_NC_DDR12 (3 << 0) +#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */ +#define AT91_DDRSDRC_NR_11 (0 << 2) +#define AT91_DDRSDRC_NR_12 (1 << 2) +#define AT91_DDRSDRC_NR_13 (2 << 2) +#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */ +#define AT91_DDRSDRC_CAS_2 (2 << 4) +#define AT91_DDRSDRC_CAS_3 (3 << 4) +#define AT91_DDRSDRC_CAS_25 (6 << 4) +#define AT91_DDRSDRC_DLL (1 << 7) /* Reset DLL */ +#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */ + +#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */ +#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */ +#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */ +#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */ +#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */ +#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ +#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ +#define AT91_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */ +#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ + +#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */ +#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */ +#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */ +#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */ +#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */ + +#define AT91_DDRSDRC_LPR 0x18 /* Low Power Register */ +#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ +#define AT91_DDRSDRC_LPCB_DISABLE 0 +#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 +#define AT91_DDRSDRC_LPCB_POWER_DOWN 2 +#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3 +#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */ +#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */ +#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ +#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */ +#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ +#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12) +#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12) +#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12) + +#define AT91_DDRSDRC_MDR 0x1C /* Memory Device Register */ +#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ +#define AT91_DDRSDRC_MD_SDR 0 +#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 +#define AT91_DDRSDRC_MD_DDR 2 +#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 + +#define AT91_DDRSDRC_DLLR 0x20 /* DLL Information Register */ +#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ +#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ +#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ +#define AT91_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */ +#define AT91_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */ +#define AT91_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */ +#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ +#define AT91_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */ +#define AT91_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */ + +/* Register access macros */ +#define at91_ramc_read(num, reg) \ + at91_sys_read(AT91_DDRSDRC##num + reg) +#define at91_ramc_write(num, reg, value) \ + at91_sys_write(AT91_DDRSDRC##num + reg, value) + + +#endif diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h index fa5ca278adeb..f937c476bb67 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -83,6 +83,7 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9260_BASE_ECC 0xffffe800 @@ -91,7 +92,6 @@ #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 -#define AT91SAM9260_BASE_RSTC 0xfffffd00 #define AT91SAM9260_BASE_SHDWC 0xfffffd10 #define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91SAM9260_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h index 7cde2d36570e..175604e261be 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -68,6 +68,7 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9261_BASE_SMC 0xffffec00 @@ -75,7 +76,6 @@ #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 -#define AT91SAM9261_BASE_RSTC 0xfffffd00 #define AT91SAM9261_BASE_SHDWC 0xfffffd10 #define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91SAM9261_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h index 5949abda962b..80c915002d83 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -78,6 +78,7 @@ #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9263_BASE_ECC0 0xffffe000 @@ -90,7 +91,6 @@ #define AT91SAM9263_BASE_PIOC 0xfffff600 #define AT91SAM9263_BASE_PIOD 0xfffff800 #define AT91SAM9263_BASE_PIOE 0xfffffa00 -#define AT91SAM9263_BASE_RSTC 0xfffffd00 #define AT91SAM9263_BASE_SHDWC 0xfffffd10 #define AT91SAM9263_BASE_RTT0 0xfffffd20 #define AT91SAM9263_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h index e2f8da8ce5bc..d27b15ba8ebf 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h @@ -46,10 +46,10 @@ #define AT91_DDRSDRC_CAS_25 (6 << 4) #define AT91_DDRSDRC_RST_DLL (1 << 7) /* Reset DLL */ #define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */ -#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL [SAM9 Only] */ -#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver [SAM9 Only] */ -#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared [SAM9 Only] */ -#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */ +#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL */ +#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver */ +#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared */ +#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y */ #define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */ #define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */ @@ -59,8 +59,7 @@ #define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ #define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ #define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */ -#define AT91CAP9_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */ -#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay [SAM9 Only] */ +#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay */ #define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ #define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */ @@ -69,14 +68,13 @@ #define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */ #define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */ -#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register [SAM9 Only] */ +#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register */ #define AT91_DDRSDRC_TXARD (0xf << 0) /* Exit active power down delay to read command in mode "Fast Exit" */ #define AT91_DDRSDRC_TXARDS (0xf << 4) /* Exit active power down delay to read command in mode "Slow Exit" */ #define AT91_DDRSDRC_TRPA (0xf << 8) /* Row Precharge All delay */ #define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */ #define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */ -#define AT91CAP9_DDRSDRC_LPR 0x18 /* Low Power Register */ #define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ #define AT91_DDRSDRC_LPCB_DISABLE 0 #define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 @@ -94,40 +92,32 @@ #define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */ #define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */ -#define AT91CAP9_DDRSDRC_MDR 0x1C /* Memory Device Register */ #define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ #define AT91_DDRSDRC_MD_SDR 0 #define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 -#define AT91CAP9_DDRSDRC_MD_DDR 2 #define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 -#define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */ +#define AT91_DDRSDRC_MD_DDR2 6 #define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */ #define AT91_DDRSDRC_DBW_32BITS (0 << 4) #define AT91_DDRSDRC_DBW_16BITS (1 << 4) #define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */ -#define AT91CAP9_DDRSDRC_DLL 0x20 /* DLL Information Register */ #define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ #define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ #define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ -#define AT91CAP9_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */ -#define AT91CAP9_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */ -#define AT91CAP9_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */ #define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ -#define AT91CAP9_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */ -#define AT91CAP9_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */ -#define AT91_DDRSDRC_HS 0x2C /* High Speed Register [SAM9 Only] */ +#define AT91_DDRSDRC_HS 0x2C /* High Speed Register */ #define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */ #define AT91_DDRSDRC_DELAY(n) (0x30 + (0x4 * (n))) /* Delay I/O Register n */ -#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register [SAM9 Only] */ +#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register */ #define AT91_DDRSDRC_WP (1 << 0) /* Write protect enable */ #define AT91_DDRSDRC_WPKEY (0xffffff << 8) /* Write protect key */ #define AT91_DDRSDRC_KEY (0x444452 << 8) /* Write protect key = "DDR" */ -#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register [SAM9 Only] */ +#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register */ #define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */ #define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */ diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h index dd9c95ea0862..f0c23c960dec 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -90,6 +90,7 @@ #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9G45_BASE_ECC 0xffffe200 @@ -101,7 +102,6 @@ #define AT91SAM9G45_BASE_PIOC 0xfffff600 #define AT91SAM9G45_BASE_PIOD 0xfffff800 #define AT91SAM9G45_BASE_PIOE 0xfffffa00 -#define AT91SAM9G45_BASE_RSTC 0xfffffd00 #define AT91SAM9G45_BASE_SHDWC 0xfffffd10 #define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h index d7bead7118da..2bb359e60b97 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -72,6 +72,7 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -83,7 +84,6 @@ #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 #define AT91SAM9RL_BASE_PIOD 0xfffffa00 -#define AT91SAM9RL_BASE_RSTC 0xfffffd00 #define AT91SAM9RL_BASE_SHDWC 0xfffffd10 #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/board.h b/trunk/arch/arm/mach-at91/include/mach/board.h index 3b33f07b1e11..d0b377b21bd7 100644 --- a/trunk/arch/arm/mach-at91/include/mach/board.h +++ b/trunk/arch/arm/mach-at91/include/mach/board.h @@ -88,7 +88,7 @@ extern void __init at91_add_device_eth(struct macb_platform_data *data); struct at91_usbh_data { u8 ports; /* number of ports on root hub */ int vbus_pin[2]; /* port power-control pin */ - u8 vbus_pin_active_low[2]; + u8 vbus_pin_inverted; u8 overcurrent_supported; int overcurrent_pin[2]; u8 overcurrent_status[2]; diff --git a/trunk/arch/arm/mach-at91/pm.c b/trunk/arch/arm/mach-at91/pm.c index 1606379ac284..62ad95556c36 100644 --- a/trunk/arch/arm/mach-at91/pm.c +++ b/trunk/arch/arm/mach-at91/pm.c @@ -34,6 +34,7 @@ /* * Show the reason for the previous system reset. */ +#if defined(AT91_RSTC) #include #include @@ -57,10 +58,10 @@ static void __init show_reset_status(void) char *reason, *r2 = reset; u32 reset_type, wake_type; - if (!at91_shdwc_base || !at91_rstc_base) + if (!at91_shdwc_base) return; - reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; + reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; wake_type = at91_shdwc_read(AT91_SHDW_SR); switch (reset_type) { @@ -101,6 +102,10 @@ static void __init show_reset_status(void) } pr_info("AT91: Starting after %s %s\n", reason, r2); } +#else +static void __init show_reset_status(void) {} +#endif + static int at91_pm_valid_state(suspend_state_t state) { diff --git a/trunk/arch/arm/mach-at91/pm.h b/trunk/arch/arm/mach-at91/pm.h index 7eb40d24242f..ce9a20699111 100644 --- a/trunk/arch/arm/mach-at91/pm.h +++ b/trunk/arch/arm/mach-at91/pm.h @@ -25,21 +25,21 @@ static inline u32 sdram_selfrefresh_enable(void) : : "r" (0)) #elif defined(CONFIG_ARCH_AT91CAP9) -#include +#include static inline u32 sdram_selfrefresh_enable(void) { u32 saved_lpr, lpr; - saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR); + saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR); lpr = saved_lpr & ~AT91_DDRSDRC_LPCB; - at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); + at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); return saved_lpr; } -#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr) +#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr) #define wait_for_interrupt_enable() cpu_do_idle() #elif defined(CONFIG_ARCH_AT91SAM9G45) diff --git a/trunk/arch/arm/mach-at91/pm_slowclock.S b/trunk/arch/arm/mach-at91/pm_slowclock.S index 92dfb8461392..f7922a436172 100644 --- a/trunk/arch/arm/mach-at91/pm_slowclock.S +++ b/trunk/arch/arm/mach-at91/pm_slowclock.S @@ -18,8 +18,9 @@ #if defined(CONFIG_ARCH_AT91RM9200) #include -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) +#elif defined(CONFIG_ARCH_AT91CAP9) +#include +#elif defined(CONFIG_ARCH_AT91SAM9G45) #include #else #include diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c index 69d3fc4c46f3..8bdcc3cb6012 100644 --- a/trunk/arch/arm/mach-at91/setup.c +++ b/trunk/arch/arm/mach-at91/setup.c @@ -29,12 +29,9 @@ EXPORT_SYMBOL(at91_soc_initdata); void __init at91rm9200_set_type(int type) { if (type == ARCH_REVISON_9200_PQFP) - at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP; - else at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; - - pr_info("AT91: filled in soc subtype: %s\n", - at91_get_soc_subtype(&at91_soc_initdata)); + else + at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP; } void __init at91_init_irq_default(void) @@ -284,15 +281,6 @@ void __init at91_ioremap_shdwc(u32 base_addr) pm_power_off = at91sam9_poweroff; } -void __iomem *at91_rstc_base; - -void __init at91_ioremap_rstc(u32 base_addr) -{ - at91_rstc_base = ioremap(base_addr, 16); - if (!at91_rstc_base) - panic("Impossible to ioremap at91_rstc_base\n"); -} - void __init at91_initialize(unsigned long main_clock) { at91_boot_soc.ioremap_registers(); diff --git a/trunk/arch/arm/mach-bcmring/arch.c b/trunk/arch/arm/mach-bcmring/arch.c index 45c97b1ee9b1..9e5e7552498c 100644 --- a/trunk/arch/arm/mach-bcmring/arch.c +++ b/trunk/arch/arm/mach-bcmring/arch.c @@ -194,6 +194,6 @@ MACHINE_START(BCMRING, "BCMRING") .init_early = bcmring_init_early, .init_irq = bcmring_init_irq, .timer = &bcmring_timer, - .init_machine = bcmring_init_machine, + .init_machine = bcmring_init_machine .restart = bcmring_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-bcmring/dma.c b/trunk/arch/arm/mach-bcmring/dma.c index 1024396797e1..1a1a27dd5654 100644 --- a/trunk/arch/arm/mach-bcmring/dma.c +++ b/trunk/arch/arm/mach-bcmring/dma.c @@ -33,11 +33,17 @@ #include +#include #include #include #include #include +/* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */ +/* especially since dc4 doesn't use kmalloc'd memory. */ + +#define ALLOW_MAP_OF_KMALLOC_MEMORY 0 + /* ---- Public Variables ------------------------------------------------- */ /* ---- Private Constants and Types -------------------------------------- */ @@ -47,18 +53,58 @@ #define CONTROLLER_FROM_HANDLE(handle) (((handle) >> 4) & 0x0f) #define CHANNEL_FROM_HANDLE(handle) ((handle) & 0x0f) +#define DMA_MAP_DEBUG 0 + +#if DMA_MAP_DEBUG +# define DMA_MAP_PRINT(fmt, args...) printk("%s: " fmt, __func__, ## args) +#else +# define DMA_MAP_PRINT(fmt, args...) +#endif /* ---- Private Variables ------------------------------------------------ */ static DMA_Global_t gDMA; static struct proc_dir_entry *gDmaDir; +static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0); +static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0); +static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0); +static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0); + #include "dma_device.c" /* ---- Private Function Prototypes -------------------------------------- */ /* ---- Functions ------------------------------------------------------- */ +/****************************************************************************/ +/** +* Displays information for /proc/dma/mem-type +*/ +/****************************************************************************/ + +static int dma_proc_read_mem_type(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf(buf + len, "dma_map_mem statistics\n"); + len += + sprintf(buf + len, "coherent: %d\n", + atomic_read(&gDmaStatMemTypeCoherent)); + len += + sprintf(buf + len, "kmalloc: %d\n", + atomic_read(&gDmaStatMemTypeKmalloc)); + len += + sprintf(buf + len, "vmalloc: %d\n", + atomic_read(&gDmaStatMemTypeVmalloc)); + len += + sprintf(buf + len, "user: %d\n", + atomic_read(&gDmaStatMemTypeUser)); + + return len; +} + /****************************************************************************/ /** * Displays information for /proc/dma/channels @@ -800,6 +846,8 @@ int dma_init(void) dma_proc_read_channels, NULL); create_proc_read_entry("devices", 0, gDmaDir, dma_proc_read_devices, NULL); + create_proc_read_entry("mem-type", 0, gDmaDir, + dma_proc_read_mem_type, NULL); } out: @@ -1517,3 +1565,767 @@ int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. } EXPORT_SYMBOL(dma_set_device_handler); + +/****************************************************************************/ +/** +* Initializes a memory mapping structure +*/ +/****************************************************************************/ + +int dma_init_mem_map(DMA_MemMap_t *memMap) +{ + memset(memMap, 0, sizeof(*memMap)); + + sema_init(&memMap->lock, 1); + + return 0; +} + +EXPORT_SYMBOL(dma_init_mem_map); + +/****************************************************************************/ +/** +* Releases any memory currently being held by a memory mapping structure. +*/ +/****************************************************************************/ + +int dma_term_mem_map(DMA_MemMap_t *memMap) +{ + down(&memMap->lock); /* Just being paranoid */ + + /* Free up any allocated memory */ + + up(&memMap->lock); + memset(memMap, 0, sizeof(*memMap)); + + return 0; +} + +EXPORT_SYMBOL(dma_term_mem_map); + +/****************************************************************************/ +/** +* Looks at a memory address and categorizes it. +* +* @return One of the values from the DMA_MemType_t enumeration. +*/ +/****************************************************************************/ + +DMA_MemType_t dma_mem_type(void *addr) +{ + unsigned long addrVal = (unsigned long)addr; + + if (addrVal >= CONSISTENT_BASE) { + /* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */ + + /* dma_alloc_xxx pages are physically and virtually contiguous */ + + return DMA_MEM_TYPE_DMA; + } + + /* Technically, we could add one more classification. Addresses between VMALLOC_END */ + /* and the beginning of the DMA virtual address could be considered to be I/O space. */ + /* Right now, nobody cares about this particular classification, so we ignore it. */ + + if (is_vmalloc_addr(addr)) { + /* Address comes from the vmalloc'd region. Pages are virtually */ + /* contiguous but NOT physically contiguous */ + + return DMA_MEM_TYPE_VMALLOC; + } + + if (addrVal >= PAGE_OFFSET) { + /* PAGE_OFFSET is typically 0xC0000000 */ + + /* kmalloc'd pages are physically contiguous */ + + return DMA_MEM_TYPE_KMALLOC; + } + + return DMA_MEM_TYPE_USER; +} + +EXPORT_SYMBOL(dma_mem_type); + +/****************************************************************************/ +/** +* Looks at a memory address and determines if we support DMA'ing to/from +* that type of memory. +* +* @return boolean - +* return value != 0 means dma supported +* return value == 0 means dma not supported +*/ +/****************************************************************************/ + +int dma_mem_supports_dma(void *addr) +{ + DMA_MemType_t memType = dma_mem_type(addr); + + return (memType == DMA_MEM_TYPE_DMA) +#if ALLOW_MAP_OF_KMALLOC_MEMORY + || (memType == DMA_MEM_TYPE_KMALLOC) +#endif + || (memType == DMA_MEM_TYPE_USER); +} + +EXPORT_SYMBOL(dma_mem_supports_dma); + +/****************************************************************************/ +/** +* Maps in a memory region such that it can be used for performing a DMA. +* +* @return +*/ +/****************************************************************************/ + +int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */ + enum dma_data_direction dir /* Direction that the mapping will be going */ + ) { + int rc; + + down(&memMap->lock); + + DMA_MAP_PRINT("memMap: %p\n", memMap); + + if (memMap->inUse) { + printk(KERN_ERR "%s: memory map %p is already being used\n", + __func__, memMap); + rc = -EBUSY; + goto out; + } + + memMap->inUse = 1; + memMap->dir = dir; + memMap->numRegionsUsed = 0; + + rc = 0; + +out: + + DMA_MAP_PRINT("returning %d", rc); + + up(&memMap->lock); + + return rc; +} + +EXPORT_SYMBOL(dma_map_start); + +/****************************************************************************/ +/** +* Adds a segment of memory to a memory map. Each segment is both +* physically and virtually contiguous. +* +* @return 0 on success, error code otherwise. +*/ +/****************************************************************************/ + +static int dma_map_add_segment(DMA_MemMap_t *memMap, /* Stores state information about the map */ + DMA_Region_t *region, /* Region that the segment belongs to */ + void *virtAddr, /* Virtual address of the segment being added */ + dma_addr_t physAddr, /* Physical address of the segment being added */ + size_t numBytes /* Number of bytes of the segment being added */ + ) { + DMA_Segment_t *segment; + + DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr, + physAddr, numBytes); + + /* Sanity check */ + + if (((unsigned long)virtAddr < (unsigned long)region->virtAddr) + || (((unsigned long)virtAddr + numBytes)) > + ((unsigned long)region->virtAddr + region->numBytes)) { + printk(KERN_ERR + "%s: virtAddr %p is outside region @ %p len: %d\n", + __func__, virtAddr, region->virtAddr, region->numBytes); + return -EINVAL; + } + + if (region->numSegmentsUsed > 0) { + /* Check to see if this segment is physically contiguous with the previous one */ + + segment = ®ion->segment[region->numSegmentsUsed - 1]; + + if ((segment->physAddr + segment->numBytes) == physAddr) { + /* It is - just add on to the end */ + + DMA_MAP_PRINT("appending %d bytes to last segment\n", + numBytes); + + segment->numBytes += numBytes; + + return 0; + } + } + + /* Reallocate to hold more segments, if required. */ + + if (region->numSegmentsUsed >= region->numSegmentsAllocated) { + DMA_Segment_t *newSegment; + size_t oldSize = + region->numSegmentsAllocated * sizeof(*newSegment); + int newAlloc = region->numSegmentsAllocated + 4; + size_t newSize = newAlloc * sizeof(*newSegment); + + newSegment = kmalloc(newSize, GFP_KERNEL); + if (newSegment == NULL) { + return -ENOMEM; + } + memcpy(newSegment, region->segment, oldSize); + memset(&((uint8_t *) newSegment)[oldSize], 0, + newSize - oldSize); + kfree(region->segment); + + region->numSegmentsAllocated = newAlloc; + region->segment = newSegment; + } + + segment = ®ion->segment[region->numSegmentsUsed]; + region->numSegmentsUsed++; + + segment->virtAddr = virtAddr; + segment->physAddr = physAddr; + segment->numBytes = numBytes; + + DMA_MAP_PRINT("returning success\n"); + + return 0; +} + +/****************************************************************************/ +/** +* Adds a region of memory to a memory map. Each region is virtually +* contiguous, but not necessarily physically contiguous. +* +* @return 0 on success, error code otherwise. +*/ +/****************************************************************************/ + +int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */ + void *mem, /* Virtual address that we want to get a map of */ + size_t numBytes /* Number of bytes being mapped */ + ) { + unsigned long addr = (unsigned long)mem; + unsigned int offset; + int rc = 0; + DMA_Region_t *region; + dma_addr_t physAddr; + + down(&memMap->lock); + + DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes); + + if (!memMap->inUse) { + printk(KERN_ERR "%s: Make sure you call dma_map_start first\n", + __func__); + rc = -EINVAL; + goto out; + } + + /* Reallocate to hold more regions. */ + + if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) { + DMA_Region_t *newRegion; + size_t oldSize = + memMap->numRegionsAllocated * sizeof(*newRegion); + int newAlloc = memMap->numRegionsAllocated + 4; + size_t newSize = newAlloc * sizeof(*newRegion); + + newRegion = kmalloc(newSize, GFP_KERNEL); + if (newRegion == NULL) { + rc = -ENOMEM; + goto out; + } + memcpy(newRegion, memMap->region, oldSize); + memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize); + + kfree(memMap->region); + + memMap->numRegionsAllocated = newAlloc; + memMap->region = newRegion; + } + + region = &memMap->region[memMap->numRegionsUsed]; + memMap->numRegionsUsed++; + + offset = addr & ~PAGE_MASK; + + region->memType = dma_mem_type(mem); + region->virtAddr = mem; + region->numBytes = numBytes; + region->numSegmentsUsed = 0; + region->numLockedPages = 0; + region->lockedPages = NULL; + + switch (region->memType) { + case DMA_MEM_TYPE_VMALLOC: + { + atomic_inc(&gDmaStatMemTypeVmalloc); + + /* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */ + + /* vmalloc'd pages are not physically contiguous */ + + rc = -EINVAL; + break; + } + + case DMA_MEM_TYPE_KMALLOC: + { + atomic_inc(&gDmaStatMemTypeKmalloc); + + /* kmalloc'd pages are physically contiguous, so they'll have exactly */ + /* one segment */ + +#if ALLOW_MAP_OF_KMALLOC_MEMORY + physAddr = + dma_map_single(NULL, mem, numBytes, memMap->dir); + rc = dma_map_add_segment(memMap, region, mem, physAddr, + numBytes); +#else + rc = -EINVAL; +#endif + break; + } + + case DMA_MEM_TYPE_DMA: + { + /* dma_alloc_xxx pages are physically contiguous */ + + atomic_inc(&gDmaStatMemTypeCoherent); + + physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset; + + dma_sync_single_for_cpu(NULL, physAddr, numBytes, + memMap->dir); + rc = dma_map_add_segment(memMap, region, mem, physAddr, + numBytes); + break; + } + + case DMA_MEM_TYPE_USER: + { + size_t firstPageOffset; + size_t firstPageSize; + struct page **pages; + struct task_struct *userTask; + + atomic_inc(&gDmaStatMemTypeUser); + +#if 1 + /* If the pages are user pages, then the dma_mem_map_set_user_task function */ + /* must have been previously called. */ + + if (memMap->userTask == NULL) { + printk(KERN_ERR + "%s: must call dma_mem_map_set_user_task when using user-mode memory\n", + __func__); + return -EINVAL; + } + + /* User pages need to be locked. */ + + firstPageOffset = + (unsigned long)region->virtAddr & (PAGE_SIZE - 1); + firstPageSize = PAGE_SIZE - firstPageOffset; + + region->numLockedPages = (firstPageOffset + + region->numBytes + + PAGE_SIZE - 1) / PAGE_SIZE; + pages = + kmalloc(region->numLockedPages * + sizeof(struct page *), GFP_KERNEL); + + if (pages == NULL) { + region->numLockedPages = 0; + return -ENOMEM; + } + + userTask = memMap->userTask; + + down_read(&userTask->mm->mmap_sem); + rc = get_user_pages(userTask, /* task */ + userTask->mm, /* mm */ + (unsigned long)region->virtAddr, /* start */ + region->numLockedPages, /* len */ + memMap->dir == DMA_FROM_DEVICE, /* write */ + 0, /* force */ + pages, /* pages (array of pointers to page) */ + NULL); /* vmas */ + up_read(&userTask->mm->mmap_sem); + + if (rc != region->numLockedPages) { + kfree(pages); + region->numLockedPages = 0; + + if (rc >= 0) { + rc = -EINVAL; + } + } else { + uint8_t *virtAddr = region->virtAddr; + size_t bytesRemaining; + int pageIdx; + + rc = 0; /* Since get_user_pages returns +ve number */ + + region->lockedPages = pages; + + /* We've locked the user pages. Now we need to walk them and figure */ + /* out the physical addresses. */ + + /* The first page may be partial */ + + dma_map_add_segment(memMap, + region, + virtAddr, + PFN_PHYS(page_to_pfn + (pages[0])) + + firstPageOffset, + firstPageSize); + + virtAddr += firstPageSize; + bytesRemaining = + region->numBytes - firstPageSize; + + for (pageIdx = 1; + pageIdx < region->numLockedPages; + pageIdx++) { + size_t bytesThisPage = + (bytesRemaining > + PAGE_SIZE ? PAGE_SIZE : + bytesRemaining); + + DMA_MAP_PRINT + ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n", + pageIdx, pages[pageIdx], + page_to_pfn(pages[pageIdx]), + PFN_PHYS(page_to_pfn + (pages[pageIdx]))); + + dma_map_add_segment(memMap, + region, + virtAddr, + PFN_PHYS(page_to_pfn + (pages + [pageIdx])), + bytesThisPage); + + virtAddr += bytesThisPage; + bytesRemaining -= bytesThisPage; + } + } +#else + printk(KERN_ERR + "%s: User mode pages are not yet supported\n", + __func__); + + /* user pages are not physically contiguous */ + + rc = -EINVAL; +#endif + break; + } + + default: + { + printk(KERN_ERR "%s: Unsupported memory type: %d\n", + __func__, region->memType); + + rc = -EINVAL; + break; + } + } + + if (rc != 0) { + memMap->numRegionsUsed--; + } + +out: + + DMA_MAP_PRINT("returning %d\n", rc); + + up(&memMap->lock); + + return rc; +} + +EXPORT_SYMBOL(dma_map_add_segment); + +/****************************************************************************/ +/** +* Maps in a memory region such that it can be used for performing a DMA. +* +* @return 0 on success, error code otherwise. +*/ +/****************************************************************************/ + +int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */ + void *mem, /* Virtual address that we want to get a map of */ + size_t numBytes, /* Number of bytes being mapped */ + enum dma_data_direction dir /* Direction that the mapping will be going */ + ) { + int rc; + + rc = dma_map_start(memMap, dir); + if (rc == 0) { + rc = dma_map_add_region(memMap, mem, numBytes); + if (rc < 0) { + /* Since the add fails, this function will fail, and the caller won't */ + /* call unmap, so we need to do it here. */ + + dma_unmap(memMap, 0); + } + } + + return rc; +} + +EXPORT_SYMBOL(dma_map_mem); + +/****************************************************************************/ +/** +* Setup a descriptor ring for a given memory map. +* +* It is assumed that the descriptor ring has already been initialized, and +* this routine will only reallocate a new descriptor ring if the existing +* one is too small. +* +* @return 0 on success, error code otherwise. +*/ +/****************************************************************************/ + +int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */ + DMA_MemMap_t *memMap, /* Memory map that will be used */ + dma_addr_t devPhysAddr /* Physical address of device */ + ) { + int rc; + int numDescriptors; + DMA_DeviceAttribute_t *devAttr; + DMA_Region_t *region; + DMA_Segment_t *segment; + dma_addr_t srcPhysAddr; + dma_addr_t dstPhysAddr; + int regionIdx; + int segmentIdx; + + devAttr = &DMA_gDeviceAttribute[dev]; + + down(&memMap->lock); + + /* Figure out how many descriptors we need */ + + numDescriptors = 0; + for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { + region = &memMap->region[regionIdx]; + + for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed; + segmentIdx++) { + segment = ®ion->segment[segmentIdx]; + + if (memMap->dir == DMA_TO_DEVICE) { + srcPhysAddr = segment->physAddr; + dstPhysAddr = devPhysAddr; + } else { + srcPhysAddr = devPhysAddr; + dstPhysAddr = segment->physAddr; + } + + rc = + dma_calculate_descriptor_count(dev, srcPhysAddr, + dstPhysAddr, + segment-> + numBytes); + if (rc < 0) { + printk(KERN_ERR + "%s: dma_calculate_descriptor_count failed: %d\n", + __func__, rc); + goto out; + } + numDescriptors += rc; + } + } + + /* Adjust the size of the ring, if it isn't big enough */ + + if (numDescriptors > devAttr->ring.descriptorsAllocated) { + dma_free_descriptor_ring(&devAttr->ring); + rc = + dma_alloc_descriptor_ring(&devAttr->ring, + numDescriptors); + if (rc < 0) { + printk(KERN_ERR + "%s: dma_alloc_descriptor_ring failed: %d\n", + __func__, rc); + goto out; + } + } else { + rc = + dma_init_descriptor_ring(&devAttr->ring, + numDescriptors); + if (rc < 0) { + printk(KERN_ERR + "%s: dma_init_descriptor_ring failed: %d\n", + __func__, rc); + goto out; + } + } + + /* Populate the descriptors */ + + for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { + region = &memMap->region[regionIdx]; + + for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed; + segmentIdx++) { + segment = ®ion->segment[segmentIdx]; + + if (memMap->dir == DMA_TO_DEVICE) { + srcPhysAddr = segment->physAddr; + dstPhysAddr = devPhysAddr; + } else { + srcPhysAddr = devPhysAddr; + dstPhysAddr = segment->physAddr; + } + + rc = + dma_add_descriptors(&devAttr->ring, dev, + srcPhysAddr, dstPhysAddr, + segment->numBytes); + if (rc < 0) { + printk(KERN_ERR + "%s: dma_add_descriptors failed: %d\n", + __func__, rc); + goto out; + } + } + } + + rc = 0; + +out: + + up(&memMap->lock); + return rc; +} + +EXPORT_SYMBOL(dma_map_create_descriptor_ring); + +/****************************************************************************/ +/** +* Maps in a memory region such that it can be used for performing a DMA. +* +* @return +*/ +/****************************************************************************/ + +int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ + int dirtied /* non-zero if any of the pages were modified */ + ) { + + int rc = 0; + int regionIdx; + int segmentIdx; + DMA_Region_t *region; + DMA_Segment_t *segment; + + down(&memMap->lock); + + for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { + region = &memMap->region[regionIdx]; + + for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed; + segmentIdx++) { + segment = ®ion->segment[segmentIdx]; + + switch (region->memType) { + case DMA_MEM_TYPE_VMALLOC: + { + printk(KERN_ERR + "%s: vmalloc'd pages are not yet supported\n", + __func__); + rc = -EINVAL; + goto out; + } + + case DMA_MEM_TYPE_KMALLOC: + { +#if ALLOW_MAP_OF_KMALLOC_MEMORY + dma_unmap_single(NULL, + segment->physAddr, + segment->numBytes, + memMap->dir); +#endif + break; + } + + case DMA_MEM_TYPE_DMA: + { + dma_sync_single_for_cpu(NULL, + segment-> + physAddr, + segment-> + numBytes, + memMap->dir); + break; + } + + case DMA_MEM_TYPE_USER: + { + /* Nothing to do here. */ + + break; + } + + default: + { + printk(KERN_ERR + "%s: Unsupported memory type: %d\n", + __func__, region->memType); + rc = -EINVAL; + goto out; + } + } + + segment->virtAddr = NULL; + segment->physAddr = 0; + segment->numBytes = 0; + } + + if (region->numLockedPages > 0) { + int pageIdx; + + /* Some user pages were locked. We need to go and unlock them now. */ + + for (pageIdx = 0; pageIdx < region->numLockedPages; + pageIdx++) { + struct page *page = + region->lockedPages[pageIdx]; + + if (memMap->dir == DMA_FROM_DEVICE) { + SetPageDirty(page); + } + page_cache_release(page); + } + kfree(region->lockedPages); + region->numLockedPages = 0; + region->lockedPages = NULL; + } + + region->memType = DMA_MEM_TYPE_NONE; + region->virtAddr = NULL; + region->numBytes = 0; + region->numSegmentsUsed = 0; + } + memMap->userTask = NULL; + memMap->numRegionsUsed = 0; + memMap->inUse = 0; + +out: + up(&memMap->lock); + + return rc; +} + +EXPORT_SYMBOL(dma_unmap); diff --git a/trunk/arch/arm/mach-bcmring/include/mach/dma.h b/trunk/arch/arm/mach-bcmring/include/mach/dma.h index 72543781207b..1f2c5319c056 100644 --- a/trunk/arch/arm/mach-bcmring/include/mach/dma.h +++ b/trunk/arch/arm/mach-bcmring/include/mach/dma.h @@ -26,9 +26,15 @@ /* ---- Include Files ---------------------------------------------------- */ #include +#include #include #include #include +#include +#include +#include +#include +#include /* ---- Constants and Types ---------------------------------------------- */ @@ -105,6 +111,78 @@ typedef struct { } DMA_DescriptorRing_t; +/**************************************************************************** +* +* The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup +* DMA chains from a variety of memory sources. +* +*****************************************************************************/ + +#define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */ + /* off not being DMA'd. */ + +typedef enum { + DMA_MEM_TYPE_NONE, /* Not a valid setting */ + DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */ + DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */ + DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */ + DMA_MEM_TYPE_USER, /* Memory came from user space. */ + +} DMA_MemType_t; + +/* A segment represents a physically and virtually contiguous chunk of memory. */ +/* i.e. each segment can be DMA'd */ +/* A user of the DMA code will add memory regions. Each region may need to be */ +/* represented by one or more segments. */ + +typedef struct { + void *virtAddr; /* Virtual address used for this segment */ + dma_addr_t physAddr; /* Physical address this segment maps to */ + size_t numBytes; /* Size of the segment, in bytes */ + +} DMA_Segment_t; + +/* A region represents a virtually contiguous chunk of memory, which may be */ +/* made up of multiple segments. */ + +typedef struct { + DMA_MemType_t memType; + void *virtAddr; + size_t numBytes; + + /* Each region (virtually contiguous) consists of one or more segments. Each */ + /* segment is virtually and physically contiguous. */ + + int numSegmentsUsed; + int numSegmentsAllocated; + DMA_Segment_t *segment; + + /* When a region corresponds to user memory, we need to lock all of the pages */ + /* down before we can figure out the physical addresses. The lockedPage array contains */ + /* the pages that were locked, and which subsequently need to be unlocked once the */ + /* memory is unmapped. */ + + unsigned numLockedPages; + struct page **lockedPages; + +} DMA_Region_t; + +typedef struct { + int inUse; /* Is this mapping currently being used? */ + struct semaphore lock; /* Acquired when using this structure */ + enum dma_data_direction dir; /* Direction this transfer is intended for */ + + /* In the event that we're mapping user memory, we need to know which task */ + /* the memory is for, so that we can obtain the correct mm locks. */ + + struct task_struct *userTask; + + int numRegionsUsed; + int numRegionsAllocated; + DMA_Region_t *region; + +} DMA_MemMap_t; + /**************************************************************************** * * The DMA_DeviceAttribute_t contains information which describes a @@ -490,6 +568,124 @@ int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */ size_t numBytes /* Number of bytes in each destination buffer */ ); +/****************************************************************************/ +/** +* Initializes a DMA_MemMap_t data structure +*/ +/****************************************************************************/ + +int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */ + ); + +/****************************************************************************/ +/** +* Releases any memory currently being held by a memory mapping structure. +*/ +/****************************************************************************/ + +int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */ + ); + +/****************************************************************************/ +/** +* Looks at a memory address and categorizes it. +* +* @return One of the values from the DMA_MemType_t enumeration. +*/ +/****************************************************************************/ + +DMA_MemType_t dma_mem_type(void *addr); + +/****************************************************************************/ +/** +* Sets the process (aka userTask) associated with a mem map. This is +* required if user-mode segments will be added to the mapping. +*/ +/****************************************************************************/ + +static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap, + struct task_struct *task) +{ + memMap->userTask = task; +} + +/****************************************************************************/ +/** +* Looks at a memory address and determines if we support DMA'ing to/from +* that type of memory. +* +* @return boolean - +* return value != 0 means dma supported +* return value == 0 means dma not supported +*/ +/****************************************************************************/ + +int dma_mem_supports_dma(void *addr); + +/****************************************************************************/ +/** +* Initializes a memory map for use. Since this function acquires a +* sempaphore within the memory map, it is VERY important that dma_unmap +* be called when you're finished using the map. +*/ +/****************************************************************************/ + +int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */ + enum dma_data_direction dir /* Direction that the mapping will be going */ + ); + +/****************************************************************************/ +/** +* Adds a segment of memory to a memory map. +* +* @return 0 on success, error code otherwise. +*/ +/****************************************************************************/ + +int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */ + void *mem, /* Virtual address that we want to get a map of */ + size_t numBytes /* Number of bytes being mapped */ + ); + +/****************************************************************************/ +/** +* Creates a descriptor ring from a memory mapping. +* +* @return 0 on success, error code otherwise. +*/ +/****************************************************************************/ + +int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */ + DMA_MemMap_t *memMap, /* Memory map that will be used */ + dma_addr_t devPhysAddr /* Physical address of device */ + ); + +/****************************************************************************/ +/** +* Maps in a memory region such that it can be used for performing a DMA. +* +* @return +*/ +/****************************************************************************/ + +int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */ + void *addr, /* Virtual address that we want to get a map of */ + size_t count, /* Number of bytes being mapped */ + enum dma_data_direction dir /* Direction that the mapping will be going */ + ); + +/****************************************************************************/ +/** +* Maps in a memory region such that it can be used for performing a DMA. +* +* @return +*/ +/****************************************************************************/ + +int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ + int dirtied /* non-zero if any of the pages were modified */ + ); + /****************************************************************************/ /** * Initiates a transfer when the descriptors have already been setup. diff --git a/trunk/arch/arm/mach-davinci/board-da850-evm.c b/trunk/arch/arm/mach-davinci/board-da850-evm.c index d5088900af6c..6b22b543a83f 100644 --- a/trunk/arch/arm/mach-davinci/board-da850-evm.c +++ b/trunk/arch/arm/mach-davinci/board-da850-evm.c @@ -44,7 +44,7 @@ #include #include -#define DA850_EVM_PHY_ID "davinci_mdio-0:00" +#define DA850_EVM_PHY_ID "0:00" #define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8) #define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15) diff --git a/trunk/arch/arm/mach-davinci/board-dm365-evm.c b/trunk/arch/arm/mach-davinci/board-dm365-evm.c index 849311d3cb7c..346e1de2f5a8 100644 --- a/trunk/arch/arm/mach-davinci/board-dm365-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm365-evm.c @@ -54,7 +54,7 @@ static inline int have_tvp7002(void) return 0; } -#define DM365_EVM_PHY_ID "davinci_mdio-0:01" +#define DM365_EVM_PHY_ID "0:01" /* * A MAX-II CPLD is used for various board control functions. */ diff --git a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c index 1247ecdcf752..a64b49cfedca 100644 --- a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c @@ -40,7 +40,7 @@ #include #include -#define DM644X_EVM_PHY_ID "davinci_mdio-0:01" +#define DM644X_EVM_PHY_ID "0:01" #define LXT971_PHY_ID (0x001378e2) #define LXT971_PHY_MASK (0xfffffff0) diff --git a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c index 872ac69fa049..64017558860b 100644 --- a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c @@ -736,7 +736,7 @@ static struct davinci_uart_config uart_config __initdata = { .enabled_uarts = (1 << 0), }; -#define DM646X_EVM_PHY_ID "davinci_mdio-0:01" +#define DM646X_EVM_PHY_ID "0:01" /* * The following EDMA channels/slots are not being used by drivers (for * example: Timer, GPIO, UART events etc) on dm646x, hence they are being diff --git a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c index 8d34f513d415..6c4a16415d47 100644 --- a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c @@ -39,7 +39,7 @@ #include #include -#define NEUROS_OSD2_PHY_ID "davinci_mdio-0:01" +#define NEUROS_OSD2_PHY_ID "0:01" #define LXT971_PHY_ID 0x001378e2 #define LXT971_PHY_MASK 0xfffffff0 diff --git a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c index 45e815760a27..e7c0c7c53493 100644 --- a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -21,7 +21,7 @@ #include #include -#define HAWKBOARD_PHY_ID "davinci_mdio-0:07" +#define HAWKBOARD_PHY_ID "0:07" #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) diff --git a/trunk/arch/arm/mach-davinci/board-sffsdr.c b/trunk/arch/arm/mach-davinci/board-sffsdr.c index 31da3c5b2ba3..0b136a831c59 100644 --- a/trunk/arch/arm/mach-davinci/board-sffsdr.c +++ b/trunk/arch/arm/mach-davinci/board-sffsdr.c @@ -42,7 +42,7 @@ #include #include -#define SFFSDR_PHY_ID "davinci_mdio-0:01" +#define SFFSDR_PHY_ID "0:01" static struct mtd_partition davinci_sffsdr_nandflash_partition[] = { /* U-Boot Environment: Block 0 * UBL: Block 1 diff --git a/trunk/arch/arm/mach-davinci/da850.c b/trunk/arch/arm/mach-davinci/da850.c index 992c4c410185..0ed7fdb64efb 100644 --- a/trunk/arch/arm/mach-davinci/da850.c +++ b/trunk/arch/arm/mach-davinci/da850.c @@ -153,6 +153,34 @@ static struct clk pll1_sysclk3 = { .div_reg = PLLDIV3, }; +static struct clk pll1_sysclk4 = { + .name = "pll1_sysclk4", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV4, +}; + +static struct clk pll1_sysclk5 = { + .name = "pll1_sysclk5", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV5, +}; + +static struct clk pll1_sysclk6 = { + .name = "pll0_sysclk6", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV6, +}; + +static struct clk pll1_sysclk7 = { + .name = "pll1_sysclk7", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV7, +}; + static struct clk i2c0_clk = { .name = "i2c0", .parent = &pll0_aux_clk, @@ -369,6 +397,10 @@ static struct clk_lookup da850_clks[] = { CLK(NULL, "pll1_aux", &pll1_aux_clk), CLK(NULL, "pll1_sysclk2", &pll1_sysclk2), CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), + CLK(NULL, "pll1_sysclk4", &pll1_sysclk4), + CLK(NULL, "pll1_sysclk5", &pll1_sysclk5), + CLK(NULL, "pll1_sysclk6", &pll1_sysclk6), + CLK(NULL, "pll1_sysclk7", &pll1_sysclk7), CLK("i2c_davinci.1", NULL, &i2c0_clk), CLK(NULL, "timer0", &timerp64_0_clk), CLK("watchdog", NULL, &timerp64_1_clk), diff --git a/trunk/arch/arm/mach-exynos/hotplug.c b/trunk/arch/arm/mach-exynos/hotplug.c index dd1ad55524c9..da70e7e39937 100644 --- a/trunk/arch/arm/mach-exynos/hotplug.c +++ b/trunk/arch/arm/mach-exynos/hotplug.c @@ -16,7 +16,6 @@ #include #include -#include #include diff --git a/trunk/arch/arm/mach-exynos/platsmp.c b/trunk/arch/arm/mach-exynos/platsmp.c index 0f2035a1eb6e..683aec786b78 100644 --- a/trunk/arch/arm/mach-exynos/platsmp.c +++ b/trunk/arch/arm/mach-exynos/platsmp.c @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-highbank/highbank.c b/trunk/arch/arm/mach-highbank/highbank.c index 8394d512a402..7afbe1e55beb 100644 --- a/trunk/arch/arm/mach-highbank/highbank.c +++ b/trunk/arch/arm/mach-highbank/highbank.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -73,7 +72,9 @@ static void __init highbank_map_io(void) void highbank_set_cpu_jump(int cpu, void *jump_addr) { +#ifdef CONFIG_SMP cpu = cpu_logical_map(cpu); +#endif writel(virt_to_phys(jump_addr), HB_JUMP_TABLE_VIRT(cpu)); __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16); outer_clean_range(HB_JUMP_TABLE_PHYS(cpu), diff --git a/trunk/arch/arm/mach-imx/Kconfig b/trunk/arch/arm/mach-imx/Kconfig index 4defb97bbfc8..09f357bcecde 100644 --- a/trunk/arch/arm/mach-imx/Kconfig +++ b/trunk/arch/arm/mach-imx/Kconfig @@ -87,6 +87,7 @@ config SOC_IMX35 config SOC_IMX5 select CPU_V7 + select ARM_L1_CACHE_SHIFT_6 select MXC_TZIC select ARCH_MXC_IOMUX_V3 select ARCH_MXC_AUDMUX_V2 diff --git a/trunk/arch/arm/mach-imx/clock-imx6q.c b/trunk/arch/arm/mach-imx/clock-imx6q.c index 2d88f8b9a454..9273c2a24b54 100644 --- a/trunk/arch/arm/mach-imx/clock-imx6q.c +++ b/trunk/arch/arm/mach-imx/clock-imx6q.c @@ -814,16 +814,6 @@ DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg); DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg); DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg); -static unsigned long twd_clk_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / 2; -} - -static struct clk twd_clk = { - .parent = &arm_clk, - .get_rate = twd_clk_get_rate, -}; - static unsigned long pll2_200m_get_rate(struct clk *clk) { return clk_get_rate(clk->parent) / 2; @@ -1904,7 +1894,6 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk), _REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk), _REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk), - _REGISTER_CLOCK("smp_twd", NULL, twd_clk), _REGISTER_CLOCK(NULL, "ckih", ckih_clk), _REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk), _REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk), diff --git a/trunk/arch/arm/mach-imx/mach-mx53_ard.c b/trunk/arch/arm/mach-imx/mach-mx53_ard.c index 753f4fc9ec04..08dfb7628d2d 100644 --- a/trunk/arch/arm/mach-imx/mach-mx53_ard.c +++ b/trunk/arch/arm/mach-imx/mach-mx53_ard.c @@ -188,10 +188,8 @@ static int weim_cs_config(void) return -ENOMEM; iomuxc_base = ioremap(MX53_IOMUXC_BASE_ADDR, SZ_4K); - if (!iomuxc_base) { - iounmap(weim_base); + if (!iomuxc_base) return -ENOMEM; - } /* CS1 timings for LAN9220 */ writel(0x20001, (weim_base + 0x18)); diff --git a/trunk/arch/arm/mach-imx/src.c b/trunk/arch/arm/mach-imx/src.c index e15f1555c59b..29bd1243781e 100644 --- a/trunk/arch/arm/mach-imx/src.c +++ b/trunk/arch/arm/mach-imx/src.c @@ -15,7 +15,6 @@ #include #include #include -#include #define SRC_SCR 0x000 #define SRC_GPR1 0x020 @@ -25,6 +24,10 @@ static void __iomem *src_base; +#ifndef CONFIG_SMP +#define cpu_logical_map(cpu) 0 +#endif + void imx_enable_cpu(int cpu, bool enable) { u32 mask, val; diff --git a/trunk/arch/arm/mach-msm/hotplug.c b/trunk/arch/arm/mach-msm/hotplug.c index a446fc14221f..41c252de0215 100644 --- a/trunk/arch/arm/mach-msm/hotplug.c +++ b/trunk/arch/arm/mach-msm/hotplug.c @@ -11,7 +11,6 @@ #include #include -#include extern volatile int pen_release; diff --git a/trunk/arch/arm/mach-msm/platsmp.c b/trunk/arch/arm/mach-msm/platsmp.c index db0117ec55f4..0b3e357c4c8c 100644 --- a/trunk/arch/arm/mach-msm/platsmp.c +++ b/trunk/arch/arm/mach-msm/platsmp.c @@ -20,7 +20,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig index d965da45160e..a8ba7b96dcd1 100644 --- a/trunk/arch/arm/mach-omap2/Kconfig +++ b/trunk/arch/arm/mach-omap2/Kconfig @@ -33,6 +33,7 @@ config ARCH_OMAP3 default y select CPU_V7 select USB_ARCH_HAS_EHCI + select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4 select ARCH_HAS_OPP select PM_OPP if PM select ARM_CPU_SUSPEND if PM @@ -213,12 +214,13 @@ config MACH_OMAP3_PANDORA depends on ARCH_OMAP3 default y select OMAP_PACKAGE_CBB - select REGULATOR_FIXED_VOLTAGE if REGULATOR + select REGULATOR_FIXED_VOLTAGE config MACH_OMAP3_TOUCHBOOK bool "OMAP3 Touch Book" depends on ARCH_OMAP3 default y + select BACKLIGHT_CLASS_DEVICE config MACH_OMAP_3430SDP bool "OMAP 3430 SDP board" @@ -264,7 +266,7 @@ config MACH_OMAP_ZOOM2 select SERIAL_8250 select SERIAL_CORE_CONSOLE select SERIAL_8250_CONSOLE - select REGULATOR_FIXED_VOLTAGE if REGULATOR + select REGULATOR_FIXED_VOLTAGE config MACH_OMAP_ZOOM3 bool "OMAP3630 Zoom3 board" @@ -274,7 +276,7 @@ config MACH_OMAP_ZOOM3 select SERIAL_8250 select SERIAL_CORE_CONSOLE select SERIAL_8250_CONSOLE - select REGULATOR_FIXED_VOLTAGE if REGULATOR + select REGULATOR_FIXED_VOLTAGE config MACH_CM_T35 bool "CompuLab CM-T35/CM-T3730 modules" @@ -333,7 +335,7 @@ config MACH_OMAP_4430SDP depends on ARCH_OMAP4 select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS - select REGULATOR_FIXED_VOLTAGE if REGULATOR + select REGULATOR_FIXED_VOLTAGE config MACH_OMAP4_PANDA bool "OMAP4 Panda Board" @@ -341,7 +343,7 @@ config MACH_OMAP4_PANDA depends on ARCH_OMAP4 select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS - select REGULATOR_FIXED_VOLTAGE if REGULATOR + select REGULATOR_FIXED_VOLTAGE config OMAP3_EMU bool "OMAP3 debugging peripherals" diff --git a/trunk/arch/arm/mach-omap2/devices.c b/trunk/arch/arm/mach-omap2/devices.c index 283d11eae693..0b510ad01a00 100644 --- a/trunk/arch/arm/mach-omap2/devices.c +++ b/trunk/arch/arm/mach-omap2/devices.c @@ -405,7 +405,6 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) break; default: pr_err("Invalid McSPI Revision value\n"); - kfree(pdata); return -EINVAL; } diff --git a/trunk/arch/arm/mach-omap2/gpmc.c b/trunk/arch/arm/mach-omap2/gpmc.c index dfffbbf4c009..130034bf01d5 100644 --- a/trunk/arch/arm/mach-omap2/gpmc.c +++ b/trunk/arch/arm/mach-omap2/gpmc.c @@ -528,13 +528,7 @@ int gpmc_cs_configure(int cs, int cmd, int wval) case GPMC_CONFIG_DEV_SIZE: regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - /* clear 2 target bits */ - regval &= ~GPMC_CONFIG1_DEVICESIZE(3); - - /* set the proper value */ regval |= GPMC_CONFIG1_DEVICESIZE(wval); - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); break; diff --git a/trunk/arch/arm/mach-omap2/hsmmc.c b/trunk/arch/arm/mach-omap2/hsmmc.c index ad0adb5a1e0e..bd844af13af5 100644 --- a/trunk/arch/arm/mach-omap2/hsmmc.c +++ b/trunk/arch/arm/mach-omap2/hsmmc.c @@ -175,15 +175,14 @@ static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc) { u32 reg; - reg = omap_ctrl_readl(control_devconf1_offset); - if (mmc->slots[0].internal_clock) + if (mmc->slots[0].internal_clock) { + reg = omap_ctrl_readl(control_devconf1_offset); reg |= OMAP2_MMCSDIO2ADPCLKISEL; - else - reg &= ~OMAP2_MMCSDIO2ADPCLKISEL; - omap_ctrl_writel(reg, control_devconf1_offset); + omap_ctrl_writel(reg, control_devconf1_offset); + } } -static void hsmmc2_before_set_reg(struct device *dev, int slot, +static void hsmmc23_before_set_reg(struct device *dev, int slot, int power_on, int vdd) { struct omap_mmc_platform_data *mmc = dev->platform_data; @@ -408,13 +407,14 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; } + /* FALLTHROUGH */ + case 3: if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { /* off-chip level shifting, or none */ - mmc->slots[0].before_set_reg = hsmmc2_before_set_reg; + mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; mmc->slots[0].after_set_reg = NULL; } break; - case 3: case 4: case 5: mmc->slots[0].before_set_reg = NULL; diff --git a/trunk/arch/arm/mach-omap2/io.c b/trunk/arch/arm/mach-omap2/io.c index eb50c29fb644..3f174d51f67f 100644 --- a/trunk/arch/arm/mach-omap2/io.c +++ b/trunk/arch/arm/mach-omap2/io.c @@ -388,7 +388,7 @@ static void __init omap_hwmod_init_postsetup(void) omap_pm_if_early_init(); } -#ifdef CONFIG_SOC_OMAP2420 +#ifdef CONFIG_ARCH_OMAP2 void __init omap2420_init_early(void) { omap2_set_globals_242x(); @@ -400,9 +400,7 @@ void __init omap2420_init_early(void) omap_hwmod_init_postsetup(); omap2420_clk_init(); } -#endif -#ifdef CONFIG_SOC_OMAP2430 void __init omap2430_init_early(void) { omap2_set_globals_243x(); diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c index f08e442af397..c11273da5dcc 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c @@ -55,6 +55,27 @@ struct omap_hwmod_class omap2_dss_hwmod_class = { .reset = omap_dss_reset, }; +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap2_dispc_sysc, +}; + /* * 'rfbi' class * remote frame buffer interface diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index 2a6729741b06..177dee20faef 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -28,28 +28,6 @@ struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = { { .name = "dispc", .dma_req = 5 }, { .dma_req = -1 } }; - -/* - * 'dispc' class - * display controller - */ - -static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | - SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -struct omap_hwmod_class omap2_dispc_hwmod_class = { - .name = "dispc", - .sysc = &omap2_dispc_sysc, -}; - /* OMAP2xxx Timer Common */ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = { .rev_offs = 0x0000, diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 3c8dd928628e..5324e8d93bc0 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1480,28 +1480,6 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = { .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters), }; -/* - * 'dispc' class - * display controller - */ - -static struct omap_hwmod_class_sysconfig omap3_dispc_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | - SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | - SYSC_HAS_ENAWAKEUP), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class omap3_dispc_hwmod_class = { - .name = "dispc", - .sysc = &omap3_dispc_sysc, -}; - /* l4_core -> dss_dispc */ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = { .master = &omap3xxx_l4_core_hwmod, @@ -1525,7 +1503,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = { static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { .name = "dss_dispc", - .class = &omap3_dispc_hwmod_class, + .class = &omap2_dispc_hwmod_class, .mpu_irqs = omap2_dispc_irqs, .main_clk = "dss1_alwon_fck", .prcm = { @@ -3545,6 +3523,12 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { &omap3xxx_uart2_hwmod, &omap3xxx_uart3_hwmod, + /* dss class */ + &omap3xxx_dss_dispc_hwmod, + &omap3xxx_dss_dsi1_hwmod, + &omap3xxx_dss_rfbi_hwmod, + &omap3xxx_dss_venc_hwmod, + /* i2c class */ &omap3xxx_i2c1_hwmod, &omap3xxx_i2c2_hwmod, @@ -3651,15 +3635,6 @@ static __initdata struct omap_hwmod *am35xx_hwmods[] = { NULL }; -static __initdata struct omap_hwmod *omap3xxx_dss_hwmods[] = { - /* dss class */ - &omap3xxx_dss_dispc_hwmod, - &omap3xxx_dss_dsi1_hwmod, - &omap3xxx_dss_rfbi_hwmod, - &omap3xxx_dss_venc_hwmod, - NULL -}; - int __init omap3xxx_hwmod_init(void) { int r; @@ -3733,21 +3708,6 @@ int __init omap3xxx_hwmod_init(void) if (h) r = omap_hwmod_register(h); - if (r < 0) - return r; - - /* - * DSS code presumes that dss_core hwmod is handled first, - * _before_ any other DSS related hwmods so register common - * DSS hwmods last to ensure that dss_core is already registered. - * Otherwise some change things may happen, for ex. if dispc - * is handled before dss_core and DSS is enabled in bootloader - * DIPSC will be reset with outputs enabled which sometimes leads - * to unrecoverable L3 error. - * XXX The long-term fix to this is to ensure modules are set up - * in dependency order in the hwmod core code. - */ - r = omap_hwmod_register(omap3xxx_dss_hwmods); return r; } diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index ef0524c10a84..f9f151081760 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1031,7 +1031,6 @@ static struct omap_hwmod_dma_info omap44xx_dmic_sdma_reqs[] = { static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = { { - .name = "mpu", .pa_start = 0x4012e000, .pa_end = 0x4012e07f, .flags = ADDR_TYPE_RT @@ -1050,7 +1049,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = { static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = { { - .name = "dma", .pa_start = 0x4902e000, .pa_end = 0x4902e07f, .flags = ADDR_TYPE_RT diff --git a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c index 9ce765407ad5..c1c4d86a79a8 100644 --- a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -19,7 +19,6 @@ #include "common.h" #include #include -#include #include "vp.h" diff --git a/trunk/arch/arm/mach-omap2/smartreflex.c b/trunk/arch/arm/mach-omap2/smartreflex.c index 7e755bb0ffc4..9dd93453e563 100644 --- a/trunk/arch/arm/mach-omap2/smartreflex.c +++ b/trunk/arch/arm/mach-omap2/smartreflex.c @@ -897,7 +897,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) ret = sr_late_init(sr_info); if (ret) { pr_warning("%s: Error in SR late init\n", __func__); - goto err_iounmap; + return ret; } } diff --git a/trunk/arch/arm/mach-omap2/timer.c b/trunk/arch/arm/mach-omap2/timer.c index 5c9acea95761..6eeff0e0ae01 100644 --- a/trunk/arch/arm/mach-omap2/timer.c +++ b/trunk/arch/arm/mach-omap2/timer.c @@ -270,7 +270,7 @@ static struct clocksource clocksource_gpt = { static u32 notrace dmtimer_read_sched_clock(void) { if (clksrc.reserved) - return __omap_dm_timer_read_counter(&clksrc, 1); + return __omap_dm_timer_read_counter(clksrc.io_base, 1); return 0; } diff --git a/trunk/arch/arm/mach-pxa/devices.c b/trunk/arch/arm/mach-pxa/devices.c index 5bc13121eac5..18fd177073f4 100644 --- a/trunk/arch/arm/mach-pxa/devices.c +++ b/trunk/arch/arm/mach-pxa/devices.c @@ -415,9 +415,29 @@ static struct resource pxa_rtc_resources[] = { }, }; +static struct resource sa1100_rtc_resources[] = { + [0] = { + .start = 0x40900000, + .end = 0x409000ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC1Hz, + .end = IRQ_RTC1Hz, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .flags = IORESOURCE_IRQ, + }, +}; + struct platform_device sa1100_device_rtc = { .name = "sa1100-rtc", .id = -1, + .num_resources = ARRAY_SIZE(sa1100_rtc_resources), + .resource = sa1100_rtc_resources, }; struct platform_device pxa_device_rtc = { diff --git a/trunk/arch/arm/mach-pxa/pxa25x.c b/trunk/arch/arm/mach-pxa/pxa25x.c index 91e4f6c03766..adf058fa97ee 100644 --- a/trunk/arch/arm/mach-pxa/pxa25x.c +++ b/trunk/arch/arm/mach-pxa/pxa25x.c @@ -209,6 +209,8 @@ static struct clk_lookup pxa25x_clkregs[] = { INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), + INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; static struct clk_lookup pxa25x_hwuart_clkreg = diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c index aed6cbcf3866..180bd8675d4b 100644 --- a/trunk/arch/arm/mach-pxa/pxa27x.c +++ b/trunk/arch/arm/mach-pxa/pxa27x.c @@ -230,6 +230,8 @@ static struct clk_lookup pxa27x_clkregs[] = { INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), + INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; #ifdef CONFIG_PM diff --git a/trunk/arch/arm/mach-pxa/pxa300.c b/trunk/arch/arm/mach-pxa/pxa300.c index 40bb16501d86..0388eda7878a 100644 --- a/trunk/arch/arm/mach-pxa/pxa300.c +++ b/trunk/arch/arm/mach-pxa/pxa300.c @@ -89,6 +89,7 @@ static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0); static struct clk_lookup common_clkregs[] = { INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL), INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0); diff --git a/trunk/arch/arm/mach-pxa/pxa320.c b/trunk/arch/arm/mach-pxa/pxa320.c index 8d614ecd8e99..d487e1ff4c9a 100644 --- a/trunk/arch/arm/mach-pxa/pxa320.c +++ b/trunk/arch/arm/mach-pxa/pxa320.c @@ -83,6 +83,7 @@ static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0); static struct clk_lookup pxa320_clkregs[] = { INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL), INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; static int __init pxa320_init(void) diff --git a/trunk/arch/arm/mach-pxa/pxa3xx.c b/trunk/arch/arm/mach-pxa/pxa3xx.c index 4f402afa6609..f107c71c7589 100644 --- a/trunk/arch/arm/mach-pxa/pxa3xx.c +++ b/trunk/arch/arm/mach-pxa/pxa3xx.c @@ -67,6 +67,7 @@ static struct clk_lookup pxa3xx_clkregs[] = { INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), /* Power I2C clock is always on */ INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL), INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"), INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"), diff --git a/trunk/arch/arm/mach-pxa/pxa95x.c b/trunk/arch/arm/mach-pxa/pxa95x.c index d082a583df78..fccc644702e6 100644 --- a/trunk/arch/arm/mach-pxa/pxa95x.c +++ b/trunk/arch/arm/mach-pxa/pxa95x.c @@ -217,6 +217,7 @@ static struct clk_lookup pxa95x_clkregs[] = { INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"), /* Power I2C clock is always on */ INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL), INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL), INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL), diff --git a/trunk/arch/arm/mach-realview/hotplug.c b/trunk/arch/arm/mach-realview/hotplug.c index eb55f05bef3a..ac1aed2a8da4 100644 --- a/trunk/arch/arm/mach-realview/hotplug.c +++ b/trunk/arch/arm/mach-realview/hotplug.c @@ -13,7 +13,6 @@ #include #include -#include extern volatile int pen_release; diff --git a/trunk/arch/arm/mach-realview/include/mach/board-eb.h b/trunk/arch/arm/mach-realview/include/mach/board-eb.h index 124bce6b4d7b..794a8d91a6a6 100644 --- a/trunk/arch/arm/mach-realview/include/mach/board-eb.h +++ b/trunk/arch/arm/mach-realview/include/mach/board-eb.h @@ -47,23 +47,21 @@ #define REALVIEW_EB_USB_BASE 0x4F000000 /* USB */ #ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB -#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000 +#define REALVIEW_EB11MP_SCU_BASE 0x10100000 /* SCU registers */ +#define REALVIEW_EB11MP_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */ +#define REALVIEW_EB11MP_TWD_BASE 0x10100600 +#define REALVIEW_EB11MP_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */ #define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */ #define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */ #else -#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000 +#define REALVIEW_EB11MP_SCU_BASE 0x1F000000 /* SCU registers */ +#define REALVIEW_EB11MP_GIC_CPU_BASE 0x1F000100 /* Generic interrupt controller CPU interface */ +#define REALVIEW_EB11MP_TWD_BASE 0x1F000600 +#define REALVIEW_EB11MP_GIC_DIST_BASE 0x1F001000 /* Generic interrupt controller distributor */ #define REALVIEW_EB11MP_L220_BASE 0x1F002000 /* L220 registers */ #define REALVIEW_EB11MP_SYS_PLD_CTRL1 0x74 /* Register offset for MPCore sysctl */ #endif -#define REALVIEW_EB11MP_PRIV_MEM_SIZE SZ_8K -#define REALVIEW_EB11MP_PRIV_MEM_OFF(x) (REALVIEW_EB11MP_PRIV_MEM_BASE + (x)) - -#define REALVIEW_EB11MP_SCU_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0) /* SCU registers */ -#define REALVIEW_EB11MP_GIC_CPU_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x0100) /* Generic interrupt controller CPU interface */ -#define REALVIEW_EB11MP_TWD_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x0600) -#define REALVIEW_EB11MP_GIC_DIST_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x1000) /* Generic interrupt controller distributor */ - /* * Core tile identification (REALVIEW_SYS_PROCID) */ diff --git a/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h b/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h index aa2d4e02ea2c..7abf918b77e9 100644 --- a/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h +++ b/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h @@ -75,8 +75,6 @@ /* * Testchip peripheral and fpga gic regions */ -#define REALVIEW_TC11MP_PRIV_MEM_BASE 0x1F000000 -#define REALVIEW_TC11MP_PRIV_MEM_SIZE SZ_8K #define REALVIEW_TC11MP_SCU_BASE 0x1F000000 /* IRQ, Test chip */ #define REALVIEW_TC11MP_GIC_CPU_BASE 0x1F000100 /* Test chip interrupt controller CPU interface */ #define REALVIEW_TC11MP_TWD_BASE 0x1F000600 diff --git a/trunk/arch/arm/mach-realview/realview_eb.c b/trunk/arch/arm/mach-realview/realview_eb.c index 9578145f2df0..e62962117763 100644 --- a/trunk/arch/arm/mach-realview/realview_eb.c +++ b/trunk/arch/arm/mach-realview/realview_eb.c @@ -91,9 +91,14 @@ static struct map_desc realview_eb_io_desc[] __initdata = { static struct map_desc realview_eb11mp_io_desc[] __initdata = { { - .virtual = IO_ADDRESS(REALVIEW_EB11MP_PRIV_MEM_BASE), - .pfn = __phys_to_pfn(REALVIEW_EB11MP_PRIV_MEM_BASE), - .length = REALVIEW_EB11MP_PRIV_MEM_SIZE, + .virtual = IO_ADDRESS(REALVIEW_EB11MP_SCU_BASE), + .pfn = __phys_to_pfn(REALVIEW_EB11MP_SCU_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = IO_ADDRESS(REALVIEW_EB11MP_GIC_DIST_BASE), + .pfn = __phys_to_pfn(REALVIEW_EB11MP_GIC_DIST_BASE), + .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = IO_ADDRESS(REALVIEW_EB11MP_L220_BASE), diff --git a/trunk/arch/arm/mach-realview/realview_pb11mp.c b/trunk/arch/arm/mach-realview/realview_pb11mp.c index 2147335f66f5..127a3fd42ab1 100644 --- a/trunk/arch/arm/mach-realview/realview_pb11mp.c +++ b/trunk/arch/arm/mach-realview/realview_pb11mp.c @@ -64,10 +64,15 @@ static struct map_desc realview_pb11mp_io_desc[] __initdata = { .pfn = __phys_to_pfn(REALVIEW_PB11MP_GIC_DIST_BASE), .length = SZ_4K, .type = MT_DEVICE, - }, { /* Maps the SCU, GIC CPU interface, TWD, GIC DIST */ - .virtual = IO_ADDRESS(REALVIEW_TC11MP_PRIV_MEM_BASE), - .pfn = __phys_to_pfn(REALVIEW_TC11MP_PRIV_MEM_BASE), - .length = REALVIEW_TC11MP_PRIV_MEM_SIZE, + }, { + .virtual = IO_ADDRESS(REALVIEW_TC11MP_GIC_CPU_BASE), + .pfn = __phys_to_pfn(REALVIEW_TC11MP_GIC_CPU_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = IO_ADDRESS(REALVIEW_TC11MP_GIC_DIST_BASE), + .pfn = __phys_to_pfn(REALVIEW_TC11MP_GIC_DIST_BASE), + .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE), diff --git a/trunk/arch/arm/mach-sa1100/assabet.c b/trunk/arch/arm/mach-sa1100/assabet.c index 0c4b76ab4d8e..ebafe8aa8956 100644 --- a/trunk/arch/arm/mach-sa1100/assabet.c +++ b/trunk/arch/arm/mach-sa1100/assabet.c @@ -202,6 +202,7 @@ static struct irda_platform_data assabet_irda_data = { static struct mcp_plat_data assabet_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init assabet_init(void) @@ -252,6 +253,17 @@ static void __init assabet_init(void) sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources, ARRAY_SIZE(assabet_flash_resources)); sa11x0_register_irda(&assabet_irda_data); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + + ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); sa11x0_register_mcp(&assabet_mcp_data); } diff --git a/trunk/arch/arm/mach-sa1100/cerf.c b/trunk/arch/arm/mach-sa1100/cerf.c index 11bb6d0b9be3..d12d0f48b1dc 100644 --- a/trunk/arch/arm/mach-sa1100/cerf.c +++ b/trunk/arch/arm/mach-sa1100/cerf.c @@ -124,12 +124,23 @@ static void __init cerf_map_io(void) static struct mcp_plat_data cerf_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init cerf_init(void) { platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices)); sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&cerf_mcp_data); } diff --git a/trunk/arch/arm/mach-sa1100/clock.c b/trunk/arch/arm/mach-sa1100/clock.c index dab3c6347a8f..d6df9f6c9f7e 100644 --- a/trunk/arch/arm/mach-sa1100/clock.c +++ b/trunk/arch/arm/mach-sa1100/clock.c @@ -11,17 +11,39 @@ #include #include #include +#include +#include #include -/* - * Very simple clock implementation - we only have one clock to deal with. - */ +struct clkops { + void (*enable)(struct clk *); + void (*disable)(struct clk *); + unsigned long (*getrate)(struct clk *); +}; + struct clk { + const struct clkops *ops; + unsigned long rate; unsigned int enabled; }; -static void clk_gpio27_enable(void) +#define INIT_CLKREG(_clk, _devname, _conname) \ + { \ + .clk = _clk, \ + .dev_id = _devname, \ + .con_id = _conname, \ + } + +#define DEFINE_CLK(_name, _ops, _rate) \ +struct clk clk_##_name = { \ + .ops = _ops, \ + .rate = _rate, \ + } + +static DEFINE_SPINLOCK(clocks_lock); + +static void clk_gpio27_enable(struct clk *clk) { /* * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: @@ -32,38 +54,22 @@ static void clk_gpio27_enable(void) TUCR = TUCR_3_6864MHz; } -static void clk_gpio27_disable(void) +static void clk_gpio27_disable(struct clk *clk) { TUCR = 0; GPDR &= ~GPIO_32_768kHz; GAFR &= ~GPIO_32_768kHz; } -static struct clk clk_gpio27; - -static DEFINE_SPINLOCK(clocks_lock); - -struct clk *clk_get(struct device *dev, const char *id) -{ - const char *devname = dev_name(dev); - - return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27; -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - int clk_enable(struct clk *clk) { unsigned long flags; spin_lock_irqsave(&clocks_lock, flags); if (clk->enabled++ == 0) - clk_gpio27_enable(); + clk->ops->enable(clk); spin_unlock_irqrestore(&clocks_lock, flags); + return 0; } EXPORT_SYMBOL(clk_enable); @@ -76,13 +82,48 @@ void clk_disable(struct clk *clk) spin_lock_irqsave(&clocks_lock, flags); if (--clk->enabled == 0) - clk_gpio27_disable(); + clk->ops->disable(clk); spin_unlock_irqrestore(&clocks_lock, flags); } EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { - return 3686400; + unsigned long rate; + + rate = clk->rate; + if (clk->ops->getrate) + rate = clk->ops->getrate(clk); + + return rate; } EXPORT_SYMBOL(clk_get_rate); + +const struct clkops clk_gpio27_ops = { + .enable = clk_gpio27_enable, + .disable = clk_gpio27_disable, +}; + +static void clk_dummy_enable(struct clk *clk) { } +static void clk_dummy_disable(struct clk *clk) { } + +const struct clkops clk_dummy_ops = { + .enable = clk_dummy_enable, + .disable = clk_dummy_disable, +}; + +static DEFINE_CLK(gpio27, &clk_gpio27_ops, 3686400); +static DEFINE_CLK(dummy, &clk_dummy_ops, 0); + +static struct clk_lookup sa11xx_clkregs[] = { + INIT_CLKREG(&clk_gpio27, "sa1111.0", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), +}; + +static int __init sa11xx_clk_init(void) +{ + clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs)); + return 0; +} + +postcore_initcall(sa11xx_clk_init); diff --git a/trunk/arch/arm/mach-sa1100/collie.c b/trunk/arch/arm/mach-sa1100/collie.c index fd5652118ed1..c483912d08af 100644 --- a/trunk/arch/arm/mach-sa1100/collie.c +++ b/trunk/arch/arm/mach-sa1100/collie.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -85,10 +86,15 @@ static struct scoop_pcmcia_config collie_pcmcia_config = { .num_devs = 1, }; +static struct ucb1x00_plat_data collie_ucb1x00_data = { + .gpio_base = COLLIE_TC35143_GPIO_BASE, +}; + static struct mcp_plat_data collie_mcp_data = { .mccr0 = MCCR0_ADM | MCCR0_ExtClk, .sclk_rate = 9216000, - .gpio_base = COLLIE_TC35143_GPIO_BASE, + .codec = "ucb1x00", + .codec_pdata = &collie_ucb1x00_data, }; /* @@ -138,6 +144,8 @@ static struct pda_power_pdata collie_power_data = { static struct resource collie_power_resource[] = { { .name = "ac", + .start = gpio_to_irq(COLLIE_GPIO_AC_IN), + .end = gpio_to_irq(COLLIE_GPIO_AC_IN), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, @@ -339,8 +347,7 @@ static void __init collie_init(void) GPSR |= _COLLIE_GPIO_UCB1x00_RESET; - collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN); - collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN); + platform_scoop_config = &collie_pcmcia_config; ret = platform_add_devices(devices, ARRAY_SIZE(devices)); @@ -350,6 +357,16 @@ static void __init collie_init(void) sa11x0_register_mtd(&collie_flash_data, collie_flash_resources, ARRAY_SIZE(collie_flash_resources)); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&collie_mcp_data); sharpsl_save_param(); diff --git a/trunk/arch/arm/mach-sa1100/cpu-sa1100.c b/trunk/arch/arm/mach-sa1100/cpu-sa1100.c index 19b2053f5af4..aaa8acf76b7b 100644 --- a/trunk/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/trunk/arch/arm/mach-sa1100/cpu-sa1100.c @@ -228,7 +228,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy) return 0; } -static struct cpufreq_driver sa1100_driver __refdata = { +static struct cpufreq_driver sa1100_driver = { .flags = CPUFREQ_STICKY, .verify = sa11x0_verify_speed, .target = sa1100_target, diff --git a/trunk/arch/arm/mach-sa1100/generic.c b/trunk/arch/arm/mach-sa1100/generic.c index bb10ee2cb89f..e3a28ca2a7b7 100644 --- a/trunk/arch/arm/mach-sa1100/generic.c +++ b/trunk/arch/arm/mach-sa1100/generic.c @@ -217,10 +217,15 @@ static struct platform_device sa11x0uart3_device = { static struct resource sa11x0mcp_resources[] = { [0] = { .start = __PREG(Ser4MCCR0), - .end = __PREG(Ser4MCCR0) + 0xffff, + .end = __PREG(Ser4MCCR0) + 0x1C - 1, .flags = IORESOURCE_MEM, }, [1] = { + .start = __PREG(Ser4MCCR1), + .end = __PREG(Ser4MCCR1) + 0x4 - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { .start = IRQ_Ser4MCP, .end = IRQ_Ser4MCP, .flags = IORESOURCE_IRQ, @@ -345,9 +350,29 @@ void sa11x0_register_irda(struct irda_platform_data *irda) sa11x0_register_device(&sa11x0ir_device, irda); } +static struct resource sa11x0rtc_resources[] = { + [0] = { + .start = 0x90010000, + .end = 0x900100ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC1Hz, + .end = IRQ_RTC1Hz, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .flags = IORESOURCE_IRQ, + }, +}; + static struct platform_device sa11x0rtc_device = { .name = "sa1100-rtc", .id = -1, + .resource = sa11x0rtc_resources, + .num_resources = ARRAY_SIZE(sa11x0rtc_resources), }; static struct platform_device *sa11x0_devices[] __initdata = { diff --git a/trunk/arch/arm/mach-sa1100/include/mach/mcp.h b/trunk/arch/arm/mach-sa1100/include/mach/mcp.h index ed1a331508a7..586cec898b35 100644 --- a/trunk/arch/arm/mach-sa1100/include/mach/mcp.h +++ b/trunk/arch/arm/mach-sa1100/include/mach/mcp.h @@ -17,6 +17,8 @@ struct mcp_plat_data { u32 mccr1; unsigned int sclk_rate; int gpio_base; + const char *codec; + void *codec_pdata; }; #endif diff --git a/trunk/arch/arm/mach-sa1100/jornada720_ssp.c b/trunk/arch/arm/mach-sa1100/jornada720_ssp.c index b412fc09c80c..f50b00bd18a0 100644 --- a/trunk/arch/arm/mach-sa1100/jornada720_ssp.c +++ b/trunk/arch/arm/mach-sa1100/jornada720_ssp.c @@ -198,5 +198,3 @@ static int __init jornada_ssp_init(void) { return platform_driver_register(&jornadassp_driver); } - -module_init(jornada_ssp_init); diff --git a/trunk/arch/arm/mach-sa1100/lart.c b/trunk/arch/arm/mach-sa1100/lart.c index af4e2761f3db..d117ceab6215 100644 --- a/trunk/arch/arm/mach-sa1100/lart.c +++ b/trunk/arch/arm/mach-sa1100/lart.c @@ -24,10 +24,20 @@ static struct mcp_plat_data lart_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init lart_init(void) { + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&lart_mcp_data); } diff --git a/trunk/arch/arm/mach-sa1100/shannon.c b/trunk/arch/arm/mach-sa1100/shannon.c index 318b2b766a0b..748d34435b3f 100644 --- a/trunk/arch/arm/mach-sa1100/shannon.c +++ b/trunk/arch/arm/mach-sa1100/shannon.c @@ -55,11 +55,22 @@ static struct resource shannon_flash_resource = { static struct mcp_plat_data shannon_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init shannon_init(void) { sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&shannon_mcp_data); } diff --git a/trunk/arch/arm/mach-sa1100/simpad.c b/trunk/arch/arm/mach-sa1100/simpad.c index e17c04d6e324..458ececefa58 100644 --- a/trunk/arch/arm/mach-sa1100/simpad.c +++ b/trunk/arch/arm/mach-sa1100/simpad.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -187,10 +188,15 @@ static struct resource simpad_flash_resources [] = { } }; +static struct ucb1x00_plat_data simpad_ucb1x00_data = { + .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, +}; + static struct mcp_plat_data simpad_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, - .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, + .codec = "ucb1300", + .codec_pdata = &simpad_ucb1x00_data, }; @@ -378,6 +384,16 @@ static int __init simpad_init(void) sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, ARRAY_SIZE(simpad_flash_resources)); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&simpad_mcp_data); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); diff --git a/trunk/arch/arm/mach-shmobile/setup-sh7372.c b/trunk/arch/arm/mach-shmobile/setup-sh7372.c index a83cf51fc099..6fcf304d3cdf 100644 --- a/trunk/arch/arm/mach-shmobile/setup-sh7372.c +++ b/trunk/arch/arm/mach-shmobile/setup-sh7372.c @@ -662,7 +662,6 @@ static struct sh_dmae_pdata usb_dma0_platform_data = { .dmaor_is_32bit = 1, .needs_tend_set = 1, .no_dmars = 1, - .slave_only = 1, }; static struct resource sh7372_usb_dmae0_resources[] = { @@ -724,7 +723,6 @@ static struct sh_dmae_pdata usb_dma1_platform_data = { .dmaor_is_32bit = 1, .needs_tend_set = 1, .no_dmars = 1, - .slave_only = 1, }; static struct resource sh7372_usb_dmae1_resources[] = { diff --git a/trunk/arch/arm/mach-shmobile/smp-r8a7779.c b/trunk/arch/arm/mach-shmobile/smp-r8a7779.c index 4fe2e9eaf501..cc97ef892d1b 100644 --- a/trunk/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/trunk/arch/arm/mach-shmobile/smp-r8a7779.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-shmobile/smp-sh73a0.c b/trunk/arch/arm/mach-shmobile/smp-sh73a0.c index 0d159d64a345..be1ade76ccc8 100644 --- a/trunk/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/trunk/arch/arm/mach-shmobile/smp-sh73a0.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-ux500/Kconfig b/trunk/arch/arm/mach-ux500/Kconfig index 52af00446a63..a3e0c8692f0d 100644 --- a/trunk/arch/arm/mach-ux500/Kconfig +++ b/trunk/arch/arm/mach-ux500/Kconfig @@ -7,7 +7,6 @@ config UX500_SOC_COMMON select HAS_MTU select ARM_ERRATA_753970 select ARM_ERRATA_754322 - select ARM_ERRATA_764369 menu "Ux500 SoC" diff --git a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c index 5dde4d4ebe88..23be34b3bb6e 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c @@ -261,8 +261,6 @@ void __init mop500_sdi_init(void) void __init snowball_sdi_init(void) { - /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */ - mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED; /* On-board eMMC */ db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); /* External Micro SD slot */ diff --git a/trunk/arch/arm/mach-ux500/cache-l2x0.c b/trunk/arch/arm/mach-ux500/cache-l2x0.c index da5569d83d58..122ddde00ba7 100644 --- a/trunk/arch/arm/mach-ux500/cache-l2x0.c +++ b/trunk/arch/arm/mach-ux500/cache-l2x0.c @@ -12,6 +12,44 @@ static void __iomem *l2x0_base; +static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) +{ + /* wait for the operation to complete */ + while (readl_relaxed(reg) & mask) + cpu_relax(); +} + +static inline void ux500_cache_sync(void) +{ + writel_relaxed(0, l2x0_base + L2X0_CACHE_SYNC); + ux500_cache_wait(l2x0_base + L2X0_CACHE_SYNC, 1); +} + +/* + * The L2 cache cannot be turned off in the non-secure world. + * Dummy until a secure service is in place. + */ +static void ux500_l2x0_disable(void) +{ +} + +/* + * This is only called when doing a kexec, just after turning off the L2 + * and L1 cache, and it is surrounded by a spinlock in the generic version. + * However, we're not really turning off the L2 cache right now and the + * PL310 does not support exclusive accesses (used to implement the spinlock). + * So, the invalidation needs to be done without the spinlock. + */ +static void ux500_l2x0_inv_all(void) +{ + uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ + + /* invalidate all ways */ + writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); + ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); + ux500_cache_sync(); +} + static int __init ux500_l2x0_unlock(void) { int i; @@ -47,13 +85,9 @@ static int __init ux500_l2x0_init(void) /* 64KB way size, 8 way associativity, force WA */ l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); - /* - * We can't disable l2 as we are in non secure mode, currently - * this seems be called only during kexec path. So let's - * override outer.disable with nasty assignment until we have - * some SMI service available. - */ - outer_cache.disable = NULL; + /* Override invalidate function */ + outer_cache.disable = ux500_l2x0_disable; + outer_cache.inv_all = ux500_l2x0_inv_all; return 0; } diff --git a/trunk/arch/arm/mach-ux500/hotplug.c b/trunk/arch/arm/mach-ux500/hotplug.c index c76f0f456f04..572015e57cd9 100644 --- a/trunk/arch/arm/mach-ux500/hotplug.c +++ b/trunk/arch/arm/mach-ux500/hotplug.c @@ -13,7 +13,6 @@ #include #include -#include extern volatile int pen_release; diff --git a/trunk/arch/arm/mach-ux500/platsmp.c b/trunk/arch/arm/mach-ux500/platsmp.c index d2058ef8345f..a19e398dade3 100644 --- a/trunk/arch/arm/mach-ux500/platsmp.c +++ b/trunk/arch/arm/mach-ux500/platsmp.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-ux500/usb.c b/trunk/arch/arm/mach-ux500/usb.c index 9f9e1c203061..0a01cbdfe063 100644 --- a/trunk/arch/arm/mach-ux500/usb.c +++ b/trunk/arch/arm/mach-ux500/usb.c @@ -95,7 +95,13 @@ static struct musb_hdrc_config musb_hdrc_config = { }; static struct musb_hdrc_platform_data musb_platform_data = { +#if defined(CONFIG_USB_MUSB_OTG) .mode = MUSB_OTG, +#elif defined(CONFIG_USB_MUSB_PERIPHERAL) + .mode = MUSB_PERIPHERAL, +#else /* defined(CONFIG_USB_MUSB_HOST) */ + .mode = MUSB_HOST, +#endif .config = &musb_hdrc_config, .board_data = &musb_board_data, }; diff --git a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c index b1e87c184e54..2b1e836a76ed 100644 --- a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c @@ -217,7 +217,7 @@ static void __init ct_ca9x4_init(void) } #ifdef CONFIG_SMP -static void __init ct_ca9x4_init_cpu_map(void) +static void ct_ca9x4_init_cpu_map(void) { int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU)); @@ -233,7 +233,7 @@ static void __init ct_ca9x4_init_cpu_map(void) set_smp_cross_call(gic_raise_softirq); } -static void __init ct_ca9x4_smp_enable(unsigned int max_cpus) +static void ct_ca9x4_smp_enable(unsigned int max_cpus) { scu_enable(MMIO_P2V(A9_MPCORE_SCU)); } diff --git a/trunk/arch/arm/mach-vexpress/hotplug.c b/trunk/arch/arm/mach-vexpress/hotplug.c index 3034a4dab4a1..813ee08f96e6 100644 --- a/trunk/arch/arm/mach-vexpress/hotplug.c +++ b/trunk/arch/arm/mach-vexpress/hotplug.c @@ -13,7 +13,6 @@ #include #include -#include #include extern volatile int pen_release; diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 1a3ca2488164..4cefb57d9ed2 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -882,7 +882,6 @@ config CACHE_XSC3L2 config ARM_L1_CACHE_SHIFT_6 bool - default y if CPU_V7 help Setting ARM L1 cache line size to 64 Bytes. diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 5dc7d127a40f..6ec1226fc62d 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -310,7 +310,7 @@ static void arm_memory_present(void) static bool arm_memblock_steal_permitted = true; -phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align) +phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align) { phys_addr_t phys; diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index 0404ccbb8aa3..7e9b5bf910c1 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -148,6 +148,10 @@ ENDPROC(cpu_v7_do_resume) * Initialise TLB, Caches, and MMU state ready to switch the MMU * on. Return in r0 the new CP15 C1 control register setting. * + * We automatically detect if we have a Harvard cache, and use the + * Harvard cache control instructions insead of the unified cache + * control instructions. + * * This should be able to cover all ARMv7 cores. * * It is assumed that: @@ -247,7 +251,9 @@ __v7_setup: #endif 3: mov r10, #0 +#ifdef HARVARD_CACHE mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate +#endif dsb #ifdef CONFIG_MMU mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs @@ -323,6 +329,16 @@ __v7_ca5mp_proc_info: __v7_proc __v7_ca5mp_setup .size __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info + /* + * ARM Ltd. Cortex A7 processor. + */ + .type __v7_ca7mp_proc_info, #object +__v7_ca7mp_proc_info: + .long 0x410fc070 + .long 0xff0ffff0 + __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV + .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info + /* * ARM Ltd. Cortex A9 processor. */ @@ -334,16 +350,6 @@ __v7_ca9mp_proc_info: .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info #endif /* CONFIG_ARM_LPAE */ - /* - * ARM Ltd. Cortex A7 processor. - */ - .type __v7_ca7mp_proc_info, #object -__v7_ca7mp_proc_info: - .long 0x410fc070 - .long 0xff0ffff0 - __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV - .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info - /* * ARM Ltd. Cortex A15 processor. */ diff --git a/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h b/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h index f7d18046c04f..6fa8a707b9a0 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h +++ b/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h @@ -96,6 +96,6 @@ extern int mxc_gpio_mode(int gpio_mode); extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, const char *label); -extern int imx_iomuxv1_init(void __iomem *base, int numports); +extern int __init imx_iomuxv1_init(void __iomem *base, int numports); #endif /* __MACH_IOMUX_V1_H__ */ diff --git a/trunk/arch/arm/plat-versatile/platsmp.c b/trunk/arch/arm/plat-versatile/platsmp.c index 49c7db48c7f1..92f18d372b69 100644 --- a/trunk/arch/arm/plat-versatile/platsmp.c +++ b/trunk/arch/arm/plat-versatile/platsmp.c @@ -16,7 +16,6 @@ #include #include -#include #include /* diff --git a/trunk/arch/avr32/Kconfig b/trunk/arch/avr32/Kconfig index 3dea7231f637..197e96f70405 100644 --- a/trunk/arch/avr32/Kconfig +++ b/trunk/arch/avr32/Kconfig @@ -8,7 +8,6 @@ config AVR32 select HAVE_KPROBES select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE - select GENERIC_ATOMIC64 select HARDIRQS_SW_RESEND select GENERIC_IRQ_SHOW select ARCH_HAVE_NMI_SAFE_CMPXCHG diff --git a/trunk/arch/m68k/atari/config.c b/trunk/arch/m68k/atari/config.c index c4ac15c4f065..4203d101363c 100644 --- a/trunk/arch/m68k/atari/config.c +++ b/trunk/arch/m68k/atari/config.c @@ -414,9 +414,9 @@ void __init config_atari(void) * FDC val = 4 -> Supervisor only */ asm volatile ("\n" " .chip 68030\n" - " pmove %0,%/tt1\n" + " pmove %0@,%/tt1\n" " .chip 68k" - : : "m" (tt1_val)); + : : "a" (&tt1_val)); } else { asm volatile ("\n" " .chip 68040\n" @@ -569,10 +569,10 @@ static void atari_reset(void) : "d0"); } else asm volatile ("\n" - " pmove %0,%%tc\n" + " pmove %0@,%%tc\n" " jmp %1@" : /* no outputs */ - : "m" (tc_val), "a" (reset_addr)); + : "a" (&tc_val), "a" (reset_addr)); } diff --git a/trunk/arch/m68k/include/asm/irq.h b/trunk/arch/m68k/include/asm/irq.h index c1155f0e22cc..0e89fa05de0e 100644 --- a/trunk/arch/m68k/include/asm/irq.h +++ b/trunk/arch/m68k/include/asm/irq.h @@ -50,6 +50,19 @@ #define IRQ_USER 8 +/* + * various flags for request_irq() - the Amiga now uses the standard + * mechanism like all other architectures - IRQF_DISABLED and + * IRQF_SHARED are your friends. + */ +#ifndef MACH_AMIGA_ONLY +#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ +#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ +#define IRQ_FLG_FAST (0x0004) +#define IRQ_FLG_SLOW (0x0008) +#define IRQ_FLG_STD (0x8000) /* internally used */ +#endif + struct irq_data; struct irq_chip; struct irq_desc; diff --git a/trunk/arch/m68k/kernel/process_mm.c b/trunk/arch/m68k/kernel/process_mm.c index 099283ee1a8f..125f34e00bf0 100644 --- a/trunk/arch/m68k/kernel/process_mm.c +++ b/trunk/arch/m68k/kernel/process_mm.c @@ -172,7 +172,7 @@ void flush_thread(void) current->thread.fs = __USER_DS; if (!FPU_IS_EMU) - asm volatile("frestore %0": :"m" (zero)); + asm volatile ("frestore %0@" : : "a" (&zero) : "memory"); } /* diff --git a/trunk/arch/m68k/kernel/process_no.c b/trunk/arch/m68k/kernel/process_no.c index 5e1078cabe0e..69c1803fcf1b 100644 --- a/trunk/arch/m68k/kernel/process_no.c +++ b/trunk/arch/m68k/kernel/process_no.c @@ -163,8 +163,8 @@ void flush_thread(void) #ifdef CONFIG_FPU if (!FPU_IS_EMU) asm volatile (".chip 68k/68881\n\t" - "frestore %0\n\t" - ".chip 68k" : : "m" (zero)); + "frestore %0@\n\t" + ".chip 68k" : : "a" (&zero)); #endif } diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c index daaa9187654c..a76452ca964e 100644 --- a/trunk/arch/m68k/kernel/traps.c +++ b/trunk/arch/m68k/kernel/traps.c @@ -552,13 +552,13 @@ static inline void bus_error030 (struct frame *fp) #ifdef DEBUG asm volatile ("ptestr %3,%2@,#7,%0\n\t" - "pmove %%psr,%1" - : "=a&" (desc), "=m" (temp) - : "a" (addr), "d" (ssw)); + "pmove %%psr,%1@" + : "=a&" (desc) + : "a" (&temp), "a" (addr), "d" (ssw)); #else asm volatile ("ptestr %2,%1@,#7\n\t" - "pmove %%psr,%0" - : "=m" (temp) : "a" (addr), "d" (ssw)); + "pmove %%psr,%0@" + : : "a" (&temp), "a" (addr), "d" (ssw)); #endif mmusr = temp; @@ -605,18 +605,20 @@ static inline void bus_error030 (struct frame *fp) !(ssw & RW) ? "write" : "read", addr, fp->ptregs.pc, ssw); asm volatile ("ptestr #1,%1@,#0\n\t" - "pmove %%psr,%0" - : "=m" (temp) - : "a" (addr)); + "pmove %%psr,%0@" + : /* no outputs */ + : "a" (&temp), "a" (addr)); mmusr = temp; printk ("level 0 mmusr is %#x\n", mmusr); #if 0 - asm volatile ("pmove %%tt0,%0" - : "=m" (tlong)); + asm volatile ("pmove %%tt0,%0@" + : /* no outputs */ + : "a" (&tlong)); printk("tt0 is %#lx, ", tlong); - asm volatile ("pmove %%tt1,%0" - : "=m" (tlong)); + asm volatile ("pmove %%tt1,%0@" + : /* no outputs */ + : "a" (&tlong)); printk("tt1 is %#lx\n", tlong); #endif #ifdef DEBUG @@ -666,13 +668,13 @@ static inline void bus_error030 (struct frame *fp) #ifdef DEBUG asm volatile ("ptestr #1,%2@,#7,%0\n\t" - "pmove %%psr,%1" - : "=a&" (desc), "=m" (temp) - : "a" (addr)); + "pmove %%psr,%1@" + : "=a&" (desc) + : "a" (&temp), "a" (addr)); #else asm volatile ("ptestr #1,%1@,#7\n\t" - "pmove %%psr,%0" - : "=m" (temp) : "a" (addr)); + "pmove %%psr,%0@" + : : "a" (&temp), "a" (addr)); #endif mmusr = temp; diff --git a/trunk/arch/m68k/mm/cache.c b/trunk/arch/m68k/mm/cache.c index 3d84c1f2ffb2..95d0bf66e2e2 100644 --- a/trunk/arch/m68k/mm/cache.c +++ b/trunk/arch/m68k/mm/cache.c @@ -52,9 +52,9 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr) unsigned long *descaddr; asm volatile ("ptestr %3,%2@,#7,%0\n\t" - "pmove %%psr,%1" - : "=a&" (descaddr), "=m" (mmusr) - : "a" (vaddr), "d" (get_fs().seg)); + "pmove %%psr,%1@" + : "=a&" (descaddr) + : "a" (&mmusr), "a" (vaddr), "d" (get_fs().seg)); if (mmusr & (MMU_I|MMU_B|MMU_L)) return 0; descaddr = phys_to_virt((unsigned long)descaddr); diff --git a/trunk/arch/microblaze/Kconfig b/trunk/arch/microblaze/Kconfig index c8d6efb99dbf..74f23a460ba2 100644 --- a/trunk/arch/microblaze/Kconfig +++ b/trunk/arch/microblaze/Kconfig @@ -19,7 +19,6 @@ config MICROBLAZE select GENERIC_IRQ_SHOW select GENERIC_PCI_IOMAP select GENERIC_CPU_DEVICES - select GENERIC_ATOMIC64 config SWAP def_bool n diff --git a/trunk/arch/microblaze/include/asm/atomic.h b/trunk/arch/microblaze/include/asm/atomic.h index 615f53992c65..6d2e1d418be7 100644 --- a/trunk/arch/microblaze/include/asm/atomic.h +++ b/trunk/arch/microblaze/include/asm/atomic.h @@ -2,7 +2,6 @@ #define _ASM_MICROBLAZE_ATOMIC_H #include -#include /* * Atomically test *v and decrement if it is greater than 0. diff --git a/trunk/arch/microblaze/kernel/setup.c b/trunk/arch/microblaze/kernel/setup.c index 604cd9dd1333..d4fc1a971779 100644 --- a/trunk/arch/microblaze/kernel/setup.c +++ b/trunk/arch/microblaze/kernel/setup.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -226,5 +227,23 @@ static int __init setup_bus_notifier(void) return 0; } - arch_initcall(setup_bus_notifier); + +static DEFINE_PER_CPU(struct cpu, cpu_devices); + +static int __init topology_init(void) +{ + int i, ret; + + for_each_present_cpu(i) { + struct cpu *c = &per_cpu(cpu_devices, i); + + ret = register_cpu(c, i); + if (ret) + printk(KERN_WARNING "topology_init: register_cpu %d " + "failed (%d)\n", i, ret); + } + + return 0; +} +subsys_initcall(topology_init); diff --git a/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi index b37da56018b6..89af62637707 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi @@ -236,10 +236,6 @@ }; /include/ "pq3-esdhc-0.dtsi" - sdhc@2e000 { - compatible = "fsl,mpc8536-esdhc", "fsl,esdhc"; - }; - /include/ "pq3-sec3.0-0.dtsi" /include/ "pq3-mpic.dtsi" /include/ "pq3-mpic-timer-B.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index a97d1263372c..bd9e163c764b 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -158,8 +158,7 @@ /include/ "pq3-usb2-dr-0.dtsi" /include/ "pq3-esdhc-0.dtsi" sdhc@2e000 { - compatible = "fsl,p1010-esdhc", "fsl,esdhc"; - sdhci,auto-cmd12; + fsl,sdhci-auto-cmd12; }; /include/ "pq3-sec4.4-0.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi index 5de5fc351314..fc924c5ffebe 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi @@ -145,10 +145,6 @@ /include/ "pq3-usb2-dr-1.dtsi" /include/ "pq3-esdhc-0.dtsi" - sdhc@2e000 { - compatible = "fsl,p1020-esdhc", "fsl,esdhc"; - sdhci,auto-cmd12; - }; /include/ "pq3-sec3.3-0.dtsi" /include/ "pq3-mpic.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi index ff9ed1d87929..16239b199d0a 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi @@ -203,8 +203,7 @@ /include/ "pq3-esdhc-0.dtsi" sdhc@2e000 { - compatible = "fsl,p1022-esdhc", "fsl,esdhc"; - sdhci,auto-cmd12; + fsl,sdhci-auto-cmd12; }; /include/ "pq3-sec3.3-0.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi index 332e9e75e6c2..c041050561a7 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi @@ -182,10 +182,6 @@ /include/ "pq3-etsec1-1.dtsi" /include/ "pq3-etsec1-2.dtsi" /include/ "pq3-esdhc-0.dtsi" - sdhc@2e000 { - compatible = "fsl,p2020-esdhc", "fsl,esdhc"; - }; - /include/ "pq3-sec3.1-0.dtsi" /include/ "pq3-mpic.dtsi" /include/ "pq3-mpic-timer-B.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/p1020rdb.dtsi b/trunk/arch/powerpc/boot/dts/p1020rdb.dtsi index 1fb7e0e0940f..b5bd86f4baf2 100644 --- a/trunk/arch/powerpc/boot/dts/p1020rdb.dtsi +++ b/trunk/arch/powerpc/boot/dts/p1020rdb.dtsi @@ -1,7 +1,7 @@ /* * P1020 RDB Device Tree Source stub (no addresses or top-level ranges) * - * Copyright 2011-2012 Freescale Semiconductor Inc. + * Copyright 2011 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -190,16 +190,17 @@ usb@22000 { phy_type = "ulpi"; - dr_mode = "host"; }; - /* USB2 is shared with localbus. It is used - only in case of SPI and SD boot after - appropriate device-tree fixup done by uboot */ + /* USB2 is shared with localbus, so it must be disabled + by default. We can't put 'status = "disabled";' here + since U-Boot doesn't clear the status property when + it enables USB2. OTOH, U-Boot does create a new node + when there isn't any. So, just comment it out. usb@23000 { phy_type = "ulpi"; - dr_mode = "host"; }; + */ mdio@24000 { phy0: ethernet-phy@0 { diff --git a/trunk/arch/powerpc/boot/dts/p1021mds.dts b/trunk/arch/powerpc/boot/dts/p1021mds.dts index 97116f198a37..d9540791e434 100644 --- a/trunk/arch/powerpc/boot/dts/p1021mds.dts +++ b/trunk/arch/powerpc/boot/dts/p1021mds.dts @@ -1,7 +1,7 @@ /* * P1021 MDS Device Tree Source * - * Copyright 2010,2012 Freescale Semiconductor Inc. + * Copyright 2010 Freescale Semiconductor Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -151,7 +151,6 @@ usb@22000 { phy_type = "ulpi"; - dr_mode = "host"; }; mdio@24000 { diff --git a/trunk/arch/powerpc/boot/dts/p2020ds.dtsi b/trunk/arch/powerpc/boot/dts/p2020ds.dtsi index d3b939c573b0..c1cf6cef4dd6 100644 --- a/trunk/arch/powerpc/boot/dts/p2020ds.dtsi +++ b/trunk/arch/powerpc/boot/dts/p2020ds.dtsi @@ -1,7 +1,7 @@ /* * P2020DS Device Tree Source stub (no addresses or top-level ranges) * - * Copyright 2011-2012 Freescale Semiconductor Inc. + * Copyright 2011 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -134,7 +134,6 @@ &board_soc { usb@22000 { phy_type = "ulpi"; - dr_mode = "host"; }; mdio@24520 { diff --git a/trunk/arch/powerpc/boot/dts/p2020rdb.dts b/trunk/arch/powerpc/boot/dts/p2020rdb.dts index eb8a6aa2bda5..26759a591712 100644 --- a/trunk/arch/powerpc/boot/dts/p2020rdb.dts +++ b/trunk/arch/powerpc/boot/dts/p2020rdb.dts @@ -1,7 +1,7 @@ /* * P2020 RDB Device Tree Source * - * Copyright 2009-2012 Freescale Semiconductor Inc. + * Copyright 2009-2011 Freescale Semiconductor Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -197,7 +197,6 @@ usb@22000 { phy_type = "ulpi"; - dr_mode = "host"; }; mdio@24520 { diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c index abef75176c07..28be3452e67a 100644 --- a/trunk/arch/powerpc/kernel/crash.c +++ b/trunk/arch/powerpc/kernel/crash.c @@ -46,6 +46,7 @@ /* This keeps a track of which one is the crashing cpu. */ int crashing_cpu = -1; +static atomic_t cpus_in_crash; static int time_to_dump; #define CRASH_HANDLER_MAX 3 @@ -65,7 +66,6 @@ static int handle_fault(struct pt_regs *regs) #ifdef CONFIG_SMP -static atomic_t cpus_in_crash; void crash_ipi_callback(struct pt_regs *regs) { static cpumask_t cpus_state_saved = CPU_MASK_NONE; diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c index bedd12e1cfbc..3fea3689527e 100644 --- a/trunk/arch/powerpc/kernel/legacy_serial.c +++ b/trunk/arch/powerpc/kernel/legacy_serial.c @@ -442,10 +442,8 @@ static void __init fixup_port_irq(int index, port->irq = virq; -#ifdef CONFIG_SERIAL_8250_FSL if (of_device_is_compatible(np, "fsl,ns16550")) port->handle_irq = fsl8250_handle_irq; -#endif } static void __init fixup_port_pio(int index, diff --git a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c index b0984ada3f83..bb3d84f4046f 100644 --- a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c @@ -25,7 +25,6 @@ #include #include -#include #include #include "smp.h" diff --git a/trunk/arch/powerpc/platforms/powernv/pci-ioda.c b/trunk/arch/powerpc/platforms/powernv/pci-ioda.c index 5e155dfc4320..f31162cfdaa9 100644 --- a/trunk/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/trunk/arch/powerpc/platforms/powernv/pci-ioda.c @@ -204,10 +204,11 @@ static void __devinit pnv_ioda_offset_bus(struct pci_bus *bus, pr_devel(" -> OBR %s [%x] +%016llx\n", bus->self ? pci_name(bus->self) : "root", flags, offset); - pci_bus_for_each_resource(bus, r, i) { + for (i = 0; i < 2; i++) { + r = bus->resource[i]; if (r && (r->flags & flags)) { - r->start += offset; - r->end += offset; + bus->resource[i]->start += offset; + bus->resource[i]->end += offset; } } list_for_each_entry(dev, &bus->devices, bus_list) @@ -287,17 +288,12 @@ static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags, * assignment algorithm is going to be uber-trivial for now, we * can try to be smarter later at filling out holes. */ - if (bus->self) { - /* No offset for downstream bridges */ - start = 0; - } else { - /* Offset from the root */ - if (flags & IORESOURCE_IO) - /* Don't hand out IO 0 */ - start = hose->io_resource.start + 0x1000; - else - start = hose->mem_resources[0].start; - } + start = bus->self ? 0 : bus->resource[bres]->start; + + /* Don't hand out IO 0 */ + if ((flags & IORESOURCE_IO) && !bus->self) + start += 0x1000; + while(!list_empty(&head)) { w = list_first_entry(&head, struct resource_wrap, link); list_del(&w->link); @@ -325,20 +321,13 @@ static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags, empty: /* Only setup P2P's, not the PHB itself */ if (bus->self) { - struct resource *res = bus->resource[bres]; - - if (WARN_ON(res == NULL)) - return; + WARN_ON(bus->resource[bres] == NULL); + bus->resource[bres]->start = 0; + bus->resource[bres]->flags = (*size) ? flags : 0; + bus->resource[bres]->end = (*size) ? (*size - 1) : 0; - /* - * FIXME: We should probably export and call - * pci_bridge_check_ranges() to properly re-initialize - * the PCI portion of the flags here, and to detect - * what the bridge actually supports. - */ - res->start = 0; - res->flags = (*size) ? flags : 0; - res->end = (*size) ? (*size - 1) : 0; + /* Clear prefetch bus resources for now */ + bus->resource[2]->flags = 0; } pr_devel("<- CBR %s [%x] *size=%016llx *align=%016llx\n", diff --git a/trunk/arch/powerpc/platforms/pseries/Kconfig b/trunk/arch/powerpc/platforms/pseries/Kconfig index 31f22c1f657d..ae7b6d41fed3 100644 --- a/trunk/arch/powerpc/platforms/pseries/Kconfig +++ b/trunk/arch/powerpc/platforms/pseries/Kconfig @@ -122,7 +122,7 @@ config DTL Say N if you are unsure. config PSERIES_IDLE - bool "Cpuidle driver for pSeries platforms" + tristate "Cpuidle driver for pSeries platforms" depends on CPU_IDLE depends on PPC_PSERIES default y diff --git a/trunk/arch/powerpc/sysdev/fsl_pci.c b/trunk/arch/powerpc/sysdev/fsl_pci.c index 30eb17ecad49..3b61e8cf3421 100644 --- a/trunk/arch/powerpc/sysdev/fsl_pci.c +++ b/trunk/arch/powerpc/sysdev/fsl_pci.c @@ -205,12 +205,12 @@ static void __init setup_pci_atmu(struct pci_controller *hose, if (paddr_hi == paddr_lo) { pr_err("%s: No outbound window space\n", name); - goto out; + return ; } if (paddr_lo == 0) { pr_err("%s: No space for inbound window\n", name); - goto out; + return ; } /* setup PCSRBAR/PEXCSRBAR */ @@ -357,7 +357,6 @@ static void __init setup_pci_atmu(struct pci_controller *hose, (u64)hose->dma_window_size); } -out: iounmap(pci); } diff --git a/trunk/arch/s390/Makefile b/trunk/arch/s390/Makefile index 0ad2f1e1ce9e..e9f353341693 100644 --- a/trunk/arch/s390/Makefile +++ b/trunk/arch/s390/Makefile @@ -88,6 +88,7 @@ KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare KBUILD_AFLAGS += $(aflags-y) OBJCOPYFLAGS := -O binary +LDFLAGS_vmlinux := -e start head-y := arch/s390/kernel/head.o head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o) diff --git a/trunk/arch/s390/kernel/vmlinux.lds.S b/trunk/arch/s390/kernel/vmlinux.lds.S index 21109c63eb12..e4c79ebb40e6 100644 --- a/trunk/arch/s390/kernel/vmlinux.lds.S +++ b/trunk/arch/s390/kernel/vmlinux.lds.S @@ -9,12 +9,12 @@ #ifndef CONFIG_64BIT OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") OUTPUT_ARCH(s390) -ENTRY(startup) +ENTRY(_start) jiffies = jiffies_64 + 4; #else OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") OUTPUT_ARCH(s390:64-bit) -ENTRY(startup) +ENTRY(_start) jiffies = jiffies_64; #endif diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index ca5580e4d813..96657992a72e 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -33,7 +33,6 @@ config SPARC config SPARC32 def_bool !64BIT select GENERIC_ATOMIC64 - select CLZ_TAB config SPARC64 def_bool 64BIT diff --git a/trunk/arch/sparc/kernel/sun4m_irq.c b/trunk/arch/sparc/kernel/sun4m_irq.c index e61165161dd3..422c16dad1f6 100644 --- a/trunk/arch/sparc/kernel/sun4m_irq.c +++ b/trunk/arch/sparc/kernel/sun4m_irq.c @@ -399,9 +399,6 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn) timers_global = (void __iomem *) (unsigned long) addr[num_cpu_timers]; - /* Every per-cpu timer works in timer mode */ - sbus_writel(0x00000000, &timers_global->timer_config); - sbus_writel((((1000000/HZ) + 1) << 10), &timers_global->l10_limit); master_l10_counter = &timers_global->l10_count; diff --git a/trunk/arch/sparc/lib/divdi3.S b/trunk/arch/sparc/lib/divdi3.S index d74bc0925f2d..681b3683da9e 100644 --- a/trunk/arch/sparc/lib/divdi3.S +++ b/trunk/arch/sparc/lib/divdi3.S @@ -17,9 +17,23 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + .data + .align 8 + .globl __clz_tab +__clz_tab: + .byte 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 + .byte 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 + .byte 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + .byte 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + .size __clz_tab,256 + .global .udiv + .text .align 4 - .global .udiv .globl __divdi3 __divdi3: save %sp,-104,%sp diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 5bed94e189fa..864cc6e6ac8e 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -360,6 +360,7 @@ config X86_NUMACHIP depends on NUMA depends on SMP depends on X86_X2APIC + depends on !EDAC_AMD64 ---help--- Adds support for Numascale NumaChip large-SMP systems. Needed to enable more than ~168 cores. diff --git a/trunk/arch/x86/boot/compressed/misc.c b/trunk/arch/x86/boot/compressed/misc.c index 7116dcba0c9e..3a19d04cebeb 100644 --- a/trunk/arch/x86/boot/compressed/misc.c +++ b/trunk/arch/x86/boot/compressed/misc.c @@ -321,8 +321,6 @@ static void parse_elf(void *output) default: /* Ignore other PT_* */ break; } } - - free(phdrs); } asmlinkage void decompress_kernel(void *rmode, memptr heap, diff --git a/trunk/arch/x86/include/asm/cmpxchg.h b/trunk/arch/x86/include/asm/cmpxchg.h index b3b733262909..0c9fa2745f13 100644 --- a/trunk/arch/x86/include/asm/cmpxchg.h +++ b/trunk/arch/x86/include/asm/cmpxchg.h @@ -145,13 +145,13 @@ extern void __add_wrong_size(void) #ifdef __HAVE_ARCH_CMPXCHG #define cmpxchg(ptr, old, new) \ - __cmpxchg(ptr, old, new, sizeof(*(ptr))) + __cmpxchg((ptr), (old), (new), sizeof(*ptr)) #define sync_cmpxchg(ptr, old, new) \ - __sync_cmpxchg(ptr, old, new, sizeof(*(ptr))) + __sync_cmpxchg((ptr), (old), (new), sizeof(*ptr)) #define cmpxchg_local(ptr, old, new) \ - __cmpxchg_local(ptr, old, new, sizeof(*(ptr))) + __cmpxchg_local((ptr), (old), (new), sizeof(*ptr)) #endif /* diff --git a/trunk/arch/x86/include/asm/cpufeature.h b/trunk/arch/x86/include/asm/cpufeature.h index 8d67d428b0f9..17c5d4bdee5e 100644 --- a/trunk/arch/x86/include/asm/cpufeature.h +++ b/trunk/arch/x86/include/asm/cpufeature.h @@ -159,7 +159,6 @@ #define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */ #define X86_FEATURE_LWP (6*32+15) /* Light Weight Profiling */ #define X86_FEATURE_FMA4 (6*32+16) /* 4 operands MAC instructions */ -#define X86_FEATURE_TCE (6*32+17) /* translation cache extension */ #define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */ #define X86_FEATURE_TBM (6*32+21) /* trailing bit manipulations */ #define X86_FEATURE_TOPOEXT (6*32+22) /* topology extensions CPUID leafs */ diff --git a/trunk/arch/x86/include/asm/kvm_emulate.h b/trunk/arch/x86/include/asm/kvm_emulate.h index 7b9cfc4878af..ab4092e3214e 100644 --- a/trunk/arch/x86/include/asm/kvm_emulate.h +++ b/trunk/arch/x86/include/asm/kvm_emulate.h @@ -190,9 +190,6 @@ struct x86_emulate_ops { int (*intercept)(struct x86_emulate_ctxt *ctxt, struct x86_instruction_info *info, enum x86_intercept_stage stage); - - bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, - u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); }; typedef u32 __attribute__((vector_size(16))) sse128_t; @@ -301,19 +298,6 @@ struct x86_emulate_ctxt { #define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \ X86EMUL_MODE_PROT64) -/* CPUID vendors */ -#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541 -#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163 -#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65 - -#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41 -#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574 -#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273 - -#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547 -#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e -#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69 - enum x86_intercept_stage { X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */ X86_ICPT_PRE_EXCEPT, diff --git a/trunk/arch/x86/include/asm/uv/uv_hub.h b/trunk/arch/x86/include/asm/uv/uv_hub.h index 21f7385badb8..54a13aaebc40 100644 --- a/trunk/arch/x86/include/asm/uv/uv_hub.h +++ b/trunk/arch/x86/include/asm/uv/uv_hub.h @@ -318,13 +318,13 @@ uv_gpa_in_mmr_space(unsigned long gpa) /* UV global physical address --> socket phys RAM */ static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa) { - unsigned long paddr; + unsigned long paddr = gpa & uv_hub_info->gpa_mask; unsigned long remap_base = uv_hub_info->lowmem_remap_base; unsigned long remap_top = uv_hub_info->lowmem_remap_top; gpa = ((gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift) | ((gpa >> uv_hub_info->n_lshift) << uv_hub_info->m_val); - paddr = gpa & uv_hub_info->gpa_mask; + gpa = gpa & uv_hub_info->gpa_mask; if (paddr >= remap_base && paddr < remap_base + remap_top) paddr -= remap_base; return paddr; diff --git a/trunk/arch/x86/kernel/dumpstack.c b/trunk/arch/x86/kernel/dumpstack.c index 4025fe4f928f..1aae78f775fc 100644 --- a/trunk/arch/x86/kernel/dumpstack.c +++ b/trunk/arch/x86/kernel/dumpstack.c @@ -252,8 +252,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) unsigned short ss; unsigned long sp; #endif - printk(KERN_DEFAULT - "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); + printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); #endif diff --git a/trunk/arch/x86/kernel/dumpstack_64.c b/trunk/arch/x86/kernel/dumpstack_64.c index 17107bd6e1f0..6d728d9284bd 100644 --- a/trunk/arch/x86/kernel/dumpstack_64.c +++ b/trunk/arch/x86/kernel/dumpstack_64.c @@ -129,7 +129,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (!stack) { if (regs) stack = (unsigned long *)regs->sp; - else if (task != current) + else if (task && task != current) stack = (unsigned long *)task->thread.sp; else stack = &dummy; @@ -269,11 +269,11 @@ void show_registers(struct pt_regs *regs) unsigned char c; u8 *ip; - printk(KERN_DEFAULT "Stack:\n"); + printk(KERN_EMERG "Stack:\n"); show_stack_log_lvl(NULL, regs, (unsigned long *)sp, - 0, KERN_DEFAULT); + 0, KERN_EMERG); - printk(KERN_DEFAULT "Code: "); + printk(KERN_EMERG "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { diff --git a/trunk/arch/x86/kernel/microcode_amd.c b/trunk/arch/x86/kernel/microcode_amd.c index ac0417be9131..fe86493f3ed1 100644 --- a/trunk/arch/x86/kernel/microcode_amd.c +++ b/trunk/arch/x86/kernel/microcode_amd.c @@ -311,33 +311,13 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) return state; } -/* - * AMD microcode firmware naming convention, up to family 15h they are in - * the legacy file: - * - * amd-ucode/microcode_amd.bin - * - * This legacy file is always smaller than 2K in size. - * - * Starting at family 15h they are in family specific firmware files: - * - * amd-ucode/microcode_amd_fam15h.bin - * amd-ucode/microcode_amd_fam16h.bin - * ... - * - * These might be larger than 2K. - */ static enum ucode_state request_microcode_amd(int cpu, struct device *device) { - char fw_name[36] = "amd-ucode/microcode_amd.bin"; + const char *fw_name = "amd-ucode/microcode_amd.bin"; const struct firmware *fw; enum ucode_state ret = UCODE_NFOUND; - struct cpuinfo_x86 *c = &cpu_data(cpu); - - if (c->x86 >= 0x15) - snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); - if (request_firmware(&fw, (const char *)fw_name, device)) { + if (request_firmware(&fw, fw_name, device)) { pr_err("failed to load file %s\n", fw_name); goto out; } diff --git a/trunk/arch/x86/kernel/reboot.c b/trunk/arch/x86/kernel/reboot.c index d840e69a853c..37a458b521a6 100644 --- a/trunk/arch/x86/kernel/reboot.c +++ b/trunk/arch/x86/kernel/reboot.c @@ -39,14 +39,6 @@ static int reboot_mode; enum reboot_type reboot_type = BOOT_ACPI; int reboot_force; -/* This variable is used privately to keep track of whether or not - * reboot_type is still set to its default value (i.e., reboot= hasn't - * been set on the command line). This is needed so that we can - * suppress DMI scanning for reboot quirks. Without it, it's - * impossible to override a faulty reboot quirk without recompiling. - */ -static int reboot_default = 1; - #if defined(CONFIG_X86_32) && defined(CONFIG_SMP) static int reboot_cpu = -1; #endif @@ -75,12 +67,6 @@ bool port_cf9_safe = false; static int __init reboot_setup(char *str) { for (;;) { - /* Having anything passed on the command line via - * reboot= will cause us to disable DMI checking - * below. - */ - reboot_default = 0; - switch (*str) { case 'w': reboot_mode = 0x1234; @@ -309,6 +295,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "P4S800"), }, }, + { /* Handle problems with rebooting on VersaLogic Menlow boards */ + .callback = set_bios_reboot, + .ident = "VersaLogic Menlow based board", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "VersaLogic Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"), + }, + }, { /* Handle reboot issue on Acer Aspire one */ .callback = set_kbd_reboot, .ident = "Acer Aspire One A110", @@ -322,12 +316,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { static int __init reboot_init(void) { - /* Only do the DMI check if reboot_type hasn't been overridden - * on the command line - */ - if (reboot_default) { - dmi_check_system(reboot_dmi_table); - } + dmi_check_system(reboot_dmi_table); return 0; } core_initcall(reboot_init); @@ -476,12 +465,7 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { static int __init pci_reboot_init(void) { - /* Only do the DMI check if reboot_type hasn't been overridden - * on the command line - */ - if (reboot_default) { - dmi_check_system(pci_reboot_dmi_table); - } + dmi_check_system(pci_reboot_dmi_table); return 0; } core_initcall(pci_reboot_init); diff --git a/trunk/arch/x86/kvm/emulate.c b/trunk/arch/x86/kvm/emulate.c index 0982507b962a..05a562b85025 100644 --- a/trunk/arch/x86/kvm/emulate.c +++ b/trunk/arch/x86/kvm/emulate.c @@ -1891,51 +1891,6 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt, ss->p = 1; } -static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt) -{ - struct x86_emulate_ops *ops = ctxt->ops; - u32 eax, ebx, ecx, edx; - - /* - * syscall should always be enabled in longmode - so only become - * vendor specific (cpuid) if other modes are active... - */ - if (ctxt->mode == X86EMUL_MODE_PROT64) - return true; - - eax = 0x00000000; - ecx = 0x00000000; - if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) { - /* - * Intel ("GenuineIntel") - * remark: Intel CPUs only support "syscall" in 64bit - * longmode. Also an 64bit guest with a - * 32bit compat-app running will #UD !! While this - * behaviour can be fixed (by emulating) into AMD - * response - CPUs of AMD can't behave like Intel. - */ - if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx && - ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx && - edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx) - return false; - - /* AMD ("AuthenticAMD") */ - if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx && - ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx && - edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx) - return true; - - /* AMD ("AMDisbetter!") */ - if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx && - ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx && - edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx) - return true; - } - - /* default: (not Intel, not AMD), apply Intel's stricter rules... */ - return false; -} - static int em_syscall(struct x86_emulate_ctxt *ctxt) { struct x86_emulate_ops *ops = ctxt->ops; @@ -1949,15 +1904,9 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt) ctxt->mode == X86EMUL_MODE_VM86) return emulate_ud(ctxt); - if (!(em_syscall_is_enabled(ctxt))) - return emulate_ud(ctxt); - ops->get_msr(ctxt, MSR_EFER, &efer); setup_syscalls_segments(ctxt, &cs, &ss); - if (!(efer & EFER_SCE)) - return emulate_ud(ctxt); - ops->get_msr(ctxt, MSR_STAR, &msr_data); msr_data >>= 32; cs_sel = (u16)(msr_data & 0xfffc); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 9cbfc0698118..14d6cadc4ba6 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -1495,8 +1495,6 @@ static void record_steal_time(struct kvm_vcpu *vcpu) int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) { - bool pr = false; - switch (msr) { case MSR_EFER: return set_efer(vcpu, data); @@ -1637,18 +1635,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) pr_unimpl(vcpu, "unimplemented perfctr wrmsr: " "0x%x data 0x%llx\n", msr, data); break; - case MSR_P6_PERFCTR0: - case MSR_P6_PERFCTR1: - pr = true; - case MSR_P6_EVNTSEL0: - case MSR_P6_EVNTSEL1: - if (kvm_pmu_msr(vcpu, msr)) - return kvm_pmu_set_msr(vcpu, msr, data); - - if (pr || data != 0) - pr_unimpl(vcpu, "disabled perfctr wrmsr: " - "0x%x data 0x%llx\n", msr, data); - break; case MSR_K7_CLK_CTL: /* * Ignore all writes to this no longer documented MSR. @@ -1849,14 +1835,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_FAM10H_MMIO_CONF_BASE: data = 0; break; - case MSR_P6_PERFCTR0: - case MSR_P6_PERFCTR1: - case MSR_P6_EVNTSEL0: - case MSR_P6_EVNTSEL1: - if (kvm_pmu_msr(vcpu, msr)) - return kvm_pmu_get_msr(vcpu, msr, pdata); - data = 0; - break; case MSR_IA32_UCODE_REV: data = 0x100000000ULL; break; @@ -4202,28 +4180,6 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt, return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage); } -static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt, - u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) -{ - struct kvm_cpuid_entry2 *cpuid = NULL; - - if (eax && ecx) - cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt), - *eax, *ecx); - - if (cpuid) { - *eax = cpuid->eax; - *ecx = cpuid->ecx; - if (ebx) - *ebx = cpuid->ebx; - if (edx) - *edx = cpuid->edx; - return true; - } - - return false; -} - static struct x86_emulate_ops emulate_ops = { .read_std = kvm_read_guest_virt_system, .write_std = kvm_write_guest_virt_system, @@ -4255,7 +4211,6 @@ static struct x86_emulate_ops emulate_ops = { .get_fpu = emulator_get_fpu, .put_fpu = emulator_put_fpu, .intercept = emulator_intercept, - .get_cpuid = emulator_get_cpuid, }; static void cache_all_regs(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index f0b4caf85c1a..9d74824a708d 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -673,7 +673,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, stackend = end_of_stack(tsk); if (tsk != &init_task && *stackend != STACK_END_MAGIC) - printk(KERN_EMERG "Thread overran stack, or stack corrupted\n"); + printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); tsk->thread.cr2 = address; tsk->thread.trap_no = 14; @@ -684,7 +684,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, sig = 0; /* Executive summary in case the body of the oops scrolled away */ - printk(KERN_DEFAULT "CR2: %016lx\n", address); + printk(KERN_EMERG "CR2: %016lx\n", address); oops_end(flags, regs, sig); } diff --git a/trunk/arch/x86/net/bpf_jit_comp.c b/trunk/arch/x86/net/bpf_jit_comp.c index 7c1b765ecc59..7b65f752c5f8 100644 --- a/trunk/arch/x86/net/bpf_jit_comp.c +++ b/trunk/arch/x86/net/bpf_jit_comp.c @@ -151,18 +151,17 @@ void bpf_jit_compile(struct sk_filter *fp) cleanup_addr = proglen; /* epilogue address */ for (pass = 0; pass < 10; pass++) { - u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen; /* no prologue/epilogue for trivial filters (RET something) */ proglen = 0; prog = temp; - if (seen_or_pass0) { + if (seen) { EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */ EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */ /* note : must save %rbx in case bpf_error is hit */ - if (seen_or_pass0 & (SEEN_XREG | SEEN_DATAREF)) + if (seen & (SEEN_XREG | SEEN_DATAREF)) EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */ - if (seen_or_pass0 & SEEN_XREG) + if (seen & SEEN_XREG) CLEAR_X(); /* make sure we dont leek kernel memory */ /* @@ -171,7 +170,7 @@ void bpf_jit_compile(struct sk_filter *fp) * r9 = skb->len - skb->data_len * r8 = skb->data */ - if (seen_or_pass0 & SEEN_DATAREF) { + if (seen & SEEN_DATAREF) { if (offsetof(struct sk_buff, len) <= 127) /* mov off8(%rdi),%r9d */ EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len)); @@ -261,14 +260,9 @@ void bpf_jit_compile(struct sk_filter *fp) case BPF_S_ALU_DIV_X: /* A /= X; */ seen |= SEEN_XREG; EMIT2(0x85, 0xdb); /* test %ebx,%ebx */ - if (pc_ret0 > 0) { - /* addrs[pc_ret0 - 1] is start address of target - * (addrs[i] - 4) is the address following this jmp - * ("xor %edx,%edx; div %ebx" being 4 bytes long) - */ - EMIT_COND_JMP(X86_JE, addrs[pc_ret0 - 1] - - (addrs[i] - 4)); - } else { + if (pc_ret0 != -1) + EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4)); + else { EMIT_COND_JMP(X86_JNE, 2 + 5); CLEAR_A(); EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */ @@ -341,12 +335,12 @@ void bpf_jit_compile(struct sk_filter *fp) } /* fallinto */ case BPF_S_RET_A: - if (seen_or_pass0) { + if (seen) { if (i != flen - 1) { EMIT_JMP(cleanup_addr - addrs[i]); break; } - if (seen_or_pass0 & SEEN_XREG) + if (seen & SEEN_XREG) EMIT4(0x48, 0x8b, 0x5d, 0xf8); /* mov -8(%rbp),%rbx */ EMIT1(0xc9); /* leaveq */ } @@ -489,9 +483,8 @@ common_load: seen |= SEEN_DATAREF; goto common_load; case BPF_S_LDX_B_MSH: if ((int)K < 0) { - if (pc_ret0 > 0) { - /* addrs[pc_ret0 - 1] is the start address */ - EMIT_JMP(addrs[pc_ret0 - 1] - addrs[i]); + if (pc_ret0 != -1) { + EMIT_JMP(addrs[pc_ret0] - addrs[i]); break; } CLEAR_A(); @@ -606,14 +599,13 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; * use it to give the cleanup instruction(s) addr */ cleanup_addr = proglen - 1; /* ret */ - if (seen_or_pass0) + if (seen) cleanup_addr -= 1; /* leaveq */ - if (seen_or_pass0 & SEEN_XREG) + if (seen & SEEN_XREG) cleanup_addr -= 4; /* mov -8(%rbp),%rbx */ if (image) { - if (proglen != oldproglen) - pr_err("bpb_jit_compile proglen=%u != oldproglen=%u\n", proglen, oldproglen); + WARN_ON(proglen != oldproglen); break; } if (proglen == oldproglen) { diff --git a/trunk/arch/x86/platform/uv/tlb_uv.c b/trunk/arch/x86/platform/uv/tlb_uv.c index 3ae0e61abd23..9be4cff00a2d 100644 --- a/trunk/arch/x86/platform/uv/tlb_uv.c +++ b/trunk/arch/x86/platform/uv/tlb_uv.c @@ -1851,8 +1851,6 @@ static void __init init_per_cpu_tunables(void) bcp->cong_reps = congested_reps; bcp->cong_period = congested_period; bcp->clocks_per_100_usec = usec_2_cycles(100); - spin_lock_init(&bcp->queue_lock); - spin_lock_init(&bcp->uvhub_lock); } } diff --git a/trunk/arch/x86/platform/uv/uv_irq.c b/trunk/arch/x86/platform/uv/uv_irq.c index f25c2765a5c9..374a05d8ad22 100644 --- a/trunk/arch/x86/platform/uv/uv_irq.c +++ b/trunk/arch/x86/platform/uv/uv_irq.c @@ -25,7 +25,7 @@ struct uv_irq_2_mmr_pnode{ int irq; }; -static DEFINE_SPINLOCK(uv_irq_lock); +static spinlock_t uv_irq_lock; static struct rb_root uv_irq_root; static int uv_set_irq_affinity(struct irq_data *, const struct cpumask *, bool); diff --git a/trunk/arch/x86/xen/spinlock.c b/trunk/arch/x86/xen/spinlock.c index d69cc6c3f808..cc9b1e182fcf 100644 --- a/trunk/arch/x86/xen/spinlock.c +++ b/trunk/arch/x86/xen/spinlock.c @@ -116,26 +116,9 @@ static inline void spin_time_accum_blocked(u64 start) } #endif /* CONFIG_XEN_DEBUG_FS */ -/* - * Size struct xen_spinlock so it's the same as arch_spinlock_t. - */ -#if NR_CPUS < 256 -typedef u8 xen_spinners_t; -# define inc_spinners(xl) \ - asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory"); -# define dec_spinners(xl) \ - asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory"); -#else -typedef u16 xen_spinners_t; -# define inc_spinners(xl) \ - asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory"); -# define dec_spinners(xl) \ - asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory"); -#endif - struct xen_spinlock { unsigned char lock; /* 0 -> free; 1 -> locked */ - xen_spinners_t spinners; /* count of waiting cpus */ + unsigned short spinners; /* count of waiting cpus */ }; static int xen_spin_is_locked(struct arch_spinlock *lock) @@ -181,7 +164,8 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl) wmb(); /* set lock of interest before count */ - inc_spinners(xl); + asm(LOCK_PREFIX " incw %0" + : "+m" (xl->spinners) : : "memory"); return prev; } @@ -192,7 +176,8 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl) */ static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock *prev) { - dec_spinners(xl); + asm(LOCK_PREFIX " decw %0" + : "+m" (xl->spinners) : : "memory"); wmb(); /* decrement count before restoring lock */ __this_cpu_write(lock_spinners, prev); } @@ -388,8 +373,6 @@ void xen_uninit_lock_cpu(int cpu) void __init xen_init_spinlocks(void) { - BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); - pv_lock_ops.spin_is_locked = xen_spin_is_locked; pv_lock_ops.spin_is_contended = xen_spin_is_contended; pv_lock_ops.spin_lock = xen_spin_lock; diff --git a/trunk/arch/xtensa/include/asm/string.h b/trunk/arch/xtensa/include/asm/string.h index 405a8c49ff2c..5fb8c27cbef5 100644 --- a/trunk/arch/xtensa/include/asm/string.h +++ b/trunk/arch/xtensa/include/asm/string.h @@ -118,4 +118,7 @@ extern void *memmove(void *__dest, __const__ void *__src, size_t __n); /* Don't build bcopy at all ... */ #define __HAVE_ARCH_BCOPY +#define __HAVE_ARCH_MEMSCAN +#define memscan memchr + #endif /* _XTENSA_STRING_H */ diff --git a/trunk/crypto/sha512_generic.c b/trunk/crypto/sha512_generic.c index 88f160b77b1f..9ed9f60316e5 100644 --- a/trunk/crypto/sha512_generic.c +++ b/trunk/crypto/sha512_generic.c @@ -21,6 +21,8 @@ #include #include +static DEFINE_PER_CPU(u64[80], msg_schedule); + static inline u64 Ch(u64 x, u64 y, u64 z) { return z ^ (x & (y ^ z)); @@ -78,7 +80,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input) static inline void BLEND_OP(int I, u64 *W) { - W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]); + W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; } static void @@ -87,48 +89,38 @@ sha512_transform(u64 *state, const u8 *input) u64 a, b, c, d, e, f, g, h, t1, t2; int i; - u64 W[16]; + u64 *W = get_cpu_var(msg_schedule); /* load the input */ for (i = 0; i < 16; i++) LOAD_OP(i, W, input); + for (i = 16; i < 80; i++) { + BLEND_OP(i, W); + } + /* load the state into our registers */ a=state[0]; b=state[1]; c=state[2]; d=state[3]; e=state[4]; f=state[5]; g=state[6]; h=state[7]; -#define SHA512_0_15(i, a, b, c, d, e, f, g, h) \ - t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i]; \ - t2 = e0(a) + Maj(a, b, c); \ - d += t1; \ - h = t1 + t2 - -#define SHA512_16_79(i, a, b, c, d, e, f, g, h) \ - BLEND_OP(i, W); \ - t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \ - t2 = e0(a) + Maj(a, b, c); \ - d += t1; \ - h = t1 + t2 - - for (i = 0; i < 16; i += 8) { - SHA512_0_15(i, a, b, c, d, e, f, g, h); - SHA512_0_15(i + 1, h, a, b, c, d, e, f, g); - SHA512_0_15(i + 2, g, h, a, b, c, d, e, f); - SHA512_0_15(i + 3, f, g, h, a, b, c, d, e); - SHA512_0_15(i + 4, e, f, g, h, a, b, c, d); - SHA512_0_15(i + 5, d, e, f, g, h, a, b, c); - SHA512_0_15(i + 6, c, d, e, f, g, h, a, b); - SHA512_0_15(i + 7, b, c, d, e, f, g, h, a); - } - for (i = 16; i < 80; i += 8) { - SHA512_16_79(i, a, b, c, d, e, f, g, h); - SHA512_16_79(i + 1, h, a, b, c, d, e, f, g); - SHA512_16_79(i + 2, g, h, a, b, c, d, e, f); - SHA512_16_79(i + 3, f, g, h, a, b, c, d, e); - SHA512_16_79(i + 4, e, f, g, h, a, b, c, d); - SHA512_16_79(i + 5, d, e, f, g, h, a, b, c); - SHA512_16_79(i + 6, c, d, e, f, g, h, a, b); - SHA512_16_79(i + 7, b, c, d, e, f, g, h, a); + /* now iterate */ + for (i=0; i<80; i+=8) { + t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ]; + t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; + t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1]; + t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; + t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2]; + t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; + t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3]; + t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; + t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4]; + t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; + t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5]; + t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; + t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6]; + t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; + t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7]; + t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; } state[0] += a; state[1] += b; state[2] += c; state[3] += d; @@ -136,6 +128,8 @@ sha512_transform(u64 *state, const u8 *input) /* erase our data */ a = b = c = d = e = f = g = h = t1 = t2 = 0; + memset(W, 0, sizeof(__get_cpu_var(msg_schedule))); + put_cpu_var(msg_schedule); } static int diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index 1567028d2038..c07f44f05f9d 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -19,6 +19,7 @@ obj-y += acpi.o \ # All the builtin files are in the "acpi." module_param namespace. acpi-y += osl.o utils.o reboot.o +acpi-y += atomicio.o acpi-y += nvs.o # sleep related files diff --git a/trunk/drivers/acpi/apei/apei-base.c b/trunk/drivers/acpi/apei/apei-base.c index e5d53b7ddc7e..e45350cb6ac8 100644 --- a/trunk/drivers/acpi/apei/apei-base.c +++ b/trunk/drivers/acpi/apei/apei-base.c @@ -596,19 +596,33 @@ int apei_read(u64 *val, struct acpi_generic_address *reg) { int rc; u64 address; + u32 tmp, width = reg->bit_width; acpi_status status; rc = apei_check_gar(reg, &address); if (rc) return rc; + if (width == 64) + width = 32; /* Break into two 32-bit transfers */ + *val = 0; switch(reg->space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: - status = acpi_os_read_memory64((acpi_physical_address) - address, val, reg->bit_width); + status = acpi_os_read_memory((acpi_physical_address) + address, &tmp, width); if (ACPI_FAILURE(status)) return -EIO; + *val = tmp; + + if (reg->bit_width == 64) { + /* Read the top 32 bits */ + status = acpi_os_read_memory((acpi_physical_address) + (address + 4), &tmp, 32); + if (ACPI_FAILURE(status)) + return -EIO; + *val |= ((u64)tmp << 32); + } break; case ACPI_ADR_SPACE_SYSTEM_IO: status = acpi_os_read_port(address, (u32 *)val, reg->bit_width); @@ -628,18 +642,31 @@ int apei_write(u64 val, struct acpi_generic_address *reg) { int rc; u64 address; + u32 width = reg->bit_width; acpi_status status; rc = apei_check_gar(reg, &address); if (rc) return rc; + if (width == 64) + width = 32; /* Break into two 32-bit transfers */ + switch (reg->space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: - status = acpi_os_write_memory64((acpi_physical_address) - address, val, reg->bit_width); + status = acpi_os_write_memory((acpi_physical_address) + address, ACPI_LODWORD(val), + width); if (ACPI_FAILURE(status)) return -EIO; + + if (reg->bit_width == 64) { + status = acpi_os_write_memory((acpi_physical_address) + (address + 4), + ACPI_HIDWORD(val), 32); + if (ACPI_FAILURE(status)) + return -EIO; + } break; case ACPI_ADR_SPACE_SYSTEM_IO: status = acpi_os_write_port(address, val, reg->bit_width); diff --git a/trunk/drivers/acpi/apei/einj.c b/trunk/drivers/acpi/apei/einj.c index 4ca087dd5f4f..5b898d4dda99 100644 --- a/trunk/drivers/acpi/apei/einj.c +++ b/trunk/drivers/acpi/apei/einj.c @@ -141,6 +141,21 @@ static DEFINE_MUTEX(einj_mutex); static void *einj_param; +#ifndef readq +static inline __u64 readq(volatile void __iomem *addr) +{ + return ((__u64)readl(addr+4) << 32) + readl(addr); +} +#endif + +#ifndef writeq +static inline void writeq(__u64 val, volatile void __iomem *addr) +{ + writel(val, addr); + writel(val >> 32, addr+4); +} +#endif + static void einj_exec_ctx_init(struct apei_exec_context *ctx) { apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), @@ -189,21 +204,22 @@ static int einj_timedout(u64 *t) static void check_vendor_extension(u64 paddr, struct set_error_type_with_address *v5param) { - int offset = v5param->vendor_extension; + int offset = readl(&v5param->vendor_extension); struct vendor_error_type_extension *v; u32 sbdf; if (!offset) return; - v = acpi_os_map_memory(paddr + offset, sizeof(*v)); + v = ioremap(paddr + offset, sizeof(*v)); if (!v) return; - sbdf = v->pcie_sbdf; + sbdf = readl(&v->pcie_sbdf); sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n", sbdf >> 24, (sbdf >> 16) & 0xff, (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, - v->vendor_id, v->device_id, v->rev_id); - acpi_os_unmap_memory(v, sizeof(*v)); + readw(&v->vendor_id), readw(&v->device_id), + readb(&v->rev_id)); + iounmap(v); } static void *einj_get_parameter_address(void) @@ -231,7 +247,7 @@ static void *einj_get_parameter_address(void) if (paddrv5) { struct set_error_type_with_address *v5param; - v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param)); + v5param = ioremap(paddrv5, sizeof(*v5param)); if (v5param) { acpi5 = 1; check_vendor_extension(paddrv5, v5param); @@ -241,17 +257,17 @@ static void *einj_get_parameter_address(void) if (paddrv4) { struct einj_parameter *v4param; - v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param)); + v4param = ioremap(paddrv4, sizeof(*v4param)); if (!v4param) - return NULL; - if (v4param->reserved1 || v4param->reserved2) { - acpi_os_unmap_memory(v4param, sizeof(*v4param)); - return NULL; + return 0; + if (readq(&v4param->reserved1) || readq(&v4param->reserved2)) { + iounmap(v4param); + return 0; } return v4param; } - return NULL; + return 0; } /* do sanity check to trigger table */ @@ -260,7 +276,7 @@ static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab) if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger)) return -EINVAL; if (trigger_tab->table_size > PAGE_SIZE || - trigger_tab->table_size < trigger_tab->header_size) + trigger_tab->table_size <= trigger_tab->header_size) return -EINVAL; if (trigger_tab->entry_count != (trigger_tab->table_size - trigger_tab->header_size) / @@ -324,11 +340,6 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type, "The trigger error action table is invalid\n"); goto out_rel_header; } - - /* No action structures in the TRIGGER_ERROR table, nothing to do */ - if (!trigger_tab->entry_count) - goto out_rel_header; - rc = -EIO; table_size = trigger_tab->table_size; r = request_mem_region(trigger_paddr + sizeof(*trigger_tab), @@ -424,41 +435,41 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) if (acpi5) { struct set_error_type_with_address *v5param = einj_param; - v5param->type = type; + writel(type, &v5param->type); if (type & 0x80000000) { switch (vendor_flags) { case SETWA_FLAGS_APICID: - v5param->apicid = param1; + writel(param1, &v5param->apicid); break; case SETWA_FLAGS_MEM: - v5param->memory_address = param1; - v5param->memory_address_range = param2; + writeq(param1, &v5param->memory_address); + writeq(param2, &v5param->memory_address_range); break; case SETWA_FLAGS_PCIE_SBDF: - v5param->pcie_sbdf = param1; + writel(param1, &v5param->pcie_sbdf); break; } - v5param->flags = vendor_flags; + writel(vendor_flags, &v5param->flags); } else { switch (type) { case ACPI_EINJ_PROCESSOR_CORRECTABLE: case ACPI_EINJ_PROCESSOR_UNCORRECTABLE: case ACPI_EINJ_PROCESSOR_FATAL: - v5param->apicid = param1; - v5param->flags = SETWA_FLAGS_APICID; + writel(param1, &v5param->apicid); + writel(SETWA_FLAGS_APICID, &v5param->flags); break; case ACPI_EINJ_MEMORY_CORRECTABLE: case ACPI_EINJ_MEMORY_UNCORRECTABLE: case ACPI_EINJ_MEMORY_FATAL: - v5param->memory_address = param1; - v5param->memory_address_range = param2; - v5param->flags = SETWA_FLAGS_MEM; + writeq(param1, &v5param->memory_address); + writeq(param2, &v5param->memory_address_range); + writel(SETWA_FLAGS_MEM, &v5param->flags); break; case ACPI_EINJ_PCIX_CORRECTABLE: case ACPI_EINJ_PCIX_UNCORRECTABLE: case ACPI_EINJ_PCIX_FATAL: - v5param->pcie_sbdf = param1; - v5param->flags = SETWA_FLAGS_PCIE_SBDF; + writel(param1, &v5param->pcie_sbdf); + writel(SETWA_FLAGS_PCIE_SBDF, &v5param->flags); break; } } @@ -468,8 +479,8 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) return rc; if (einj_param) { struct einj_parameter *v4param = einj_param; - v4param->param1 = param1; - v4param->param2 = param2; + writeq(param1, &v4param->param1); + writeq(param2, &v4param->param2); } } rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION); @@ -720,13 +731,8 @@ static int __init einj_init(void) return 0; err_unmap: - if (einj_param) { - acpi_size size = (acpi5) ? - sizeof(struct set_error_type_with_address) : - sizeof(struct einj_parameter); - - acpi_os_unmap_memory(einj_param, size); - } + if (einj_param) + iounmap(einj_param); apei_exec_post_unmap_gars(&ctx); err_release: apei_resources_release(&einj_resources); @@ -742,13 +748,8 @@ static void __exit einj_exit(void) { struct apei_exec_context ctx; - if (einj_param) { - acpi_size size = (acpi5) ? - sizeof(struct set_error_type_with_address) : - sizeof(struct einj_parameter); - - acpi_os_unmap_memory(einj_param, size); - } + if (einj_param) + iounmap(einj_param); einj_exec_ctx_init(&ctx); apei_exec_post_unmap_gars(&ctx); apei_resources_release(&einj_resources); diff --git a/trunk/drivers/acpi/atomicio.c b/trunk/drivers/acpi/atomicio.c new file mode 100644 index 000000000000..d4a5b3d3657b --- /dev/null +++ b/trunk/drivers/acpi/atomicio.c @@ -0,0 +1,422 @@ +/* + * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then + * accessing in atomic context. + * + * This is used for NMI handler to access IO memory area, because + * ioremap/iounmap can not be used in NMI handler. The IO memory area + * is pre-mapped in process context and accessed in NMI handler. + * + * Copyright (C) 2009-2010, Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACPI_PFX "ACPI: " + +static LIST_HEAD(acpi_iomaps); +/* + * Used for mutual exclusion between writers of acpi_iomaps list, for + * synchronization between readers and writer, RCU is used. + */ +static DEFINE_SPINLOCK(acpi_iomaps_lock); + +struct acpi_iomap { + struct list_head list; + void __iomem *vaddr; + unsigned long size; + phys_addr_t paddr; + struct kref ref; +}; + +/* acpi_iomaps_lock or RCU read lock must be held before calling */ +static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr, + unsigned long size) +{ + struct acpi_iomap *map; + + list_for_each_entry_rcu(map, &acpi_iomaps, list) { + if (map->paddr + map->size >= paddr + size && + map->paddr <= paddr) + return map; + } + return NULL; +} + +/* + * Atomic "ioremap" used by NMI handler, if the specified IO memory + * area is not pre-mapped, NULL will be returned. + * + * acpi_iomaps_lock or RCU read lock must be held before calling + */ +static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr, + unsigned long size) +{ + struct acpi_iomap *map; + + map = __acpi_find_iomap(paddr, size/8); + if (map) + return map->vaddr + (paddr - map->paddr); + else + return NULL; +} + +/* acpi_iomaps_lock must be held before calling */ +static void __iomem *__acpi_try_ioremap(phys_addr_t paddr, + unsigned long size) +{ + struct acpi_iomap *map; + + map = __acpi_find_iomap(paddr, size); + if (map) { + kref_get(&map->ref); + return map->vaddr + (paddr - map->paddr); + } else + return NULL; +} + +#ifndef CONFIG_IA64 +#define should_use_kmap(pfn) page_is_ram(pfn) +#else +/* ioremap will take care of cache attributes */ +#define should_use_kmap(pfn) 0 +#endif + +static void __iomem *acpi_map(phys_addr_t pg_off, unsigned long pg_sz) +{ + unsigned long pfn; + + pfn = pg_off >> PAGE_SHIFT; + if (should_use_kmap(pfn)) { + if (pg_sz > PAGE_SIZE) + return NULL; + return (void __iomem __force *)kmap(pfn_to_page(pfn)); + } else + return ioremap(pg_off, pg_sz); +} + +static void acpi_unmap(phys_addr_t pg_off, void __iomem *vaddr) +{ + unsigned long pfn; + + pfn = pg_off >> PAGE_SHIFT; + if (page_is_ram(pfn)) + kunmap(pfn_to_page(pfn)); + else + iounmap(vaddr); +} + +/* + * Used to pre-map the specified IO memory area. First try to find + * whether the area is already pre-mapped, if it is, increase the + * reference count (in __acpi_try_ioremap) and return; otherwise, do + * the real ioremap, and add the mapping into acpi_iomaps list. + */ +static void __iomem *acpi_pre_map(phys_addr_t paddr, + unsigned long size) +{ + void __iomem *vaddr; + struct acpi_iomap *map; + unsigned long pg_sz, flags; + phys_addr_t pg_off; + + spin_lock_irqsave(&acpi_iomaps_lock, flags); + vaddr = __acpi_try_ioremap(paddr, size); + spin_unlock_irqrestore(&acpi_iomaps_lock, flags); + if (vaddr) + return vaddr; + + pg_off = paddr & PAGE_MASK; + pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off; + vaddr = acpi_map(pg_off, pg_sz); + if (!vaddr) + return NULL; + map = kmalloc(sizeof(*map), GFP_KERNEL); + if (!map) + goto err_unmap; + INIT_LIST_HEAD(&map->list); + map->paddr = pg_off; + map->size = pg_sz; + map->vaddr = vaddr; + kref_init(&map->ref); + + spin_lock_irqsave(&acpi_iomaps_lock, flags); + vaddr = __acpi_try_ioremap(paddr, size); + if (vaddr) { + spin_unlock_irqrestore(&acpi_iomaps_lock, flags); + acpi_unmap(pg_off, map->vaddr); + kfree(map); + return vaddr; + } + list_add_tail_rcu(&map->list, &acpi_iomaps); + spin_unlock_irqrestore(&acpi_iomaps_lock, flags); + + return map->vaddr + (paddr - map->paddr); +err_unmap: + acpi_unmap(pg_off, vaddr); + return NULL; +} + +/* acpi_iomaps_lock must be held before calling */ +static void __acpi_kref_del_iomap(struct kref *ref) +{ + struct acpi_iomap *map; + + map = container_of(ref, struct acpi_iomap, ref); + list_del_rcu(&map->list); +} + +/* + * Used to post-unmap the specified IO memory area. The iounmap is + * done only if the reference count goes zero. + */ +static void acpi_post_unmap(phys_addr_t paddr, unsigned long size) +{ + struct acpi_iomap *map; + unsigned long flags; + int del; + + spin_lock_irqsave(&acpi_iomaps_lock, flags); + map = __acpi_find_iomap(paddr, size); + BUG_ON(!map); + del = kref_put(&map->ref, __acpi_kref_del_iomap); + spin_unlock_irqrestore(&acpi_iomaps_lock, flags); + + if (!del) + return; + + synchronize_rcu(); + acpi_unmap(map->paddr, map->vaddr); + kfree(map); +} + +/* In NMI handler, should set silent = 1 */ +static int acpi_check_gar(struct acpi_generic_address *reg, + u64 *paddr, int silent) +{ + u32 width, space_id; + + width = reg->bit_width; + space_id = reg->space_id; + /* Handle possible alignment issues */ + memcpy(paddr, ®->address, sizeof(*paddr)); + if (!*paddr) { + if (!silent) + pr_warning(FW_BUG ACPI_PFX + "Invalid physical address in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { + if (!silent) + pr_warning(FW_BUG ACPI_PFX + "Invalid bit width in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && + space_id != ACPI_ADR_SPACE_SYSTEM_IO) { + if (!silent) + pr_warning(FW_BUG ACPI_PFX + "Invalid address space type in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + return 0; +} + +/* Pre-map, working on GAR */ +int acpi_pre_map_gar(struct acpi_generic_address *reg) +{ + u64 paddr; + void __iomem *vaddr; + int rc; + + if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) + return 0; + + rc = acpi_check_gar(reg, &paddr, 0); + if (rc) + return rc; + + vaddr = acpi_pre_map(paddr, reg->bit_width / 8); + if (!vaddr) + return -EIO; + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_pre_map_gar); + +/* Post-unmap, working on GAR */ +int acpi_post_unmap_gar(struct acpi_generic_address *reg) +{ + u64 paddr; + int rc; + + if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) + return 0; + + rc = acpi_check_gar(reg, &paddr, 0); + if (rc) + return rc; + + acpi_post_unmap(paddr, reg->bit_width / 8); + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_post_unmap_gar); + +#ifdef readq +static inline u64 read64(const volatile void __iomem *addr) +{ + return readq(addr); +} +#else +static inline u64 read64(const volatile void __iomem *addr) +{ + u64 l, h; + l = readl(addr); + h = readl(addr+4); + return l | (h << 32); +} +#endif + +/* + * Can be used in atomic (including NMI) or process context. RCU read + * lock can only be released after the IO memory area accessing. + */ +static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width) +{ + void __iomem *addr; + + rcu_read_lock(); + addr = __acpi_ioremap_fast(paddr, width); + switch (width) { + case 8: + *val = readb(addr); + break; + case 16: + *val = readw(addr); + break; + case 32: + *val = readl(addr); + break; + case 64: + *val = read64(addr); + break; + default: + return -EINVAL; + } + rcu_read_unlock(); + + return 0; +} + +#ifdef writeq +static inline void write64(u64 val, volatile void __iomem *addr) +{ + writeq(val, addr); +} +#else +static inline void write64(u64 val, volatile void __iomem *addr) +{ + writel(val, addr); + writel(val>>32, addr+4); +} +#endif + +static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width) +{ + void __iomem *addr; + + rcu_read_lock(); + addr = __acpi_ioremap_fast(paddr, width); + switch (width) { + case 8: + writeb(val, addr); + break; + case 16: + writew(val, addr); + break; + case 32: + writel(val, addr); + break; + case 64: + write64(val, addr); + break; + default: + return -EINVAL; + } + rcu_read_unlock(); + + return 0; +} + +/* GAR accessing in atomic (including NMI) or process context */ +int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg) +{ + u64 paddr; + int rc; + + rc = acpi_check_gar(reg, &paddr, 1); + if (rc) + return rc; + + *val = 0; + switch (reg->space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + return acpi_atomic_read_mem(paddr, val, reg->bit_width); + case ACPI_ADR_SPACE_SYSTEM_IO: + return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width); + default: + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(acpi_atomic_read); + +int acpi_atomic_write(u64 val, struct acpi_generic_address *reg) +{ + u64 paddr; + int rc; + + rc = acpi_check_gar(reg, &paddr, 1); + if (rc) + return rc; + + switch (reg->space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + return acpi_atomic_write_mem(paddr, val, reg->bit_width); + case ACPI_ADR_SPACE_SYSTEM_IO: + return acpi_os_write_port(paddr, val, reg->bit_width); + default: + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(acpi_atomic_write); diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 412a1e04a922..fcc12d842bcc 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -322,37 +321,6 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size) return NULL; } -#ifndef CONFIG_IA64 -#define should_use_kmap(pfn) page_is_ram(pfn) -#else -/* ioremap will take care of cache attributes */ -#define should_use_kmap(pfn) 0 -#endif - -static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz) -{ - unsigned long pfn; - - pfn = pg_off >> PAGE_SHIFT; - if (should_use_kmap(pfn)) { - if (pg_sz > PAGE_SIZE) - return NULL; - return (void __iomem __force *)kmap(pfn_to_page(pfn)); - } else - return acpi_os_ioremap(pg_off, pg_sz); -} - -static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) -{ - unsigned long pfn; - - pfn = pg_off >> PAGE_SHIFT; - if (page_is_ram(pfn)) - kunmap(pfn_to_page(pfn)); - else - iounmap(vaddr); -} - void __iomem *__init_refok acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { @@ -385,7 +353,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) pg_off = round_down(phys, PAGE_SIZE); pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; - virt = acpi_map(pg_off, pg_sz); + virt = acpi_os_ioremap(pg_off, pg_sz); if (!virt) { mutex_unlock(&acpi_ioremap_lock); kfree(map); @@ -416,7 +384,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map) { if (!map->refcount) { synchronize_rcu(); - acpi_unmap(map->phys, map->virt); + iounmap(map->virt); kfree(map); } } @@ -742,67 +710,6 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) return AE_OK; } -#ifdef readq -static inline u64 read64(const volatile void __iomem *addr) -{ - return readq(addr); -} -#else -static inline u64 read64(const volatile void __iomem *addr) -{ - u64 l, h; - l = readl(addr); - h = readl(addr+4); - return l | (h << 32); -} -#endif - -acpi_status -acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) -{ - void __iomem *virt_addr; - unsigned int size = width / 8; - bool unmap = false; - u64 dummy; - - rcu_read_lock(); - virt_addr = acpi_map_vaddr_lookup(phys_addr, size); - if (!virt_addr) { - rcu_read_unlock(); - virt_addr = acpi_os_ioremap(phys_addr, size); - if (!virt_addr) - return AE_BAD_ADDRESS; - unmap = true; - } - - if (!value) - value = &dummy; - - switch (width) { - case 8: - *(u8 *) value = readb(virt_addr); - break; - case 16: - *(u16 *) value = readw(virt_addr); - break; - case 32: - *(u32 *) value = readl(virt_addr); - break; - case 64: - *(u64 *) value = read64(virt_addr); - break; - default: - BUG(); - } - - if (unmap) - iounmap(virt_addr); - else - rcu_read_unlock(); - - return AE_OK; -} - acpi_status acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) { @@ -842,61 +749,6 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) return AE_OK; } -#ifdef writeq -static inline void write64(u64 val, volatile void __iomem *addr) -{ - writeq(val, addr); -} -#else -static inline void write64(u64 val, volatile void __iomem *addr) -{ - writel(val, addr); - writel(val>>32, addr+4); -} -#endif - -acpi_status -acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width) -{ - void __iomem *virt_addr; - unsigned int size = width / 8; - bool unmap = false; - - rcu_read_lock(); - virt_addr = acpi_map_vaddr_lookup(phys_addr, size); - if (!virt_addr) { - rcu_read_unlock(); - virt_addr = acpi_os_ioremap(phys_addr, size); - if (!virt_addr) - return AE_BAD_ADDRESS; - unmap = true; - } - - switch (width) { - case 8: - writeb(value, virt_addr); - break; - case 16: - writew(value, virt_addr); - break; - case 32: - writel(value, virt_addr); - break; - case 64: - write64(value, virt_addr); - break; - default: - BUG(); - } - - if (unmap) - iounmap(virt_addr); - else - rcu_read_unlock(); - - return AE_OK; -} - acpi_status acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, u64 *value, u32 width) diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index 2b805d7ef317..0034ede38710 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -84,7 +84,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type); static void acpi_processor_notify(struct acpi_device *device, u32 event); static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr); static int acpi_processor_handle_eject(struct acpi_processor *pr); -static int acpi_processor_start(struct acpi_processor *pr); + static const struct acpi_device_id processor_device_ids[] = { {ACPI_PROCESSOR_OBJECT_HID, 0}, @@ -423,29 +423,10 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, struct acpi_processor *pr = per_cpu(processors, cpu); if (action == CPU_ONLINE && pr) { - /* CPU got physically hotplugged and onlined the first time: - * Initialize missing things - */ - if (pr->flags.need_hotplug_init) { - struct cpuidle_driver *idle_driver = - cpuidle_get_driver(); - - printk(KERN_INFO "Will online and init hotplugged " - "CPU: %d\n", pr->id); - WARN(acpi_processor_start(pr), "Failed to start CPU:" - " %d\n", pr->id); - pr->flags.need_hotplug_init = 0; - if (idle_driver && !strcmp(idle_driver->name, - "intel_idle")) { - intel_idle_cpu_init(pr->id); - } - /* Normal CPU soft online event */ - } else { - acpi_processor_ppc_has_changed(pr, 0); - acpi_processor_cst_has_changed(pr); - acpi_processor_reevaluate_tstate(pr, action); - acpi_processor_tstate_has_changed(pr); - } + acpi_processor_ppc_has_changed(pr, 0); + acpi_processor_hotplug(pr); + acpi_processor_reevaluate_tstate(pr, action); + acpi_processor_tstate_has_changed(pr); } if (action == CPU_DEAD && pr) { /* invalidate the flag.throttling after one CPU is offline */ @@ -459,71 +440,6 @@ static struct notifier_block acpi_cpu_notifier = .notifier_call = acpi_cpu_soft_notify, }; -/* - * acpi_processor_start() is called by the cpu_hotplug_notifier func: - * acpi_cpu_soft_notify(). Getting it __cpuinit{data} is difficult, the - * root cause seem to be that acpi_processor_uninstall_hotplug_notify() - * is in the module_exit (__exit) func. Allowing acpi_processor_start() - * to not be in __cpuinit section, but being called from __cpuinit funcs - * via __ref looks like the right thing to do here. - */ -static __ref int acpi_processor_start(struct acpi_processor *pr) -{ - struct acpi_device *device = per_cpu(processor_device_array, pr->id); - int result = 0; - -#ifdef CONFIG_CPU_FREQ - acpi_processor_ppc_has_changed(pr, 0); -#endif - acpi_processor_get_throttling_info(pr); - acpi_processor_get_limit_info(pr); - - if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) - acpi_processor_power_init(pr, device); - - pr->cdev = thermal_cooling_device_register("Processor", device, - &processor_cooling_ops); - if (IS_ERR(pr->cdev)) { - result = PTR_ERR(pr->cdev); - goto err_power_exit; - } - - dev_dbg(&device->dev, "registered as cooling_device%d\n", - pr->cdev->id); - - result = sysfs_create_link(&device->dev.kobj, - &pr->cdev->device.kobj, - "thermal_cooling"); - if (result) { - printk(KERN_ERR PREFIX "Create sysfs link\n"); - goto err_thermal_unregister; - } - result = sysfs_create_link(&pr->cdev->device.kobj, - &device->dev.kobj, - "device"); - if (result) { - printk(KERN_ERR PREFIX "Create sysfs link\n"); - goto err_remove_sysfs_thermal; - } - - return 0; - -err_remove_sysfs_thermal: - sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); -err_thermal_unregister: - thermal_cooling_device_unregister(pr->cdev); -err_power_exit: - acpi_processor_power_exit(pr, device); - - return result; -} - -/* - * Do not put anything in here which needs the core to be online. - * For example MSR access or setting up things which check for cpuinfo_x86 - * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc. - * Such things have to be put in and set up above in acpi_processor_start() - */ static int __cpuinit acpi_processor_add(struct acpi_device *device) { struct acpi_processor *pr = NULL; @@ -579,27 +495,48 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) goto err_free_cpumask; } - /* - * Do not start hotplugged CPUs now, but when they - * are onlined the first time - */ - if (pr->flags.need_hotplug_init) - return 0; +#ifdef CONFIG_CPU_FREQ + acpi_processor_ppc_has_changed(pr, 0); +#endif + acpi_processor_get_throttling_info(pr); + acpi_processor_get_limit_info(pr); - /* - * Do not start hotplugged CPUs now, but when they - * are onlined the first time - */ - if (pr->flags.need_hotplug_init) - return 0; + if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) + acpi_processor_power_init(pr, device); - result = acpi_processor_start(pr); - if (result) + pr->cdev = thermal_cooling_device_register("Processor", device, + &processor_cooling_ops); + if (IS_ERR(pr->cdev)) { + result = PTR_ERR(pr->cdev); + goto err_power_exit; + } + + dev_dbg(&device->dev, "registered as cooling_device%d\n", + pr->cdev->id); + + result = sysfs_create_link(&device->dev.kobj, + &pr->cdev->device.kobj, + "thermal_cooling"); + if (result) { + printk(KERN_ERR PREFIX "Create sysfs link\n"); + goto err_thermal_unregister; + } + result = sysfs_create_link(&pr->cdev->device.kobj, + &device->dev.kobj, + "device"); + if (result) { + printk(KERN_ERR PREFIX "Create sysfs link\n"); goto err_remove_sysfs; + } return 0; err_remove_sysfs: + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); +err_thermal_unregister: + thermal_cooling_device_unregister(pr->cdev); +err_power_exit: + acpi_processor_power_exit(pr, device); sysfs_remove_link(&device->dev.kobj, "sysdev"); err_free_cpumask: free_cpumask_var(pr->throttling.shared_cpu_map); @@ -798,17 +735,6 @@ static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) return AE_ERROR; } - /* CPU got hot-plugged, but cpu_data is not initialized yet - * Set flag to delay cpu_idle/throttling initialization - * in: - * acpi_processor_add() - * acpi_processor_get_info() - * and do it when the CPU gets online the first time - * TBD: Cleanup above functions and try to do this more elegant. - */ - printk(KERN_INFO "CPU %d got hotplugged\n", pr->id); - pr->flags.need_hotplug_init = 1; - return AE_OK; } diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index ca191ff97844..0a7ed69546ba 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -438,14 +438,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, { .callback = init_nvs_nosave, - .ident = "Sony Vaio VPCCW29FX", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"), - }, - }, - { - .callback = init_nvs_nosave, .ident = "Averatec AV1020-ED2", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"), diff --git a/trunk/drivers/base/Makefile b/trunk/drivers/base/Makefile index 610f9997a403..2c8272dd93c4 100644 --- a/trunk/drivers/base/Makefile +++ b/trunk/drivers/base/Makefile @@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o bus.o dd.o syscore.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o \ diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 74dda4f697f9..4a67cc0c8b37 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -632,11 +632,6 @@ static void klist_children_put(struct klist_node *n) * may be used for reference counting of @dev after calling this * function. * - * All fields in @dev must be initialized by the caller to 0, except - * for those explicitly set to some other value. The simplest - * approach is to use kzalloc() to allocate the structure containing - * @dev. - * * NOTE: Use put_device() to give up your reference instead of freeing * @dev directly once you have called this function. */ @@ -935,13 +930,6 @@ int device_private_init(struct device *dev) * to the global and sibling lists for the device, then * adds it to the other relevant subsystems of the driver model. * - * Do not call this routine or device_register() more than once for - * any device structure. The driver model core is not designed to work - * with devices that get unregistered and then spring back to life. - * (Among other things, it's very hard to guarantee that all references - * to the previous incarnation of @dev have been dropped.) Allocate - * and register a fresh new struct device instead. - * * NOTE: _Never_ directly free @dev after calling this function, even * if it returned an error! Always use put_device() to give up your * reference instead. @@ -1034,7 +1022,7 @@ int device_add(struct device *dev) device_pm_add(dev); /* Notify clients of device addition. This call must come - * after dpm_sysfs_add() and before kobject_uevent(). + * after dpm_sysf_add() and before kobject_uevent(). */ if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, @@ -1102,9 +1090,6 @@ int device_add(struct device *dev) * have a clearly defined need to use and refcount the device * before it is added to the hierarchy. * - * For more information, see the kerneldoc for device_initialize() - * and device_add(). - * * NOTE: _Never_ directly free @dev after calling this function, even * if it returned an error! Always use put_device() to give up the * reference initialized in this function instead. diff --git a/trunk/drivers/base/regmap/regmap.c b/trunk/drivers/base/regmap/regmap.c index 65558034318f..be10a4ff6609 100644 --- a/trunk/drivers/base/regmap/regmap.c +++ b/trunk/drivers/base/regmap/regmap.c @@ -284,9 +284,6 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) map->precious_reg = config->precious_reg; map->cache_type = config->cache_type; - map->cache_bypass = false; - map->cache_only = false; - ret = regcache_init(map, config); mutex_unlock(&map->lock); diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c new file mode 100644 index 000000000000..409f5ce78829 --- /dev/null +++ b/trunk/drivers/base/sys.c @@ -0,0 +1,383 @@ +/* + * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc) + * + * Copyright (c) 2002-3 Patrick Mochel + * 2002-3 Open Source Development Lab + * + * This file is released under the GPLv2 + * + * This exports a 'system' bus type. + * By default, a 'sys' bus gets added to the root of the system. There will + * always be core system devices. Devices can use sysdev_register() to + * add themselves as children of the system bus. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "base.h" + +#define to_sysdev(k) container_of(k, struct sys_device, kobj) +#define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) + + +static ssize_t +sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer) +{ + struct sys_device *sysdev = to_sysdev(kobj); + struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); + + if (sysdev_attr->show) + return sysdev_attr->show(sysdev, sysdev_attr, buffer); + return -EIO; +} + + +static ssize_t +sysdev_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) +{ + struct sys_device *sysdev = to_sysdev(kobj); + struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); + + if (sysdev_attr->store) + return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); + return -EIO; +} + +static const struct sysfs_ops sysfs_ops = { + .show = sysdev_show, + .store = sysdev_store, +}; + +static struct kobj_type ktype_sysdev = { + .sysfs_ops = &sysfs_ops, +}; + + +int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a) +{ + return sysfs_create_file(&s->kobj, &a->attr); +} + + +void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a) +{ + sysfs_remove_file(&s->kobj, &a->attr); +} + +EXPORT_SYMBOL_GPL(sysdev_create_file); +EXPORT_SYMBOL_GPL(sysdev_remove_file); + +#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj) +#define to_sysdev_class_attr(a) container_of(a, \ + struct sysdev_class_attribute, attr) + +static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, + char *buffer) +{ + struct sysdev_class *class = to_sysdev_class(kobj); + struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); + + if (class_attr->show) + return class_attr->show(class, class_attr, buffer); + return -EIO; +} + +static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) +{ + struct sysdev_class *class = to_sysdev_class(kobj); + struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); + + if (class_attr->store) + return class_attr->store(class, class_attr, buffer, count); + return -EIO; +} + +static const struct sysfs_ops sysfs_class_ops = { + .show = sysdev_class_show, + .store = sysdev_class_store, +}; + +static struct kobj_type ktype_sysdev_class = { + .sysfs_ops = &sysfs_class_ops, +}; + +int sysdev_class_create_file(struct sysdev_class *c, + struct sysdev_class_attribute *a) +{ + return sysfs_create_file(&c->kset.kobj, &a->attr); +} +EXPORT_SYMBOL_GPL(sysdev_class_create_file); + +void sysdev_class_remove_file(struct sysdev_class *c, + struct sysdev_class_attribute *a) +{ + sysfs_remove_file(&c->kset.kobj, &a->attr); +} +EXPORT_SYMBOL_GPL(sysdev_class_remove_file); + +extern struct kset *system_kset; + +int sysdev_class_register(struct sysdev_class *cls) +{ + int retval; + + pr_debug("Registering sysdev class '%s'\n", cls->name); + + INIT_LIST_HEAD(&cls->drivers); + memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); + cls->kset.kobj.parent = &system_kset->kobj; + cls->kset.kobj.ktype = &ktype_sysdev_class; + cls->kset.kobj.kset = system_kset; + + retval = kobject_set_name(&cls->kset.kobj, "%s", cls->name); + if (retval) + return retval; + + retval = kset_register(&cls->kset); + if (!retval && cls->attrs) + retval = sysfs_create_files(&cls->kset.kobj, + (const struct attribute **)cls->attrs); + return retval; +} + +void sysdev_class_unregister(struct sysdev_class *cls) +{ + pr_debug("Unregistering sysdev class '%s'\n", + kobject_name(&cls->kset.kobj)); + if (cls->attrs) + sysfs_remove_files(&cls->kset.kobj, + (const struct attribute **)cls->attrs); + kset_unregister(&cls->kset); +} + +EXPORT_SYMBOL_GPL(sysdev_class_register); +EXPORT_SYMBOL_GPL(sysdev_class_unregister); + +static DEFINE_MUTEX(sysdev_drivers_lock); + +/* + * @dev != NULL means that we're unwinding because some drv->add() + * failed for some reason. You need to grab sysdev_drivers_lock before + * calling this. + */ +static void __sysdev_driver_remove(struct sysdev_class *cls, + struct sysdev_driver *drv, + struct sys_device *from_dev) +{ + struct sys_device *dev = from_dev; + + list_del_init(&drv->entry); + if (!cls) + return; + + if (!drv->remove) + goto kset_put; + + if (dev) + list_for_each_entry_continue_reverse(dev, &cls->kset.list, + kobj.entry) + drv->remove(dev); + else + list_for_each_entry(dev, &cls->kset.list, kobj.entry) + drv->remove(dev); + +kset_put: + kset_put(&cls->kset); +} + +/** + * sysdev_driver_register - Register auxiliary driver + * @cls: Device class driver belongs to. + * @drv: Driver. + * + * @drv is inserted into @cls->drivers to be + * called on each operation on devices of that class. The refcount + * of @cls is incremented. + */ +int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) +{ + struct sys_device *dev = NULL; + int err = 0; + + if (!cls) { + WARN(1, KERN_WARNING "sysdev: invalid class passed to %s!\n", + __func__); + return -EINVAL; + } + + /* Check whether this driver has already been added to a class. */ + if (drv->entry.next && !list_empty(&drv->entry)) + WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already" + " been registered to a class, something is wrong, but " + "will forge on!\n", cls->name, drv); + + mutex_lock(&sysdev_drivers_lock); + if (cls && kset_get(&cls->kset)) { + list_add_tail(&drv->entry, &cls->drivers); + + /* If devices of this class already exist, tell the driver */ + if (drv->add) { + list_for_each_entry(dev, &cls->kset.list, kobj.entry) { + err = drv->add(dev); + if (err) + goto unwind; + } + } + } else { + err = -EINVAL; + WARN(1, KERN_ERR "%s: invalid device class\n", __func__); + } + + goto unlock; + +unwind: + __sysdev_driver_remove(cls, drv, dev); + +unlock: + mutex_unlock(&sysdev_drivers_lock); + return err; +} + +/** + * sysdev_driver_unregister - Remove an auxiliary driver. + * @cls: Class driver belongs to. + * @drv: Driver. + */ +void sysdev_driver_unregister(struct sysdev_class *cls, + struct sysdev_driver *drv) +{ + mutex_lock(&sysdev_drivers_lock); + __sysdev_driver_remove(cls, drv, NULL); + mutex_unlock(&sysdev_drivers_lock); +} +EXPORT_SYMBOL_GPL(sysdev_driver_register); +EXPORT_SYMBOL_GPL(sysdev_driver_unregister); + +/** + * sysdev_register - add a system device to the tree + * @sysdev: device in question + * + */ +int sysdev_register(struct sys_device *sysdev) +{ + int error; + struct sysdev_class *cls = sysdev->cls; + + if (!cls) + return -EINVAL; + + pr_debug("Registering sys device of class '%s'\n", + kobject_name(&cls->kset.kobj)); + + /* initialize the kobject to 0, in case it had previously been used */ + memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); + + /* Make sure the kset is set */ + sysdev->kobj.kset = &cls->kset; + + /* Register the object */ + error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL, + "%s%d", kobject_name(&cls->kset.kobj), + sysdev->id); + + if (!error) { + struct sysdev_driver *drv; + + pr_debug("Registering sys device '%s'\n", + kobject_name(&sysdev->kobj)); + + mutex_lock(&sysdev_drivers_lock); + /* Generic notification is implicit, because it's that + * code that should have called us. + */ + + /* Notify class auxiliary drivers */ + list_for_each_entry(drv, &cls->drivers, entry) { + if (drv->add) + drv->add(sysdev); + } + mutex_unlock(&sysdev_drivers_lock); + kobject_uevent(&sysdev->kobj, KOBJ_ADD); + } + + return error; +} + +void sysdev_unregister(struct sys_device *sysdev) +{ + struct sysdev_driver *drv; + + mutex_lock(&sysdev_drivers_lock); + list_for_each_entry(drv, &sysdev->cls->drivers, entry) { + if (drv->remove) + drv->remove(sysdev); + } + mutex_unlock(&sysdev_drivers_lock); + + kobject_put(&sysdev->kobj); +} + +EXPORT_SYMBOL_GPL(sysdev_register); +EXPORT_SYMBOL_GPL(sysdev_unregister); + +#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) + +ssize_t sysdev_store_ulong(struct sys_device *sysdev, + struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + struct sysdev_ext_attribute *ea = to_ext_attr(attr); + char *end; + unsigned long new = simple_strtoul(buf, &end, 0); + if (end == buf) + return -EINVAL; + *(unsigned long *)(ea->var) = new; + /* Always return full write size even if we didn't consume all */ + return size; +} +EXPORT_SYMBOL_GPL(sysdev_store_ulong); + +ssize_t sysdev_show_ulong(struct sys_device *sysdev, + struct sysdev_attribute *attr, + char *buf) +{ + struct sysdev_ext_attribute *ea = to_ext_attr(attr); + return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); +} +EXPORT_SYMBOL_GPL(sysdev_show_ulong); + +ssize_t sysdev_store_int(struct sys_device *sysdev, + struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + struct sysdev_ext_attribute *ea = to_ext_attr(attr); + char *end; + long new = simple_strtol(buf, &end, 0); + if (end == buf || new > INT_MAX || new < INT_MIN) + return -EINVAL; + *(int *)(ea->var) = new; + /* Always return full write size even if we didn't consume all */ + return size; +} +EXPORT_SYMBOL_GPL(sysdev_store_int); + +ssize_t sysdev_show_int(struct sys_device *sysdev, + struct sysdev_attribute *attr, + char *buf) +{ + struct sysdev_ext_attribute *ea = to_ext_attr(attr); + return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); +} +EXPORT_SYMBOL_GPL(sysdev_show_int); + diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index a6278e7e61a0..3fd31dec8c9c 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -380,7 +380,6 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr, rbdc = __rbd_client_find(opt); if (rbdc) { ceph_destroy_options(opt); - kfree(rbd_opts); /* using an existing client */ kref_get(&rbdc->kref); @@ -407,15 +406,15 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr, /* * Destroy ceph client - * - * Caller must hold node_lock. */ static void rbd_client_release(struct kref *kref) { struct rbd_client *rbdc = container_of(kref, struct rbd_client, kref); dout("rbd_release_client %p\n", rbdc); + spin_lock(&node_lock); list_del(&rbdc->node); + spin_unlock(&node_lock); ceph_destroy_client(rbdc->client); kfree(rbdc->rbd_opts); @@ -428,9 +427,7 @@ static void rbd_client_release(struct kref *kref) */ static void rbd_put_client(struct rbd_device *rbd_dev) { - spin_lock(&node_lock); kref_put(&rbd_dev->rbd_client->kref, rbd_client_release); - spin_unlock(&node_lock); rbd_dev->rbd_client = NULL; rbd_dev->client = NULL; } diff --git a/trunk/drivers/char/agp/backend.c b/trunk/drivers/char/agp/backend.c index 317c28ce8328..4b71647782d0 100644 --- a/trunk/drivers/char/agp/backend.c +++ b/trunk/drivers/char/agp/backend.c @@ -194,10 +194,10 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) err_out: if (bridge->driver->needs_scratch_page) { - struct page *page = bridge->scratch_page_page; + void *va = page_address(bridge->scratch_page_page); - bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_UNMAP); - bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_FREE); + bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); + bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); } if (got_gatt) bridge->driver->free_gatt_table(bridge); @@ -221,10 +221,10 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) { - struct page *page = bridge->scratch_page_page; + void *va = page_address(bridge->scratch_page_page); - bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_UNMAP); - bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_FREE); + bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); + bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); } } diff --git a/trunk/drivers/dma/at_hdmac.c b/trunk/drivers/dma/at_hdmac.c index f4aed5fc2cb6..97f87b29b9f3 100644 --- a/trunk/drivers/dma/at_hdmac.c +++ b/trunk/drivers/dma/at_hdmac.c @@ -1343,7 +1343,7 @@ static int __init at_dma_probe(struct platform_device *pdev) tasklet_init(&atchan->tasklet, atc_tasklet, (unsigned long)atchan); - atc_enable_chan_irq(atdma, i); + atc_enable_irq(atchan); } /* set base routines */ @@ -1410,7 +1410,7 @@ static int __exit at_dma_remove(struct platform_device *pdev) struct at_dma_chan *atchan = to_at_dma_chan(chan); /* Disable interrupts */ - atc_disable_chan_irq(atdma, chan->chan_id); + atc_disable_irq(atchan); tasklet_disable(&atchan->tasklet); tasklet_kill(&atchan->tasklet); diff --git a/trunk/drivers/dma/at_hdmac_regs.h b/trunk/drivers/dma/at_hdmac_regs.h index a8d3277d60b5..dcaedfc181cf 100644 --- a/trunk/drivers/dma/at_hdmac_regs.h +++ b/trunk/drivers/dma/at_hdmac_regs.h @@ -327,27 +327,28 @@ static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli) } -static void atc_setup_irq(struct at_dma *atdma, int chan_id, int on) +static void atc_setup_irq(struct at_dma_chan *atchan, int on) { - u32 ebci; + struct at_dma *atdma = to_at_dma(atchan->chan_common.device); + u32 ebci; /* enable interrupts on buffer transfer completion & error */ - ebci = AT_DMA_BTC(chan_id) - | AT_DMA_ERR(chan_id); + ebci = AT_DMA_BTC(atchan->chan_common.chan_id) + | AT_DMA_ERR(atchan->chan_common.chan_id); if (on) dma_writel(atdma, EBCIER, ebci); else dma_writel(atdma, EBCIDR, ebci); } -static void atc_enable_chan_irq(struct at_dma *atdma, int chan_id) +static inline void atc_enable_irq(struct at_dma_chan *atchan) { - atc_setup_irq(atdma, chan_id, 1); + atc_setup_irq(atchan, 1); } -static void atc_disable_chan_irq(struct at_dma *atdma, int chan_id) +static inline void atc_disable_irq(struct at_dma_chan *atchan) { - atc_setup_irq(atdma, chan_id, 0); + atc_setup_irq(atchan, 0); } diff --git a/trunk/drivers/dma/dmatest.c b/trunk/drivers/dma/dmatest.c index 24225f0fdcd8..2b8661b54eaf 100644 --- a/trunk/drivers/dma/dmatest.c +++ b/trunk/drivers/dma/dmatest.c @@ -599,7 +599,7 @@ static int dmatest_add_channel(struct dma_chan *chan) } if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) { cnt = dmatest_add_threads(dtc, DMA_PQ); - thread_count += cnt > 0 ? cnt : 0; + thread_count += cnt > 0 ?: 0; } pr_info("dmatest: Started %u threads using %s\n", diff --git a/trunk/drivers/dma/imx-sdma.c b/trunk/drivers/dma/imx-sdma.c index 8bc5acf36ee5..a8af379680c1 100644 --- a/trunk/drivers/dma/imx-sdma.c +++ b/trunk/drivers/dma/imx-sdma.c @@ -1102,13 +1102,11 @@ static int sdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, case DMA_SLAVE_CONFIG: if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { sdmac->per_address = dmaengine_cfg->src_addr; - sdmac->watermark_level = dmaengine_cfg->src_maxburst * - dmaengine_cfg->src_addr_width; + sdmac->watermark_level = dmaengine_cfg->src_maxburst; sdmac->word_size = dmaengine_cfg->src_addr_width; } else { sdmac->per_address = dmaengine_cfg->dst_addr; - sdmac->watermark_level = dmaengine_cfg->dst_maxburst * - dmaengine_cfg->dst_addr_width; + sdmac->watermark_level = dmaengine_cfg->dst_maxburst; sdmac->word_size = dmaengine_cfg->dst_addr_width; } sdmac->direction = dmaengine_cfg->direction; diff --git a/trunk/drivers/dma/shdma.c b/trunk/drivers/dma/shdma.c index 812fd76e9c18..54043cd831c8 100644 --- a/trunk/drivers/dma/shdma.c +++ b/trunk/drivers/dma/shdma.c @@ -1262,8 +1262,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) INIT_LIST_HEAD(&shdev->common.channels); - if (!pdata->slave_only) - dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask); + dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask); if (pdata->slave && pdata->slave_num) dma_cap_set(DMA_SLAVE, shdev->common.cap_mask); diff --git a/trunk/drivers/firewire/ohci.c b/trunk/drivers/firewire/ohci.c index 7f5f0da726da..6628feaa7622 100644 --- a/trunk/drivers/firewire/ohci.c +++ b/trunk/drivers/firewire/ohci.c @@ -263,7 +263,6 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) static char ohci_driver_name[] = KBUILD_MODNAME; #define PCI_DEVICE_ID_AGERE_FW643 0x5901 -#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 #define PCI_DEVICE_ID_TI_TSB12LV26 0x8020 @@ -290,9 +289,6 @@ static const struct { {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, QUIRK_NO_MSI}, - {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID, - QUIRK_RESET_PACKET}, - {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID, QUIRK_NO_MSI}, @@ -303,7 +299,7 @@ static const struct { QUIRK_NO_MSI}, {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, - QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, + QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID, QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A}, diff --git a/trunk/drivers/gpio/gpio-lpc32xx.c b/trunk/drivers/gpio/gpio-lpc32xx.c index ddfacc5ce56d..5b6948081f8f 100644 --- a/trunk/drivers/gpio/gpio-lpc32xx.c +++ b/trunk/drivers/gpio/gpio-lpc32xx.c @@ -96,7 +96,7 @@ static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = { }; static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = { - "gpio00", "gpio01", "gpio02", "gpio03", + "gpi000", "gpio01", "gpio02", "gpio03", "gpio04", "gpio05" }; diff --git a/trunk/drivers/gpio/gpio-ml-ioh.c b/trunk/drivers/gpio/gpio-ml-ioh.c index f0febe5b8221..03d6dd5dcb77 100644 --- a/trunk/drivers/gpio/gpio-ml-ioh.c +++ b/trunk/drivers/gpio/gpio-ml-ioh.c @@ -448,7 +448,6 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev, chip->reg = chip->base; chip->ch = i; mutex_init(&chip->lock); - spin_lock_init(&chip->spinlock); ioh_gpio_setup(chip, num_ports[i]); ret = gpiochip_add(&chip->gpio); if (ret) { diff --git a/trunk/drivers/gpio/gpio-pch.c b/trunk/drivers/gpio/gpio-pch.c index e8729cc2ba2b..68fa55e86eb1 100644 --- a/trunk/drivers/gpio/gpio-pch.c +++ b/trunk/drivers/gpio/gpio-pch.c @@ -392,7 +392,6 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, chip->reg = chip->base; pci_set_drvdata(pdev, chip); mutex_init(&chip->lock); - spin_lock_init(&chip->spinlock); pch_gpio_setup(chip); ret = gpiochip_add(&chip->gpio); if (ret) { diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c index 0a79a1167a25..a7661773c052 100644 --- a/trunk/drivers/gpio/gpio-samsung.c +++ b/trunk/drivers/gpio/gpio-samsung.c @@ -2387,30 +2387,27 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { }; #if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) -static int exynos4_gpio_xlate(struct gpio_chip *gc, - const struct of_phandle_args *gpiospec, u32 *flags) +static int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np, + const void *gpio_spec, u32 *flags) { - unsigned int pin; + const __be32 *gpio = gpio_spec; + const u32 n = be32_to_cpup(gpio); + unsigned int pin = gc->base + be32_to_cpu(gpio[0]); if (WARN_ON(gc->of_gpio_n_cells < 4)) return -EINVAL; - if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) + if (n > gc->ngpio) return -EINVAL; - if (gpiospec->args[0] > gc->ngpio) - return -EINVAL; - - pin = gc->base + gpiospec->args[0]; - - if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1]))) + if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1])))) pr_warn("gpio_xlate: failed to set pin function\n"); - if (s3c_gpio_setpull(pin, gpiospec->args[2])) + if (s3c_gpio_setpull(pin, be32_to_cpu(gpio[2]))) pr_warn("gpio_xlate: failed to set pin pull up/down\n"); - if (s5p_gpio_set_drvstr(pin, gpiospec->args[3])) + if (s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3]))) pr_warn("gpio_xlate: failed to set pin drive strength\n"); - return gpiospec->args[0]; + return n; } static const struct of_device_id exynos4_gpio_dt_match[] __initdata = { diff --git a/trunk/drivers/gpu/drm/drm_auth.c b/trunk/drivers/gpu/drm/drm_auth.c index ba23790450e9..3f46772f0cb2 100644 --- a/trunk/drivers/gpu/drm/drm_auth.c +++ b/trunk/drivers/gpu/drm/drm_auth.c @@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv, * Searches and unlinks the entry in drm_device::magiclist with the magic * number hash key, while holding the drm_device::struct_mutex lock. */ -int drm_remove_magic(struct drm_master *master, drm_magic_t magic) +static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) { struct drm_magic_entry *pt; struct drm_hash_item *hash; @@ -136,8 +136,6 @@ int drm_remove_magic(struct drm_master *master, drm_magic_t magic) * If there is a magic number in drm_file::magic then use it, otherwise * searches an unique non-zero magic number and add it associating it with \p * file_priv. - * This ioctl needs protection by the drm_global_mutex, which protects - * struct drm_file::magic and struct drm_magic_entry::priv. */ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -175,8 +173,6 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) * \return zero if authentication successed, or a negative number otherwise. * * Checks if \p file_priv is associated with the magic number passed in \arg. - * This ioctl needs protection by the drm_global_mutex, which protects - * struct drm_file::magic and struct drm_magic_entry::priv. */ int drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 6263b0147598..c00cf154cc0b 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -487,11 +487,6 @@ int drm_release(struct inode *inode, struct file *filp) (long)old_encode_dev(file_priv->minor->device), dev->open_count); - /* Release any auth tokens that might point to this file_priv, - (do that under the drm_global_mutex) */ - if (file_priv->magic) - (void) drm_remove_magic(file_priv->master, file_priv->magic); - /* if the master has gone away we can't do anything with the lock */ if (file_priv->minor->master) drm_master_release(dev, filp); diff --git a/trunk/drivers/gpu/drm/drm_gem.c b/trunk/drivers/gpu/drm/drm_gem.c index f8625e290728..396e60ce8114 100644 --- a/trunk/drivers/gpu/drm/drm_gem.c +++ b/trunk/drivers/gpu/drm/drm_gem.c @@ -140,7 +140,7 @@ int drm_gem_object_init(struct drm_device *dev, obj->dev = dev; obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); if (IS_ERR(obj->filp)) - return PTR_ERR(obj->filp); + return -ENOMEM; kref_init(&obj->refcount); atomic_set(&obj->handle_count, 0); diff --git a/trunk/drivers/gpu/drm/exynos/Kconfig b/trunk/drivers/gpu/drm/exynos/Kconfig index b9e5266c341b..f9aaa56eae07 100644 --- a/trunk/drivers/gpu/drm/exynos/Kconfig +++ b/trunk/drivers/gpu/drm/exynos/Kconfig @@ -13,7 +13,7 @@ config DRM_EXYNOS config DRM_EXYNOS_FIMD tristate "Exynos DRM FIMD" - depends on DRM_EXYNOS && !FB_S3C + depends on DRM_EXYNOS default n help Choose this option if you want to use Exynos FIMD for DRM. @@ -21,7 +21,7 @@ config DRM_EXYNOS_FIMD config DRM_EXYNOS_HDMI tristate "Exynos DRM HDMI" - depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV + depends on DRM_EXYNOS help Choose this option if you want to use Exynos HDMI for DRM. If M is selected, the module will be called exynos_drm_hdmi diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index b6a737d196ae..ca83139cd309 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -158,8 +158,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - if (!ctx->suspended) - pm_runtime_put_sync(subdrv_dev); + pm_runtime_put_sync(subdrv_dev); break; default: DRM_DEBUG_KMS("unspecified mode %d\n", mode); @@ -735,46 +734,6 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) writel(val, ctx->regs + SHADOWCON); } -static int fimd_power_on(struct fimd_context *ctx, bool enable) -{ - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->manager.dev; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (enable != false && enable != true) - return -EINVAL; - - if (enable) { - int ret; - - ret = clk_enable(ctx->bus_clk); - if (ret < 0) - return ret; - - ret = clk_enable(ctx->lcd_clk); - if (ret < 0) { - clk_disable(ctx->bus_clk); - return ret; - } - - ctx->suspended = false; - - /* if vblank was enabled status, enable it again. */ - if (test_and_clear_bit(0, &ctx->irq_flags)) - fimd_enable_vblank(dev); - - fimd_apply(dev); - } else { - clk_disable(ctx->lcd_clk); - clk_disable(ctx->bus_clk); - - ctx->suspended = true; - } - - return 0; -} - static int __devinit fimd_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -952,30 +911,39 @@ static int __devexit fimd_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int fimd_suspend(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + int ret; if (pm_runtime_suspended(dev)) return 0; - /* - * do not use pm_runtime_suspend(). if pm_runtime_suspend() is - * called here, an error would be returned by that interface - * because the usage_count of pm runtime is more than 1. - */ - return fimd_power_on(ctx, false); + ret = pm_runtime_suspend(dev); + if (ret < 0) + return ret; + + return 0; } static int fimd_resume(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + int ret; - /* - * if entered to sleep when lcd panel was on, the usage_count - * of pm runtime would still be 1 so in this case, fimd driver - * should be on directly not drawing on pm runtime interface. - */ - if (!pm_runtime_suspended(dev)) - return fimd_power_on(ctx, true); + ret = pm_runtime_resume(dev); + if (ret < 0) { + DRM_ERROR("failed to resume runtime pm.\n"); + return ret; + } + + pm_runtime_disable(dev); + + ret = pm_runtime_set_active(dev); + if (ret < 0) { + DRM_ERROR("failed to active runtime pm.\n"); + pm_runtime_enable(dev); + pm_runtime_suspend(dev); + return ret; + } + + pm_runtime_enable(dev); return 0; } @@ -988,16 +956,39 @@ static int fimd_runtime_suspend(struct device *dev) DRM_DEBUG_KMS("%s\n", __FILE__); - return fimd_power_on(ctx, false); + clk_disable(ctx->lcd_clk); + clk_disable(ctx->bus_clk); + + ctx->suspended = true; + return 0; } static int fimd_runtime_resume(struct device *dev) { struct fimd_context *ctx = get_fimd_context(dev); + int ret; DRM_DEBUG_KMS("%s\n", __FILE__); - return fimd_power_on(ctx, true); + ret = clk_enable(ctx->bus_clk); + if (ret < 0) + return ret; + + ret = clk_enable(ctx->lcd_clk); + if (ret < 0) { + clk_disable(ctx->bus_clk); + return ret; + } + + ctx->suspended = false; + + /* if vblank was enabled status, enable it again. */ + if (test_and_clear_bit(0, &ctx->irq_flags)) + fimd_enable_vblank(dev); + + fimd_apply(dev); + + return 0; } #endif diff --git a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c index 3429d3fd93f3..f48f7ce92f5f 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1116,8 +1116,8 @@ static int __devinit hdmi_probe(struct platform_device *pdev) err_iomap: iounmap(hdata->regs); err_req_region: - release_mem_region(hdata->regs_res->start, - resource_size(hdata->regs_res)); + release_resource(hdata->regs_res); + kfree(hdata->regs_res); err_resource: hdmi_resources_cleanup(hdata); err_data: @@ -1145,8 +1145,8 @@ static int __devexit hdmi_remove(struct platform_device *pdev) iounmap(hdata->regs); - release_mem_region(hdata->regs_res->start, - resource_size(hdata->regs_res)); + release_resource(hdata->regs_res); + kfree(hdata->regs_res); /* hdmiphy i2c driver */ i2c_del_driver(&hdmiphy_driver); diff --git a/trunk/drivers/gpu/drm/gma500/framebuffer.c b/trunk/drivers/gpu/drm/gma500/framebuffer.c index 830dfdd6bf15..791c0ef1a65b 100644 --- a/trunk/drivers/gpu/drm/gma500/framebuffer.c +++ b/trunk/drivers/gpu/drm/gma500/framebuffer.c @@ -113,12 +113,12 @@ static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) void psbfb_suspend(struct drm_device *dev) { - struct drm_framebuffer *fb; + struct drm_framebuffer *fb = 0; + struct psb_framebuffer *psbfb = to_psb_fb(fb); console_lock(); mutex_lock(&dev->mode_config.mutex); list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - struct psb_framebuffer *psbfb = to_psb_fb(fb); struct fb_info *info = psbfb->fbdev; fb_set_suspend(info, 1); drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); @@ -129,12 +129,12 @@ void psbfb_suspend(struct drm_device *dev) void psbfb_resume(struct drm_device *dev) { - struct drm_framebuffer *fb; + struct drm_framebuffer *fb = 0; + struct psb_framebuffer *psbfb = to_psb_fb(fb); console_lock(); mutex_lock(&dev->mode_config.mutex); list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - struct psb_framebuffer *psbfb = to_psb_fb(fb); struct fb_info *info = psbfb->fbdev; fb_set_suspend(info, 0); drm_fb_helper_blank(FB_BLANK_UNBLANK, info); diff --git a/trunk/drivers/gpu/drm/gma500/gtt.c b/trunk/drivers/gpu/drm/gma500/gtt.c index 5d5330f667f1..e770bd190a5c 100644 --- a/trunk/drivers/gpu/drm/gma500/gtt.c +++ b/trunk/drivers/gpu/drm/gma500/gtt.c @@ -20,7 +20,6 @@ */ #include -#include #include "psb_drv.h" @@ -204,7 +203,9 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) gt->npage = pages; for (i = 0; i < pages; i++) { - p = shmem_read_mapping_page(mapping, i); + /* FIXME: needs updating as per mail from Hugh Dickins */ + p = read_cache_page_gfp(mapping, i, + __GFP_COLD | GFP_KERNEL); if (IS_ERR(p)) goto err; gt->pages[i] = p; diff --git a/trunk/drivers/gpu/drm/i810/i810_dma.c b/trunk/drivers/gpu/drm/i810/i810_dma.c index 7f4b4e10246e..f7c17b239833 100644 --- a/trunk/drivers/gpu/drm/i810/i810_dma.c +++ b/trunk/drivers/gpu/drm/i810/i810_dma.c @@ -886,7 +886,7 @@ static int i810_flush_queue(struct drm_device *dev) } /* Must be called with the lock held */ -static void i810_reclaim_buffers(struct drm_device *dev, +void i810_driver_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) { struct drm_device_dma *dma = dev->dma; @@ -1223,12 +1223,17 @@ void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) if (dev_priv->page_flipping) i810_do_cleanup_pageflip(dev); } -} -void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv) -{ - i810_reclaim_buffers(dev, file_priv); + if (file_priv->master && file_priv->master->lock.hw_lock) { + drm_idlelock_take(&file_priv->master->lock); + i810_driver_reclaim_buffers(dev, file_priv); + drm_idlelock_release(&file_priv->master->lock); + } else { + /* master disappeared, clean up stuff anyway and hope nothing + * goes wrong */ + i810_driver_reclaim_buffers(dev, file_priv); + } + } int i810_driver_dma_quiescent(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i810/i810_drv.c b/trunk/drivers/gpu/drm/i810/i810_drv.c index ec12f7dc717a..053f1ee58393 100644 --- a/trunk/drivers/gpu/drm/i810/i810_drv.c +++ b/trunk/drivers/gpu/drm/i810/i810_drv.c @@ -63,7 +63,6 @@ static struct drm_driver driver = { .lastclose = i810_driver_lastclose, .preclose = i810_driver_preclose, .device_is_agp = i810_driver_device_is_agp, - .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, .dma_quiescent = i810_driver_dma_quiescent, .ioctls = i810_ioctls, .fops = &i810_driver_fops, diff --git a/trunk/drivers/gpu/drm/i810/i810_drv.h b/trunk/drivers/gpu/drm/i810/i810_drv.h index c9339f481795..6e0acad9e0f5 100644 --- a/trunk/drivers/gpu/drm/i810/i810_drv.h +++ b/trunk/drivers/gpu/drm/i810/i810_drv.h @@ -116,14 +116,12 @@ typedef struct drm_i810_private { /* i810_dma.c */ extern int i810_driver_dma_quiescent(struct drm_device *dev); -extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); +void i810_driver_reclaim_buffers(struct drm_device *dev, + struct drm_file *file_priv); extern int i810_driver_load(struct drm_device *, unsigned long flags); extern void i810_driver_lastclose(struct drm_device *dev); extern void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); -extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); extern int i810_driver_device_is_agp(struct drm_device *dev); extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index deaa657292b4..11807989f918 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -121,11 +121,11 @@ static const char *cache_level_str(int type) static void describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) { - seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s", + seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s", &obj->base, get_pin_flag(obj), get_tiling_flag(obj), - obj->base.size / 1024, + obj->base.size, obj->base.read_domains, obj->base.write_domain, obj->last_rendering_seqno, @@ -653,7 +653,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) seq_printf(m, " Size : %08x\n", ring->size); seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); - if (IS_GEN6(dev) || IS_GEN7(dev)) { + if (IS_GEN6(dev)) { seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); } @@ -1075,7 +1075,6 @@ static int gen6_drpc_info(struct seq_file *m) struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 rpmodectl1, gt_core_status, rcctl1; - unsigned forcewake_count; int count=0, ret; @@ -1083,13 +1082,9 @@ static int gen6_drpc_info(struct seq_file *m) if (ret) return ret; - spin_lock_irq(&dev_priv->gt_lock); - forcewake_count = dev_priv->forcewake_count; - spin_unlock_irq(&dev_priv->gt_lock); - - if (forcewake_count) { - seq_printf(m, "RC information inaccurate because somebody " - "holds a forcewake reference \n"); + if (atomic_read(&dev_priv->forcewake_count)) { + seq_printf(m, "RC information inaccurate because userspace " + "holds a reference \n"); } else { /* NB: we cannot use forcewake, else we read the wrong values */ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) @@ -1111,7 +1106,7 @@ static int gen6_drpc_info(struct seq_file *m) seq_printf(m, "SW control enabled: %s\n", yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == GEN6_RP_MEDIA_SW_MODE)); - seq_printf(m, "RC1e Enabled: %s\n", + seq_printf(m, "RC6 Enabled: %s\n", yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); seq_printf(m, "RC6 Enabled: %s\n", yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE)); @@ -1403,13 +1398,9 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - unsigned forcewake_count; - - spin_lock_irq(&dev_priv->gt_lock); - forcewake_count = dev_priv->forcewake_count; - spin_unlock_irq(&dev_priv->gt_lock); - seq_printf(m, "forcewake count = %u\n", forcewake_count); + seq_printf(m, "forcewake count = %d\n", + atomic_read(&dev_priv->forcewake_count)); return 0; } @@ -1674,7 +1665,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file) struct drm_i915_private *dev_priv = dev->dev_private; int ret; - if (INTEL_INFO(dev)->gen < 6) + if (!IS_GEN6(dev)) return 0; ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -1691,7 +1682,7 @@ int i915_forcewake_release(struct inode *inode, struct file *file) struct drm_device *dev = inode->i_private; struct drm_i915_private *dev_priv = dev->dev_private; - if (INTEL_INFO(dev)->gen < 6) + if (!IS_GEN6(dev)) return 0; /* diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index ddfe3d902b2a..5f4d5893e983 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -2045,7 +2045,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!IS_I945G(dev) && !IS_I945GM(dev)) pci_enable_msi(dev->pdev); - spin_lock_init(&dev_priv->gt_lock); spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->error_lock); spin_lock_init(&dev_priv->rps_lock); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 308f81913562..8f7187915b0d 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -368,12 +368,11 @@ void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) */ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { - unsigned long irqflags; + WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - if (dev_priv->forcewake_count++ == 0) + /* Forcewake is atomic in case we get in here without the lock */ + if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) dev_priv->display.force_wake_get(dev_priv); - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); } void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) @@ -393,12 +392,10 @@ void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) */ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { - unsigned long irqflags; + WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - if (--dev_priv->forcewake_count == 0) + if (atomic_dec_and_test(&dev_priv->forcewake_count)) dev_priv->display.force_wake_put(dev_priv); - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); } void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) @@ -600,36 +597,9 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags) static int gen6_do_reset(struct drm_device *dev, u8 flags) { struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - unsigned long irqflags; - /* Hold gt_lock across reset to prevent any register access - * with forcewake not set correctly - */ - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - - /* Reset the chip */ - - /* GEN6_GDRST is not in the gt power well, no need to check - * for fifo space for the write or forcewake the chip for - * the read - */ - I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); - - /* Spin waiting for the device to ack the reset request */ - ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); - - /* If reset with a user forcewake, try to restore, otherwise turn it off */ - if (dev_priv->forcewake_count) - dev_priv->display.force_wake_get(dev_priv); - else - dev_priv->display.force_wake_put(dev_priv); - - /* Restore fifo count */ - dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); - - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); - return ret; + I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL); + return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); } /** @@ -673,6 +643,9 @@ int i915_reset(struct drm_device *dev, u8 flags) case 7: case 6: ret = gen6_do_reset(dev, flags); + /* If reset with a user forcewake, try to restore */ + if (atomic_read(&dev_priv->forcewake_count)) + __gen6_gt_force_wake_get(dev_priv); break; case 5: ret = ironlake_do_reset(dev, flags); @@ -954,14 +927,9 @@ MODULE_LICENSE("GPL and additional rights"); u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ u##x val = 0; \ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ - unsigned long irqflags; \ - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ - if (dev_priv->forcewake_count == 0) \ - dev_priv->display.force_wake_get(dev_priv); \ + gen6_gt_force_wake_get(dev_priv); \ val = read##y(dev_priv->regs + reg); \ - if (dev_priv->forcewake_count == 0) \ - dev_priv->display.force_wake_put(dev_priv); \ - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ + gen6_gt_force_wake_put(dev_priv); \ } else { \ val = read##y(dev_priv->regs + reg); \ } \ diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 9689ca38b2b3..602bc80baabb 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -288,13 +288,7 @@ typedef struct drm_i915_private { int relative_constants_mode; void __iomem *regs; - /** gt_fifo_count and the subsequent register write are synchronized - * with dev->struct_mutex. */ - unsigned gt_fifo_count; - /** forcewake_count is protected by gt_lock */ - unsigned forcewake_count; - /** gt_lock is also taken in irq contexts. */ - struct spinlock gt_lock; + u32 gt_fifo_count; struct intel_gmbus { struct i2c_adapter adapter; @@ -747,6 +741,8 @@ typedef struct drm_i915_private { struct drm_property *broadcast_rgb_property; struct drm_property *force_audio_property; + + atomic_t forcewake_count; } drm_i915_private_t; enum i915_cache_level { diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 5bd4361ea84d..5d433fc11ace 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -1751,8 +1751,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev) INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); I915_WRITE(HWSTAM, 0xeffe); - - if (IS_GEN6(dev)) { + if (IS_GEN6(dev) || IS_GEN7(dev)) { /* Workaround stalls observed on Sandy Bridge GPUs by * making the blitter command streamer generate a * write to the Hardware Status Page for diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 2b5eb229ff2c..7886e4fb60e3 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -28,19 +28,14 @@ #include "drm.h" #include "i915_drm.h" #include "intel_drv.h" -#include "i915_reg.h" static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; u32 dpll_reg; - /* On IVB, 3rd pipe shares PLL with another one */ - if (pipe > 1) - return false; - if (HAS_PCH_SPLIT(dev)) - dpll_reg = PCH_DPLL(pipe); + dpll_reg = (pipe == PIPE_A) ? _PCH_DPLL_A : _PCH_DPLL_B; else dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; @@ -827,7 +822,7 @@ int i915_save_state(struct drm_device *dev) if (IS_IRONLAKE_M(dev)) ironlake_disable_drps(dev); - if (INTEL_INFO(dev)->gen >= 6) + if (IS_GEN6(dev)) gen6_disable_rps(dev); /* Cache mode state */ @@ -886,7 +881,7 @@ int i915_restore_state(struct drm_device *dev) intel_init_emon(dev); } - if (INTEL_INFO(dev)->gen >= 6) { + if (IS_GEN6(dev)) { gen6_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.h b/trunk/drivers/gpu/drm/i915/intel_bios.h index dbda6e3bdf07..8af3735e27c6 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.h +++ b/trunk/drivers/gpu/drm/i915/intel_bios.h @@ -467,12 +467,8 @@ struct edp_link_params { struct bdb_edp { struct edp_power_seq power_seqs[16]; u32 color_depth; - struct edp_link_params link_params[16]; u32 sdrrs_msa_timing_delay; - - /* ith bit indicates enabled/disabled for (i+1)th panel */ - u16 edp_s3d_feature; - u16 edp_t3_optimization; + struct edp_link_params link_params[16]; } __attribute__ ((packed)); void intel_setup_bios(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index dd729d46a61f..fee0ad02c6d0 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -24,7 +24,6 @@ * Eric Anholt */ -#include #include #include #include "drmP.h" @@ -541,24 +540,6 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { .destroy = intel_encoder_destroy, }; -static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Skipping CRT initialization for %s\n", id->ident); - return 1; -} - -static const struct dmi_system_id intel_no_crt[] = { - { - .callback = intel_no_crt_dmi_callback, - .ident = "ACER ZGB", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ACER"), - DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), - }, - }, - { } -}; - void intel_crt_init(struct drm_device *dev) { struct drm_connector *connector; @@ -566,10 +547,6 @@ void intel_crt_init(struct drm_device *dev) struct intel_connector *intel_connector; struct drm_i915_private *dev_priv = dev->dev_private; - /* Skip machines without VGA that falsely report hotplug events */ - if (dmi_check_system(intel_no_crt)) - return; - crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); if (!crt) return; diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index b3b51c43dad0..2a3f707caab8 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -5808,15 +5808,12 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, if (is_lvds) { temp = I915_READ(PCH_LVDS); temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - if (HAS_PCH_CPT(dev)) { - temp &= ~PORT_TRANS_SEL_MASK; + if (HAS_PCH_CPT(dev)) temp |= PORT_TRANS_SEL_CPT(pipe); - } else { - if (pipe == 1) - temp |= LVDS_PIPEB_SELECT; - else - temp &= ~LVDS_PIPEB_SELECT; - } + else if (pipe == 1) + temp |= LVDS_PIPEB_SELECT; + else + temp &= ~LVDS_PIPEB_SELECT; /* set the corresponsding LVDS_BORDER bit */ temp |= dev_priv->lvds_border_bits; @@ -9028,9 +9025,12 @@ void intel_modeset_init(struct drm_device *dev) for (i = 0; i < dev_priv->num_pipe; i++) { intel_crtc_init(dev, i); - ret = intel_plane_init(dev, i); - if (ret) - DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); + if (HAS_PCH_SPLIT(dev)) { + ret = intel_plane_init(dev, i); + if (ret) + DRM_ERROR("plane %d init failed: %d\n", + i, ret); + } } /* Just disable it once at startup */ diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 798f6e1aa544..e44191132ac4 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -708,14 +708,6 @@ static const struct dmi_system_id intel_no_lvds[] = { }, }, { - .callback = intel_no_lvds_dmi_callback, - .ident = "Clientron E830", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), - DMI_MATCH(DMI_PRODUCT_NAME, "E830"), - }, - }, - { .callback = intel_no_lvds_dmi_callback, .ident = "Asus EeeBox PC EB1007", .matches = { diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 1ab842c6032e..77e729d4e4f0 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -635,19 +635,6 @@ render_ring_add_request(struct intel_ring_buffer *ring, return 0; } -static u32 -gen6_ring_get_seqno(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - - /* Workaround to force correct ordering between irq and seqno writes on - * ivb (and maybe also on snb) by reading from a CS register (like - * ACTHD) before reading the status page. */ - if (IS_GEN7(dev)) - intel_ring_get_active_head(ring); - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); -} - static u32 ring_get_seqno(struct intel_ring_buffer *ring) { @@ -804,6 +791,17 @@ ring_add_request(struct intel_ring_buffer *ring, return 0; } +static bool +gen7_blt_ring_get_irq(struct intel_ring_buffer *ring) +{ + /* The BLT ring on IVB appears to have broken synchronization + * between the seqno write and the interrupt, so that the + * interrupt appears first. Returning false here makes + * i915_wait_request() do a polling loop, instead. + */ + return false; +} + static bool gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) { @@ -813,12 +811,6 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) if (!dev->irq_enabled) return false; - /* It looks like we need to prevent the gt from suspending while waiting - * for an notifiy irq, otherwise irqs seem to get lost on at least the - * blt/bsd rings on ivb. */ - if (IS_GEN7(dev)) - gen6_gt_force_wake_get(dev_priv); - spin_lock(&ring->irq_lock); if (ring->irq_refcount++ == 0) { ring->irq_mask &= ~rflag; @@ -843,9 +835,6 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) ironlake_disable_irq(dev_priv, gflag); } spin_unlock(&ring->irq_lock); - - if (IS_GEN7(dev)) - gen6_gt_force_wake_put(dev_priv); } static bool @@ -1352,7 +1341,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .write_tail = gen6_bsd_ring_write_tail, .flush = gen6_ring_flush, .add_request = gen6_add_request, - .get_seqno = gen6_ring_get_seqno, + .get_seqno = ring_get_seqno, .irq_get = gen6_bsd_ring_get_irq, .irq_put = gen6_bsd_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, @@ -1487,7 +1476,7 @@ static const struct intel_ring_buffer gen6_blt_ring = { .write_tail = ring_write_tail, .flush = blt_ring_flush, .add_request = gen6_add_request, - .get_seqno = gen6_ring_get_seqno, + .get_seqno = ring_get_seqno, .irq_get = blt_ring_get_irq, .irq_put = blt_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, @@ -1510,7 +1499,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring->flush = gen6_render_ring_flush; ring->irq_get = gen6_render_ring_get_irq; ring->irq_put = gen6_render_ring_put_irq; - ring->get_seqno = gen6_ring_get_seqno; } else if (IS_GEN5(dev)) { ring->add_request = pc_render_add_request; ring->get_seqno = pc_render_get_seqno; @@ -1589,5 +1577,8 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) *ring = gen6_blt_ring; + if (IS_GEN7(dev)) + ring->irq_get = gen7_blt_ring_get_irq; + return intel_init_ring_buffer(dev, ring); } diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index e334ec33a47d..f7b9268df266 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -1066,13 +1066,15 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, /* Set the SDVO control regs. */ if (INTEL_INFO(dev)->gen >= 4) { - /* The real mode polarity is set by the SDVO commands, using - * struct intel_sdvo_dtd. */ - sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; + sdvox = 0; if (intel_sdvo->is_hdmi) sdvox |= intel_sdvo->color_range; if (INTEL_INFO(dev)->gen < 5) sdvox |= SDVO_BORDER_ENABLE; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + sdvox |= SDVO_VSYNC_ACTIVE_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + sdvox |= SDVO_HSYNC_ACTIVE_HIGH; } else { sdvox = I915_READ(intel_sdvo->sdvo_reg); switch (intel_sdvo->sdvo_reg) { diff --git a/trunk/drivers/gpu/drm/i915/intel_sprite.c b/trunk/drivers/gpu/drm/i915/intel_sprite.c index 2288abf88cce..d13989fda501 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sprite.c +++ b/trunk/drivers/gpu/drm/i915/intel_sprite.c @@ -466,8 +466,10 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, mutex_lock(&dev->struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); - if (ret) + if (ret) { + DRM_ERROR("failed to pin object\n"); goto out_unlock; + } intel_plane->obj = obj; @@ -630,8 +632,10 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) unsigned long possible_crtcs; int ret; - if (!(IS_GEN6(dev) || IS_GEN7(dev))) + if (!(IS_GEN6(dev) || IS_GEN7(dev))) { + DRM_ERROR("new plane code only for SNB+\n"); return -ENODEV; + } intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); if (!intel_plane) diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index 1571be37ce3e..f3c6a9a8b081 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -417,7 +417,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-M", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ @@ -460,7 +460,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-443", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ @@ -502,7 +502,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-J", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -545,7 +545,7 @@ static const struct tv_mode tv_modes[] = { { .name = "PAL-M", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -589,7 +589,7 @@ static const struct tv_mode tv_modes[] = { /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ .name = "PAL-N", .clock = 108000, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -634,7 +634,7 @@ static const struct tv_mode tv_modes[] = { /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ .name = "PAL", .clock = 108000, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -673,6 +673,78 @@ static const struct tv_mode tv_modes[] = { .filter_table = filter_table, }, + { + .name = "480p@59.94Hz", + .clock = 107520, + .refresh = 59940, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 122, + .hblank_start = 842, .htotal = 857, + + .progressive = true, .trilevel_sync = false, + + .vsync_start_f1 = 12, .vsync_start_f2 = 12, + .vsync_len = 12, + + .veq_ena = false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end = 479, + + .burst_ena = false, + + .filter_table = filter_table, + }, + { + .name = "480p@60Hz", + .clock = 107520, + .refresh = 60000, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 122, + .hblank_start = 842, .htotal = 856, + + .progressive = true, .trilevel_sync = false, + + .vsync_start_f1 = 12, .vsync_start_f2 = 12, + .vsync_len = 12, + + .veq_ena = false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end = 479, + + .burst_ena = false, + + .filter_table = filter_table, + }, + { + .name = "576p", + .clock = 107520, + .refresh = 50000, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 139, + .hblank_start = 859, .htotal = 863, + + .progressive = true, .trilevel_sync = false, + + .vsync_start_f1 = 10, .vsync_start_f2 = 10, + .vsync_len = 10, + + .veq_ena = false, + + .vi_end_f1 = 48, .vi_end_f2 = 48, + .nbr_end = 575, + + .burst_ena = false, + + .filter_table = filter_table, + }, { .name = "720p@60Hz", .clock = 148800, @@ -697,6 +769,30 @@ static const struct tv_mode tv_modes[] = { .filter_table = filter_table, }, + { + .name = "720p@59.94Hz", + .clock = 148800, + .refresh = 59940, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 80, .hblank_end = 300, + .hblank_start = 1580, .htotal = 1651, + + .progressive = true, .trilevel_sync = true, + + .vsync_start_f1 = 10, .vsync_start_f2 = 10, + .vsync_len = 10, + + .veq_ena = false, + + .vi_end_f1 = 29, .vi_end_f2 = 29, + .nbr_end = 719, + + .burst_ena = false, + + .filter_table = filter_table, + }, { .name = "720p@50Hz", .clock = 148800, @@ -725,7 +821,7 @@ static const struct tv_mode tv_modes[] = { { .name = "1080i@50Hz", .clock = 148800, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_2X, .component_only = 1, @@ -751,7 +847,7 @@ static const struct tv_mode tv_modes[] = { { .name = "1080i@60Hz", .clock = 148800, - .refresh = 60000, + .refresh = 30000, .oversample = TV_OVERSAMPLE_2X, .component_only = 1, @@ -772,6 +868,32 @@ static const struct tv_mode tv_modes[] = { .burst_ena = false, + .filter_table = filter_table, + }, + { + .name = "1080i@59.94Hz", + .clock = 148800, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, + .hblank_start = 2155, .htotal = 2201, + + .progressive = false, .trilevel_sync = true, + + .vsync_start_f1 = 4, .vsync_start_f2 = 5, + .vsync_len = 10, + + .veq_ena = true, .veq_start_f1 = 4, + .veq_start_f2 = 4, .veq_len = 10, + + + .vi_end_f1 = 21, .vi_end_f2 = 22, + .nbr_end = 539, + + .burst_ena = false, + .filter_table = filter_table, }, }; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h index a37c31e358aa..1e382ad5a2b8 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -54,10 +54,9 @@ struct bit_entry { int bit_table(struct drm_device *, u8 id, struct bit_entry *); enum dcb_gpio_tag { - DCB_GPIO_PANEL_POWER = 0x01, - DCB_GPIO_TVDAC0 = 0x0c, + DCB_GPIO_TVDAC0 = 0xc, DCB_GPIO_TVDAC1 = 0x2d, - DCB_GPIO_PWM_FAN = 0x09, + DCB_GPIO_PWM_FAN = 0x9, DCB_GPIO_FAN_SENSE = 0x3d, DCB_GPIO_UNUSED = 0xff }; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c index ec54364ac828..724b41a2b9e9 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -812,10 +812,6 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem) struct nouveau_bo *nvbo = nouveau_bo(bo); struct nouveau_vma *vma; - /* ttm can now (stupidly) pass the driver bos it didn't create... */ - if (bo->destroy != nouveau_bo_del_ttm) - return; - list_for_each_entry(vma, &nvbo->vma_list, head) { if (new_mem && new_mem->mem_type == TTM_PL_VRAM) { nouveau_vm_map(vma, new_mem->mm_node); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c index 795a9e3c990a..3cb52bc52b21 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c @@ -219,16 +219,6 @@ nouveau_display_init(struct drm_device *dev) if (ret) return ret; - /* power on internal panel if it's not already. the init tables of - * some vbios default this to off for some reason, causing the - * panel to not work after resume - */ - if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) { - nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true); - msleep(300); - } - - /* enable polling for external displays */ drm_kms_helper_poll_enable(dev); /* enable hotplug interrupts */ diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c index 81d7962e7252..e4a7cfe7898d 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -124,7 +124,7 @@ MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)\n"); int nouveau_ctxfw; module_param_named(ctxfw, nouveau_ctxfw, int, 0400); -MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS\n"); +MODULE_PARM_DESC(ctxfw, "Santise DCB table according to MXM-SIS\n"); int nouveau_mxmdcb = 1; module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c index 7ce3fde40743..5f0bc57fdaab 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -379,25 +379,6 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, return 0; } -static int -validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo) -{ - struct nouveau_fence *fence = NULL; - int ret = 0; - - spin_lock(&nvbo->bo.bdev->fence_lock); - if (nvbo->bo.sync_obj) - fence = nouveau_fence_ref(nvbo->bo.sync_obj); - spin_unlock(&nvbo->bo.bdev->fence_lock); - - if (fence) { - ret = nouveau_fence_sync(fence, chan); - nouveau_fence_unref(&fence); - } - - return ret; -} - static int validate_list(struct nouveau_channel *chan, struct list_head *list, struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) @@ -412,7 +393,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, list_for_each_entry(nvbo, list, entry) { struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; - ret = validate_sync(chan, nvbo); + ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); if (unlikely(ret)) { NV_ERROR(dev, "fail pre-validate sync\n"); return ret; @@ -435,7 +416,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, return ret; } - ret = validate_sync(chan, nvbo); + ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); if (unlikely(ret)) { NV_ERROR(dev, "fail post-validate sync\n"); return ret; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c index e5a64f0f4cb7..8bccddf4eff0 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c @@ -656,16 +656,7 @@ nouveau_mxm_init(struct drm_device *dev) if (mxm_shadow(dev, mxm[0])) { MXM_MSG(dev, "failed to locate valid SIS\n"); -#if 0 - /* we should, perhaps, fall back to some kind of limited - * mode here if the x86 vbios hasn't already done the - * work for us (so we prevent loading with completely - * whacked vbios tables). - */ return -EINVAL; -#else - return 0; -#endif } MXM_MSG(dev, "MXMS Version %d.%d\n", diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_pm.c b/trunk/drivers/gpu/drm/nouveau/nv50_pm.c index ec5481dfcd82..03937212e9d8 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_pm.c @@ -495,9 +495,9 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nv50_pm_state *info; struct pll_lims pll; - int clk, ret = -EINVAL; + int ret = -EINVAL; int N, M, P1, P2; - u32 out; + u32 clk, out; if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 742f17f009a9..0fda830ef806 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -355,12 +355,15 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } -static void atombios_disable_ss(struct radeon_device *rdev, int pll_id) +static void atombios_disable_ss(struct drm_crtc *crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; u32 ss_cntl; if (ASIC_IS_DCE4(rdev)) { - switch (pll_id) { + switch (radeon_crtc->pll_id) { case ATOM_PPLL1: ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; @@ -376,7 +379,7 @@ static void atombios_disable_ss(struct radeon_device *rdev, int pll_id) return; } } else if (ASIC_IS_AVIVO(rdev)) { - switch (pll_id) { + switch (radeon_crtc->pll_id) { case ATOM_PPLL1: ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); ss_cntl &= ~1; @@ -403,11 +406,13 @@ union atom_enable_ss { ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; }; -static void atombios_crtc_program_ss(struct radeon_device *rdev, +static void atombios_crtc_program_ss(struct drm_crtc *crtc, int enable, int pll_id, struct radeon_atom_ss *ss) { + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); union atom_enable_ss args; @@ -474,7 +479,7 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev, } else if (ASIC_IS_AVIVO(rdev)) { if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK)) { - atombios_disable_ss(rdev, pll_id); + atombios_disable_ss(crtc); return; } args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); @@ -486,7 +491,7 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev, } else { if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK)) { - atombios_disable_ss(rdev, pll_id); + atombios_disable_ss(crtc); return; } args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); @@ -518,7 +523,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, int encoder_mode = 0; u32 dp_clock = mode->clock; int bpc = 8; - bool is_duallink = false; /* reset the pll flags */ pll->flags = 0; @@ -553,7 +557,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, if (connector && connector->display_info.bpc) bpc = connector->display_info.bpc; encoder_mode = atombios_get_encoder_mode(encoder); - is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { if (connector) { @@ -649,7 +652,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, if (dig->coherent_mode) args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_COHERENT_MODE; - if (is_duallink) + if (mode->clock > 165000) args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK; } @@ -699,9 +702,11 @@ union set_pixel_clock { /* on DCE5, make sure the voltage is high enough to support the * required disp clk. */ -static void atombios_crtc_set_dcpll(struct radeon_device *rdev, +static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, u32 dispclk) { + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; u8 frev, crev; int index; union set_pixel_clock args; @@ -991,7 +996,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, &ref_div, &post_div); - atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); + atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss); atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, encoder_mode, radeon_encoder->encoder_id, mode->clock, @@ -1014,7 +1019,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode ss.step = step_size; } - atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); + atombios_crtc_program_ss(crtc, ATOM_ENABLE, radeon_crtc->pll_id, &ss); } } @@ -1184,7 +1189,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, - target_fb->height); + crtc->mode.vdisplay); x &= ~3; y &= ~1; WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, @@ -1353,7 +1358,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, - target_fb->height); + crtc->mode.vdisplay); x &= ~3; y &= ~1; WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, @@ -1489,24 +1494,6 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) } -void radeon_atom_dcpll_init(struct radeon_device *rdev) -{ - /* always set DCPLL */ - if (ASIC_IS_DCE4(rdev)) { - struct radeon_atom_ss ss; - bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, - ASIC_INTERNAL_SS_ON_DCPLL, - rdev->clock.default_dispclk); - if (ss_enabled) - atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); - /* XXX: DCE5, make sure voltage, dispclk is high enough */ - atombios_crtc_set_dcpll(rdev, rdev->clock.default_dispclk); - if (ss_enabled) - atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); - } - -} - int atombios_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -1528,6 +1515,19 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, } } + /* always set DCPLL */ + if (ASIC_IS_DCE4(rdev)) { + struct radeon_atom_ss ss; + bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, + ASIC_INTERNAL_SS_ON_DCPLL, + rdev->clock.default_dispclk); + if (ss_enabled) + atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss); + /* XXX: DCE5, make sure voltage, dispclk is high enough */ + atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk); + if (ss_enabled) + atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss); + } atombios_crtc_set_pll(crtc, adjusted_mode); if (ASIC_IS_DCE4(rdev)) diff --git a/trunk/drivers/gpu/drm/radeon/atombios_dp.c b/trunk/drivers/gpu/drm/radeon/atombios_dp.c index 552b436451fd..6fb335a4fdda 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_dp.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_dp.c @@ -549,8 +549,8 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) return false; } -int radeon_dp_get_panel_mode(struct drm_encoder *encoder, - struct drm_connector *connector) +static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, + struct drm_connector *connector) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; @@ -558,33 +558,28 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; if (!ASIC_IS_DCE4(rdev)) - return panel_mode; + return; if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == ENCODER_OBJECT_ID_NUTMEG) panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == - ENCODER_OBJECT_ID_TRAVIS) { - u8 id[6]; - int i; - for (i = 0; i < 6; i++) - id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); - if (id[0] == 0x73 && - id[1] == 0x69 && - id[2] == 0x76 && - id[3] == 0x61 && - id[4] == 0x72 && - id[5] == 0x54) - panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; - else - panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; - } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + ENCODER_OBJECT_ID_TRAVIS) + panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; + else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); if (tmp & 1) panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; } - return panel_mode; + atombios_dig_encoder_setup(encoder, + ATOM_ENCODER_CMD_SETUP_PANEL_MODE, + panel_mode); + + if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) && + (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { + radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1); + } } void radeon_dp_set_link_config(struct drm_connector *connector, @@ -722,8 +717,6 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; u8 tmp; /* power up the sink */ @@ -739,10 +732,7 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) radeon_write_dpcd_reg(dp_info->radeon_connector, DP_DOWNSPREAD_CTRL, 0); - if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && - (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1); - } + radeon_dp_set_panel_mode(dp_info->encoder, dp_info->connector); /* set the lane count on the sink */ tmp = dp_info->dp_lane_count; diff --git a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c index b88c4608731b..f1f06ca9f1f5 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c @@ -57,6 +57,22 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) } } +static struct drm_connector * +radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_connector *connector; + struct radeon_connector *radeon_connector; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + radeon_connector = to_radeon_connector(connector); + if (radeon_encoder->devices & radeon_connector->devices) + return connector; + } + return NULL; +} + static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -237,7 +253,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) /* R4xx, R5xx */ args.ext_tmds.sXTmdsEncoder.ucEnable = action; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + if (radeon_encoder->pixel_clock > 165000) args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; @@ -249,7 +265,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) /* DFP1, CRT1, TV1 depending on the type of port */ args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + if (radeon_encoder->pixel_clock > 165000) args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; break; case 3: @@ -333,7 +349,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) } else { if (dig->linkb) args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + if (radeon_encoder->pixel_clock > 165000) args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; /*if (pScrn->rgbBits == 8) */ args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; @@ -372,7 +388,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) } else { if (dig->linkb) args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + if (radeon_encoder->pixel_clock > 165000) args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; } break; @@ -416,7 +432,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) switch (connector->connector_type) { case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ - if (drm_detect_hdmi_monitor(radeon_connector->edid) && + if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) return ATOM_ENCODER_MODE_HDMI; else if (radeon_connector->use_digital) @@ -427,7 +443,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) case DRM_MODE_CONNECTOR_DVID: case DRM_MODE_CONNECTOR_HDMIA: default: - if (drm_detect_hdmi_monitor(radeon_connector->edid) && + if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) return ATOM_ENCODER_MODE_HDMI; else @@ -441,7 +457,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) return ATOM_ENCODER_MODE_DP; - else if (drm_detect_hdmi_monitor(radeon_connector->edid) && + else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) return ATOM_ENCODER_MODE_HDMI; else @@ -571,7 +587,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) args.v1.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v1.ucLaneNum = 8; else args.v1.ucLaneNum = 4; @@ -606,7 +622,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) args.v3.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v3.ucLaneNum = 8; else args.v3.ucLaneNum = 4; @@ -646,7 +662,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) args.v4.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v4.ucLaneNum = 8; else args.v4.ucLaneNum = 4; @@ -790,7 +806,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t if (is_dp) args.v1.usPixelClock = cpu_to_le16(dp_clock / 10); - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); else args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); @@ -805,8 +821,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t if ((rdev->flags & RADEON_IS_IGP) && (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { - if (is_dp || - !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) { + if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { if (igp_lane_info & 0x1) args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; else if (igp_lane_info & 0x2) @@ -833,7 +848,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { if (dig->coherent_mode) args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + if (radeon_encoder->pixel_clock > 165000) args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; } break; @@ -848,7 +863,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t if (is_dp) args.v2.usPixelClock = cpu_to_le16(dp_clock / 10); - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); else args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); @@ -876,7 +891,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { if (dig->coherent_mode) args.v2.acConfig.fCoherentMode = 1; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + if (radeon_encoder->pixel_clock > 165000) args.v2.acConfig.fDualLinkConnector = 1; } break; @@ -891,7 +906,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t if (is_dp) args.v3.usPixelClock = cpu_to_le16(dp_clock / 10); - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); else args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); @@ -899,7 +914,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t if (is_dp) args.v3.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v3.ucLaneNum = 8; else args.v3.ucLaneNum = 4; @@ -936,7 +951,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { if (dig->coherent_mode) args.v3.acConfig.fCoherentMode = 1; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + if (radeon_encoder->pixel_clock > 165000) args.v3.acConfig.fDualLinkConnector = 1; } break; @@ -951,7 +966,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t if (is_dp) args.v4.usPixelClock = cpu_to_le16(dp_clock / 10); - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); else args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); @@ -959,7 +974,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t if (is_dp) args.v4.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + else if (radeon_encoder->pixel_clock > 165000) args.v4.ucLaneNum = 8; else args.v4.ucLaneNum = 4; @@ -999,7 +1014,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { if (dig->coherent_mode) args.v4.acConfig.fCoherentMode = 1; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + if (radeon_encoder->pixel_clock > 165000) args.v4.acConfig.fDualLinkConnector = 1; } break; @@ -1122,7 +1137,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, if (dp_clock == 270000) args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; args.v1.sDigEncoder.ucLaneNum = dp_lane_count; - } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + } else if (radeon_encoder->pixel_clock > 165000) args.v1.sDigEncoder.ucLaneNum = 8; else args.v1.sDigEncoder.ucLaneNum = 4; @@ -1141,7 +1156,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, else if (dp_clock == 540000) args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; args.v3.sExtEncoder.ucLaneNum = dp_lane_count; - } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + } else if (radeon_encoder->pixel_clock > 165000) args.v3.sExtEncoder.ucLaneNum = 8; else args.v3.sExtEncoder.ucLaneNum = 4; @@ -1326,8 +1341,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: /* some early dce3.2 boards have a bug in their transmitter control table */ - if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || - ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) + if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); else atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); @@ -1337,6 +1351,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) ATOM_TRANSMITTER_ACTION_POWER_ON); radeon_dig_connector->edp_on = true; } + if (ASIC_IS_DCE4(rdev)) + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); radeon_dp_link_train(encoder, connector); if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); @@ -1347,10 +1363,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - else - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); @@ -1797,21 +1810,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - - if (!connector) - dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; - else - dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); - - /* setup and enable the encoder */ - atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); - atombios_dig_encoder_setup(encoder, - ATOM_ENCODER_CMD_SETUP_PANEL_MODE, - dig->panel_mode); - } else if (ASIC_IS_DCE4(rdev)) { + if (ASIC_IS_DCE4(rdev)) { /* disable the transmitter */ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); /* setup and enable the encoder */ diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index ae09fe82afbc..636660fca8c2 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -1455,7 +1455,6 @@ int evergreen_cp_resume(struct radeon_device *rdev) #endif WREG32(CP_RB_CNTL, tmp); WREG32(CP_SEM_WAIT_TIMER, 0x0); - WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); /* Set the write pointer delay */ WREG32(CP_RB_WPTR_DELAY, 0); diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index 74713d42df29..b502216d42af 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -108,7 +108,6 @@ #define CP_RB_WPTR_ADDR_HI 0xC11C #define CP_RB_WPTR_DELAY 0x8704 #define CP_SEM_WAIT_TIMER 0x85BC -#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 #define CP_DEBUG 0xC1FC diff --git a/trunk/drivers/gpu/drm/radeon/ni.c b/trunk/drivers/gpu/drm/radeon/ni.c index db09065e68fd..321137295400 100644 --- a/trunk/drivers/gpu/drm/radeon/ni.c +++ b/trunk/drivers/gpu/drm/radeon/ni.c @@ -1219,7 +1219,6 @@ int cayman_cp_resume(struct radeon_device *rdev) RREG32(GRBM_SOFT_RESET); WREG32(CP_SEM_WAIT_TIMER, 0x0); - WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); /* Set the write pointer delay */ WREG32(CP_RB_WPTR_DELAY, 0); diff --git a/trunk/drivers/gpu/drm/radeon/nid.h b/trunk/drivers/gpu/drm/radeon/nid.h index 9a7f3b6e02de..f9df2a645e79 100644 --- a/trunk/drivers/gpu/drm/radeon/nid.h +++ b/trunk/drivers/gpu/drm/radeon/nid.h @@ -222,7 +222,6 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 #define CP_SEM_WAIT_TIMER 0x85BC -#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 #define CP_COHER_CNTL2 0x85E8 #define CP_ME_CNTL 0x86D8 #define CP_ME_HALT (1 << 28) diff --git a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c index accc032c103f..d996f4381130 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -468,42 +468,27 @@ set_default_state(struct radeon_device *rdev) radeon_ring_write(ring, sq_stack_resource_mgmt_2); } -#define I2F_MAX_BITS 15 -#define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1) -#define I2F_SHIFT (24 - I2F_MAX_BITS) - -/* - * Converts unsigned integer into 32-bit IEEE floating point representation. - * Conversion is not universal and only works for the range from 0 - * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between - * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary, - * I2F_MAX_BITS can be increased, but that will add to the loop iterations - * and slow us down. Conversion is done by shifting the input and counting - * down until the first 1 reaches bit position 23. The resulting counter - * and the shifted input are, respectively, the exponent and the fraction. - * The sign is always zero. - */ static uint32_t i2f(uint32_t input) { u32 result, i, exponent, fraction; - WARN_ON_ONCE(input > I2F_MAX_INPUT); - - if ((input & I2F_MAX_INPUT) == 0) - result = 0; + if ((input & 0x3fff) == 0) + result = 0; /* 0 is a special case */ else { - exponent = 126 + I2F_MAX_BITS; - fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT; - - for (i = 0; i < I2F_MAX_BITS; i++) { + exponent = 140; /* exponent biased by 127; */ + fraction = (input & 0x3fff) << 10; /* cheat and only + handle numbers below 2^^15 */ + for (i = 0; i < 14; i++) { if (fraction & 0x800000) break; else { - fraction = fraction << 1; + fraction = fraction << 1; /* keep + shifting left until top bit = 1 */ exponent = exponent - 1; } } - result = exponent << 23 | (fraction & 0x7fffff); + result = exponent << 23 | (fraction & 0x7fffff); /* mask + off top bit; assumed 1 */ } return result; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index 1668ec1ee770..73e05cb85eca 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -156,47 +156,6 @@ static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) bool radeon_get_bios(struct radeon_device *rdev); -/* - * Mutex which allows recursive locking from the same process. - */ -struct radeon_mutex { - struct mutex mutex; - struct task_struct *owner; - int level; -}; - -static inline void radeon_mutex_init(struct radeon_mutex *mutex) -{ - mutex_init(&mutex->mutex); - mutex->owner = NULL; - mutex->level = 0; -} - -static inline void radeon_mutex_lock(struct radeon_mutex *mutex) -{ - if (mutex_trylock(&mutex->mutex)) { - /* The mutex was unlocked before, so it's ours now */ - mutex->owner = current; - } else if (mutex->owner != current) { - /* Another process locked the mutex, take it */ - mutex_lock(&mutex->mutex); - mutex->owner = current; - } - /* Otherwise the mutex was already locked by this process */ - - mutex->level++; -} - -static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) -{ - if (--mutex->level > 0) - return; - - mutex->owner = NULL; - mutex_unlock(&mutex->mutex); -} - - /* * Dummy page */ @@ -639,7 +598,7 @@ struct radeon_ib { * mutex protects scheduled_ibs, ready, alloc_bm */ struct radeon_ib_pool { - struct radeon_mutex mutex; + struct mutex mutex; struct radeon_sa_manager sa_manager; struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; bool ready; @@ -1395,6 +1354,47 @@ struct r600_vram_scratch { }; +/* + * Mutex which allows recursive locking from the same process. + */ +struct radeon_mutex { + struct mutex mutex; + struct task_struct *owner; + int level; +}; + +static inline void radeon_mutex_init(struct radeon_mutex *mutex) +{ + mutex_init(&mutex->mutex); + mutex->owner = NULL; + mutex->level = 0; +} + +static inline void radeon_mutex_lock(struct radeon_mutex *mutex) +{ + if (mutex_trylock(&mutex->mutex)) { + /* The mutex was unlocked before, so it's ours now */ + mutex->owner = current; + } else if (mutex->owner != current) { + /* Another process locked the mutex, take it */ + mutex_lock(&mutex->mutex); + mutex->owner = current; + } + /* Otherwise the mutex was already locked by this process */ + + mutex->level++; +} + +static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) +{ + if (--mutex->level > 0) + return; + + mutex->owner = NULL; + mutex_unlock(&mutex->mutex); +} + + /* * Core structure, functions and helpers. */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 98724fcb0088..9d95792bea3e 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -58,8 +58,7 @@ static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, } obj = (union acpi_object *)buffer.pointer; - memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); - len = obj->buffer.length; + memcpy(bios+offset, obj->buffer.pointer, len); kfree(buffer.pointer); return len; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_bios.c b/trunk/drivers/gpu/drm/radeon/radeon_bios.c index 501f4881e5aa..229a20f10e2b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_bios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_bios.c @@ -120,7 +120,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) ret = radeon_atrm_get_bios_chunk(rdev->bios, (i * ATRM_BIOS_PAGE), ATRM_BIOS_PAGE); - if (ret < ATRM_BIOS_PAGE) + if (ret <= 0) break; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index 49f7cb7e226b..0afb13bd8dca 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -720,7 +720,7 @@ int radeon_device_init(struct radeon_device *rdev, /* mutex initialization are all done here so we * can recall function without having locking issues */ radeon_mutex_init(&rdev->cs_mutex); - radeon_mutex_init(&rdev->ib_pool.mutex); + mutex_init(&rdev->ib_pool.mutex); for (i = 0; i < RADEON_NUM_RINGS; ++i) mutex_init(&rdev->ring[i].mutex); mutex_init(&rdev->dc_hw_i2c_mutex); @@ -883,8 +883,6 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - drm_kms_helper_poll_disable(dev); - /* turn off display hw */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); @@ -961,11 +959,9 @@ int radeon_resume_kms(struct drm_device *dev) radeon_fbdev_set_suspend(rdev, 0); console_unlock(); - /* init dig PHYs, disp eng pll */ - if (rdev->is_atom_bios) { + /* init dig PHYs */ + if (rdev->is_atom_bios) radeon_atom_encoder_init(rdev); - radeon_atom_dcpll_init(rdev); - } /* reset hpd state */ radeon_hpd_init(rdev); /* blat the mode back in */ @@ -974,8 +970,6 @@ int radeon_resume_kms(struct drm_device *dev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); } - - drm_kms_helper_poll_enable(dev); return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c index 8c49fef1ce78..d3ffc18774a6 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_display.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c @@ -1305,11 +1305,9 @@ int radeon_modeset_init(struct radeon_device *rdev) return ret; } - /* init dig PHYs, disp eng pll */ - if (rdev->is_atom_bios) { + /* init dig PHYs */ + if (rdev->is_atom_bios) radeon_atom_encoder_init(rdev); - radeon_atom_dcpll_init(rdev); - } /* initialize hpd */ radeon_hpd_init(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c index 9419c51bcf50..4b27efa4405b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c @@ -202,22 +202,6 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) return NULL; } -struct drm_connector * -radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - radeon_connector = to_radeon_connector(connector); - if (radeon_encoder->devices & radeon_connector->devices) - return connector; - } - return NULL; -} - struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; @@ -304,64 +288,3 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, } -bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, - u32 pixel_clock) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *dig_connector; - - connector = radeon_get_connector_for_encoder(encoder); - /* if we don't have an active device yet, just use one of - * the connectors tied to the encoder. - */ - if (!connector) - connector = radeon_get_connector_for_encoder_init(encoder); - radeon_connector = to_radeon_connector(connector); - - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_HDMIB: - if (radeon_connector->use_digital) { - /* HDMI 1.3 supports up to 340 Mhz over single link */ - if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { - if (pixel_clock > 340000) - return true; - else - return false; - } else { - if (pixel_clock > 165000) - return true; - else - return false; - } - } else - return false; - case DRM_MODE_CONNECTOR_DVID: - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_DisplayPort: - dig_connector = radeon_connector->con_priv; - if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || - (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) - return false; - else { - /* HDMI 1.3 supports up to 340 Mhz over single link */ - if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { - if (pixel_clock > 340000) - return true; - else - return false; - } else { - if (pixel_clock > 165000) - return true; - else - return false; - } - } - default: - return false; - } -} - diff --git a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c index 98a8ad680109..7bb1b079f480 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c @@ -897,7 +897,6 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, i2c->rec = *rec; i2c->adapter.owner = THIS_MODULE; i2c->adapter.class = I2C_CLASS_DDC; - i2c->adapter.dev.parent = &dev->pdev->dev; i2c->dev = dev; i2c_set_adapdata(&i2c->adapter, i2c); if (rec->mm_i2c || @@ -958,7 +957,6 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, i2c->rec = *rec; i2c->adapter.owner = THIS_MODULE; i2c->adapter.class = I2C_CLASS_DDC; - i2c->adapter.dev.parent = &dev->pdev->dev; i2c->dev = dev; snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "Radeon aux bus %s", name); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c index 66d5fe1c8174..be38921bf761 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -135,12 +135,6 @@ static bool radeon_msi_ok(struct radeon_device *rdev) (rdev->pdev->subsystem_device == 0x30c2)) return true; - /* Dell RS690 only seems to work with MSIs. */ - if ((rdev->pdev->device == 0x791f) && - (rdev->pdev->subsystem_vendor == 0x1028) && - (rdev->pdev->subsystem_device == 0x01fc)) - return true; - /* Dell RS690 only seems to work with MSIs. */ if ((rdev->pdev->device == 0x791f) && (rdev->pdev->subsystem_vendor == 0x1028) && diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index 4330e3253573..08ff857c8fd6 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -362,7 +362,6 @@ struct radeon_encoder_atom_dig { struct backlight_device *bl_dev; int dpms_mode; uint8_t backlight_level; - int panel_mode; }; struct radeon_encoder_atom_dac { @@ -467,10 +466,6 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev); extern struct drm_connector * radeon_get_connector_for_encoder(struct drm_encoder *encoder); -extern struct drm_connector * -radeon_get_connector_for_encoder_init(struct drm_encoder *encoder); -extern bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, - u32 pixel_clock); extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); @@ -487,11 +482,8 @@ extern void radeon_dp_link_train(struct drm_encoder *encoder, extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); -extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, - struct drm_connector *connector); extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); extern void radeon_atom_encoder_init(struct radeon_device *rdev); -extern void radeon_atom_dcpll_init(struct radeon_device *rdev); extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ring.c b/trunk/drivers/gpu/drm/radeon/radeon_ring.c index 30a4c5014c8b..e8bc70933d1b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ring.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ring.c @@ -109,12 +109,12 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, return r; } - radeon_mutex_lock(&rdev->ib_pool.mutex); + mutex_lock(&rdev->ib_pool.mutex); idx = rdev->ib_pool.head_id; retry: if (cretry > 5) { dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); - radeon_mutex_unlock(&rdev->ib_pool.mutex); + mutex_unlock(&rdev->ib_pool.mutex); radeon_fence_unref(&fence); return -ENOMEM; } @@ -139,7 +139,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, */ rdev->ib_pool.head_id = (1 + idx); rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); - radeon_mutex_unlock(&rdev->ib_pool.mutex); + mutex_unlock(&rdev->ib_pool.mutex); return 0; } } @@ -158,7 +158,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, } idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); } - radeon_mutex_unlock(&rdev->ib_pool.mutex); + mutex_unlock(&rdev->ib_pool.mutex); radeon_fence_unref(&fence); return r; } @@ -171,12 +171,12 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) if (tmp == NULL) { return; } - radeon_mutex_lock(&rdev->ib_pool.mutex); + mutex_lock(&rdev->ib_pool.mutex); if (tmp->fence && !tmp->fence->emitted) { radeon_sa_bo_free(rdev, &tmp->sa_bo); radeon_fence_unref(&tmp->fence); } - radeon_mutex_unlock(&rdev->ib_pool.mutex); + mutex_unlock(&rdev->ib_pool.mutex); } int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) @@ -204,25 +204,22 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) int radeon_ib_pool_init(struct radeon_device *rdev) { - struct radeon_sa_manager tmp; int i, r; - r = radeon_sa_bo_manager_init(rdev, &tmp, + mutex_lock(&rdev->ib_pool.mutex); + if (rdev->ib_pool.ready) { + mutex_unlock(&rdev->ib_pool.mutex); + return 0; + } + + r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager, RADEON_IB_POOL_SIZE*64*1024, RADEON_GEM_DOMAIN_GTT); if (r) { + mutex_unlock(&rdev->ib_pool.mutex); return r; } - radeon_mutex_lock(&rdev->ib_pool.mutex); - if (rdev->ib_pool.ready) { - radeon_mutex_unlock(&rdev->ib_pool.mutex); - radeon_sa_bo_manager_fini(rdev, &tmp); - return 0; - } - - rdev->ib_pool.sa_manager = tmp; - INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo); for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { rdev->ib_pool.ibs[i].fence = NULL; rdev->ib_pool.ibs[i].idx = i; @@ -239,7 +236,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) if (radeon_debugfs_ring_init(rdev)) { DRM_ERROR("Failed to register debugfs file for rings !\n"); } - radeon_mutex_unlock(&rdev->ib_pool.mutex); + mutex_unlock(&rdev->ib_pool.mutex); return 0; } @@ -247,7 +244,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) { unsigned i; - radeon_mutex_lock(&rdev->ib_pool.mutex); + mutex_lock(&rdev->ib_pool.mutex); if (rdev->ib_pool.ready) { for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); @@ -256,7 +253,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); rdev->ib_pool.ready = false; } - radeon_mutex_unlock(&rdev->ib_pool.mutex); + mutex_unlock(&rdev->ib_pool.mutex); } int radeon_ib_pool_start(struct radeon_device *rdev) diff --git a/trunk/drivers/gpu/drm/sis/sis_drv.c b/trunk/drivers/gpu/drm/sis/sis_drv.c index 573220cc5269..06da063ece2e 100644 --- a/trunk/drivers/gpu/drm/sis/sis_drv.c +++ b/trunk/drivers/gpu/drm/sis/sis_drv.c @@ -40,6 +40,7 @@ static struct pci_device_id pciidlist[] = { static int sis_driver_load(struct drm_device *dev, unsigned long chipset) { drm_sis_private_t *dev_priv; + int ret; dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); if (dev_priv == NULL) @@ -49,7 +50,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->chipset = chipset; idr_init(&dev->object_name_idr); - return 0; + return ret; } static int sis_driver_unload(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c index 7c3a57de8187..2f0eab66ece6 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c @@ -404,9 +404,6 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, } } - if (bdev->driver->move_notify) - bdev->driver->move_notify(bo, mem); - if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem); @@ -416,17 +413,11 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, else ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem); - if (ret) { - if (bdev->driver->move_notify) { - struct ttm_mem_reg tmp_mem = *mem; - *mem = bo->mem; - bo->mem = tmp_mem; - bdev->driver->move_notify(bo, mem); - bo->mem = *mem; - } - + if (ret) goto out_err; - } + + if (bdev->driver->move_notify) + bdev->driver->move_notify(bo, mem); moved: if (bo->evicted) { diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index b66ef0e3cde1..0af6ebdf205d 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -378,7 +378,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb, unsigned int *handle) { if (handle) - *handle = 0; + handle = 0; return 0; } diff --git a/trunk/drivers/hid/hid-hyperv.c b/trunk/drivers/hid/hid-hyperv.c index 406632472c1b..0c33ae9cf0f0 100644 --- a/trunk/drivers/hid/hid-hyperv.c +++ b/trunk/drivers/hid/hid-hyperv.c @@ -548,7 +548,6 @@ static int mousevsc_remove(struct hv_device *dev) struct mousevsc_dev *input_dev = hv_get_drvdata(dev); vmbus_close(dev->channel); - hid_hw_stop(input_dev->hid_device); hid_destroy_device(input_dev->hid_device); mousevsc_free_device(input_dev); diff --git a/trunk/drivers/hid/hid-wacom.c b/trunk/drivers/hid/hid-wacom.c index acab74cde727..b47e58b52d9f 100644 --- a/trunk/drivers/hid/hid-wacom.c +++ b/trunk/drivers/hid/hid-wacom.c @@ -531,6 +531,7 @@ static int wacom_probe(struct hid_device *hdev, wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; wdata->battery.use_for_apm = 0; + power_supply_powers(&wdata->battery, &hdev->dev); ret = power_supply_register(&hdev->dev, &wdata->battery); if (ret) { @@ -539,8 +540,6 @@ static int wacom_probe(struct hid_device *hdev, goto err_battery; } - power_supply_powers(&wdata->battery, &hdev->dev); - wdata->ac.properties = wacom_ac_props; wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props); wdata->ac.get_property = wacom_ac_get_property; @@ -548,14 +547,14 @@ static int wacom_probe(struct hid_device *hdev, wdata->ac.type = POWER_SUPPLY_TYPE_MAINS; wdata->ac.use_for_apm = 0; + power_supply_powers(&wdata->battery, &hdev->dev); + ret = power_supply_register(&hdev->dev, &wdata->ac); if (ret) { hid_warn(hdev, "can't create ac battery attribute, err: %d\n", ret); goto err_ac; } - - power_supply_powers(&wdata->ac, &hdev->dev); #endif return 0; diff --git a/trunk/drivers/hid/hid-wiimote-core.c b/trunk/drivers/hid/hid-wiimote-core.c index cac3589b1ed5..fc253b472f9d 100644 --- a/trunk/drivers/hid/hid-wiimote-core.c +++ b/trunk/drivers/hid/hid-wiimote-core.c @@ -1226,14 +1226,14 @@ static int wiimote_hid_probe(struct hid_device *hdev, wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; wdata->battery.use_for_apm = 0; + power_supply_powers(&wdata->battery, &hdev->dev); + ret = power_supply_register(&wdata->hdev->dev, &wdata->battery); if (ret) { hid_err(hdev, "Cannot register battery device\n"); goto err_battery; } - power_supply_powers(&wdata->battery, &hdev->dev); - ret = wiimote_leds_create(wdata); if (ret) goto err_free; diff --git a/trunk/drivers/hid/usbhid/hiddev.c b/trunk/drivers/hid/usbhid/hiddev.c index b1ec0e2aeb57..7c297d305d5d 100644 --- a/trunk/drivers/hid/usbhid/hiddev.c +++ b/trunk/drivers/hid/usbhid/hiddev.c @@ -922,11 +922,11 @@ void hiddev_disconnect(struct hid_device *hid) struct hiddev *hiddev = hid->hiddev; struct usbhid_device *usbhid = hid->driver_data; - usb_deregister_dev(usbhid->intf, &hiddev_class); - mutex_lock(&hiddev->existancelock); hiddev->exist = 0; + usb_deregister_dev(usbhid->intf, &hiddev_class); + if (hiddev->open) { mutex_unlock(&hiddev->existancelock); usbhid_close(hiddev->hid); diff --git a/trunk/drivers/hwmon/f71805f.c b/trunk/drivers/hwmon/f71805f.c index 6dbfd3e516e4..92f949767ece 100644 --- a/trunk/drivers/hwmon/f71805f.c +++ b/trunk/drivers/hwmon/f71805f.c @@ -283,11 +283,11 @@ static inline long temp_from_reg(u8 reg) static inline u8 temp_to_reg(long val) { - if (val <= 0) - return 0; - if (val >= 1000 * 0xff) - return 0xff; - return (val + 500) / 1000; + if (val < 0) + val = 0; + else if (val > 1000 * 0xff) + val = 0xff; + return ((val + 500) / 1000); } /* diff --git a/trunk/drivers/hwmon/sht15.c b/trunk/drivers/hwmon/sht15.c index 91fdd1fe18b0..6ddeae049058 100644 --- a/trunk/drivers/hwmon/sht15.c +++ b/trunk/drivers/hwmon/sht15.c @@ -883,7 +883,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb, static int __devinit sht15_probe(struct platform_device *pdev) { - int ret; + int ret = 0; struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); u8 status = 0; @@ -901,7 +901,6 @@ static int __devinit sht15_probe(struct platform_device *pdev) init_waitqueue_head(&data->wait_queue); if (pdev->dev.platform_data == NULL) { - ret = -EINVAL; dev_err(&pdev->dev, "no platform data supplied\n"); goto err_free_data; } diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index 4d383e7e051d..0e0af0445222 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -1319,7 +1319,6 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, { struct w83627ehf_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - struct w83627ehf_sio_data *sio_data = dev->platform_data; int nr = sensor_attr->index; unsigned long val; int err; @@ -1331,11 +1330,6 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, if (val > 1) return -EINVAL; - - /* On NCT67766F, DC mode is only supported for pwm1 */ - if (sio_data->kind == nct6776 && nr && val != 1) - return -EINVAL; - mutex_lock(&data->update_lock); reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); data->pwm_mode[nr] = val; @@ -1920,26 +1914,9 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data, fan4min = 0; fan5pin = 0; } else if (sio_data->kind == nct6776) { - bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80; - - superio_select(sio_data->sioreg, W83627EHF_LD_HWM); - regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE); - - if (regval & 0x80) - fan3pin = gpok; - else - fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); - - if (regval & 0x40) - fan4pin = gpok; - else - fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01); - - if (regval & 0x20) - fan5pin = gpok; - else - fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02); - + fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); + fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01); + fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02); fan4min = fan4pin; } else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) { fan3pin = 1; diff --git a/trunk/drivers/i2c/busses/i2c-omap.c b/trunk/drivers/i2c/busses/i2c-omap.c index 801df6000e9b..f713eac55047 100644 --- a/trunk/drivers/i2c/busses/i2c-omap.c +++ b/trunk/drivers/i2c/busses/i2c-omap.c @@ -1018,7 +1018,7 @@ omap_i2c_probe(struct platform_device *pdev) goto err_release_region; } - match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev); + match = of_match_device(omap_i2c_of_match, &pdev->dev); if (match) { u32 freq = 100000; /* default to 100000 Hz */ diff --git a/trunk/drivers/idle/intel_idle.c b/trunk/drivers/idle/intel_idle.c index 54ab97bae042..20bce51c2e82 100644 --- a/trunk/drivers/idle/intel_idle.c +++ b/trunk/drivers/idle/intel_idle.c @@ -527,7 +527,7 @@ int intel_idle_cpu_init(int cpu) return 0; } -EXPORT_SYMBOL_GPL(intel_idle_cpu_init); + static int __init intel_idle_init(void) { diff --git a/trunk/drivers/infiniband/core/ucma.c b/trunk/drivers/infiniband/core/ucma.c index 5034a87cc72d..b37b0c02a7b9 100644 --- a/trunk/drivers/infiniband/core/ucma.c +++ b/trunk/drivers/infiniband/core/ucma.c @@ -808,12 +808,9 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, return PTR_ERR(ctx); if (cmd.conn_param.valid) { + ctx->uid = cmd.uid; ucma_copy_conn_param(&conn_param, &cmd.conn_param); - mutex_lock(&file->mut); ret = rdma_accept(ctx->cm_id, &conn_param); - if (!ret) - ctx->uid = cmd.uid; - mutex_unlock(&file->mut); } else ret = rdma_accept(ctx->cm_id, NULL); diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c index 4d27e4c3fe34..b930da4c0c63 100644 --- a/trunk/drivers/infiniband/core/uverbs_cmd.c +++ b/trunk/drivers/infiniband/core/uverbs_cmd.c @@ -1485,7 +1485,6 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, qp->event_handler = attr.event_handler; qp->qp_context = attr.qp_context; qp->qp_type = attr.qp_type; - atomic_set(&qp->usecnt, 0); atomic_inc(&pd->usecnt); atomic_inc(&attr.send_cq->usecnt); if (attr.recv_cq) diff --git a/trunk/drivers/infiniband/core/verbs.c b/trunk/drivers/infiniband/core/verbs.c index 575b78045aaf..602b1bd723a9 100644 --- a/trunk/drivers/infiniband/core/verbs.c +++ b/trunk/drivers/infiniband/core/verbs.c @@ -421,7 +421,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, qp->uobject = NULL; qp->qp_type = qp_init_attr->qp_type; - atomic_set(&qp->usecnt, 0); if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { qp->event_handler = __ib_shared_qp_event_handler; qp->qp_context = qp; @@ -431,6 +430,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, qp->xrcd = qp_init_attr->xrcd; atomic_inc(&qp_init_attr->xrcd->usecnt); INIT_LIST_HEAD(&qp->open_list); + atomic_set(&qp->usecnt, 0); real_qp = qp; qp = __ib_open_qp(real_qp, qp_init_attr->event_handler, diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c index a4de9d58e9b4..b7d4216db3c3 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c @@ -89,7 +89,7 @@ static int create_file(const char *name, umode_t mode, error = ipathfs_mknod(parent->d_inode, *dentry, mode, fops, data); else - error = PTR_ERR(*dentry); + error = PTR_ERR(dentry); mutex_unlock(&parent->d_inode->i_mutex); return error; diff --git a/trunk/drivers/infiniband/hw/mlx4/mad.c b/trunk/drivers/infiniband/hw/mlx4/mad.c index 259b0670b51c..95c94d8f0254 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mad.c +++ b/trunk/drivers/infiniband/hw/mlx4/mad.c @@ -257,9 +257,12 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, return IB_MAD_RESULT_SUCCESS; /* - * Don't process SMInfo queries -- the SMA can't handle them. + * Don't process SMInfo queries or vendor-specific + * MADs -- the SMA can't handle them. */ - if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO) + if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO || + ((in_mad->mad_hdr.attr_id & IB_SMP_ATTR_VENDOR_MASK) == + IB_SMP_ATTR_VENDOR_MASK)) return IB_MAD_RESULT_SUCCESS; } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 || diff --git a/trunk/drivers/infiniband/hw/nes/nes.c b/trunk/drivers/infiniband/hw/nes/nes.c index 7140199f562e..7013da5e9eda 100644 --- a/trunk/drivers/infiniband/hw/nes/nes.c +++ b/trunk/drivers/infiniband/hw/nes/nes.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/infiniband/hw/nes/nes.h b/trunk/drivers/infiniband/hw/nes/nes.h index c438e4691b3c..568b4f11380a 100644 --- a/trunk/drivers/infiniband/hw/nes/nes.h +++ b/trunk/drivers/infiniband/hw/nes/nes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.c b/trunk/drivers/infiniband/hw/nes/nes_cm.c index a4972abedef1..425065b36b8c 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.c +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -233,7 +233,6 @@ static int send_mpa_reject(struct nes_cm_node *cm_node) u8 *start_ptr = &start_addr; u8 **start_buff = &start_ptr; u16 buff_len = 0; - struct ietf_mpa_v1 *mpa_frame; skb = dev_alloc_skb(MAX_CM_BUFFER); if (!skb) { @@ -243,8 +242,6 @@ static int send_mpa_reject(struct nes_cm_node *cm_node) /* send an MPA reject frame */ cm_build_mpa_frame(cm_node, start_buff, &buff_len, NULL, MPA_KEY_REPLY); - mpa_frame = (struct ietf_mpa_v1 *)*start_buff; - mpa_frame->flags |= IETF_MPA_FLAGS_REJECT; form_cm_frame(skb, cm_node, NULL, 0, *start_buff, buff_len, SET_ACK | SET_FIN); cm_node->state = NES_CM_STATE_FIN_WAIT1; @@ -1363,7 +1360,8 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi if (!memcmp(nesadapter->arp_table[arpindex].mac_addr, neigh->ha, ETH_ALEN)) { /* Mac address same as in nes_arp_table */ - goto out; + ip_rt_put(rt); + return rc; } nes_manage_arp_cache(nesvnic->netdev, @@ -1379,8 +1377,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi neigh_event_send(neigh, NULL); } } - -out: rcu_read_unlock(); ip_rt_put(rt); return rc; diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.h b/trunk/drivers/infiniband/hw/nes/nes_cm.h index 4646e6666087..bdfa1fbb35fc 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.h +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_context.h b/trunk/drivers/infiniband/hw/nes/nes_context.h index a69eef16d72d..b4393a16099d 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_context.h +++ b/trunk/drivers/infiniband/hw/nes/nes_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_hw.c b/trunk/drivers/infiniband/hw/nes/nes_hw.c index d42c9f435b1b..055f4b545df0 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_hw.c +++ b/trunk/drivers/infiniband/hw/nes/nes_hw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_hw.h b/trunk/drivers/infiniband/hw/nes/nes_hw.h index d748e4b31b8d..0b590e152c6a 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_hw.h +++ b/trunk/drivers/infiniband/hw/nes/nes_hw.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. +* Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_mgt.c b/trunk/drivers/infiniband/hw/nes/nes_mgt.c index 3ba7be369452..b3b2a240c6e9 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_mgt.c +++ b/trunk/drivers/infiniband/hw/nes/nes_mgt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_mgt.h b/trunk/drivers/infiniband/hw/nes/nes_mgt.h index 4f7f701c4a81..8c8af254555a 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_mgt.h +++ b/trunk/drivers/infiniband/hw/nes/nes_mgt.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2006 - 2011 Intel-NE, Inc. All rights reserved. +* Copyright (c) 2010 Intel-NE, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_nic.c b/trunk/drivers/infiniband/hw/nes/nes_nic.c index f3a3ecf8d09e..4b3fa711a247 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_nic.c +++ b/trunk/drivers/infiniband/hw/nes/nes_nic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_user.h b/trunk/drivers/infiniband/hw/nes/nes_user.h index 4926de744488..71e133ab209b 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_user.h +++ b/trunk/drivers/infiniband/hw/nes/nes_user.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Cisco Systems. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. diff --git a/trunk/drivers/infiniband/hw/nes/nes_utils.c b/trunk/drivers/infiniband/hw/nes/nes_utils.c index e98f4fc0b768..8b4c2ff54888 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_utils.c +++ b/trunk/drivers/infiniband/hw/nes/nes_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.c b/trunk/drivers/infiniband/hw/nes/nes_verbs.c index 0927b5cc65d3..5095bc41c6cc 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_verbs.c +++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -3427,8 +3427,6 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX, ib_wr->wr.fast_reg.length); - set_wqe_32bit_value(wqe->wqe_words, - NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX, 0); set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX, ib_wr->wr.fast_reg.rkey); @@ -3726,7 +3724,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) entry->opcode = IB_WC_SEND; break; case NES_IWARP_SQ_OP_LOCINV: - entry->opcode = IB_WC_LOCAL_INV; + entry->opcode = IB_WR_LOCAL_INV; break; case NES_IWARP_SQ_OP_FAST_REG: entry->opcode = IB_WC_FAST_REG_MR; diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.h b/trunk/drivers/infiniband/hw/nes/nes_verbs.h index 0eff7c44d76b..fe6b6e92fa90 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_verbs.h +++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c index d0c64d514813..4f18e2d332df 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c @@ -2105,7 +2105,7 @@ static void alloc_dummy_hdrq(struct qib_devdata *dd) dd->cspec->dummy_hdrq = dma_alloc_coherent(&dd->pcidev->dev, dd->rcd[0]->rcvhdrq_size, &dd->cspec->dummy_hdrq_phys, - GFP_ATOMIC | __GFP_COMP); + GFP_KERNEL | __GFP_COMP); if (!dd->cspec->dummy_hdrq) { qib_devinfo(dd->pcidev, "Couldn't allocate dummy hdrq\n"); /* fallback to just 0'ing */ diff --git a/trunk/drivers/infiniband/hw/qib/qib_pcie.c b/trunk/drivers/infiniband/hw/qib/qib_pcie.c index 0fde788e1100..f695061d688e 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_pcie.c +++ b/trunk/drivers/infiniband/hw/qib/qib_pcie.c @@ -560,7 +560,7 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd) * BIOS may not set PCIe bus-utilization parameters for best performance. * Check and optionally adjust them to maximize our throughput. */ -static int qib_pcie_caps; +static int qib_pcie_caps = 0x51; module_param_named(pcie_caps, qib_pcie_caps, int, S_IRUGO); MODULE_PARM_DESC(pcie_caps, "Max PCIe tuning: Payload (0..3), ReadReq (4..7)"); diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index afc166fcc3d9..76457d50bc34 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -386,7 +386,7 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, struct evdev_client *client = file->private_data; struct evdev *evdev = client->evdev; struct input_event event; - int retval = 0; + int retval; if (count < input_event_size()) return -EINVAL; diff --git a/trunk/drivers/input/keyboard/twl4030_keypad.c b/trunk/drivers/input/keyboard/twl4030_keypad.c index 67bec14e8b96..a588578037eb 100644 --- a/trunk/drivers/input/keyboard/twl4030_keypad.c +++ b/trunk/drivers/input/keyboard/twl4030_keypad.c @@ -34,6 +34,7 @@ #include #include + /* * The TWL4030 family chips include a keypad controller that supports * up to an 8x8 switch matrix. The controller can issue system wakeup @@ -301,7 +302,7 @@ static int __devinit twl4030_kp_program(struct twl4030_keypad *kp) if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0) return -EIO; - /* Set timeout period to 200 ms */ + /* Set timeout period to 100 ms */ i = KEYP_PERIOD_US(200000, PTV_PRESCALER); if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0) return -EIO; @@ -465,3 +466,4 @@ MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("TWL4030 Keypad Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:twl4030_keypad"); + diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index 5ec774d6c82b..b4cfc6c8be89 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -512,13 +512,6 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), }, }, - { - /* Lenovo Ideapad U455 */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20046"), - }, - }, { } }; diff --git a/trunk/drivers/input/serio/serio_raw.c b/trunk/drivers/input/serio/serio_raw.c index 4494233d331a..8250299fd64f 100644 --- a/trunk/drivers/input/serio/serio_raw.c +++ b/trunk/drivers/input/serio/serio_raw.c @@ -164,8 +164,7 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, struct serio_raw_client *client = file->private_data; struct serio_raw *serio_raw = client->serio_raw; char uninitialized_var(c); - ssize_t read = 0; - int retval; + ssize_t retval = 0; if (serio_raw->dead) return -ENODEV; @@ -181,15 +180,13 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, if (serio_raw->dead) return -ENODEV; - while (read < count && serio_raw_fetch_byte(serio_raw, &c)) { - if (put_user(c, buffer++)) { - retval = -EFAULT; - break; - } - read++; + while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) { + if (put_user(c, buffer++)) + return -EFAULT; + retval++; } - return read ?: retval; + return retval; } static ssize_t serio_raw_write(struct file *file, const char __user *buffer, diff --git a/trunk/drivers/media/dvb/dvb-usb/anysee.c b/trunk/drivers/media/dvb/dvb-usb/anysee.c index cf0c318d6989..1455e2644ab5 100644 --- a/trunk/drivers/media/dvb/dvb-usb/anysee.c +++ b/trunk/drivers/media/dvb/dvb-usb/anysee.c @@ -887,7 +887,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) /* attach demod */ adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, - &anysee_cxd2820r_config, &adap->dev->i2c_adap); + &anysee_cxd2820r_config, &adap->dev->i2c_adap, + NULL); state->has_ci = true; @@ -1188,14 +1189,6 @@ static int anysee_ci_init(struct dvb_usb_device *d) if (ret) return ret; - ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 2)|(0 << 1)|(0 << 0), 0x07); - if (ret) - return ret; - - ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 2)|(1 << 1)|(1 << 0), 0x07); - if (ret) - return ret; - ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1); if (ret) return ret; diff --git a/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c index 1efc028a76c9..8a57ed8272de 100644 --- a/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c +++ b/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c @@ -276,15 +276,14 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe) param.flags = 0; switch (fep->bandwidth_hz) { - default: case 8000000: - param.bandwidth = 8; + param.bandwidth = 0; break; case 7000000: - param.bandwidth = 7; + param.bandwidth = 1; break; case 6000000: - param.bandwidth = 6; + param.bandwidth = 2; break; } diff --git a/trunk/drivers/media/dvb/frontends/cxd2820r.h b/trunk/drivers/media/dvb/frontends/cxd2820r.h index 5aa306ebb7ef..cf0f546aa1d1 100644 --- a/trunk/drivers/media/dvb/frontends/cxd2820r.h +++ b/trunk/drivers/media/dvb/frontends/cxd2820r.h @@ -77,12 +77,14 @@ struct cxd2820r_config { (defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE)) extern struct dvb_frontend *cxd2820r_attach( const struct cxd2820r_config *config, - struct i2c_adapter *i2c + struct i2c_adapter *i2c, + struct dvb_frontend *fe ); #else static inline struct dvb_frontend *cxd2820r_attach( const struct cxd2820r_config *config, - struct i2c_adapter *i2c + struct i2c_adapter *i2c, + struct dvb_frontend *fe ) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); diff --git a/trunk/drivers/media/dvb/frontends/cxd2820r_core.c b/trunk/drivers/media/dvb/frontends/cxd2820r_core.c index 5c7c2aaf9bf5..caae7f79c837 100644 --- a/trunk/drivers/media/dvb/frontends/cxd2820r_core.c +++ b/trunk/drivers/media/dvb/frontends/cxd2820r_core.c @@ -482,19 +482,10 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) /* switch between DVB-T and DVB-T2 when tune fails */ if (priv->last_tune_failed) { - if (priv->delivery_system == SYS_DVBT) { - ret = cxd2820r_sleep_t(fe); - if (ret) - goto error; - + if (priv->delivery_system == SYS_DVBT) c->delivery_system = SYS_DVBT2; - } else if (priv->delivery_system == SYS_DVBT2) { - ret = cxd2820r_sleep_t2(fe); - if (ret) - goto error; - + else if (priv->delivery_system == SYS_DVBT2) c->delivery_system = SYS_DVBT; - } } /* set frontend */ @@ -571,7 +562,7 @@ static const struct dvb_frontend_ops cxd2820r_ops = { .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, /* default: DVB-T/T2 */ .info = { - .name = "Sony CXD2820R", + .name = "Sony CXD2820R (DVB-T/T2)", .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | @@ -581,9 +572,7 @@ static const struct dvb_frontend_ops cxd2820r_ops = { FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_QAM_16 | - FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | @@ -613,7 +602,8 @@ static const struct dvb_frontend_ops cxd2820r_ops = { }; struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, - struct i2c_adapter *i2c) + struct i2c_adapter *i2c, + struct dvb_frontend *fe) { struct cxd2820r_priv *priv = NULL; int ret; diff --git a/trunk/drivers/media/video/atmel-isi.c b/trunk/drivers/media/video/atmel-isi.c index ec3f6a06f9c3..9fe4519176a4 100644 --- a/trunk/drivers/media/video/atmel-isi.c +++ b/trunk/drivers/media/video/atmel-isi.c @@ -922,9 +922,7 @@ static int __devexit atmel_isi_remove(struct platform_device *pdev) isi->fb_descriptors_phys); iounmap(isi->regs); - clk_unprepare(isi->mck); clk_put(isi->mck); - clk_unprepare(isi->pclk); clk_put(isi->pclk); kfree(isi); @@ -957,10 +955,6 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev) if (IS_ERR(pclk)) return PTR_ERR(pclk); - ret = clk_prepare(pclk); - if (ret) - goto err_clk_prepare_pclk; - isi = kzalloc(sizeof(struct atmel_isi), GFP_KERNEL); if (!isi) { ret = -ENOMEM; @@ -984,10 +978,6 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev) goto err_clk_get; } - ret = clk_prepare(isi->mck); - if (ret) - goto err_clk_prepare_mck; - /* Set ISI_MCK's frequency, it should be faster than pixel clock */ ret = clk_set_rate(isi->mck, pdata->mck_hz); if (ret < 0) @@ -1069,14 +1059,10 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev) isi->fb_descriptors_phys); err_alloc_descriptors: err_set_mck_rate: - clk_unprepare(isi->mck); -err_clk_prepare_mck: clk_put(isi->mck); err_clk_get: kfree(isi); err_alloc_isi: - clk_unprepare(pclk); -err_clk_prepare_pclk: clk_put(pclk); return ret; diff --git a/trunk/drivers/media/video/em28xx/em28xx-dvb.c b/trunk/drivers/media/video/em28xx/em28xx-dvb.c index aabbf4854f66..9449423098e0 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-dvb.c +++ b/trunk/drivers/media/video/em28xx/em28xx-dvb.c @@ -853,7 +853,8 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM28174_BOARD_PCTV_290E: dvb->fe[0] = dvb_attach(cxd2820r_attach, &em28xx_cxd2820r_config, - &dev->i2c_adap); + &dev->i2c_adap, + NULL); if (dvb->fe[0]) { /* FE 0 attach tuner */ if (!dvb_attach(tda18271_attach, diff --git a/trunk/drivers/mfd/mcp-core.c b/trunk/drivers/mfd/mcp-core.c index 86cc3f7841cd..63be60bc3455 100644 --- a/trunk/drivers/mfd/mcp-core.c +++ b/trunk/drivers/mfd/mcp-core.c @@ -26,9 +26,35 @@ #define to_mcp(d) container_of(d, struct mcp, attached_device) #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) +static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id, + const char *codec) +{ + while (id->name[0]) { + if (strcmp(codec, id->name) == 0) + return id; + id++; + } + return NULL; +} + +const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp) +{ + const struct mcp_driver *driver = + to_mcp_driver(mcp->attached_device.driver); + + return mcp_match_id(driver->id_table, mcp->codec); +} +EXPORT_SYMBOL(mcp_get_device_id); + static int mcp_bus_match(struct device *dev, struct device_driver *drv) { - return 1; + const struct mcp *mcp = to_mcp(dev); + const struct mcp_driver *driver = to_mcp_driver(drv); + + if (driver->id_table) + return !!mcp_match_id(driver->id_table, mcp->codec); + + return 0; } static int mcp_bus_probe(struct device *dev) @@ -74,9 +100,18 @@ static int mcp_bus_resume(struct device *dev) return ret; } +static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct mcp *mcp = to_mcp(dev); + + add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec); + return 0; +} + static struct bus_type mcp_bus_type = { .name = "mcp", .match = mcp_bus_match, + .uevent = mcp_bus_uevent, .probe = mcp_bus_probe, .remove = mcp_bus_remove, .suspend = mcp_bus_suspend, @@ -93,11 +128,9 @@ static struct bus_type mcp_bus_type = { */ void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div) { - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); + spin_lock_irq(&mcp->lock); mcp->ops->set_telecom_divisor(mcp, div); - spin_unlock_irqrestore(&mcp->lock, flags); + spin_unlock_irq(&mcp->lock); } EXPORT_SYMBOL(mcp_set_telecom_divisor); @@ -110,11 +143,9 @@ EXPORT_SYMBOL(mcp_set_telecom_divisor); */ void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div) { - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); + spin_lock_irq(&mcp->lock); mcp->ops->set_audio_divisor(mcp, div); - spin_unlock_irqrestore(&mcp->lock, flags); + spin_unlock_irq(&mcp->lock); } EXPORT_SYMBOL(mcp_set_audio_divisor); @@ -167,11 +198,10 @@ EXPORT_SYMBOL(mcp_reg_read); */ void mcp_enable(struct mcp *mcp) { - unsigned long flags; - spin_lock_irqsave(&mcp->lock, flags); + spin_lock_irq(&mcp->lock); if (mcp->use_count++ == 0) mcp->ops->enable(mcp); - spin_unlock_irqrestore(&mcp->lock, flags); + spin_unlock_irq(&mcp->lock); } EXPORT_SYMBOL(mcp_enable); @@ -217,9 +247,14 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size) } EXPORT_SYMBOL(mcp_host_alloc); -int mcp_host_register(struct mcp *mcp) +int mcp_host_register(struct mcp *mcp, void *pdata) { + if (!mcp->codec) + return -EINVAL; + + mcp->attached_device.platform_data = pdata; dev_set_name(&mcp->attached_device, "mcp0"); + request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec); return device_register(&mcp->attached_device); } EXPORT_SYMBOL(mcp_host_register); diff --git a/trunk/drivers/mfd/mcp-sa11x0.c b/trunk/drivers/mfd/mcp-sa11x0.c index 02c53a0766c4..9adc2eb69492 100644 --- a/trunk/drivers/mfd/mcp-sa11x0.c +++ b/trunk/drivers/mfd/mcp-sa11x0.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -26,12 +27,19 @@ #include #include -#include - +/* Register offsets */ +#define MCCR0 0x00 +#define MCDR0 0x08 +#define MCDR1 0x0C +#define MCDR2 0x10 +#define MCSR 0x18 +#define MCCR1 0x00 struct mcp_sa11x0 { - u32 mccr0; - u32 mccr1; + u32 mccr0; + u32 mccr1; + unsigned char *mccr0_base; + unsigned char *mccr1_base; }; #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) @@ -39,25 +47,25 @@ struct mcp_sa11x0 { static void mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) { - unsigned int mccr0; + struct mcp_sa11x0 *priv = priv(mcp); divisor /= 32; - mccr0 = Ser4MCCR0 & ~0x00007f00; - mccr0 |= divisor << 8; - Ser4MCCR0 = mccr0; + priv->mccr0 &= ~0x00007f00; + priv->mccr0 |= divisor << 8; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); } static void mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) { - unsigned int mccr0; + struct mcp_sa11x0 *priv = priv(mcp); divisor /= 32; - mccr0 = Ser4MCCR0 & ~0x0000007f; - mccr0 |= divisor; - Ser4MCCR0 = mccr0; + priv->mccr0 &= ~0x0000007f; + priv->mccr0 |= divisor; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); } /* @@ -71,12 +79,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val) { int ret = -ETIME; int i; + u32 mcpreg; + struct mcp_sa11x0 *priv = priv(mcp); - Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff); + mcpreg = reg << 17 | MCDR2_Wr | (val & 0xffff); + __raw_writel(mcpreg, priv->mccr0_base + MCDR2); for (i = 0; i < 2; i++) { udelay(mcp->rw_timeout); - if (Ser4MCSR & MCSR_CWC) { + mcpreg = __raw_readl(priv->mccr0_base + MCSR); + if (mcpreg & MCSR_CWC) { ret = 0; break; } @@ -97,13 +109,18 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) { int ret = -ETIME; int i; + u32 mcpreg; + struct mcp_sa11x0 *priv = priv(mcp); - Ser4MCDR2 = reg << 17 | MCDR2_Rd; + mcpreg = reg << 17 | MCDR2_Rd; + __raw_writel(mcpreg, priv->mccr0_base + MCDR2); for (i = 0; i < 2; i++) { udelay(mcp->rw_timeout); - if (Ser4MCSR & MCSR_CRC) { - ret = Ser4MCDR2 & 0xffff; + mcpreg = __raw_readl(priv->mccr0_base + MCSR); + if (mcpreg & MCSR_CRC) { + ret = __raw_readl(priv->mccr0_base + MCDR2) + & 0xffff; break; } } @@ -116,13 +133,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) static void mcp_sa11x0_enable(struct mcp *mcp) { - Ser4MCSR = -1; - Ser4MCCR0 |= MCCR0_MCE; + struct mcp_sa11x0 *priv = priv(mcp); + + __raw_writel(-1, priv->mccr0_base + MCSR); + priv->mccr0 |= MCCR0_MCE; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); } static void mcp_sa11x0_disable(struct mcp *mcp) { - Ser4MCCR0 &= ~MCCR0_MCE; + struct mcp_sa11x0 *priv = priv(mcp); + + priv->mccr0 &= ~MCCR0_MCE; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); } /* @@ -142,50 +165,69 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) struct mcp_plat_data *data = pdev->dev.platform_data; struct mcp *mcp; int ret; + struct mcp_sa11x0 *priv; + struct resource *res_mem0, *res_mem1; + u32 size0, size1; if (!data) return -ENODEV; - if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) + if (!data->codec) + return -ENODEV; + + res_mem0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_mem0) + return -ENODEV; + size0 = res_mem0->end - res_mem0->start + 1; + + res_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res_mem1) + return -ENODEV; + size1 = res_mem1->end - res_mem1->start + 1; + + if (!request_mem_region(res_mem0->start, size0, "sa11x0-mcp")) return -EBUSY; + if (!request_mem_region(res_mem1->start, size1, "sa11x0-mcp")) { + ret = -EBUSY; + goto release; + } + mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0)); if (!mcp) { ret = -ENOMEM; - goto release; + goto release2; } + priv = priv(mcp); + mcp->owner = THIS_MODULE; mcp->ops = &mcp_sa11x0; mcp->sclk_rate = data->sclk_rate; - mcp->dma_audio_rd = DMA_Ser4MCP0Rd; - mcp->dma_audio_wr = DMA_Ser4MCP0Wr; - mcp->dma_telco_rd = DMA_Ser4MCP1Rd; - mcp->dma_telco_wr = DMA_Ser4MCP1Wr; - mcp->gpio_base = data->gpio_base; + mcp->dma_audio_rd = DDAR_DevAdd(res_mem0->start + MCDR0) + + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev; + mcp->dma_audio_wr = DDAR_DevAdd(res_mem0->start + MCDR0) + + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev; + mcp->dma_telco_rd = DDAR_DevAdd(res_mem0->start + MCDR1) + + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev; + mcp->dma_telco_wr = DDAR_DevAdd(res_mem0->start + MCDR1) + + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev; + mcp->codec = data->codec; platform_set_drvdata(pdev, mcp); - if (machine_is_assabet()) { - ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); - } - - /* - * Setup the PPC unit correctly. - */ - PPDR &= ~PPC_RXD4; - PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; - PSDR |= PPC_RXD4; - PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); - PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); - /* * Initialise device. Note that we initially * set the sampling rate to minimum. */ - Ser4MCSR = -1; - Ser4MCCR1 = data->mccr1; - Ser4MCCR0 = data->mccr0 | 0x7f7f; + priv->mccr0_base = ioremap(res_mem0->start, size0); + priv->mccr1_base = ioremap(res_mem1->start, size1); + + __raw_writel(-1, priv->mccr0_base + MCSR); + priv->mccr1 = data->mccr1; + priv->mccr0 = data->mccr0 | 0x7f7f; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); + __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1); /* * Calculate the read/write timeout (us) from the bit clock @@ -195,36 +237,53 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / mcp->sclk_rate; - ret = mcp_host_register(mcp); + ret = mcp_host_register(mcp, data->codec_pdata); if (ret == 0) goto out; + release2: + release_mem_region(res_mem1->start, size1); release: - release_mem_region(0x80060000, 0x60); + release_mem_region(res_mem0->start, size0); platform_set_drvdata(pdev, NULL); out: return ret; } -static int mcp_sa11x0_remove(struct platform_device *dev) +static int mcp_sa11x0_remove(struct platform_device *pdev) { - struct mcp *mcp = platform_get_drvdata(dev); + struct mcp *mcp = platform_get_drvdata(pdev); + struct mcp_sa11x0 *priv = priv(mcp); + struct resource *res_mem; + u32 size; - platform_set_drvdata(dev, NULL); + platform_set_drvdata(pdev, NULL); mcp_host_unregister(mcp); - release_mem_region(0x80060000, 0x60); + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res_mem) { + size = res_mem->end - res_mem->start + 1; + release_mem_region(res_mem->start, size); + } + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res_mem) { + size = res_mem->end - res_mem->start + 1; + release_mem_region(res_mem->start, size); + } + iounmap(priv->mccr0_base); + iounmap(priv->mccr1_base); return 0; } static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) { struct mcp *mcp = platform_get_drvdata(dev); + struct mcp_sa11x0 *priv = priv(mcp); + u32 mccr0; - priv(mcp)->mccr0 = Ser4MCCR0; - priv(mcp)->mccr1 = Ser4MCCR1; - Ser4MCCR0 &= ~MCCR0_MCE; + mccr0 = priv->mccr0 & ~MCCR0_MCE; + __raw_writel(mccr0, priv->mccr0_base + MCCR0); return 0; } @@ -232,9 +291,10 @@ static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) static int mcp_sa11x0_resume(struct platform_device *dev) { struct mcp *mcp = platform_get_drvdata(dev); + struct mcp_sa11x0 *priv = priv(mcp); - Ser4MCCR1 = priv(mcp)->mccr1; - Ser4MCCR0 = priv(mcp)->mccr0; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); + __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1); return 0; } @@ -251,6 +311,7 @@ static struct platform_driver mcp_sa11x0_driver = { .resume = mcp_sa11x0_resume, .driver = { .name = "sa11x0-mcp", + .owner = THIS_MODULE, }, }; diff --git a/trunk/drivers/mfd/twl6040-core.c b/trunk/drivers/mfd/twl6040-core.c index b2d8e512d3cb..dda86293dc9f 100644 --- a/trunk/drivers/mfd/twl6040-core.c +++ b/trunk/drivers/mfd/twl6040-core.c @@ -282,7 +282,6 @@ int twl6040_power(struct twl6040 *twl6040, int on) /* Default PLL configuration after power up */ twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; twl6040->sysclk = 19200000; - twl6040->mclk = 32768; } else { /* already powered-down */ if (!twl6040->power_count) { @@ -306,7 +305,6 @@ int twl6040_power(struct twl6040 *twl6040, int on) twl6040_power_down(twl6040); } twl6040->sysclk = 0; - twl6040->mclk = 0; } out: @@ -326,38 +324,23 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, hppllctl = twl6040_reg_read(twl6040, TWL6040_REG_HPPLLCTL); lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL); - /* Force full reconfiguration when switching between PLL */ - if (pll_id != twl6040->pll) { - twl6040->sysclk = 0; - twl6040->mclk = 0; - } - switch (pll_id) { case TWL6040_SYSCLK_SEL_LPPLL: /* low-power PLL divider */ - /* Change the sysclk configuration only if it has been canged */ - if (twl6040->sysclk != freq_out) { - switch (freq_out) { - case 17640000: - lppllctl |= TWL6040_LPLLFIN; - break; - case 19200000: - lppllctl &= ~TWL6040_LPLLFIN; - break; - default: - dev_err(twl6040->dev, - "freq_out %d not supported\n", - freq_out); - ret = -EINVAL; - goto pll_out; - } - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, - lppllctl); - } - - /* The PLL in use has not been change, we can exit */ - if (twl6040->pll == pll_id) + switch (freq_out) { + case 17640000: + lppllctl |= TWL6040_LPLLFIN; + break; + case 19200000: + lppllctl &= ~TWL6040_LPLLFIN; break; + default: + dev_err(twl6040->dev, + "freq_out %d not supported\n", freq_out); + ret = -EINVAL; + goto pll_out; + } + twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); switch (freq_in) { case 32768: @@ -388,56 +371,48 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, goto pll_out; } - if (twl6040->mclk != freq_in) { - hppllctl &= ~TWL6040_MCLK_MSK; - - switch (freq_in) { - case 12000000: - /* PLL enabled, active mode */ - hppllctl |= TWL6040_MCLK_12000KHZ | - TWL6040_HPLLENA; - break; - case 19200000: - /* - * PLL disabled - * (enable PLL if MCLK jitter quality - * doesn't meet specification) - */ - hppllctl |= TWL6040_MCLK_19200KHZ; - break; - case 26000000: - /* PLL enabled, active mode */ - hppllctl |= TWL6040_MCLK_26000KHZ | - TWL6040_HPLLENA; - break; - case 38400000: - /* PLL enabled, active mode */ - hppllctl |= TWL6040_MCLK_38400KHZ | - TWL6040_HPLLENA; - break; - default: - dev_err(twl6040->dev, - "freq_in %d not supported\n", freq_in); - ret = -EINVAL; - goto pll_out; - } + hppllctl &= ~TWL6040_MCLK_MSK; + switch (freq_in) { + case 12000000: + /* PLL enabled, active mode */ + hppllctl |= TWL6040_MCLK_12000KHZ | + TWL6040_HPLLENA; + break; + case 19200000: /* - * enable clock slicer to ensure input waveform is - * square + * PLL disabled + * (enable PLL if MCLK jitter quality + * doesn't meet specification) */ - hppllctl |= TWL6040_HPLLSQRENA; - - twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL, - hppllctl); - usleep_range(500, 700); - lppllctl |= TWL6040_HPLLSEL; - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, - lppllctl); - lppllctl &= ~TWL6040_LPLLENA; - twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, - lppllctl); + hppllctl |= TWL6040_MCLK_19200KHZ; + break; + case 26000000: + /* PLL enabled, active mode */ + hppllctl |= TWL6040_MCLK_26000KHZ | + TWL6040_HPLLENA; + break; + case 38400000: + /* PLL enabled, active mode */ + hppllctl |= TWL6040_MCLK_38400KHZ | + TWL6040_HPLLENA; + break; + default: + dev_err(twl6040->dev, + "freq_in %d not supported\n", freq_in); + ret = -EINVAL; + goto pll_out; } + + /* enable clock slicer to ensure input waveform is square */ + hppllctl |= TWL6040_HPLLSQRENA; + + twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL, hppllctl); + usleep_range(500, 700); + lppllctl |= TWL6040_HPLLSEL; + twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); + lppllctl &= ~TWL6040_LPLLENA; + twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); break; default: dev_err(twl6040->dev, "unknown pll id %d\n", pll_id); @@ -446,7 +421,6 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, } twl6040->sysclk = freq_out; - twl6040->mclk = freq_in; twl6040->pll = pll_id; pll_out: diff --git a/trunk/drivers/mfd/ucb1x00-core.c b/trunk/drivers/mfd/ucb1x00-core.c index febc90cdef7e..91c4f25e0e55 100644 --- a/trunk/drivers/mfd/ucb1x00-core.c +++ b/trunk/drivers/mfd/ucb1x00-core.c @@ -36,6 +36,15 @@ static DEFINE_MUTEX(ucb1x00_mutex); static LIST_HEAD(ucb1x00_drivers); static LIST_HEAD(ucb1x00_devices); +static struct mcp_device_id ucb1x00_id[] = { + { "ucb1x00", 0 }, /* auto-detection */ + { "ucb1200", UCB_ID_1200 }, + { "ucb1300", UCB_ID_1300 }, + { "tc35143", UCB_ID_TC35143 }, + { } +}; +MODULE_DEVICE_TABLE(mcp, ucb1x00_id); + /** * ucb1x00_io_set_dir - set IO direction * @ucb: UCB1x00 structure describing chip @@ -148,22 +157,16 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); unsigned long flags; - unsigned old, mask = 1 << offset; spin_lock_irqsave(&ucb->io_lock, flags); - old = ucb->io_out; + ucb->io_dir |= (1 << offset); + ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); + if (value) - ucb->io_out |= mask; + ucb->io_out |= 1 << offset; else - ucb->io_out &= ~mask; - - if (old != ucb->io_out) - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - - if (!(ucb->io_dir & mask)) { - ucb->io_dir |= mask; - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - } + ucb->io_out &= ~(1 << offset); + ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); spin_unlock_irqrestore(&ucb->io_lock, flags); return 0; @@ -533,17 +536,33 @@ static struct class ucb1x00_class = { static int ucb1x00_probe(struct mcp *mcp) { + const struct mcp_device_id *mid; struct ucb1x00 *ucb; struct ucb1x00_driver *drv; + struct ucb1x00_plat_data *pdata; unsigned int id; int ret = -ENODEV; int temp; mcp_enable(mcp); id = mcp_reg_read(mcp, UCB_ID); + mid = mcp_get_device_id(mcp); - if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { - printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); + if (mid && mid->driver_data) { + if (id != mid->driver_data) { + printk(KERN_WARNING "%s wrong ID %04x found: %04x\n", + mid->name, (unsigned int) mid->driver_data, id); + goto err_disable; + } + } else { + mid = &ucb1x00_id[1]; + while (mid->driver_data) { + if (id == mid->driver_data) + break; + mid++; + } + printk(KERN_WARNING "%s ID not found: %04x\n", + ucb1x00_id[0].name, id); goto err_disable; } @@ -552,28 +571,28 @@ static int ucb1x00_probe(struct mcp *mcp) if (!ucb) goto err_disable; - + pdata = mcp->attached_device.platform_data; ucb->dev.class = &ucb1x00_class; ucb->dev.parent = &mcp->attached_device; - dev_set_name(&ucb->dev, "ucb1x00"); + dev_set_name(&ucb->dev, mid->name); spin_lock_init(&ucb->lock); spin_lock_init(&ucb->io_lock); sema_init(&ucb->adc_sem, 1); - ucb->id = id; + ucb->id = mid; ucb->mcp = mcp; ucb->irq = ucb1x00_detect_irq(ucb); if (ucb->irq == NO_IRQ) { - printk(KERN_ERR "UCB1x00: IRQ probe failed\n"); + printk(KERN_ERR "%s: IRQ probe failed\n", mid->name); ret = -ENODEV; goto err_free; } ucb->gpio.base = -1; - if (mcp->gpio_base != 0) { + if (pdata && (pdata->gpio_base >= 0)) { ucb->gpio.label = dev_name(&ucb->dev); - ucb->gpio.base = mcp->gpio_base; + ucb->gpio.base = pdata->gpio_base; ucb->gpio.ngpio = 10; ucb->gpio.set = ucb1x00_gpio_set; ucb->gpio.get = ucb1x00_gpio_get; @@ -586,10 +605,10 @@ static int ucb1x00_probe(struct mcp *mcp) dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, - "UCB1x00", ucb); + mid->name, ucb); if (ret) { - printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", - ucb->irq, ret); + printk(KERN_ERR "%s: unable to grab irq%d: %d\n", + mid->name, ucb->irq, ret); goto err_gpio; } @@ -693,7 +712,6 @@ static int ucb1x00_resume(struct mcp *mcp) struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00_dev *dev; - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); mutex_lock(&ucb1x00_mutex); list_for_each_entry(dev, &ucb->devs, dev_node) { @@ -712,6 +730,7 @@ static struct mcp_driver ucb1x00_driver = { .remove = ucb1x00_remove, .suspend = ucb1x00_suspend, .resume = ucb1x00_resume, + .id_table = ucb1x00_id, }; static int __init ucb1x00_init(void) diff --git a/trunk/drivers/mfd/ucb1x00-ts.c b/trunk/drivers/mfd/ucb1x00-ts.c index 63a3cbdfa3f3..40ec3c118868 100644 --- a/trunk/drivers/mfd/ucb1x00-ts.c +++ b/trunk/drivers/mfd/ucb1x00-ts.c @@ -47,6 +47,7 @@ struct ucb1x00_ts { u16 x_res; u16 y_res; + unsigned int restart:1; unsigned int adcsync:1; }; @@ -206,17 +207,15 @@ static int ucb1x00_thread(void *_ts) { struct ucb1x00_ts *ts = _ts; DECLARE_WAITQUEUE(wait, current); - bool frozen, ignore = false; int valid = 0; set_freezable(); add_wait_queue(&ts->irq_wait, &wait); - while (!kthread_freezable_should_stop(&frozen)) { + while (!kthread_should_stop()) { unsigned int x, y, p; signed long timeout; - if (frozen) - ignore = true; + ts->restart = 0; ucb1x00_adc_enable(ts->ucb); @@ -259,7 +258,7 @@ static int ucb1x00_thread(void *_ts) * space. We therefore leave it to user space * to do any filtering they please. */ - if (!ignore) { + if (!ts->restart) { ucb1x00_ts_evt_add(ts, p, x, y); valid = 1; } @@ -268,6 +267,8 @@ static int ucb1x00_thread(void *_ts) timeout = HZ / 100; } + try_to_freeze(); + schedule_timeout(timeout); } @@ -339,6 +340,26 @@ static void ucb1x00_ts_close(struct input_dev *idev) ucb1x00_disable(ts->ucb); } +#ifdef CONFIG_PM +static int ucb1x00_ts_resume(struct ucb1x00_dev *dev) +{ + struct ucb1x00_ts *ts = dev->priv; + + if (ts->rtask != NULL) { + /* + * Restart the TS thread to ensure the + * TS interrupt mode is set up again + * after sleep. + */ + ts->restart = 1; + wake_up(&ts->irq_wait); + } + return 0; +} +#else +#define ucb1x00_ts_resume NULL +#endif + /* * Initialisation. @@ -361,7 +382,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; idev->name = "Touchscreen panel"; - idev->id.product = ts->ucb->id; + idev->id.product = ts->ucb->id->driver_data; idev->open = ucb1x00_ts_open; idev->close = ucb1x00_ts_close; @@ -404,6 +425,7 @@ static void ucb1x00_ts_remove(struct ucb1x00_dev *dev) static struct ucb1x00_driver ucb1x00_ts_driver = { .add = ucb1x00_ts_add, .remove = ucb1x00_ts_remove, + .resume = ucb1x00_ts_resume, }; static int __init ucb1x00_ts_init(void) diff --git a/trunk/drivers/misc/lkdtm.c b/trunk/drivers/misc/lkdtm.c index 28adefe70f96..150cd7061b80 100644 --- a/trunk/drivers/misc/lkdtm.c +++ b/trunk/drivers/misc/lkdtm.c @@ -354,7 +354,6 @@ static void lkdtm_do_action(enum ctype which) static void lkdtm_handler(void) { unsigned long flags; - bool do_it = false; spin_lock_irqsave(&count_lock, flags); count--; @@ -362,13 +361,10 @@ static void lkdtm_handler(void) cp_name_to_str(cpoint), cp_type_to_str(cptype), count); if (count == 0) { - do_it = true; + lkdtm_do_action(cptype); count = cpoint_count; } spin_unlock_irqrestore(&count_lock, flags); - - if (do_it) - lkdtm_do_action(cptype); } static int lkdtm_register_cpoint(enum cname which) diff --git a/trunk/drivers/mtd/mtdcore.c b/trunk/drivers/mtd/mtdcore.c index 9a9ce71a71fc..6ae9ca01388b 100644 --- a/trunk/drivers/mtd/mtdcore.c +++ b/trunk/drivers/mtd/mtdcore.c @@ -119,7 +119,7 @@ static int mtd_cls_suspend(struct device *dev, pm_message_t state) { struct mtd_info *mtd = dev_get_drvdata(dev); - return mtd ? mtd_suspend(mtd) : 0; + return mtd_suspend(mtd); } static int mtd_cls_resume(struct device *dev) diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/atmel_nand.c index 35b4fb55dbd6..4dd056e2e16a 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/atmel_nand.c @@ -161,37 +161,6 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) !!host->board->rdy_pin_active_low; } -/* - * Minimal-overhead PIO for data access. - */ -static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) -{ - struct nand_chip *nand_chip = mtd->priv; - - __raw_readsb(nand_chip->IO_ADDR_R, buf, len); -} - -static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) -{ - struct nand_chip *nand_chip = mtd->priv; - - __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); -} - -static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len) -{ - struct nand_chip *nand_chip = mtd->priv; - - __raw_writesb(nand_chip->IO_ADDR_W, buf, len); -} - -static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) -{ - struct nand_chip *nand_chip = mtd->priv; - - __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); -} - static void dma_complete_func(void *completion) { complete(completion); @@ -266,33 +235,27 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *chip = mtd->priv; - struct atmel_nand_host *host = chip->priv; if (use_dma && len > mtd->oobsize) /* only use DMA for bigger than oob size: better performances */ if (atmel_nand_dma_op(mtd, buf, len, 1) == 0) return; - if (host->board->bus_width_16) - atmel_read_buf16(mtd, buf, len); - else - atmel_read_buf8(mtd, buf, len); + /* if no DMA operation possible, use PIO */ + memcpy_fromio(buf, chip->IO_ADDR_R, len); } static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { struct nand_chip *chip = mtd->priv; - struct atmel_nand_host *host = chip->priv; if (use_dma && len > mtd->oobsize) /* only use DMA for bigger than oob size: better performances */ if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0) return; - if (host->board->bus_width_16) - atmel_write_buf16(mtd, buf, len); - else - atmel_write_buf8(mtd, buf, len); + /* if no DMA operation possible, use PIO */ + memcpy_toio(chip->IO_ADDR_W, buf, len); } /* diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 7db6555ed3ba..7f680420bfab 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -69,19 +69,17 @@ static int clear_poll_bit(void __iomem *addr, u32 mask) * [1] enable the module. * [2] reset the module. * - * In most of the cases, it's ok. - * But in MX23, there is a hardware bug in the BCH block (see erratum #2847). + * In most of the cases, it's ok. But there is a hardware bug in the BCH block. * If you try to soft reset the BCH block, it becomes unusable until * the next hard reset. This case occurs in the NAND boot mode. When the board * boots by NAND, the ROM of the chip will initialize the BCH blocks itself. * So If the driver tries to reset the BCH again, the BCH will not work anymore. - * You will see a DMA timeout in this case. The bug has been fixed - * in the following chips, such as MX28. + * You will see a DMA timeout in this case. * * To avoid this bug, just add a new parameter `just_enable` for * the mxs_reset_block(), and rewrite it here. */ -static int gpmi_reset_block(void __iomem *reset_addr, bool just_enable) +int gpmi_reset_block(void __iomem *reset_addr, bool just_enable) { int ret; int timeout = 0x400; @@ -208,15 +206,7 @@ int bch_set_geometry(struct gpmi_nand_data *this) if (ret) goto err_out; - /* - * Due to erratum #2847 of the MX23, the BCH cannot be soft reset on this - * chip, otherwise it will lock up. So we skip resetting BCH on the MX23. - * On the other hand, the MX28 needs the reset, because one case has been - * seen where the BCH produced ECC errors constantly after 10000 - * consecutive reboots. The latter case has not been seen on the MX23 yet, - * still we don't know if it could happen there as well. - */ - ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this)); + ret = gpmi_reset_block(r->bch_regs, true); if (ret) goto err_out; diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 8a393f9e6027..35b4565050f1 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -2588,7 +2588,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, instr->state = MTD_ERASING; while (len) { - /* Check if we have a bad block, we do not erase bad blocks! */ + /* Heck if we have a bad block, we do not erase bad blocks! */ if (nand_block_checkbad(mtd, ((loff_t) page) << chip->page_shift, 0, allowbbt)) { pr_warn("%s: attempt to erase a bad block at page 0x%08x\n", diff --git a/trunk/drivers/net/bonding/bond_alb.c b/trunk/drivers/net/bonding/bond_alb.c index f820b26b9db3..342626f4bc46 100644 --- a/trunk/drivers/net/bonding/bond_alb.c +++ b/trunk/drivers/net/bonding/bond_alb.c @@ -909,12 +909,16 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) } } -static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[]) +/* hw is a boolean parameter that determines whether we should try and + * set the hw address of the device as well as the hw address of the + * net_device + */ +static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw) { struct net_device *dev = slave->dev; struct sockaddr s_addr; - if (slave->bond->params.mode == BOND_MODE_TLB) { + if (!hw) { memcpy(dev->dev_addr, addr, dev->addr_len); return 0; } @@ -944,8 +948,8 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct u8 tmp_mac_addr[ETH_ALEN]; memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN); - alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr); - alb_set_slave_mac_addr(slave2, tmp_mac_addr); + alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled); + alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled); } @@ -1092,7 +1096,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav /* Try setting slave mac to bond address and fall-through to code handling that situation below... */ - alb_set_slave_mac_addr(slave, bond->dev->dev_addr); + alb_set_slave_mac_addr(slave, bond->dev->dev_addr, + bond->alb_info.rlb_enabled); } /* The slave's address is equal to the address of the bond. @@ -1128,7 +1133,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav } if (free_mac_slave) { - alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr); + alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr, + bond->alb_info.rlb_enabled); pr_warning("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n", bond->dev->name, slave->dev->name, @@ -1485,7 +1491,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave) { int res; - res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr); + res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr, + bond->alb_info.rlb_enabled); if (res) { return res; } @@ -1636,7 +1643,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave alb_swap_mac_addr(bond, swap_slave, new_slave); } else { /* set the new_slave to the bond mac address */ - alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr); + alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr, + bond->alb_info.rlb_enabled); } if (swap_slave) { @@ -1696,7 +1704,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave); alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave); } else { - alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr); + alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr, + bond->alb_info.rlb_enabled); read_lock(&bond->lock); alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr); diff --git a/trunk/drivers/net/dsa/mv88e6060.c b/trunk/drivers/net/dsa/mv88e6060.c index 325391d19bad..7fc4e81d4d43 100644 --- a/trunk/drivers/net/dsa/mv88e6060.c +++ b/trunk/drivers/net/dsa/mv88e6060.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include diff --git a/trunk/drivers/net/dsa/mv88e6123_61_65.c b/trunk/drivers/net/dsa/mv88e6123_61_65.c index c17c75b9f531..c0a458fc698f 100644 --- a/trunk/drivers/net/dsa/mv88e6123_61_65.c +++ b/trunk/drivers/net/dsa/mv88e6123_61_65.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include @@ -21,25 +20,12 @@ static char *mv88e6123_61_65_probe(struct mii_bus *bus, int sw_addr) ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03); if (ret >= 0) { - if (ret == 0x1212) - return "Marvell 88E6123 (A1)"; - if (ret == 0x1213) - return "Marvell 88E6123 (A2)"; - if ((ret & 0xfff0) == 0x1210) + ret &= 0xfff0; + if (ret == 0x1210) return "Marvell 88E6123"; - - if (ret == 0x1612) - return "Marvell 88E6161 (A1)"; - if (ret == 0x1613) - return "Marvell 88E6161 (A2)"; - if ((ret & 0xfff0) == 0x1610) + if (ret == 0x1610) return "Marvell 88E6161"; - - if (ret == 0x1652) - return "Marvell 88E6165 (A1)"; - if (ret == 0x1653) - return "Marvell 88e6165 (A2)"; - if ((ret & 0xfff0) == 0x1650) + if (ret == 0x1650) return "Marvell 88E6165"; } diff --git a/trunk/drivers/net/dsa/mv88e6131.c b/trunk/drivers/net/dsa/mv88e6131.c index 55888b06d8b4..e0eb68243834 100644 --- a/trunk/drivers/net/dsa/mv88e6131.c +++ b/trunk/drivers/net/dsa/mv88e6131.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include diff --git a/trunk/drivers/net/dsa/mv88e6xxx.c b/trunk/drivers/net/dsa/mv88e6xxx.c index a2c62c2f30ee..5467c040824a 100644 --- a/trunk/drivers/net/dsa/mv88e6xxx.c +++ b/trunk/drivers/net/dsa/mv88e6xxx.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 03f3935fd8c2..2b731b253598 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3117,7 +3117,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) int rx_ring_size = 0; #ifdef BCM_CNIC - if (!bp->rx_ring_size && IS_MF_ISCSI_SD(bp)) { + if (IS_MF_ISCSI_SD(bp)) { rx_ring_size = MIN_RX_SIZE_NONTPA; bp->rx_ring_size = rx_ring_size; } else diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 31a8b38ab15e..f99c6e312a5d 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1738,7 +1738,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) struct bnx2x_fp_txdata *txdata = &fp_tx->txdata[0]; u16 tx_start_idx, tx_idx; u16 rx_start_idx, rx_idx; - u16 pkt_prod, bd_prod; + u16 pkt_prod, bd_prod, rx_comp_cons; struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; @@ -1873,7 +1873,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) if (rx_idx != rx_start_idx + num_pkts) goto test_loopback_exit; - cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)]; + rx_comp_cons = le16_to_cpu(fp_rx->rx_comp_cons); + cqe = &fp_rx->rx_comp_ring[RCQ_BD(rx_comp_cons)]; cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE; if (!CQE_TYPE_FAST(cqe_fp_type) || (cqe_fp_flags & ETH_RX_ERROR_FALGS)) @@ -2120,16 +2121,18 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) case ETH_SS_STATS: if (is_multi(bp)) { num_stats = bnx2x_num_stat_queues(bp) * - BNX2X_NUM_Q_STATS; - } else - num_stats = 0; - if (IS_MF_MODE_STAT(bp)) { - for (i = 0; i < BNX2X_NUM_STATS; i++) - if (IS_FUNC_STAT(i)) - num_stats++; - } else - num_stats += BNX2X_NUM_STATS; - + BNX2X_NUM_Q_STATS; + if (!IS_MF_MODE_STAT(bp)) + num_stats += BNX2X_NUM_STATS; + } else { + if (IS_MF_MODE_STAT(bp)) { + num_stats = 0; + for (i = 0; i < BNX2X_NUM_STATS; i++) + if (IS_FUNC_STAT(i)) + num_stats++; + } else + num_stats = BNX2X_NUM_STATS; + } return num_stats; case ETH_SS_TEST: @@ -2148,8 +2151,8 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) switch (stringset) { case ETH_SS_STATS: - k = 0; if (is_multi(bp)) { + k = 0; for_each_eth_queue(bp, i) { memset(queue_name, 0, sizeof(queue_name)); sprintf(queue_name, "%d", i); @@ -2160,17 +2163,20 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) queue_name); k += BNX2X_NUM_Q_STATS; } + if (IS_MF_MODE_STAT(bp)) + break; + for (j = 0; j < BNX2X_NUM_STATS; j++) + strcpy(buf + (k + j)*ETH_GSTRING_LEN, + bnx2x_stats_arr[j].string); + } else { + for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { + if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) + continue; + strcpy(buf + j*ETH_GSTRING_LEN, + bnx2x_stats_arr[i].string); + j++; + } } - - - for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) - continue; - strcpy(buf + (k + j)*ETH_GSTRING_LEN, - bnx2x_stats_arr[i].string); - j++; - } - break; case ETH_SS_TEST: @@ -2184,9 +2190,10 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, { struct bnx2x *bp = netdev_priv(dev); u32 *hw_stats, *offset; - int i, j, k = 0; + int i, j, k; if (is_multi(bp)) { + k = 0; for_each_eth_queue(bp, i) { hw_stats = (u32 *)&bp->fp[i].eth_q_stats; for (j = 0; j < BNX2X_NUM_Q_STATS; j++) { @@ -2207,28 +2214,46 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, } k += BNX2X_NUM_Q_STATS; } - } - - hw_stats = (u32 *)&bp->eth_stats; - for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) - continue; - if (bnx2x_stats_arr[i].size == 0) { - /* skip this counter */ - buf[k + j] = 0; - j++; - continue; + if (IS_MF_MODE_STAT(bp)) + return; + hw_stats = (u32 *)&bp->eth_stats; + for (j = 0; j < BNX2X_NUM_STATS; j++) { + if (bnx2x_stats_arr[j].size == 0) { + /* skip this counter */ + buf[k + j] = 0; + continue; + } + offset = (hw_stats + bnx2x_stats_arr[j].offset); + if (bnx2x_stats_arr[j].size == 4) { + /* 4-byte counter */ + buf[k + j] = (u64) *offset; + continue; + } + /* 8-byte counter */ + buf[k + j] = HILO_U64(*offset, *(offset + 1)); } - offset = (hw_stats + bnx2x_stats_arr[i].offset); - if (bnx2x_stats_arr[i].size == 4) { - /* 4-byte counter */ - buf[k + j] = (u64) *offset; + } else { + hw_stats = (u32 *)&bp->eth_stats; + for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { + if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) + continue; + if (bnx2x_stats_arr[i].size == 0) { + /* skip this counter */ + buf[j] = 0; + j++; + continue; + } + offset = (hw_stats + bnx2x_stats_arr[i].offset); + if (bnx2x_stats_arr[i].size == 4) { + /* 4-byte counter */ + buf[j] = (u64) *offset; + j++; + continue; + } + /* 8-byte counter */ + buf[j] = HILO_U64(*offset, *(offset + 1)); j++; - continue; } - /* 8-byte counter */ - buf[k + j] = HILO_U64(*offset, *(offset + 1)); - j++; } } diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 1e3f978ee6da..ffeaaa95ed96 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -941,7 +941,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j]; BNX2X_ERR("fp%d: rx_bd[%x]=[%x:%x] sw_bd=[%p]\n", - i, j, rx_bd[1], rx_bd[0], sw_bd->data); + i, j, rx_bd[1], rx_bd[0], sw_bd->skb); } start = RX_SGE(fp->rx_sge_prod); @@ -10536,9 +10536,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, { struct bnx2x *bp; int rc; - bool chip_is_e1x = (board_type == BCM57710 || - board_type == BCM57711 || - board_type == BCM57711E); SET_NETDEV_DEV(dev, &pdev->dev); bp = netdev_priv(dev); @@ -10627,7 +10624,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0, 0); REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0, 0); - if (chip_is_e1x) { + if (CHIP_IS_E1x(bp)) { REG_WR(bp, PXP2_REG_PGL_ADDR_88_F1, 0); REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F1, 0); REG_WR(bp, PXP2_REG_PGL_ADDR_90_F1, 0); @@ -10638,7 +10635,9 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, * Enable internal target-read (in case we are probed after PF FLR). * Must be done prior to any BAR read access. Only for 57712 and up */ - if (!chip_is_e1x) + if (board_type != BCM57710 && + board_type != BCM57711 && + board_type != BCM57711E) REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); /* Reset the load counter */ diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index cb6339c35571..5ac616093f9f 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -50,7 +50,6 @@ static inline void bnx2x_exe_queue_init(struct bnx2x *bp, int exe_len, union bnx2x_qable_obj *owner, exe_q_validate validate, - exe_q_remove remove, exe_q_optimize optimize, exe_q_execute exec, exe_q_get get) @@ -67,7 +66,6 @@ static inline void bnx2x_exe_queue_init(struct bnx2x *bp, /* Owner specific callbacks */ o->validate = validate; - o->remove = remove; o->optimize = optimize; o->execute = exec; o->get = get; @@ -1342,35 +1340,6 @@ static int bnx2x_validate_vlan_mac(struct bnx2x *bp, } } -static int bnx2x_remove_vlan_mac(struct bnx2x *bp, - union bnx2x_qable_obj *qo, - struct bnx2x_exeq_elem *elem) -{ - int rc = 0; - - /* If consumption wasn't required, nothing to do */ - if (test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, - &elem->cmd_data.vlan_mac.vlan_mac_flags)) - return 0; - - switch (elem->cmd_data.vlan_mac.cmd) { - case BNX2X_VLAN_MAC_ADD: - case BNX2X_VLAN_MAC_MOVE: - rc = qo->vlan_mac.put_credit(&qo->vlan_mac); - break; - case BNX2X_VLAN_MAC_DEL: - rc = qo->vlan_mac.get_credit(&qo->vlan_mac); - break; - default: - return -EINVAL; - } - - if (rc != true) - return -EINVAL; - - return 0; -} - /** * bnx2x_wait_vlan_mac - passivly wait for 5 seconds until all work completes. * @@ -1832,14 +1801,8 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) { if (exeq_pos->cmd_data.vlan_mac.vlan_mac_flags == - *vlan_mac_flags) { - rc = exeq->remove(bp, exeq->owner, exeq_pos); - if (rc) { - BNX2X_ERR("Failed to remove command\n"); - return rc; - } + *vlan_mac_flags) list_del(&exeq_pos->link); - } } spin_unlock_bh(&exeq->lock); @@ -1945,7 +1908,6 @@ void bnx2x_init_mac_obj(struct bnx2x *bp, bnx2x_exe_queue_init(bp, &mac_obj->exe_queue, 1, qable_obj, bnx2x_validate_vlan_mac, - bnx2x_remove_vlan_mac, bnx2x_optimize_vlan_mac, bnx2x_execute_vlan_mac, bnx2x_exeq_get_mac); @@ -1962,7 +1924,6 @@ void bnx2x_init_mac_obj(struct bnx2x *bp, bnx2x_exe_queue_init(bp, &mac_obj->exe_queue, CLASSIFY_RULES_COUNT, qable_obj, bnx2x_validate_vlan_mac, - bnx2x_remove_vlan_mac, bnx2x_optimize_vlan_mac, bnx2x_execute_vlan_mac, bnx2x_exeq_get_mac); @@ -2002,7 +1963,6 @@ void bnx2x_init_vlan_obj(struct bnx2x *bp, bnx2x_exe_queue_init(bp, &vlan_obj->exe_queue, CLASSIFY_RULES_COUNT, qable_obj, bnx2x_validate_vlan_mac, - bnx2x_remove_vlan_mac, bnx2x_optimize_vlan_mac, bnx2x_execute_vlan_mac, bnx2x_exeq_get_vlan); @@ -2049,7 +2009,6 @@ void bnx2x_init_vlan_mac_obj(struct bnx2x *bp, bnx2x_exe_queue_init(bp, &vlan_mac_obj->exe_queue, 1, qable_obj, bnx2x_validate_vlan_mac, - bnx2x_remove_vlan_mac, bnx2x_optimize_vlan_mac, bnx2x_execute_vlan_mac, bnx2x_exeq_get_vlan_mac); @@ -2066,7 +2025,6 @@ void bnx2x_init_vlan_mac_obj(struct bnx2x *bp, &vlan_mac_obj->exe_queue, CLASSIFY_RULES_COUNT, qable_obj, bnx2x_validate_vlan_mac, - bnx2x_remove_vlan_mac, bnx2x_optimize_vlan_mac, bnx2x_execute_vlan_mac, bnx2x_exeq_get_vlan_mac); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index 66da39f0c84a..992308ff82e8 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -161,10 +161,6 @@ typedef int (*exe_q_validate)(struct bnx2x *bp, union bnx2x_qable_obj *o, struct bnx2x_exeq_elem *elem); -typedef int (*exe_q_remove)(struct bnx2x *bp, - union bnx2x_qable_obj *o, - struct bnx2x_exeq_elem *elem); - /** * @return positive is entry was optimized, 0 - if not, negative * in case of an error. @@ -207,18 +203,11 @@ struct bnx2x_exe_queue_obj { */ exe_q_validate validate; - /** - * Called before removing pending commands, cleaning allocated - * resources (e.g., credits from validate) - */ - exe_q_remove remove; /** * This will try to cancel the current pending commands list * considering the new command. * - * Returns the number of optimized commands or a negative error code - * * Must run under exe_queue->lock */ exe_q_optimize optimize; diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index a1f2e0fed78b..d529af99157d 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -6667,9 +6667,14 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) iph = ip_hdr(skb); tcp_opt_len = tcp_optlen(skb); - hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN; + if (skb_is_gso_v6(skb)) { + hdr_len = skb_headlen(skb) - ETH_HLEN; + } else { + u32 ip_tcp_len; + + ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); + hdr_len = ip_tcp_len + tcp_opt_len; - if (!skb_is_gso_v6(skb)) { iph->check = 0; iph->tot_len = htons(mss + hdr_len); } diff --git a/trunk/drivers/net/ethernet/cisco/enic/enic.h b/trunk/drivers/net/ethernet/cisco/enic/enic.h index ee93a2087fe6..fe0c29acdbe6 100644 --- a/trunk/drivers/net/ethernet/cisco/enic/enic.h +++ b/trunk/drivers/net/ethernet/cisco/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.31" +#define DRV_VERSION "2.1.1.28" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/trunk/drivers/net/ethernet/cisco/enic/enic_main.c b/trunk/drivers/net/ethernet/cisco/enic/enic_main.c index ab3f67f980d8..2fd9db4b1be5 100644 --- a/trunk/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/trunk/drivers/net/ethernet/cisco/enic/enic_main.c @@ -57,13 +57,11 @@ #define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043 /* ethernet vnic */ #define PCI_DEVICE_ID_CISCO_VIC_ENET_DYN 0x0044 /* enet dynamic vnic */ -#define PCI_DEVICE_ID_CISCO_VIC_ENET_VF 0x0071 /* enet SRIOV VF */ /* Supported devices */ static DEFINE_PCI_DEVICE_TABLE(enic_id_table) = { { PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET) }, { PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_DYN) }, - { PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_VF) }, { 0, } /* end of table */ }; @@ -134,11 +132,6 @@ int enic_sriov_enabled(struct enic *enic) return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0; } -static int enic_is_sriov_vf(struct enic *enic) -{ - return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_VF; -} - int enic_is_valid_vf(struct enic *enic, int vf) { #ifdef CONFIG_PCI_IOV @@ -444,7 +437,7 @@ static void enic_mtu_check(struct enic *enic) if (mtu && mtu != enic->port_mtu) { enic->port_mtu = mtu; - if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic)) { + if (enic_is_dynamic(enic)) { mtu = max_t(int, ENIC_MIN_MTU, min_t(int, ENIC_MAX_MTU, mtu)); if (mtu != netdev->mtu) @@ -856,7 +849,7 @@ static int enic_set_mac_addr(struct net_device *netdev, char *addr) { struct enic *enic = netdev_priv(netdev); - if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic)) { + if (enic_is_dynamic(enic)) { if (!is_valid_ether_addr(addr) && !is_zero_ether_addr(addr)) return -EADDRNOTAVAIL; } else { @@ -1615,7 +1608,7 @@ static int enic_open(struct net_device *netdev) for (i = 0; i < enic->rq_count; i++) vnic_rq_enable(&enic->rq[i]); - if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) + if (!enic_is_dynamic(enic)) enic_dev_add_station_addr(enic); enic_set_rx_mode(netdev); @@ -1666,7 +1659,7 @@ static int enic_stop(struct net_device *netdev) netif_carrier_off(netdev); netif_tx_disable(netdev); - if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) + if (!enic_is_dynamic(enic)) enic_dev_del_station_addr(enic); for (i = 0; i < enic->wq_count; i++) { @@ -1703,7 +1696,7 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu) if (new_mtu < ENIC_MIN_MTU || new_mtu > ENIC_MAX_MTU) return -EINVAL; - if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic)) + if (enic_is_dynamic(enic)) return -EOPNOTSUPP; if (running) @@ -2270,10 +2263,10 @@ static int __devinit enic_probe(struct pci_dev *pdev, int using_dac = 0; unsigned int i; int err; + int num_pps = 1; #ifdef CONFIG_PCI_IOV int pos = 0; #endif - int num_pps = 1; /* Allocate net device structure and initialize. Private * instance data is initialized to zero. @@ -2383,14 +2376,14 @@ static int __devinit enic_probe(struct pci_dev *pdev, num_pps = enic->num_vfs; } } -#endif +#endif /* Allocate structure for port profiles */ enic->pp = kcalloc(num_pps, sizeof(*enic->pp), GFP_KERNEL); if (!enic->pp) { pr_err("port profile alloc failed, aborting\n"); err = -ENOMEM; - goto err_out_disable_sriov_pp; + goto err_out_disable_sriov; } /* Issue device open to get device in known state @@ -2399,7 +2392,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = enic_dev_open(enic); if (err) { dev_err(dev, "vNIC dev open failed, aborting\n"); - goto err_out_disable_sriov; + goto err_out_free_pp; } /* Setup devcmd lock @@ -2433,7 +2426,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, * called later by an upper layer. */ - if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) { + if (!enic_is_dynamic(enic)) { err = vnic_dev_init(enic->vdev, 0); if (err) { dev_err(dev, "vNIC dev init failed, aborting\n"); @@ -2467,7 +2460,8 @@ static int __devinit enic_probe(struct pci_dev *pdev, (void)enic_change_mtu(netdev, enic->port_mtu); #ifdef CONFIG_PCI_IOV - if (enic_is_sriov_vf(enic) && is_zero_ether_addr(enic->mac_addr)) + if (enic_is_dynamic(enic) && pdev->is_virtfn && + is_zero_ether_addr(enic->mac_addr)) random_ether_addr(enic->mac_addr); #endif @@ -2480,7 +2474,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, enic->tx_coalesce_usecs = enic->config.intr_timer_usec; enic->rx_coalesce_usecs = enic->tx_coalesce_usecs; - if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic)) + if (enic_is_dynamic(enic)) netdev->netdev_ops = &enic_netdev_dynamic_ops; else netdev->netdev_ops = &enic_netdev_ops; @@ -2522,17 +2516,17 @@ static int __devinit enic_probe(struct pci_dev *pdev, enic_dev_deinit(enic); err_out_dev_close: vnic_dev_close(enic->vdev); -err_out_disable_sriov: +err_out_free_pp: kfree(enic->pp); -err_out_disable_sriov_pp: +err_out_disable_sriov: #ifdef CONFIG_PCI_IOV if (enic_sriov_enabled(enic)) { pci_disable_sriov(pdev); enic->priv_flags &= ~ENIC_SRIOV_ENABLED; } err_out_vnic_unregister: -#endif vnic_dev_unregister(enic->vdev); +#endif err_out_iounmap: enic_iounmap(enic); err_out_release_regions: diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index e703d64434f8..a6bcdb5cd2be 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -1786,7 +1786,8 @@ static void be_rx_queues_destroy(struct be_adapter *adapter) static u32 be_num_rxqs_want(struct be_adapter *adapter) { if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) && - !sriov_enabled(adapter) && be_physfn(adapter)) { + !sriov_enabled(adapter) && be_physfn(adapter) && + !be_is_mc(adapter)) { return 1 + MAX_RSS_QS; /* one default non-RSS queue */ } else { dev_warn(&adapter->pdev->dev, diff --git a/trunk/drivers/net/ethernet/faraday/ftgmac100.c b/trunk/drivers/net/ethernet/faraday/ftgmac100.c index 47f85c337cf7..fb5579a3b19d 100644 --- a/trunk/drivers/net/ethernet/faraday/ftgmac100.c +++ b/trunk/drivers/net/ethernet/faraday/ftgmac100.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/net/ethernet/faraday/ftmac100.c b/trunk/drivers/net/ethernet/faraday/ftmac100.c index bb336a0959c9..a127cb2476c7 100644 --- a/trunk/drivers/net/ethernet/faraday/ftmac100.c +++ b/trunk/drivers/net/ethernet/faraday/ftmac100.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/net/ethernet/intel/igb/Makefile b/trunk/drivers/net/ethernet/intel/igb/Makefile index 6565c463185c..c6e4621b6262 100644 --- a/trunk/drivers/net/ethernet/intel/igb/Makefile +++ b/trunk/drivers/net/ethernet/intel/igb/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel 82575 PCI-Express Ethernet Linux driver -# Copyright(c) 1999 - 2012 Intel Corporation. +# Copyright(c) 1999 - 2011 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c index 08bdc33715ee..b8e20f037d0a 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.h b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.h index b927d79ab536..08a757eb6608 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_defines.h b/trunk/drivers/net/ethernet/intel/igb/e1000_defines.h index aed217449f0d..f5fc5725ea94 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_hw.h b/trunk/drivers/net/ethernet/intel/igb/e1000_hw.h index f67cbd3fa307..4519a1367170 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_hw.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_hw.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_mac.c b/trunk/drivers/net/ethernet/intel/igb/e1000_mac.c index f57338afd71f..73aac082c44d 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_mac.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_mac.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -151,7 +151,7 @@ void igb_clear_vfta_i350(struct e1000_hw *hw) * Writes value at the given offset in the register array which stores * the VLAN filter table. **/ -static void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value) +void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value) { int i; diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_mac.h b/trunk/drivers/net/ethernet/intel/igb/e1000_mac.h index cbddc4e51e30..e45996b4ea34 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_mac.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_mac.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_mbx.c b/trunk/drivers/net/ethernet/intel/igb/e1000_mbx.c index 5988b8958baf..469d95eaa154 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_mbx.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_mbx.h b/trunk/drivers/net/ethernet/intel/igb/e1000_mbx.h index dbcfa3d5caec..eddb0f83dcea 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_mbx.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.c b/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.c index fa2c6ba62139..40407124e722 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.h b/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.h index 825b0228cac0..a2a7ca9fa733 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2012 Intel Corporation. + Copyright(c) 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_phy.c b/trunk/drivers/net/ethernet/intel/igb/e1000_phy.c index 789de5b83aad..b17d7c20f817 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_phy.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_phy.h b/trunk/drivers/net/ethernet/intel/igb/e1000_phy.h index 4c32ac66ff39..8510797b9d81 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_phy.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_phy.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h b/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h index ccdf36d503fd..0a860bc1198e 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/igb.h b/trunk/drivers/net/ethernet/intel/igb/igb.h index 8e33bdd33eea..3d12e67eebb4 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb.h +++ b/trunk/drivers/net/ethernet/intel/igb/igb.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c b/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c index aa399a8a8f0d..7998bf4d5946 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_main.c b/trunk/drivers/net/ethernet/intel/igb/igb_main.c index e91d73c8aa4e..01e5e89ef959 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_main.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_main.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -68,7 +68,7 @@ char igb_driver_name[] = "igb"; char igb_driver_version[] = DRV_VERSION; static const char igb_driver_string[] = "Intel(R) Gigabit Ethernet Network Driver"; -static const char igb_copyright[] = "Copyright (c) 2007-2012 Intel Corporation."; +static const char igb_copyright[] = "Copyright (c) 2007-2011 Intel Corporation."; static const struct e1000_info *igb_info_tbl[] = { [board_82575] = &e1000_82575_info, @@ -4003,8 +4003,8 @@ static void igb_set_itr(struct igb_q_vector *q_vector) } } -static void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens, - u32 type_tucmd, u32 mss_l4len_idx) +void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens, + u32 type_tucmd, u32 mss_l4len_idx) { struct e1000_adv_tx_context_desc *context_desc; u16 i = tx_ring->next_to_use; @@ -5623,7 +5623,7 @@ static irqreturn_t igb_intr(int irq, void *data) return IRQ_HANDLED; } -static void igb_ring_irq_enable(struct igb_q_vector *q_vector) +void igb_ring_irq_enable(struct igb_q_vector *q_vector) { struct igb_adapter *adapter = q_vector->adapter; struct e1000_hw *hw = &adapter->hw; diff --git a/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c b/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c index 2dba53446064..7b600a1f6366 100644 --- a/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c @@ -468,5 +468,6 @@ static const struct ethtool_ops igbvf_ethtool_ops = { void igbvf_set_ethtool_ops(struct net_device *netdev) { - SET_ETHTOOL_OPS(netdev, &igbvf_ethtool_ops); + /* have to "undeclare" const on this struct to remove warnings */ + SET_ETHTOOL_OPS(netdev, (struct ethtool_ops *)&igbvf_ethtool_ops); } diff --git a/trunk/drivers/net/ethernet/intel/igbvf/netdev.c b/trunk/drivers/net/ethernet/intel/igbvf/netdev.c index a4b20c865759..fd3da3076c2f 100644 --- a/trunk/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/trunk/drivers/net/ethernet/intel/igbvf/netdev.c @@ -1194,6 +1194,11 @@ static int igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct igbvf_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + igbvf_irq_disable(adapter); + + if (!test_bit(__IGBVF_DOWN, &adapter->state)) + igbvf_irq_enable(adapter); + if (hw->mac.ops.set_vfta(hw, vid, false)) { dev_err(&adapter->pdev->dev, "Failed to remove vlan id %d\n", vid); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 775602ef90e5..802bfa0f62cc 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -161,19 +161,19 @@ /* Receive DMA Registers */ #define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : \ - (0x0D000 + (((_i) - 64) * 0x40))) + (0x0D000 + ((_i - 64) * 0x40))) #define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : \ - (0x0D004 + (((_i) - 64) * 0x40))) + (0x0D004 + ((_i - 64) * 0x40))) #define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : \ - (0x0D008 + (((_i) - 64) * 0x40))) + (0x0D008 + ((_i - 64) * 0x40))) #define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : \ - (0x0D010 + (((_i) - 64) * 0x40))) + (0x0D010 + ((_i - 64) * 0x40))) #define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : \ - (0x0D018 + (((_i) - 64) * 0x40))) + (0x0D018 + ((_i - 64) * 0x40))) #define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \ - (0x0D028 + (((_i) - 64) * 0x40))) + (0x0D028 + ((_i - 64) * 0x40))) #define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \ - (0x0D02C + (((_i) - 64) * 0x40))) + (0x0D02C + ((_i - 64) * 0x40))) #define IXGBE_RSCDBU 0x03028 #define IXGBE_RDDCC 0x02F20 #define IXGBE_RXMEMWRAP 0x03190 @@ -186,7 +186,7 @@ */ #define IXGBE_SRRCTL(_i) (((_i) <= 15) ? (0x02100 + ((_i) * 4)) : \ (((_i) < 64) ? (0x01014 + ((_i) * 0x40)) : \ - (0x0D014 + (((_i) - 64) * 0x40)))) + (0x0D014 + ((_i - 64) * 0x40)))) /* * Rx DCA Control Register: * 00-15 : 0x02200 + n*4 @@ -195,7 +195,7 @@ */ #define IXGBE_DCA_RXCTRL(_i) (((_i) <= 15) ? (0x02200 + ((_i) * 4)) : \ (((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \ - (0x0D00C + (((_i) - 64) * 0x40)))) + (0x0D00C + ((_i - 64) * 0x40)))) #define IXGBE_RDRXCTL 0x02F00 #define IXGBE_RXPBSIZE(_i) (0x03C00 + ((_i) * 4)) /* 8 of these 0x03C00 - 0x03C1C */ @@ -344,9 +344,9 @@ #define IXGBE_WUPL 0x05900 #define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */ -#define IXGBE_FHFT(_n) (0x09000 + ((_n) * 0x100)) /* Flex host filter table */ -#define IXGBE_FHFT_EXT(_n) (0x09800 + ((_n) * 0x100)) /* Ext Flexible Host - * Filter Table */ +#define IXGBE_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flex host filter table */ +#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100)) /* Ext Flexible Host + * Filter Table */ #define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4 #define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2 @@ -1485,7 +1485,7 @@ enum { #define IXGBE_LED_BLINK_BASE 0x00000080 #define IXGBE_LED_MODE_MASK_BASE 0x0000000F #define IXGBE_LED_OFFSET(_base, _i) (_base << (8 * (_i))) -#define IXGBE_LED_MODE_SHIFT(_i) (8 * (_i)) +#define IXGBE_LED_MODE_SHIFT(_i) (8*(_i)) #define IXGBE_LED_IVRT(_i) IXGBE_LED_OFFSET(IXGBE_LED_IVRT_BASE, _i) #define IXGBE_LED_BLINK(_i) IXGBE_LED_OFFSET(IXGBE_LED_BLINK_BASE, _i) #define IXGBE_LED_MODE_MASK(_i) IXGBE_LED_OFFSET(IXGBE_LED_MODE_MASK_BASE, _i) @@ -2068,9 +2068,9 @@ enum { /* SR-IOV specific macros */ #define IXGBE_MBVFICR_INDEX(vf_number) (vf_number >> 4) -#define IXGBE_MBVFICR(_i) (0x00710 + ((_i) * 4)) -#define IXGBE_VFLRE(_i) ((((_i) & 1) ? 0x001C0 : 0x00600)) -#define IXGBE_VFLREC(_i) (0x00700 + ((_i) * 4)) +#define IXGBE_MBVFICR(_i) (0x00710 + (_i * 4)) +#define IXGBE_VFLRE(_i) (((_i & 1) ? 0x001C0 : 0x00600)) +#define IXGBE_VFLREC(_i) (0x00700 + (_i * 4)) enum ixgbe_fdir_pballoc_type { IXGBE_FDIR_PBALLOC_NONE = 0, diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/trunk/drivers/net/ethernet/intel/ixgbevf/ethtool.c index c85700318147..dc8e6511c640 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ethtool.c @@ -56,8 +56,7 @@ struct ixgbe_stats { offsetof(struct ixgbevf_adapter, m), \ offsetof(struct ixgbevf_adapter, b), \ offsetof(struct ixgbevf_adapter, r) - -static const struct ixgbe_stats ixgbe_gstrings_stats[] = { +static struct ixgbe_stats ixgbe_gstrings_stats[] = { {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc, stats.saved_reset_vfgprc)}, {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc, @@ -672,7 +671,7 @@ static int ixgbevf_nway_reset(struct net_device *netdev) return 0; } -static const struct ethtool_ops ixgbevf_ethtool_ops = { +static struct ethtool_ops ixgbevf_ethtool_ops = { .get_settings = ixgbevf_get_settings, .get_drvinfo = ixgbevf_get_drvinfo, .get_regs_len = ixgbevf_get_regs_len, diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 9075c1d61039..e6c9d1a927a9 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -279,12 +279,12 @@ enum ixgbevf_boards { board_X540_vf, }; -extern const struct ixgbevf_info ixgbevf_82599_vf_info; -extern const struct ixgbevf_info ixgbevf_X540_vf_info; -extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops; +extern struct ixgbevf_info ixgbevf_82599_vf_info; +extern struct ixgbevf_info ixgbevf_X540_vf_info; +extern struct ixgbe_mbx_operations ixgbevf_mbx_ops; /* needed by ethtool.c */ -extern const char ixgbevf_driver_name[]; +extern char ixgbevf_driver_name[]; extern const char ixgbevf_driver_version[]; extern int ixgbevf_up(struct ixgbevf_adapter *adapter); diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index bed411bada21..891162d1610c 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -53,7 +53,7 @@ #include "ixgbevf.h" -const char ixgbevf_driver_name[] = "ixgbevf"; +char ixgbevf_driver_name[] = "ixgbevf"; static const char ixgbevf_driver_string[] = "Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver"; @@ -917,34 +917,31 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data) struct ixgbe_hw *hw = &adapter->hw; u32 eicr; u32 msg; - bool got_ack = false; eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS); IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr); - if (!hw->mbx.ops.check_for_ack(hw)) - got_ack = true; - - if (!hw->mbx.ops.check_for_msg(hw)) { - hw->mbx.ops.read(hw, &msg, 1); - - if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG) - mod_timer(&adapter->watchdog_timer, - round_jiffies(jiffies + 1)); - - if (msg & IXGBE_VT_MSGTYPE_NACK) - pr_warn("Last Request of type %2.2x to PF Nacked\n", - msg & 0xFF); + if (!hw->mbx.ops.check_for_ack(hw)) { + /* + * checking for the ack clears the PFACK bit. Place + * it back in the v2p_mailbox cache so that anyone + * polling for an ack will not miss it. Also + * avoid the read below because the code to read + * the mailbox will also clear the ack bit. This was + * causing lost acks. Just cache the bit and exit + * the IRQ handler. + */ + hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK; goto out; } - /* - * checking for the ack clears the PFACK bit. Place - * it back in the v2p_mailbox cache so that anyone - * polling for an ack will not miss it - */ - if (got_ack) - hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK; + /* Not an ack interrupt, go ahead and read the message */ + hw->mbx.ops.read(hw, &msg, 1); + + if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG) + mod_timer(&adapter->watchdog_timer, + round_jiffies(jiffies + 1)); + out: return IRQ_HANDLED; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/mbx.c b/trunk/drivers/net/ethernet/intel/ixgbevf/mbx.c index 13532d9ba72d..930fa83f2568 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/mbx.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/mbx.c @@ -26,7 +26,6 @@ *******************************************************************************/ #include "mbx.h" -#include "ixgbevf.h" /** * ixgbevf_poll_for_msg - Wait for message notification @@ -329,7 +328,7 @@ static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw) return 0; } -const struct ixgbe_mbx_operations ixgbevf_mbx_ops = { +struct ixgbe_mbx_operations ixgbevf_mbx_ops = { .init_params = ixgbevf_init_mbx_params_vf, .read = ixgbevf_read_mbx_vf, .write = ixgbevf_write_mbx_vf, diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/vf.c b/trunk/drivers/net/ethernet/intel/ixgbevf/vf.c index d0138d7a31a1..21533e300367 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/vf.c @@ -26,7 +26,6 @@ *******************************************************************************/ #include "vf.h" -#include "ixgbevf.h" /** * ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx @@ -402,7 +401,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw, return 0; } -static const struct ixgbe_mac_operations ixgbevf_mac_ops = { +static struct ixgbe_mac_operations ixgbevf_mac_ops = { .init_hw = ixgbevf_init_hw_vf, .reset_hw = ixgbevf_reset_hw_vf, .start_hw = ixgbevf_start_hw_vf, @@ -416,12 +415,12 @@ static const struct ixgbe_mac_operations ixgbevf_mac_ops = { .set_vfta = ixgbevf_set_vfta_vf, }; -const struct ixgbevf_info ixgbevf_82599_vf_info = { +struct ixgbevf_info ixgbevf_82599_vf_info = { .mac = ixgbe_mac_82599_vf, .mac_ops = &ixgbevf_mac_ops, }; -const struct ixgbevf_info ixgbevf_X540_vf_info = { +struct ixgbevf_info ixgbevf_X540_vf_info = { .mac = ixgbe_mac_X540_vf, .mac_ops = &ixgbevf_mac_ops, }; diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/vf.h b/trunk/drivers/net/ethernet/intel/ixgbevf/vf.h index d556619a9212..10306b492ee6 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/vf.h +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/vf.h @@ -167,7 +167,7 @@ struct ixgbevf_hw_stats { struct ixgbevf_info { enum ixgbe_mac_type mac; - const struct ixgbe_mac_operations *mac_ops; + struct ixgbe_mac_operations *mac_ops; }; #endif /* __IXGBE_VF_H__ */ diff --git a/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c b/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c index 9edecfa1f0f4..9c049d2cb97d 100644 --- a/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -136,8 +136,6 @@ static char mv643xx_eth_driver_version[] = "1.4"; #define INT_MASK 0x0068 #define INT_MASK_EXT 0x006c #define TX_FIFO_URGENT_THRESHOLD 0x0074 -#define RX_DISCARD_FRAME_CNT 0x0084 -#define RX_OVERRUN_FRAME_CNT 0x0088 #define TXQ_FIX_PRIO_CONF_MOVED 0x00dc #define TX_BW_RATE_MOVED 0x00e0 #define TX_BW_MTU_MOVED 0x00e8 @@ -336,9 +334,6 @@ struct mib_counters { u32 bad_crc_event; u32 collision; u32 late_collision; - /* Non MIB hardware counters */ - u32 rx_discard; - u32 rx_overrun; }; struct lro_counters { @@ -1230,10 +1225,6 @@ static void mib_counters_clear(struct mv643xx_eth_private *mp) for (i = 0; i < 0x80; i += 4) mib_read(mp, i); - - /* Clear non MIB hw counters also */ - rdlp(mp, RX_DISCARD_FRAME_CNT); - rdlp(mp, RX_OVERRUN_FRAME_CNT); } static void mib_counters_update(struct mv643xx_eth_private *mp) @@ -1271,9 +1262,6 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) p->bad_crc_event += mib_read(mp, 0x74); p->collision += mib_read(mp, 0x78); p->late_collision += mib_read(mp, 0x7c); - /* Non MIB hardware counters */ - p->rx_discard += rdlp(mp, RX_DISCARD_FRAME_CNT); - p->rx_overrun += rdlp(mp, RX_OVERRUN_FRAME_CNT); spin_unlock_bh(&mp->mib_counters_lock); mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); @@ -1425,8 +1413,6 @@ static const struct mv643xx_eth_stats mv643xx_eth_stats[] = { MIBSTAT(bad_crc_event), MIBSTAT(collision), MIBSTAT(late_collision), - MIBSTAT(rx_discard), - MIBSTAT(rx_overrun), LROSTAT(lro_aggregated), LROSTAT(lro_flushed), LROSTAT(lro_no_desc), diff --git a/trunk/drivers/net/ethernet/marvell/skge.c b/trunk/drivers/net/ethernet/marvell/skge.c index edb9bda55d55..18a87a57fc0a 100644 --- a/trunk/drivers/net/ethernet/marvell/skge.c +++ b/trunk/drivers/net/ethernet/marvell/skge.c @@ -931,20 +931,17 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base) } /* Allocate and setup a new buffer for receiving */ -static int skge_rx_setup(struct pci_dev *pdev, - struct skge_element *e, - struct sk_buff *skb, unsigned int bufsize) +static void skge_rx_setup(struct skge_port *skge, struct skge_element *e, + struct sk_buff *skb, unsigned int bufsize) { struct skge_rx_desc *rd = e->desc; - dma_addr_t map; + u64 map; - map = pci_map_single(pdev, skb->data, bufsize, + map = pci_map_single(skge->hw->pdev, skb->data, bufsize, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(pdev, map)) - goto mapping_error; - rd->dma_lo = lower_32_bits(map); - rd->dma_hi = upper_32_bits(map); + rd->dma_lo = map; + rd->dma_hi = map >> 32; e->skb = skb; rd->csum1_start = ETH_HLEN; rd->csum2_start = ETH_HLEN; @@ -956,13 +953,6 @@ static int skge_rx_setup(struct pci_dev *pdev, rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize; dma_unmap_addr_set(e, mapaddr, map); dma_unmap_len_set(e, maplen, bufsize); - return 0; - -mapping_error: - if (net_ratelimit()) - dev_warn(&pdev->dev, "%s: rx mapping error\n", - skb->dev->name); - return -EIO; } /* Resume receiving using existing skb, @@ -1024,11 +1014,7 @@ static int skge_rx_fill(struct net_device *dev) return -ENOMEM; skb_reserve(skb, NET_IP_ALIGN); - if (skge_rx_setup(skge->hw->pdev, e, skb, skge->rx_buf_size)) { - kfree_skb(skb); - return -ENOMEM; - } - + skge_rx_setup(skge, e, skb, skge->rx_buf_size); } while ((e = e->next) != ring->start); ring->to_clean = ring->start; @@ -2590,7 +2576,6 @@ static int skge_up(struct net_device *dev) } /* Initialize MAC */ - netif_carrier_off(dev); spin_lock_bh(&hw->phy_lock); if (is_genesis(hw)) genesis_mac_init(hw, port); @@ -2743,7 +2728,7 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, struct skge_tx_desc *td; int i; u32 control, len; - dma_addr_t map; + u64 map; if (skb_padto(skb, ETH_ZLEN)) return NETDEV_TX_OK; @@ -2757,14 +2742,11 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, e->skb = skb; len = skb_headlen(skb); map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(hw->pdev, map)) - goto mapping_error; - dma_unmap_addr_set(e, mapaddr, map); dma_unmap_len_set(e, maplen, len); - td->dma_lo = lower_32_bits(map); - td->dma_hi = upper_32_bits(map); + td->dma_lo = map; + td->dma_hi = map >> 32; if (skb->ip_summed == CHECKSUM_PARTIAL) { const int offset = skb_checksum_start_offset(skb); @@ -2795,16 +2777,14 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, map = skb_frag_dma_map(&hw->pdev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); - if (dma_mapping_error(&hw->pdev->dev, map)) - goto mapping_unwind; e = e->next; e->skb = skb; tf = e->desc; BUG_ON(tf->control & BMU_OWN); - tf->dma_lo = lower_32_bits(map); - tf->dma_hi = upper_32_bits(map); + tf->dma_lo = map; + tf->dma_hi = (u64) map >> 32; dma_unmap_addr_set(e, mapaddr, map); dma_unmap_len_set(e, maplen, skb_frag_size(frag)); @@ -2817,8 +2797,6 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, td->control = BMU_OWN | BMU_SW | BMU_STF | control | len; wmb(); - netdev_sent_queue(dev, skb->len); - skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START); netif_printk(skge, tx_queued, KERN_DEBUG, skge->netdev, @@ -2834,35 +2812,15 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, } return NETDEV_TX_OK; - -mapping_unwind: - /* unroll any pages that were already mapped. */ - if (e != skge->tx_ring.to_use) { - struct skge_element *u; - - for (u = skge->tx_ring.to_use->next; u != e; u = u->next) - pci_unmap_page(hw->pdev, dma_unmap_addr(u, mapaddr), - dma_unmap_len(u, maplen), - PCI_DMA_TODEVICE); - e = skge->tx_ring.to_use; - } - /* undo the mapping for the skb header */ - pci_unmap_single(hw->pdev, dma_unmap_addr(e, mapaddr), - dma_unmap_len(e, maplen), - PCI_DMA_TODEVICE); -mapping_error: - /* mapping error causes error message and packet to be discarded. */ - if (net_ratelimit()) - dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name); - dev_kfree_skb(skb); - return NETDEV_TX_OK; } /* Free resources associated with this reing element */ -static inline void skge_tx_unmap(struct pci_dev *pdev, struct skge_element *e, - u32 control) +static void skge_tx_free(struct skge_port *skge, struct skge_element *e, + u32 control) { + struct pci_dev *pdev = skge->hw->pdev; + /* skb header vs. fragment */ if (control & BMU_STF) pci_unmap_single(pdev, dma_unmap_addr(e, mapaddr), @@ -2872,6 +2830,13 @@ static inline void skge_tx_unmap(struct pci_dev *pdev, struct skge_element *e, pci_unmap_page(pdev, dma_unmap_addr(e, mapaddr), dma_unmap_len(e, maplen), PCI_DMA_TODEVICE); + + if (control & BMU_EOF) { + netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev, + "tx done slot %td\n", e - skge->tx_ring.start); + + dev_kfree_skb(e->skb); + } } /* Free all buffers in transmit ring */ @@ -2882,15 +2847,10 @@ static void skge_tx_clean(struct net_device *dev) for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) { struct skge_tx_desc *td = e->desc; - - skge_tx_unmap(skge->hw->pdev, e, td->control); - - if (td->control & BMU_EOF) - dev_kfree_skb(e->skb); + skge_tx_free(skge, e, td->control); td->control = 0; } - netdev_reset_queue(dev); skge->tx_ring.to_clean = e; } @@ -3099,17 +3059,13 @@ static struct sk_buff *skge_rx_get(struct net_device *dev, if (!nskb) goto resubmit; - if (unlikely(skge_rx_setup(skge->hw->pdev, e, nskb, skge->rx_buf_size))) { - dev_kfree_skb(nskb); - goto resubmit; - } - pci_unmap_single(skge->hw->pdev, dma_unmap_addr(e, mapaddr), dma_unmap_len(e, maplen), PCI_DMA_FROMDEVICE); skb = e->skb; prefetch(skb->data); + skge_rx_setup(skge, e, nskb, skge->rx_buf_size); } skb_put(skb, len); @@ -3155,7 +3111,6 @@ static void skge_tx_done(struct net_device *dev) struct skge_port *skge = netdev_priv(dev); struct skge_ring *ring = &skge->tx_ring; struct skge_element *e; - unsigned int bytes_compl = 0, pkts_compl = 0; skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F); @@ -3165,20 +3120,8 @@ static void skge_tx_done(struct net_device *dev) if (control & BMU_OWN) break; - skge_tx_unmap(skge->hw->pdev, e, control); - - if (control & BMU_EOF) { - netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev, - "tx done slot %td\n", - e - skge->tx_ring.start); - - pkts_compl++; - bytes_compl += e->skb->len; - - dev_kfree_skb(e->skb); - } + skge_tx_free(skge, e, control); } - netdev_completed_queue(dev, pkts_compl, bytes_compl); skge->tx_ring.to_clean = e; /* Can run lockless until we need to synchronize to restart queue. */ diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/cmd.c b/trunk/drivers/net/ethernet/mellanox/mlx4/cmd.c index 405e6ac3faf6..978f593094c0 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1247,7 +1247,6 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, u32 reply; u32 slave_status = 0; u8 is_going_down = 0; - int i; slave_state[slave].comm_toggle ^= 1; reply = (u32) slave_state[slave].comm_toggle << 31; @@ -1259,10 +1258,6 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, if (cmd == MLX4_COMM_CMD_RESET) { mlx4_warn(dev, "Received reset from slave:%d\n", slave); slave_state[slave].active = false; - for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) { - slave_state[slave].event_eq[i].eqn = -1; - slave_state[slave].event_eq[i].token = 0; - } /*check if we are in the middle of FLR process, if so return "retry" status to the slave*/ if (MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd) { @@ -1457,7 +1452,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_slave_state *s_state; - int i, j, err, port; + int i, err, port; priv->mfunc.vhcr = dma_alloc_coherent(&(dev->pdev->dev), PAGE_SIZE, &priv->mfunc.vhcr_dma, @@ -1490,8 +1485,6 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) for (i = 0; i < dev->num_slaves; ++i) { s_state = &priv->mfunc.master.slave_state[i]; s_state->last_cmd = MLX4_COMM_CMD_RESET; - for (j = 0; j < MLX4_EVENT_TYPES_NUM; ++j) - s_state->event_eq[j].eqn = -1; __raw_writel((__force u32) 0, &priv->mfunc.comm[i].slave_write); __raw_writel((__force u32) 0, diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/cq.c b/trunk/drivers/net/ethernet/mellanox/mlx4/cq.c index 7e64033d7de3..475f9d6af955 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/cq.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/cq.c @@ -96,7 +96,7 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type) static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, int cq_num) { - return mlx4_cmd(dev, mailbox->dma, cq_num, 0, + return mlx4_cmd(dev, mailbox->dma | dev->caps.function, cq_num, 0, MLX4_CMD_SW2HW_CQ, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); } @@ -111,7 +111,7 @@ static int mlx4_MODIFY_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox static int mlx4_HW2SW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, int cq_num) { - return mlx4_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, + return mlx4_cmd_box(dev, dev->caps.function, mailbox ? mailbox->dma : 0, cq_num, mailbox ? 0 : 1, MLX4_CMD_HW2SW_CQ, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 70346fd7f9c4..7dbc6a230779 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -183,11 +183,10 @@ static int mlx4_en_set_wol(struct net_device *netdev, static int mlx4_en_get_sset_count(struct net_device *dev, int sset) { struct mlx4_en_priv *priv = netdev_priv(dev); - int bit_count = hweight64(priv->stats_bitmap); switch (sset) { case ETH_SS_STATS: - return (priv->stats_bitmap ? bit_count : NUM_ALL_STATS) + + return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2; case ETH_SS_TEST: return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags @@ -202,34 +201,14 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, { struct mlx4_en_priv *priv = netdev_priv(dev); int index = 0; - int i, j = 0; + int i; spin_lock_bh(&priv->stats_lock); - if (!(priv->stats_bitmap)) { - for (i = 0; i < NUM_MAIN_STATS; i++) - data[index++] = - ((unsigned long *) &priv->stats)[i]; - for (i = 0; i < NUM_PORT_STATS; i++) - data[index++] = - ((unsigned long *) &priv->port_stats)[i]; - for (i = 0; i < NUM_PKT_STATS; i++) - data[index++] = - ((unsigned long *) &priv->pkstats)[i]; - } else { - for (i = 0; i < NUM_MAIN_STATS; i++) { - if ((priv->stats_bitmap >> j) & 1) - data[index++] = - ((unsigned long *) &priv->stats)[i]; - j++; - } - for (i = 0; i < NUM_PORT_STATS; i++) { - if ((priv->stats_bitmap >> j) & 1) - data[index++] = - ((unsigned long *) &priv->port_stats)[i]; - j++; - } - } + for (i = 0; i < NUM_MAIN_STATS; i++) + data[index++] = ((unsigned long *) &priv->stats)[i]; + for (i = 0; i < NUM_PORT_STATS; i++) + data[index++] = ((unsigned long *) &priv->port_stats)[i]; for (i = 0; i < priv->tx_ring_num; i++) { data[index++] = priv->tx_ring[i].packets; data[index++] = priv->tx_ring[i].bytes; @@ -238,6 +217,8 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, data[index++] = priv->rx_ring[i].packets; data[index++] = priv->rx_ring[i].bytes; } + for (i = 0; i < NUM_PKT_STATS; i++) + data[index++] = ((unsigned long *) &priv->pkstats)[i]; spin_unlock_bh(&priv->stats_lock); } @@ -266,29 +247,11 @@ static void mlx4_en_get_strings(struct net_device *dev, case ETH_SS_STATS: /* Add main counters */ - if (!priv->stats_bitmap) { - for (i = 0; i < NUM_MAIN_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, - main_strings[i]); - for (i = 0; i < NUM_PORT_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, - main_strings[i + - NUM_MAIN_STATS]); - for (i = 0; i < NUM_PKT_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, - main_strings[i + - NUM_MAIN_STATS + - NUM_PORT_STATS]); - } else - for (i = 0; i < NUM_MAIN_STATS + NUM_PORT_STATS; i++) { - if ((priv->stats_bitmap >> i) & 1) { - strcpy(data + - (index++) * ETH_GSTRING_LEN, - main_strings[i]); - } - if (!(priv->stats_bitmap >> i)) - break; - } + for (i = 0; i < NUM_MAIN_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); + for (i = 0; i< NUM_PORT_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, + main_strings[i + NUM_MAIN_STATS]); for (i = 0; i < priv->tx_ring_num; i++) { sprintf(data + (index++) * ETH_GSTRING_LEN, "tx%d_packets", i); @@ -301,6 +264,9 @@ static void mlx4_en_get_strings(struct net_device *dev, sprintf(data + (index++) * ETH_GSTRING_LEN, "rx%d_bytes", i); } + for (i = 0; i< NUM_PKT_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, + main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]); break; } } @@ -513,95 +479,6 @@ static void mlx4_en_get_ringparam(struct net_device *dev, param->tx_pending = priv->tx_ring[0].size; } -static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - - return priv->rx_ring_num; -} - -static int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_rss_map *rss_map = &priv->rss_map; - int rss_rings; - size_t n = priv->rx_ring_num; - int err = 0; - - rss_rings = priv->prof->rss_rings ?: priv->rx_ring_num; - - while (n--) { - ring_index[n] = rss_map->qps[n % rss_rings].qpn - - rss_map->base_qpn; - } - - return err; -} - -static int mlx4_en_set_rxfh_indir(struct net_device *dev, - const u32 *ring_index) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - int port_up = 0; - int err = 0; - int i; - int rss_rings = 0; - - /* Calculate RSS table size and make sure flows are spread evenly - * between rings - */ - for (i = 0; i < priv->rx_ring_num; i++) { - if (i > 0 && !ring_index[i] && !rss_rings) - rss_rings = i; - - if (ring_index[i] != (i % (rss_rings ?: priv->rx_ring_num))) - return -EINVAL; - } - - if (!rss_rings) - rss_rings = priv->rx_ring_num; - - /* RSS table size must be an order of 2 */ - if (!is_power_of_2(rss_rings)) - return -EINVAL; - - mutex_lock(&mdev->state_lock); - if (priv->port_up) { - port_up = 1; - mlx4_en_stop_port(dev); - } - - priv->prof->rss_rings = rss_rings; - - if (port_up) { - err = mlx4_en_start_port(dev); - if (err) - en_err(priv, "Failed starting port\n"); - } - - mutex_unlock(&mdev->state_lock); - return err; -} - -static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, - u32 *rule_locs) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - int err = 0; - - switch (cmd->cmd) { - case ETHTOOL_GRXRINGS: - cmd->data = priv->rx_ring_num; - break; - default: - err = -EOPNOTSUPP; - break; - } - - return err; -} - const struct ethtool_ops mlx4_en_ethtool_ops = { .get_drvinfo = mlx4_en_get_drvinfo, .get_settings = mlx4_en_get_settings, @@ -621,10 +498,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .set_pauseparam = mlx4_en_set_pauseparam, .get_ringparam = mlx4_en_get_ringparam, .set_ringparam = mlx4_en_set_ringparam, - .get_rxnfc = mlx4_en_get_rxnfc, - .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, - .get_rxfh_indir = mlx4_en_get_rxfh_indir, - .set_rxfh_indir = mlx4_en_set_rxfh_indir, }; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_main.c index 2097a7d3c5b8..a06096fcc0b8 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_main.c @@ -62,6 +62,10 @@ static const char mlx4_en_version[] = * Device scope module parameters */ + +/* Enable RSS TCP traffic */ +MLX4_EN_PARM_INT(tcp_rss, 1, + "Enable RSS for incomming TCP traffic or disabled (0)"); /* Enable RSS UDP traffic */ MLX4_EN_PARM_INT(udp_rss, 1, "Enable RSS for incomming UDP traffic or disabled (0)"); @@ -100,6 +104,7 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) struct mlx4_en_profile *params = &mdev->profile; int i; + params->tcp_rss = tcp_rss; params->udp_rss = udp_rss; if (params->udp_rss && !(mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UDP_RSS)) { @@ -115,7 +120,6 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS + (!!pfcrx) * MLX4_EN_NUM_PPP_RINGS; - params->prof[i].rss_rings = 0; } return 0; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 467ae5824875..72fa807b69ce 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -702,8 +702,6 @@ int mlx4_en_start_port(struct net_device *dev) /* Schedule multicast task to populate multicast list */ queue_work(mdev->workqueue, &priv->mcast_task); - mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); - priv->port_up = true; netif_tx_start_all_queues(dev); return 0; @@ -809,50 +807,38 @@ static void mlx4_en_restart(struct work_struct *work) mutex_unlock(&mdev->state_lock); } -static void mlx4_en_clear_stats(struct net_device *dev) + +static int mlx4_en_open(struct net_device *dev) { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; int i; + int err = 0; + + mutex_lock(&mdev->state_lock); + + if (!mdev->device_up) { + en_err(priv, "Cannot open - device down/disabled\n"); + err = -EBUSY; + goto out; + } + /* Reset HW statistics and performance counters */ if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1)) en_dbg(HW, priv, "Failed dumping statistics\n"); memset(&priv->stats, 0, sizeof(priv->stats)); memset(&priv->pstats, 0, sizeof(priv->pstats)); - memset(&priv->pkstats, 0, sizeof(priv->pkstats)); - memset(&priv->port_stats, 0, sizeof(priv->port_stats)); for (i = 0; i < priv->tx_ring_num; i++) { priv->tx_ring[i].bytes = 0; priv->tx_ring[i].packets = 0; - priv->tx_ring[i].tx_csum = 0; } for (i = 0; i < priv->rx_ring_num; i++) { priv->rx_ring[i].bytes = 0; priv->rx_ring[i].packets = 0; - priv->rx_ring[i].csum_ok = 0; - priv->rx_ring[i].csum_none = 0; - } -} - -static int mlx4_en_open(struct net_device *dev) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - int err = 0; - - mutex_lock(&mdev->state_lock); - - if (!mdev->device_up) { - en_err(priv, "Cannot open - device down/disabled\n"); - err = -EBUSY; - goto out; } - /* Reset HW statistics and SW counters */ - mlx4_en_clear_stats(dev); - err = mlx4_en_start_port(dev); if (err) en_err(priv, "Failed starting port:%d\n", priv->port); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 971d4b6b8dfe..e8d6ad2dce0a 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -853,7 +853,6 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) struct mlx4_en_rss_map *rss_map = &priv->rss_map; struct mlx4_qp_context context; struct mlx4_rss_context *rss_context; - int rss_rings; void *ptr; u8 rss_mask = (MLX4_RSS_IPV4 | MLX4_RSS_TCP_IPV4 | MLX4_RSS_IPV6 | MLX4_RSS_TCP_IPV6); @@ -894,15 +893,10 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn, priv->rx_ring[0].cqn, &context); - if (!priv->prof->rss_rings || priv->prof->rss_rings > priv->rx_ring_num) - rss_rings = priv->rx_ring_num; - else - rss_rings = priv->prof->rss_rings; - ptr = ((void *) &context) + offsetof(struct mlx4_qp_context, pri_path) + MLX4_RSS_OFFSET_IN_QPC_PRI_PATH; rss_context = ptr; - rss_context->base_qpn = cpu_to_be32(ilog2(rss_rings) << 24 | + rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 | (rss_map->base_qpn)); rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn); if (priv->mdev->profile.udp_rss) { diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c b/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c index 55d7bd4e210a..1e9b55eb7217 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -513,22 +513,25 @@ int mlx4_MAP_EQ_wrapper(struct mlx4_dev *dev, int slave, { struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_slave_event_eq_info *event_eq = - priv->mfunc.master.slave_state[slave].event_eq; + &priv->mfunc.master.slave_state[slave].event_eq; u32 in_modifier = vhcr->in_modifier; u32 eqn = in_modifier & 0x1FF; u64 in_param = vhcr->in_param; int err = 0; - int i; if (slave == dev->caps.function) err = mlx4_cmd(dev, in_param, (in_modifier & 0x80000000) | eqn, 0, MLX4_CMD_MAP_EQ, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); - if (!err) - for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) - if (in_param & (1LL << i)) - event_eq[i].eqn = in_modifier >> 31 ? -1 : eqn; - + if (!err) { + if (in_modifier >> 31) { + /* unmap */ + event_eq->event_type &= ~in_param; + } else { + event_eq->eqn = eqn; + event_eq->event_type = in_param; + } + } return err; } @@ -543,7 +546,7 @@ static int mlx4_MAP_EQ(struct mlx4_dev *dev, u64 event_mask, int unmap, static int mlx4_SW2HW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, int eq_num) { - return mlx4_cmd(dev, mailbox->dma, eq_num, 0, + return mlx4_cmd(dev, mailbox->dma | dev->caps.function, eq_num, 0, MLX4_CMD_SW2HW_EQ, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); } @@ -551,7 +554,7 @@ static int mlx4_SW2HW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, static int mlx4_HW2SW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, int eq_num) { - return mlx4_cmd_box(dev, 0, mailbox->dma, eq_num, + return mlx4_cmd_box(dev, dev->caps.function, mailbox->dma, eq_num, 0, MLX4_CMD_HW2SW_EQ, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c index 8a21e10952ea..a424a19280cc 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -158,6 +158,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 +#define QUERY_FUNC_CAP_FUNCTION_OFFSET 0x3 #define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 #define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10 #define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14 @@ -181,6 +182,9 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, field = 1 << 7; /* enable only ethernet interface */ MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); + field = slave; + MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FUNCTION_OFFSET); + field = dev->caps.num_ports; MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); @@ -245,6 +249,9 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap) goto out; } + MLX4_GET(field, outbox, QUERY_FUNC_CAP_FUNCTION_OFFSET); + func_cap->function = field; + MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); func_cap->num_ports = field; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.h b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.h index e1a5fa56bcbc..119e0cc9fab3 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -119,6 +119,7 @@ struct mlx4_dev_cap { }; struct mlx4_func_cap { + u8 function; u8 num_ports; u8 flags; u32 pf_context_behaviour; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c index 678558b502fc..6bb62c580e2d 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c @@ -108,7 +108,7 @@ static struct mlx4_profile default_profile = { .num_cq = 1 << 16, .num_mcg = 1 << 13, .num_mpt = 1 << 19, - .num_mtt = 1 << 20, /* It is really num mtt segements */ + .num_mtt = 1 << 20, }; static int log_num_mac = 7; @@ -471,6 +471,7 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) return -ENOSYS; } + dev->caps.function = func_cap.function; dev->caps.num_ports = func_cap.num_ports; dev->caps.num_qps = func_cap.qp_quota; dev->caps.num_srqs = func_cap.srq_quota; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h index c92269f8c057..a80121a2b519 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -388,8 +388,9 @@ struct mlx4_slave_eqe { }; struct mlx4_slave_event_eq_info { - int eqn; + u32 eqn; u16 token; + u64 event_type; }; struct mlx4_profile { @@ -448,8 +449,6 @@ struct mlx4_steer_index { struct list_head duplicates; }; -#define MLX4_EVENT_TYPES_NUM 64 - struct mlx4_slave_state { u8 comm_toggle; u8 last_cmd; @@ -462,8 +461,7 @@ struct mlx4_slave_state { struct mlx4_slave_eqe eq[MLX4_MFUNC_MAX_EQES]; struct list_head mcast_filters[MLX4_MAX_PORTS + 1]; struct mlx4_vlan_fltr *vlan_filter[MLX4_MAX_PORTS + 1]; - /* event type to eq number lookup */ - struct mlx4_slave_event_eq_info event_eq[MLX4_EVENT_TYPES_NUM]; + struct mlx4_slave_event_eq_info event_eq; u16 eq_pi; u16 eq_ci; spinlock_t lock; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 35f08840813c..f2a8e65f5f88 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -325,11 +325,11 @@ struct mlx4_en_port_profile { u8 rx_ppp; u8 tx_pause; u8 tx_ppp; - int rss_rings; }; struct mlx4_en_profile { int rss_xor; + int tcp_rss; int udp_rss; u8 rss_mask; u32 active_ports; @@ -476,7 +476,6 @@ struct mlx4_en_priv { struct mlx4_en_perf_stats pstats; struct mlx4_en_pkt_stats pkstats; struct mlx4_en_port_stats port_stats; - u64 stats_bitmap; char *mc_addrs; int mc_addrs_cnt; struct mlx4_en_stat_out_mbox hw_stats; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c b/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c index 8deeef98280c..01df5567e16e 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -291,7 +291,7 @@ static u32 key_to_hw_index(u32 key) static int mlx4_SW2HW_MPT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, int mpt_index) { - return mlx4_cmd(dev, mailbox->dma, mpt_index, + return mlx4_cmd(dev, mailbox->dma | dev->caps.function , mpt_index, 0, MLX4_CMD_SW2HW_MPT, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c b/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c index db4746d0dca7..5c9a54df17ab 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c @@ -52,7 +52,8 @@ int mlx4_pd_alloc(struct mlx4_dev *dev, u32 *pdn) *pdn = mlx4_bitmap_alloc(&priv->pd_bitmap); if (*pdn == -1) return -ENOMEM; - + if (mlx4_is_mfunc(dev)) + *pdn |= (dev->caps.function + 1) << NOT_MASKED_PD_BITS; return 0; } EXPORT_SYMBOL_GPL(mlx4_pd_alloc); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/port.c b/trunk/drivers/net/ethernet/mellanox/mlx4/port.c index f44ae555bf43..88b52e547524 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/port.c @@ -44,11 +44,6 @@ #define MLX4_VLAN_VALID (1u << 31) #define MLX4_VLAN_MASK 0xfff -#define MLX4_STATS_TRAFFIC_COUNTERS_MASK 0xfULL -#define MLX4_STATS_TRAFFIC_DROPS_MASK 0xc0ULL -#define MLX4_STATS_ERROR_COUNTERS_MASK 0x1ffc30ULL -#define MLX4_STATS_PORT_COUNTERS_MASK 0x1fe00000ULL - void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table) { int i; @@ -903,24 +898,6 @@ int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd) { - if (slave != dev->caps.function) - return 0; return mlx4_common_dump_eth_stats(dev, slave, vhcr->in_modifier, outbox); } - -void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap) -{ - if (!mlx4_is_mfunc(dev)) { - *stats_bitmap = 0; - return; - } - - *stats_bitmap = (MLX4_STATS_TRAFFIC_COUNTERS_MASK | - MLX4_STATS_TRAFFIC_DROPS_MASK | - MLX4_STATS_PORT_COUNTERS_MASK); - - if (mlx4_is_master(dev)) - *stats_bitmap |= MLX4_STATS_ERROR_COUNTERS_MASK; -} -EXPORT_SYMBOL(mlx4_set_stats_bitmap); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/profile.c b/trunk/drivers/net/ethernet/mellanox/mlx4/profile.c index 1129677daa62..66f91ca7a7c6 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/profile.c @@ -110,7 +110,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, profile[MLX4_RES_EQ].num = min_t(unsigned, dev_cap->max_eqs, MAX_MSIX); profile[MLX4_RES_DMPT].num = request->num_mpt; profile[MLX4_RES_CMPT].num = MLX4_NUM_CMPTS; - profile[MLX4_RES_MTT].num = request->num_mtt * (1 << log_mtts_per_seg); + profile[MLX4_RES_MTT].num = request->num_mtt; profile[MLX4_RES_MCG].num = request->num_mcg; for (i = 0; i < MLX4_RES_NUM; ++i) { diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/qp.c b/trunk/drivers/net/ethernet/mellanox/mlx4/qp.c index 738f950a1ce5..6b03ac8b9002 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -162,7 +162,7 @@ static int __mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, ((struct mlx4_qp_context *) (mailbox->buf + 8))->local_qpn = cpu_to_be32(qp->qpn); - ret = mlx4_cmd(dev, mailbox->dma, + ret = mlx4_cmd(dev, mailbox->dma | dev->caps.function, qp->qpn | (!!sqd_event << 31), new_state == MLX4_QP_STATE_RST ? 2 : 0, op[cur_state][new_state], MLX4_CMD_TIME_CLASS_C, native); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index dcd819bfb2f0..ed20751a057d 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -1561,6 +1561,11 @@ static int mr_get_mtt_size(struct mlx4_mpt_entry *mpt) return be32_to_cpu(mpt->mtt_sz); } +static int mr_get_pdn(struct mlx4_mpt_entry *mpt) +{ + return be32_to_cpu(mpt->pd_flags) & 0xffffff; +} + static int qp_get_mtt_addr(struct mlx4_qp_context *qpc) { return be32_to_cpu(qpc->mtt_base_addr_l) & 0xfffffff8; @@ -1597,6 +1602,16 @@ static int qp_get_mtt_size(struct mlx4_qp_context *qpc) return total_pages; } +static int qp_get_pdn(struct mlx4_qp_context *qpc) +{ + return be32_to_cpu(qpc->pd) & 0xffffff; +} + +static int pdn2slave(int pdn) +{ + return (pdn >> NOT_MASKED_PD_BITS) - 1; +} + static int check_mtt_range(struct mlx4_dev *dev, int slave, int start, int size, struct res_mtt *mtt) { @@ -1641,6 +1656,11 @@ int mlx4_SW2HW_MPT_wrapper(struct mlx4_dev *dev, int slave, mpt->mtt = mtt; } + if (pdn2slave(mr_get_pdn(inbox->buf)) != slave) { + err = -EPERM; + goto ex_put; + } + err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); if (err) goto ex_put; @@ -1772,6 +1792,11 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave, if (err) goto ex_put_mtt; + if (pdn2slave(qp_get_pdn(qpc)) != slave) { + err = -EPERM; + goto ex_put_mtt; + } + err = get_res(dev, slave, rcqn, RES_CQ, &rcq); if (err) goto ex_put_mtt; @@ -2023,10 +2048,10 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe) if (!priv->mfunc.master.slave_state) return -EINVAL; - event_eq = &priv->mfunc.master.slave_state[slave].event_eq[eqe->type]; + event_eq = &priv->mfunc.master.slave_state[slave].event_eq; /* Create the event only if the slave is registered */ - if (event_eq->eqn < 0) + if ((event_eq->event_type & (1 << eqe->type)) == 0) return 0; mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]); @@ -2264,6 +2289,11 @@ int mlx4_MODIFY_CQ_wrapper(struct mlx4_dev *dev, int slave, return err; } +static int srq_get_pdn(struct mlx4_srq_context *srqc) +{ + return be32_to_cpu(srqc->pd) & 0xffffff; +} + static int srq_get_mtt_size(struct mlx4_srq_context *srqc) { int log_srq_size = (be32_to_cpu(srqc->state_logsize_srqn) >> 24) & 0xf; @@ -2303,6 +2333,11 @@ int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave, if (err) goto ex_put_mtt; + if (pdn2slave(srq_get_pdn(srqc)) != slave) { + err = -EPERM; + goto ex_put_mtt; + } + err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); if (err) goto ex_put_mtt; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/srq.c b/trunk/drivers/net/ethernet/mellanox/mlx4/srq.c index feda6c00829f..2823fffc6383 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/srq.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/srq.c @@ -67,7 +67,7 @@ void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type) static int mlx4_SW2HW_SRQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, int srq_num) { - return mlx4_cmd(dev, mailbox->dma, srq_num, 0, + return mlx4_cmd(dev, mailbox->dma | dev->caps.function, srq_num, 0, MLX4_CMD_SW2HW_SRQ, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); } diff --git a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 3ead111111e1..964e9c0948bc 100644 --- a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -1745,12 +1745,6 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; int err; - /* Ensure we have a valid MAC */ - if (!is_valid_ether_addr(adapter->hw.mac.addr)) { - pr_err("Error: Invalid MAC address\n"); - return -EINVAL; - } - /* hardware has been reset, we need to reload some things */ pch_gbe_set_multi(netdev); @@ -2474,14 +2468,9 @@ static int pch_gbe_probe(struct pci_dev *pdev, memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); if (!is_valid_ether_addr(netdev->dev_addr)) { - /* - * If the MAC is invalid (or just missing), display a warning - * but do not abort setting up the device. pch_gbe_up will - * prevent the interface from being brought up until a valid MAC - * is set. - */ - dev_err(&pdev->dev, "Invalid MAC address, " - "interface disabled.\n"); + dev_err(&pdev->dev, "Invalid MAC Address\n"); + ret = -EIO; + goto err_free_adapter; } setup_timer(&adapter->watchdog_timer, pch_gbe_watchdog, (unsigned long)adapter); diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index 73195329aa46..da4a1042523a 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -154,7 +154,7 @@ int stmmac_mdio_register(struct net_device *ndev) else irqlist = priv->mii_irq; - new_bus->name = "stmmac"; + new_bus->name = "STMMAC MII Bus"; new_bus->read = &stmmac_mdio_read; new_bus->write = &stmmac_mdio_write; new_bus->reset = &stmmac_mdio_reset; diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index c796de9eed72..54a819a36487 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -170,9 +170,9 @@ static int stmmac_pci_resume(struct pci_dev *pdev) #define STMMAC_DEVICE_ID 0x1108 static DEFINE_PCI_DEVICE_TABLE(stmmac_id_table) = { - {PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, - {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)}, - {} + { + PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, { + } }; MODULE_DEVICE_TABLE(pci, stmmac_id_table); diff --git a/trunk/drivers/net/hyperv/netvsc_drv.c b/trunk/drivers/net/hyperv/netvsc_drv.c index 1a1ca6cfc74a..462d05f05e84 100644 --- a/trunk/drivers/net/hyperv/netvsc_drv.c +++ b/trunk/drivers/net/hyperv/netvsc_drv.c @@ -68,11 +68,11 @@ static void do_set_multicast(struct work_struct *w) nvdev = hv_get_drvdata(ndevctx->device_ctx); if (nvdev == NULL) - goto out; + return; rdev = nvdev->extension; if (rdev == NULL) - goto out; + return; if (net->flags & IFF_PROMISC) rndis_filter_set_packet_filter(rdev, @@ -83,7 +83,6 @@ static void do_set_multicast(struct work_struct *w) NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_DIRECTED); -out: kfree(w); } diff --git a/trunk/drivers/net/macvlan.c b/trunk/drivers/net/macvlan.c index 9ea99217f116..f2f820c4b40a 100644 --- a/trunk/drivers/net/macvlan.c +++ b/trunk/drivers/net/macvlan.c @@ -173,7 +173,6 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN); if (!skb) return RX_HANDLER_CONSUMED; - eth = eth_hdr(skb); src = macvlan_hash_lookup(port, eth->h_source); if (!src) /* frame comes from an external address */ diff --git a/trunk/drivers/net/phy/mdio_bus.c b/trunk/drivers/net/phy/mdio_bus.c index 8985cc62cf41..88cc5db9affd 100644 --- a/trunk/drivers/net/phy/mdio_bus.c +++ b/trunk/drivers/net/phy/mdio_bus.c @@ -38,11 +38,12 @@ /** * mdiobus_alloc_size - allocate a mii_bus structure - * @size: extra amount of memory to allocate for private storage. - * If non-zero, then bus->priv is points to that memory. * * Description: called by a bus driver to allocate an mii_bus * structure to fill in. + * + * 'size' is an an extra amount of memory to allocate for private storage. + * If non-zero, then bus->priv is points to that memory. */ struct mii_bus *mdiobus_alloc_size(size_t size) { diff --git a/trunk/drivers/net/team/team.c b/trunk/drivers/net/team/team.c index 6b678f38e5ce..ed2a862b835d 100644 --- a/trunk/drivers/net/team/team.c +++ b/trunk/drivers/net/team/team.c @@ -92,9 +92,9 @@ struct team_option *__team_find_option(struct team *team, const char *opt_name) return NULL; } -int __team_options_register(struct team *team, - const struct team_option *option, - size_t option_count) +int team_options_register(struct team *team, + const struct team_option *option, + size_t option_count) { int i; struct team_option **dst_opts; @@ -116,11 +116,8 @@ int __team_options_register(struct team *team, } } - for (i = 0; i < option_count; i++) { - dst_opts[i]->changed = true; - dst_opts[i]->removed = false; + for (i = 0; i < option_count; i++) list_add_tail(&dst_opts[i]->list, &team->option_list); - } kfree(dst_opts); return 0; @@ -133,22 +130,10 @@ int __team_options_register(struct team *team, return err; } -static void __team_options_mark_removed(struct team *team, - const struct team_option *option, - size_t option_count) -{ - int i; - - for (i = 0; i < option_count; i++, option++) { - struct team_option *del_opt; +EXPORT_SYMBOL(team_options_register); - del_opt = __team_find_option(team, option->name); - if (del_opt) { - del_opt->changed = true; - del_opt->removed = true; - } - } -} +static void __team_options_change_check(struct team *team, + struct team_option *changed_option); static void __team_options_unregister(struct team *team, const struct team_option *option, @@ -167,29 +152,12 @@ static void __team_options_unregister(struct team *team, } } -static void __team_options_change_check(struct team *team); - -int team_options_register(struct team *team, - const struct team_option *option, - size_t option_count) -{ - int err; - - err = __team_options_register(team, option, option_count); - if (err) - return err; - __team_options_change_check(team); - return 0; -} -EXPORT_SYMBOL(team_options_register); - void team_options_unregister(struct team *team, const struct team_option *option, size_t option_count) { - __team_options_mark_removed(team, option, option_count); - __team_options_change_check(team); __team_options_unregister(team, option, option_count); + __team_options_change_check(team, NULL); } EXPORT_SYMBOL(team_options_unregister); @@ -208,8 +176,7 @@ static int team_option_set(struct team *team, struct team_option *option, if (err) return err; - option->changed = true; - __team_options_change_check(team); + __team_options_change_check(team, option); return err; } @@ -686,7 +653,6 @@ static int team_port_del(struct team *team, struct net_device *port_dev) return -ENOENT; } - port->removed = true; __team_port_change_check(port, false); team_port_list_del_port(team, port); team_adjust_ops(team); @@ -1234,9 +1200,10 @@ static int team_nl_send_generic(struct genl_info *info, struct team *team, return err; } -static int team_nl_fill_options_get(struct sk_buff *skb, - u32 pid, u32 seq, int flags, - struct team *team, bool fillall) +static int team_nl_fill_options_get_changed(struct sk_buff *skb, + u32 pid, u32 seq, int flags, + struct team *team, + struct team_option *changed_option) { struct nlattr *option_list; void *hdr; @@ -1256,19 +1223,12 @@ static int team_nl_fill_options_get(struct sk_buff *skb, struct nlattr *option_item; long arg; - /* Include only changed options if fill all mode is not on */ - if (!fillall && !option->changed) - continue; option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION); if (!option_item) goto nla_put_failure; NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_NAME, option->name); - if (option->changed) { + if (option == changed_option) NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_CHANGED); - option->changed = false; - } - if (option->removed) - NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_REMOVED); switch (option->type) { case TEAM_OPTION_TYPE_U32: NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32); @@ -1295,13 +1255,13 @@ static int team_nl_fill_options_get(struct sk_buff *skb, return -EMSGSIZE; } -static int team_nl_fill_options_get_all(struct sk_buff *skb, - struct genl_info *info, int flags, - struct team *team) +static int team_nl_fill_options_get(struct sk_buff *skb, + struct genl_info *info, int flags, + struct team *team) { - return team_nl_fill_options_get(skb, info->snd_pid, - info->snd_seq, NLM_F_ACK, - team, true); + return team_nl_fill_options_get_changed(skb, info->snd_pid, + info->snd_seq, NLM_F_ACK, + team, NULL); } static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info) @@ -1313,7 +1273,7 @@ static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info) if (!team) return -EINVAL; - err = team_nl_send_generic(info, team, team_nl_fill_options_get_all); + err = team_nl_send_generic(info, team, team_nl_fill_options_get); team_nl_team_put(team); @@ -1405,10 +1365,10 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) return err; } -static int team_nl_fill_port_list_get(struct sk_buff *skb, - u32 pid, u32 seq, int flags, - struct team *team, - bool fillall) +static int team_nl_fill_port_list_get_changed(struct sk_buff *skb, + u32 pid, u32 seq, int flags, + struct team *team, + struct team_port *changed_port) { struct nlattr *port_list; void *hdr; @@ -1427,19 +1387,12 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb, list_for_each_entry(port, &team->port_list, list) { struct nlattr *port_item; - /* Include only changed ports if fill all mode is not on */ - if (!fillall && !port->changed) - continue; port_item = nla_nest_start(skb, TEAM_ATTR_ITEM_PORT); if (!port_item) goto nla_put_failure; NLA_PUT_U32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex); - if (port->changed) { + if (port == changed_port) NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_CHANGED); - port->changed = false; - } - if (port->removed) - NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_REMOVED); if (port->linkup) NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_LINKUP); NLA_PUT_U32(skb, TEAM_ATTR_PORT_SPEED, port->speed); @@ -1455,13 +1408,13 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb, return -EMSGSIZE; } -static int team_nl_fill_port_list_get_all(struct sk_buff *skb, - struct genl_info *info, int flags, - struct team *team) +static int team_nl_fill_port_list_get(struct sk_buff *skb, + struct genl_info *info, int flags, + struct team *team) { - return team_nl_fill_port_list_get(skb, info->snd_pid, - info->snd_seq, NLM_F_ACK, - team, true); + return team_nl_fill_port_list_get_changed(skb, info->snd_pid, + info->snd_seq, NLM_F_ACK, + team, NULL); } static int team_nl_cmd_port_list_get(struct sk_buff *skb, @@ -1474,7 +1427,7 @@ static int team_nl_cmd_port_list_get(struct sk_buff *skb, if (!team) return -EINVAL; - err = team_nl_send_generic(info, team, team_nl_fill_port_list_get_all); + err = team_nl_send_generic(info, team, team_nl_fill_port_list_get); team_nl_team_put(team); @@ -1511,7 +1464,8 @@ static struct genl_multicast_group team_change_event_mcgrp = { .name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME, }; -static int team_nl_send_event_options_get(struct team *team) +static int team_nl_send_event_options_get(struct team *team, + struct team_option *changed_option) { struct sk_buff *skb; int err; @@ -1521,7 +1475,8 @@ static int team_nl_send_event_options_get(struct team *team) if (!skb) return -ENOMEM; - err = team_nl_fill_options_get(skb, 0, 0, 0, team, false); + err = team_nl_fill_options_get_changed(skb, 0, 0, 0, team, + changed_option); if (err < 0) goto err_fill; @@ -1534,17 +1489,18 @@ static int team_nl_send_event_options_get(struct team *team) return err; } -static int team_nl_send_event_port_list_get(struct team *team) +static int team_nl_send_event_port_list_get(struct team_port *port) { struct sk_buff *skb; int err; - struct net *net = dev_net(team->dev); + struct net *net = dev_net(port->team->dev); skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); if (!skb) return -ENOMEM; - err = team_nl_fill_port_list_get(skb, 0, 0, 0, team, false); + err = team_nl_fill_port_list_get_changed(skb, 0, 0, 0, + port->team, port); if (err < 0) goto err_fill; @@ -1588,11 +1544,12 @@ static void team_nl_fini(void) * Change checkers ******************/ -static void __team_options_change_check(struct team *team) +static void __team_options_change_check(struct team *team, + struct team_option *changed_option) { int err; - err = team_nl_send_event_options_get(team); + err = team_nl_send_event_options_get(team, changed_option); if (err) netdev_warn(team->dev, "Failed to send options change via netlink\n"); } @@ -1602,10 +1559,9 @@ static void __team_port_change_check(struct team_port *port, bool linkup) { int err; - if (!port->removed && port->linkup == linkup) + if (port->linkup == linkup) return; - port->changed = true; port->linkup = linkup; if (linkup) { struct ethtool_cmd ecmd; @@ -1621,7 +1577,7 @@ static void __team_port_change_check(struct team_port *port, bool linkup) port->duplex = 0; send_event: - err = team_nl_send_event_port_list_get(port->team); + err = team_nl_send_event_port_list_get(port); if (err) netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink\n", port->dev->name); diff --git a/trunk/drivers/net/wireless/b43/Kconfig b/trunk/drivers/net/wireless/b43/Kconfig index 3876c7ea54f4..b97a40ed5fff 100644 --- a/trunk/drivers/net/wireless/b43/Kconfig +++ b/trunk/drivers/net/wireless/b43/Kconfig @@ -31,12 +31,6 @@ config B43_BCMA depends on B43 && BCMA default y -config B43_BCMA_EXTRA - bool "Hardware support that overlaps with the brcmsmac driver" - depends on B43_BCMA - default n if BRCMSMAC || BRCMSMAC_MODULE - default y - config B43_SSB bool depends on B43 && SSB diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 23ffb1b9a86f..b91f28ef1032 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -116,10 +116,8 @@ MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); #ifdef CONFIG_B43_BCMA static const struct bcma_device_id b43_bcma_tbl[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS), -#ifdef CONFIG_B43_BCMA_EXTRA BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), -#endif BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), BCMA_CORETABLE_END }; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index f6affc6fd12a..f7ed34034f88 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -7981,21 +7981,13 @@ int brcms_c_get_curband(struct brcms_c_info *wlc) void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) { - int timeout = 20; - /* flush packet queue when requested */ if (drop) brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); /* wait for queue and DMA fifos to run dry */ - while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) { + while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) brcms_msleep(wlc->wl, 1); - - if (--timeout == 0) - break; - } - - WARN_ON_ONCE(timeout == 0); } void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 65d1f05007be..752493f00406 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -972,11 +972,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) } #endif + spin_unlock_irqrestore(&trans->shrd->lock, flags); + /* saved interrupt in inta variable now we can reset trans_pcie->inta */ trans_pcie->inta = 0; - spin_unlock_irqrestore(&trans->shrd->lock, flags); - /* Now service all interrupt bits discovered above. */ if (inta & CSR_INT_BIT_HW_ERR) { IWL_ERR(trans, "Hardware error detected. Restarting.\n"); diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index 698b905058dd..fa679057630f 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -68,7 +68,7 @@ struct netfront_cb { #define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) -#define TX_MAX_TARGET min_t(int, NET_TX_RING_SIZE, 256) +#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) struct netfront_stats { u64 rx_packets; diff --git a/trunk/drivers/pcmcia/sa1111_generic.c b/trunk/drivers/pcmcia/sa1111_generic.c index 27f2fe3b7fb4..59866905ea37 100644 --- a/trunk/drivers/pcmcia/sa1111_generic.c +++ b/trunk/drivers/pcmcia/sa1111_generic.c @@ -205,8 +205,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev) dev_set_drvdata(&dev->dev, NULL); - for (; s; s = next) { - next = s->next; + for (; next = s->next, s; s = next) { soc_pcmcia_remove_one(&s->soc); kfree(s); } diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index 8fe15cf15ac8..569bdb3ef104 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -510,12 +510,10 @@ static struct dentry *debugfs_root; static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) { - struct dentry *device_root; + static struct dentry *device_root; device_root = debugfs_create_dir(dev_name(pctldev->dev), debugfs_root); - pctldev->device_root = device_root; - if (IS_ERR(device_root) || !device_root) { pr_warn("failed to create debugfs directory for %s\n", dev_name(pctldev->dev)); @@ -531,11 +529,6 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) pinconf_init_device_debugfs(device_root, pctldev); } -static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) -{ - debugfs_remove_recursive(pctldev->device_root); -} - static void pinctrl_init_debugfs(void) { debugfs_root = debugfs_create_dir("pinctrl", NULL); @@ -560,10 +553,6 @@ static void pinctrl_init_debugfs(void) { } -static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) -{ -} - #endif /** @@ -583,40 +572,40 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, if (pctldesc->name == NULL) return NULL; - pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); - if (pctldev == NULL) - return NULL; - - /* Initialize pin control device struct */ - pctldev->owner = pctldesc->owner; - pctldev->desc = pctldesc; - pctldev->driver_data = driver_data; - INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); - spin_lock_init(&pctldev->pin_desc_tree_lock); - INIT_LIST_HEAD(&pctldev->gpio_ranges); - mutex_init(&pctldev->gpio_ranges_lock); - pctldev->dev = dev; - /* If we're implementing pinmuxing, check the ops for sanity */ if (pctldesc->pmxops) { - ret = pinmux_check_ops(pctldev); + ret = pinmux_check_ops(pctldesc->pmxops); if (ret) { pr_err("%s pinmux ops lacks necessary functions\n", pctldesc->name); - goto out_err; + return NULL; } } /* If we're implementing pinconfig, check the ops for sanity */ if (pctldesc->confops) { - ret = pinconf_check_ops(pctldev); + ret = pinconf_check_ops(pctldesc->confops); if (ret) { pr_err("%s pin config ops lacks necessary functions\n", pctldesc->name); - goto out_err; + return NULL; } } + pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); + if (pctldev == NULL) + return NULL; + + /* Initialize pin control device struct */ + pctldev->owner = pctldesc->owner; + pctldev->desc = pctldesc; + pctldev->driver_data = driver_data; + INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); + spin_lock_init(&pctldev->pin_desc_tree_lock); + INIT_LIST_HEAD(&pctldev->gpio_ranges); + mutex_init(&pctldev->gpio_ranges_lock); + pctldev->dev = dev; + /* Register all the pins */ pr_debug("try to register %d pins on %s...\n", pctldesc->npins, pctldesc->name); @@ -652,7 +641,6 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) if (pctldev == NULL) return; - pinctrl_remove_device_debugfs(pctldev); pinmux_unhog_maps(pctldev); /* TODO: check that no pinmuxes are still active? */ mutex_lock(&pinctrldev_list_mutex); diff --git a/trunk/drivers/pinctrl/core.h b/trunk/drivers/pinctrl/core.h index cfa86da6b4b1..177a3310547f 100644 --- a/trunk/drivers/pinctrl/core.h +++ b/trunk/drivers/pinctrl/core.h @@ -41,9 +41,6 @@ struct pinctrl_dev { struct device *dev; struct module *owner; void *driver_data; -#ifdef CONFIG_DEBUG_FS - struct dentry *device_root; -#endif #ifdef CONFIG_PINMUX struct mutex pinmux_hogs_lock; struct list_head pinmux_hogs; diff --git a/trunk/drivers/pinctrl/pinconf.c b/trunk/drivers/pinctrl/pinconf.c index 9fb75456824c..1259872b0a1d 100644 --- a/trunk/drivers/pinctrl/pinconf.c +++ b/trunk/drivers/pinctrl/pinconf.c @@ -205,10 +205,8 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, } EXPORT_SYMBOL(pin_config_group_set); -int pinconf_check_ops(struct pinctrl_dev *pctldev) +int pinconf_check_ops(const struct pinconf_ops *ops) { - const struct pinconf_ops *ops = pctldev->desc->confops; - /* We must be able to read out pin status */ if (!ops->pin_config_get && !ops->pin_config_group_get) return -EINVAL; @@ -238,7 +236,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what) seq_puts(s, "Format: pin (name): pinmux setting array\n"); /* The pin number can be retrived from the pin controller descriptor */ - for (i = 0; i < pctldev->desc->npins; i++) { + for (i = 0; pin < pctldev->desc->npins; i++) { struct pin_desc *desc; pin = pctldev->desc->pins[i].number; diff --git a/trunk/drivers/pinctrl/pinconf.h b/trunk/drivers/pinctrl/pinconf.h index 006b77fa737e..e7dc6165032a 100644 --- a/trunk/drivers/pinctrl/pinconf.h +++ b/trunk/drivers/pinctrl/pinconf.h @@ -13,7 +13,7 @@ #ifdef CONFIG_PINCONF -int pinconf_check_ops(struct pinctrl_dev *pctldev); +int pinconf_check_ops(const struct pinconf_ops *ops); void pinconf_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, @@ -23,7 +23,7 @@ int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin, #else -static inline int pinconf_check_ops(struct pinctrl_dev *pctldev) +static inline int pinconf_check_ops(const struct pinconf_ops *ops) { return 0; } diff --git a/trunk/drivers/pinctrl/pinmux.c b/trunk/drivers/pinctrl/pinmux.c index 7c3193f7a044..a76a348321bb 100644 --- a/trunk/drivers/pinctrl/pinmux.c +++ b/trunk/drivers/pinctrl/pinmux.c @@ -53,6 +53,11 @@ struct pinmux_group { * @dev: the device using this pinmux * @usecount: the number of active users of this mux setting, used to keep * track of nested use cases + * @pins: an array of discrete physical pins used in this mapping, taken + * from the global pin enumeration space (copied from pinmux map) + * @num_pins: the number of pins in this mapping array, i.e. the number of + * elements in .pins so we can iterate over that array (copied from + * pinmux map) * @pctldev: pin control device handling this pinmux * @func_selector: the function selector for the pinmux device handling * this pinmux @@ -147,7 +152,8 @@ static int pin_request(struct pinctrl_dev *pctldev, status = 0; if (status) - dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", + dev_err(pctldev->dev, "->request on device %s failed " + "for pin %d\n", pctldev->desc->name, pin); out_free_pin: if (status) { @@ -349,20 +355,21 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, /* First sanity check the new mapping */ for (i = 0; i < num_maps; i++) { if (!maps[i].name) { - pr_err("failed to register map %d: no map name given\n", - i); + pr_err("failed to register map %d: " + "no map name given\n", i); return -EINVAL; } if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { - pr_err("failed to register map %s (%d): no pin control device given\n", + pr_err("failed to register map %s (%d): " + "no pin control device given\n", maps[i].name, i); return -EINVAL; } if (!maps[i].function) { - pr_err("failed to register map %s (%d): no function ID given\n", - maps[i].name, i); + pr_err("failed to register map %s (%d): " + "no function ID given\n", maps[i].name, i); return -EINVAL; } @@ -404,7 +411,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, } /** - * acquire_pins() - acquire all the pins for a certain function on a pinmux + * acquire_pins() - acquire all the pins for a certain funcion on a pinmux * @pctldev: the device to take the pins on * @func_selector: the function selector to acquire the pins for * @group_selector: the group selector containing the pins to acquire @@ -435,7 +442,8 @@ static int acquire_pins(struct pinctrl_dev *pctldev, ret = pin_request(pctldev, pins[i], func, NULL); if (ret) { dev_err(pctldev->dev, - "could not get pin %d for function %s on device %s - conflicting mux mappings?\n", + "could not get pin %d for function %s " + "on device %s - conflicting mux mappings?\n", pins[i], func ? : "(undefined)", pinctrl_dev_get_name(pctldev)); /* On error release all taken pins */ @@ -450,7 +458,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev, /** * release_pins() - release pins taken by earlier acquirement - * @pctldev: the device to free the pins on + * @pctldev: the device to free the pinx on * @group_selector: the group selector containing the pins to free */ static void release_pins(struct pinctrl_dev *pctldev, @@ -465,7 +473,8 @@ static void release_pins(struct pinctrl_dev *pctldev, ret = pctlops->get_group_pins(pctldev, group_selector, &pins, &num_pins); if (ret) { - dev_err(pctldev->dev, "could not get pins to release for group selector %d\n", + dev_err(pctldev->dev, "could not get pins to release for " + "group selector %d\n", group_selector); return; } @@ -517,7 +526,8 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, ret = pinctrl_get_group_selector(pctldev, groups[0]); if (ret < 0) { dev_err(pctldev->dev, - "function %s wants group %s but the pin controller does not seem to have that group\n", + "function %s wants group %s but the pin " + "controller does not seem to have that group\n", pmxops->get_function_name(pctldev, func_selector), groups[0]); return ret; @@ -525,7 +535,8 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, if (num_groups > 1) dev_dbg(pctldev->dev, - "function %s support more than one group, default-selecting first group %s (%d)\n", + "function %s support more than one group, " + "default-selecting first group %s (%d)\n", pmxops->get_function_name(pctldev, func_selector), groups[0], ret); @@ -617,8 +628,10 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, if (pmx->pctldev && pmx->pctldev != pctldev) { dev_err(pctldev->dev, - "different pin control devices given for device %s, function %s\n", - devname, map->function); + "different pin control devices given for device %s, " + "function %s\n", + devname, + map->function); return -EINVAL; } pmx->dev = dev; @@ -682,6 +695,7 @@ static void pinmux_free_groups(struct pinmux *pmx) */ struct pinmux *pinmux_get(struct device *dev, const char *name) { + struct pinmux_map const *map = NULL; struct pinctrl_dev *pctldev = NULL; const char *devname = NULL; @@ -731,7 +745,8 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) else if (map->ctrl_dev_name) devname = map->ctrl_dev_name; - pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", + pr_warning("could not find a pinctrl device for pinmux " + "function %s, fishy, they shall all have one\n", map->function); pr_warning("given pinctrl device name: %s", devname ? devname : "UNDEFINED"); @@ -889,11 +904,8 @@ void pinmux_disable(struct pinmux *pmx) } EXPORT_SYMBOL_GPL(pinmux_disable); -int pinmux_check_ops(struct pinctrl_dev *pctldev) +int pinmux_check_ops(const struct pinmux_ops *ops) { - const struct pinmux_ops *ops = pctldev->desc->pmxops; - unsigned selector = 0; - /* Check that we implement required operations */ if (!ops->list_functions || !ops->get_function_name || @@ -902,18 +914,6 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) !ops->disable) return -EINVAL; - /* Check that all functions registered have names */ - while (ops->list_functions(pctldev, selector) >= 0) { - const char *fname = ops->get_function_name(pctldev, - selector); - if (!fname) { - pr_err("pinmux ops has no name for function%u\n", - selector); - return -EINVAL; - } - selector++; - } - return 0; } @@ -932,8 +932,8 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, * without any problems, so then we can hog pinmuxes for * all devices that just want a static pin mux at this point. */ - dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n", - map->name); + dev_err(pctldev->dev, "map %s wants to hog a non-system " + "pinmux, this is not going to work\n", map->name); return -EINVAL; } @@ -993,12 +993,9 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) for (i = 0; i < pinmux_maps_num; i++) { struct pinmux_map const *map = &pinmux_maps[i]; - if (!map->hog_on_boot) - continue; - - if ((map->ctrl_dev == dev) || - (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname))) { + if (((map->ctrl_dev == dev) || + !strcmp(map->ctrl_dev_name, devname)) && + map->hog_on_boot) { /* OK time to hog! */ ret = pinmux_hog_map(pctldev, map); if (ret) @@ -1125,15 +1122,13 @@ static int pinmux_show(struct seq_file *s, void *what) seq_printf(s, "device: %s function: %s (%u),", pinctrl_dev_get_name(pmx->pctldev), - pmxops->get_function_name(pctldev, - pmx->func_selector), + pmxops->get_function_name(pctldev, pmx->func_selector), pmx->func_selector); seq_printf(s, " groups: ["); list_for_each_entry(grp, &pmx->groups, node) { seq_printf(s, " %s (%u)", - pctlops->get_group_name(pctldev, - grp->group_selector), + pctlops->get_group_name(pctldev, grp->group_selector), grp->group_selector); } seq_printf(s, " ]"); diff --git a/trunk/drivers/pinctrl/pinmux.h b/trunk/drivers/pinctrl/pinmux.h index 97f52223fbc2..844500b3331b 100644 --- a/trunk/drivers/pinctrl/pinmux.h +++ b/trunk/drivers/pinctrl/pinmux.h @@ -12,7 +12,7 @@ */ #ifdef CONFIG_PINMUX -int pinmux_check_ops(struct pinctrl_dev *pctldev); +int pinmux_check_ops(const struct pinmux_ops *ops); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); void pinmux_init_debugfs(struct dentry *subsys_root); @@ -21,7 +21,7 @@ void pinmux_unhog_maps(struct pinctrl_dev *pctldev); #else -static inline int pinmux_check_ops(struct pinctrl_dev *pctldev) +static inline int pinmux_check_ops(const struct pinmux_ops *ops) { return 0; } diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index e9a83f84adaf..b1fa25d6583a 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -2731,8 +2731,7 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) * @dev: struct device for the regulator * @init_data: platform provided init data, passed through by driver * @driver_data: private regulator data - * @of_node: OpenFirmware node to parse for device tree bindings (may be - * NULL). + * @of_node: target open firmware device structure (may be NULL) * * Called by regulator drivers to register a regulator. * Returns 0 on success. diff --git a/trunk/drivers/regulator/of_regulator.c b/trunk/drivers/regulator/of_regulator.c index 679734d26a16..f1651eb69648 100644 --- a/trunk/drivers/regulator/of_regulator.c +++ b/trunk/drivers/regulator/of_regulator.c @@ -35,7 +35,7 @@ static void of_get_regulation_constraints(struct device_node *np, if (constraints->min_uV != constraints->max_uV) constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; /* Only one voltage? Then make sure it's set. */ - if (min_uV && max_uV && constraints->min_uV == constraints->max_uV) + if (constraints->min_uV == constraints->max_uV) constraints->apply_uV = true; uV_offset = of_get_property(np, "regulator-microvolt-offset", NULL); diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 3a125b835546..e19a4031f45e 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -774,7 +774,7 @@ config RTC_DRV_EP93XX config RTC_DRV_SA1100 tristate "SA11x0/PXA2xx" - depends on ARCH_SA1100 || ARCH_PXA + depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP help If you say Y here you will get access to the real time clock built into your SA11x0 or PXA2xx CPU. diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index cb9a585312cc..4595d3e645a7 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -27,34 +27,42 @@ #include #include #include -#include #include -#include +#include +#include +#include #include #include -#ifdef CONFIG_ARCH_PXA -#include -#endif - #define RTC_DEF_DIVIDER (32768 - 1) #define RTC_DEF_TRIM 0 - -static const unsigned long RTC_FREQ = 1024; -static struct rtc_time rtc_alarm; -static DEFINE_SPINLOCK(sa1100_rtc_lock); - -static inline int rtc_periodic_alarm(struct rtc_time *tm) -{ - return (tm->tm_year == -1) || - ((unsigned)tm->tm_mon >= 12) || - ((unsigned)(tm->tm_mday - 1) >= 31) || - ((unsigned)tm->tm_hour > 23) || - ((unsigned)tm->tm_min > 59) || - ((unsigned)tm->tm_sec > 59); -} - +#define RTC_FREQ 1024 + +#define RCNR 0x00 /* RTC Count Register */ +#define RTAR 0x04 /* RTC Alarm Register */ +#define RTSR 0x08 /* RTC Status Register */ +#define RTTR 0x0c /* RTC Timer Trim Register */ + +#define RTSR_HZE (1 << 3) /* HZ interrupt enable */ +#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ +#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ +#define RTSR_AL (1 << 0) /* RTC alarm detected */ + +#define rtc_readl(sa1100_rtc, reg) \ + readl_relaxed((sa1100_rtc)->base + (reg)) +#define rtc_writel(sa1100_rtc, reg, value) \ + writel_relaxed((value), (sa1100_rtc)->base + (reg)) + +struct sa1100_rtc { + struct resource *ress; + void __iomem *base; + struct clk *clk; + int irq_1Hz; + int irq_Alrm; + struct rtc_device *rtc; + spinlock_t lock; /* Protects this structure */ +}; /* * Calculate the next alarm time given the requested alarm time mask * and the current time. @@ -82,46 +90,26 @@ static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, } } -static int rtc_update_alarm(struct rtc_time *alrm) -{ - struct rtc_time alarm_tm, now_tm; - unsigned long now, time; - int ret; - - do { - now = RCNR; - rtc_time_to_tm(now, &now_tm); - rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); - ret = rtc_tm_to_time(&alarm_tm, &time); - if (ret != 0) - break; - - RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); - RTAR = time; - } while (now != RCNR); - - return ret; -} - static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) { struct platform_device *pdev = to_platform_device(dev_id); - struct rtc_device *rtc = platform_get_drvdata(pdev); + struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev); unsigned int rtsr; unsigned long events = 0; - spin_lock(&sa1100_rtc_lock); + spin_lock(&sa1100_rtc->lock); - rtsr = RTSR; /* clear interrupt sources */ - RTSR = 0; + rtsr = rtc_readl(sa1100_rtc, RTSR); + rtc_writel(sa1100_rtc, RTSR, 0); + /* Fix for a nasty initialization problem the in SA11xx RTSR register. * See also the comments in sa1100_rtc_probe(). */ if (rtsr & (RTSR_ALE | RTSR_HZE)) { /* This is the original code, before there was the if test * above. This code does not clear interrupts that were not * enabled. */ - RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); + rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ) & (rtsr >> 2)); } else { /* For some reason, it is possible to enter this routine * without interruptions enabled, it has been tested with @@ -130,13 +118,13 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) * This situation leads to an infinite "loop" of interrupt * routine calling and as a result the processor seems to * lock on its first call to open(). */ - RTSR = RTSR_AL | RTSR_HZ; + rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ)); } /* clear alarm interrupt if it has occurred */ if (rtsr & RTSR_AL) rtsr &= ~RTSR_ALE; - RTSR = rtsr & (RTSR_ALE | RTSR_HZE); + rtc_writel(sa1100_rtc, RTSR, rtsr & (RTSR_ALE | RTSR_HZE)); /* update irq data & counter */ if (rtsr & RTSR_AL) @@ -144,89 +132,100 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) if (rtsr & RTSR_HZ) events |= RTC_UF | RTC_IRQF; - rtc_update_irq(rtc, 1, events); + rtc_update_irq(sa1100_rtc->rtc, 1, events); - if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) - rtc_update_alarm(&rtc_alarm); - - spin_unlock(&sa1100_rtc_lock); + spin_unlock(&sa1100_rtc->lock); return IRQ_HANDLED; } static int sa1100_rtc_open(struct device *dev) { + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); int ret; - struct platform_device *plat_dev = to_platform_device(dev); - struct rtc_device *rtc = platform_get_drvdata(plat_dev); - ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, - "rtc 1Hz", dev); + ret = request_irq(sa1100_rtc->irq_1Hz, sa1100_rtc_interrupt, + IRQF_DISABLED, "rtc 1Hz", dev); if (ret) { - dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); + dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_1Hz); goto fail_ui; } - ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, - "rtc Alrm", dev); + ret = request_irq(sa1100_rtc->irq_Alrm, sa1100_rtc_interrupt, + IRQF_DISABLED, "rtc Alrm", dev); if (ret) { - dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); + dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_Alrm); goto fail_ai; } - rtc->max_user_freq = RTC_FREQ; - rtc_irq_set_freq(rtc, NULL, RTC_FREQ); + sa1100_rtc->rtc->max_user_freq = RTC_FREQ; + rtc_irq_set_freq(sa1100_rtc->rtc, NULL, RTC_FREQ); return 0; fail_ai: - free_irq(IRQ_RTC1Hz, dev); + free_irq(sa1100_rtc->irq_1Hz, dev); fail_ui: return ret; } static void sa1100_rtc_release(struct device *dev) { - spin_lock_irq(&sa1100_rtc_lock); - RTSR = 0; - spin_unlock_irq(&sa1100_rtc_lock); + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + + spin_lock_irq(&sa1100_rtc->lock); + rtc_writel(sa1100_rtc, RTSR, 0); + spin_unlock_irq(&sa1100_rtc->lock); - free_irq(IRQ_RTCAlrm, dev); - free_irq(IRQ_RTC1Hz, dev); + free_irq(sa1100_rtc->irq_Alrm, dev); + free_irq(sa1100_rtc->irq_1Hz, dev); } static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { - spin_lock_irq(&sa1100_rtc_lock); + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + unsigned int rtsr; + + spin_lock_irq(&sa1100_rtc->lock); + + rtsr = rtc_readl(sa1100_rtc, RTSR); if (enabled) - RTSR |= RTSR_ALE; + rtsr |= RTSR_ALE; else - RTSR &= ~RTSR_ALE; - spin_unlock_irq(&sa1100_rtc_lock); + rtsr &= ~RTSR_ALE; + rtc_writel(sa1100_rtc, RTSR, rtsr); + + spin_unlock_irq(&sa1100_rtc->lock); return 0; } static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) { - rtc_time_to_tm(RCNR, tm); + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + + rtc_time_to_tm(rtc_readl(sa1100_rtc, RCNR), tm); return 0; } static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) { + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); unsigned long time; int ret; ret = rtc_tm_to_time(tm, &time); if (ret == 0) - RCNR = time; + rtc_writel(sa1100_rtc, RCNR, time); return ret; } static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - u32 rtsr; + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + unsigned long time; + unsigned int rtsr; - memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); - rtsr = RTSR; + time = rtc_readl(sa1100_rtc, RCNR); + rtc_time_to_tm(time, &alrm->time); + rtsr = rtc_readl(sa1100_rtc, RTSR); alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; return 0; @@ -234,26 +233,39 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - int ret; + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + struct rtc_time now_tm, alarm_tm; + unsigned long time, alarm; + unsigned int rtsr; - spin_lock_irq(&sa1100_rtc_lock); - ret = rtc_update_alarm(&alrm->time); - if (ret == 0) { - if (alrm->enabled) - RTSR |= RTSR_ALE; - else - RTSR &= ~RTSR_ALE; - } - spin_unlock_irq(&sa1100_rtc_lock); + spin_lock_irq(&sa1100_rtc->lock); - return ret; + time = rtc_readl(sa1100_rtc, RCNR); + rtc_time_to_tm(time, &now_tm); + rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); + rtc_tm_to_time(&alarm_tm, &alarm); + rtc_writel(sa1100_rtc, RTAR, alarm); + + rtsr = rtc_readl(sa1100_rtc, RTSR); + if (alrm->enabled) + rtsr |= RTSR_ALE; + else + rtsr &= ~RTSR_ALE; + rtc_writel(sa1100_rtc, RTSR, rtsr); + + spin_unlock_irq(&sa1100_rtc->lock); + + return 0; } static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) { - seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); - seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + seq_printf(seq, "trim/divider\t\t: 0x%08x\n", + rtc_readl(sa1100_rtc, RTTR)); + seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", + rtc_readl(sa1100_rtc, RTSR)); return 0; } @@ -270,7 +282,51 @@ static const struct rtc_class_ops sa1100_rtc_ops = { static int sa1100_rtc_probe(struct platform_device *pdev) { - struct rtc_device *rtc; + struct sa1100_rtc *sa1100_rtc; + unsigned int rttr; + int ret; + + sa1100_rtc = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL); + if (!sa1100_rtc) + return -ENOMEM; + + spin_lock_init(&sa1100_rtc->lock); + platform_set_drvdata(pdev, sa1100_rtc); + + ret = -ENXIO; + sa1100_rtc->ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!sa1100_rtc->ress) { + dev_err(&pdev->dev, "No I/O memory resource defined\n"); + goto err_ress; + } + + sa1100_rtc->irq_1Hz = platform_get_irq(pdev, 0); + if (sa1100_rtc->irq_1Hz < 0) { + dev_err(&pdev->dev, "No 1Hz IRQ resource defined\n"); + goto err_ress; + } + sa1100_rtc->irq_Alrm = platform_get_irq(pdev, 1); + if (sa1100_rtc->irq_Alrm < 0) { + dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); + goto err_ress; + } + + ret = -ENOMEM; + sa1100_rtc->base = ioremap(sa1100_rtc->ress->start, + resource_size(sa1100_rtc->ress)); + if (!sa1100_rtc->base) { + dev_err(&pdev->dev, "Unable to map pxa RTC I/O memory\n"); + goto err_map; + } + + sa1100_rtc->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(sa1100_rtc->clk)) { + dev_err(&pdev->dev, "failed to find rtc clock source\n"); + ret = PTR_ERR(sa1100_rtc->clk); + goto err_clk; + } + clk_prepare(sa1100_rtc->clk); + clk_enable(sa1100_rtc->clk); /* * According to the manual we should be able to let RTTR be zero @@ -279,24 +335,24 @@ static int sa1100_rtc_probe(struct platform_device *pdev) * If the clock divider is uninitialized then reset it to the * default value to get the 1Hz clock. */ - if (RTTR == 0) { - RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); - dev_warn(&pdev->dev, "warning: " - "initializing default clock divider/trim value\n"); + if (rtc_readl(sa1100_rtc, RTTR) == 0) { + rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); + rtc_writel(sa1100_rtc, RTTR, rttr); + dev_warn(&pdev->dev, "warning: initializing default clock" + " divider/trim value\n"); /* The current RTC value probably doesn't make sense either */ - RCNR = 0; + rtc_writel(sa1100_rtc, RCNR, 0); } device_init_wakeup(&pdev->dev, 1); - rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, - THIS_MODULE); - - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - platform_set_drvdata(pdev, rtc); - + sa1100_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, + &sa1100_rtc_ops, THIS_MODULE); + if (IS_ERR(sa1100_rtc->rtc)) { + dev_err(&pdev->dev, "Failed to register RTC device -> %d\n", + ret); + goto err_rtc_reg; + } /* Fix for a nasty initialization problem the in SA11xx RTSR register. * See also the comments in sa1100_rtc_interrupt(). * @@ -319,33 +375,46 @@ static int sa1100_rtc_probe(struct platform_device *pdev) * * Notice that clearing bit 1 and 0 is accomplished by writting ONES to * the corresponding bits in RTSR. */ - RTSR = RTSR_AL | RTSR_HZ; + rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ)); return 0; + +err_rtc_reg: +err_clk: + iounmap(sa1100_rtc->base); +err_ress: +err_map: + kfree(sa1100_rtc); + return ret; } static int sa1100_rtc_remove(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(pdev); - - if (rtc) - rtc_device_unregister(rtc); + struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev); + rtc_device_unregister(sa1100_rtc->rtc); + clk_disable(sa1100_rtc->clk); + clk_unprepare(sa1100_rtc->clk); + iounmap(sa1100_rtc->base); return 0; } #ifdef CONFIG_PM static int sa1100_rtc_suspend(struct device *dev) { + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + if (device_may_wakeup(dev)) - enable_irq_wake(IRQ_RTCAlrm); + enable_irq_wake(sa1100_rtc->irq_Alrm); return 0; } static int sa1100_rtc_resume(struct device *dev) { + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + if (device_may_wakeup(dev)) - disable_irq_wake(IRQ_RTCAlrm); + disable_irq_wake(sa1100_rtc->irq_Alrm); return 0; } diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 110137e7ec81..eef27a197c00 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -3261,12 +3261,6 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event) device->path_data.tbvpm |= eventlpm; dasd_schedule_device_bh(device); } - if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) { - DBF_DEV_EVENT(DBF_WARNING, device, "%s", - "Pathgroup re-established\n"); - if (device->discipline->kick_validate) - device->discipline->kick_validate(device); - } } dasd_put_device(device); } diff --git a/trunk/drivers/s390/block/dasd_alias.c b/trunk/drivers/s390/block/dasd_alias.c index b3beed5434e4..553b3c5abb0a 100644 --- a/trunk/drivers/s390/block/dasd_alias.c +++ b/trunk/drivers/s390/block/dasd_alias.c @@ -189,12 +189,14 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) unsigned long flags; struct alias_server *server, *newserver; struct alias_lcu *lcu, *newlcu; + int is_lcu_known; struct dasd_uid uid; private = (struct dasd_eckd_private *) device->private; device->discipline->get_uid(device, &uid); spin_lock_irqsave(&aliastree.lock, flags); + is_lcu_known = 1; server = _find_server(&uid); if (!server) { spin_unlock_irqrestore(&aliastree.lock, flags); @@ -206,6 +208,7 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) if (!server) { list_add(&newserver->server, &aliastree.serverlist); server = newserver; + is_lcu_known = 0; } else { /* someone was faster */ _free_server(newserver); @@ -223,10 +226,12 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) if (!lcu) { list_add(&newlcu->lcu, &server->lculist); lcu = newlcu; + is_lcu_known = 0; } else { /* someone was faster */ _free_lcu(newlcu); } + is_lcu_known = 0; } spin_lock(&lcu->lock); list_add(&device->alias_list, &lcu->inactive_devices); @@ -234,7 +239,64 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) spin_unlock(&lcu->lock); spin_unlock_irqrestore(&aliastree.lock, flags); - return 0; + return is_lcu_known; +} + +/* + * The first device to be registered on an LCU will have to do + * some additional setup steps to configure that LCU on the + * storage server. All further devices should wait with their + * initialization until the first device is done. + * To synchronize this work, the first device will call + * dasd_alias_lcu_setup_complete when it is done, and all + * other devices will wait for it with dasd_alias_wait_for_lcu_setup. + */ +void dasd_alias_lcu_setup_complete(struct dasd_device *device) +{ + unsigned long flags; + struct alias_server *server; + struct alias_lcu *lcu; + struct dasd_uid uid; + + device->discipline->get_uid(device, &uid); + lcu = NULL; + spin_lock_irqsave(&aliastree.lock, flags); + server = _find_server(&uid); + if (server) + lcu = _find_lcu(server, &uid); + spin_unlock_irqrestore(&aliastree.lock, flags); + if (!lcu) { + DBF_EVENT_DEVID(DBF_ERR, device->cdev, + "could not find lcu for %04x %02x", + uid.ssid, uid.real_unit_addr); + WARN_ON(1); + return; + } + complete_all(&lcu->lcu_setup); +} + +void dasd_alias_wait_for_lcu_setup(struct dasd_device *device) +{ + unsigned long flags; + struct alias_server *server; + struct alias_lcu *lcu; + struct dasd_uid uid; + + device->discipline->get_uid(device, &uid); + lcu = NULL; + spin_lock_irqsave(&aliastree.lock, flags); + server = _find_server(&uid); + if (server) + lcu = _find_lcu(server, &uid); + spin_unlock_irqrestore(&aliastree.lock, flags); + if (!lcu) { + DBF_EVENT_DEVID(DBF_ERR, device->cdev, + "could not find lcu for %04x %02x", + uid.ssid, uid.real_unit_addr); + WARN_ON(1); + return; + } + wait_for_completion(&lcu->lcu_setup); } /* diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index 70880be26015..bbcd5e9206ee 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -1534,10 +1534,6 @@ static void dasd_eckd_validate_server(struct dasd_device *device) struct dasd_eckd_private *private; int enable_pav; - private = (struct dasd_eckd_private *) device->private; - if (private->uid.type == UA_BASE_PAV_ALIAS || - private->uid.type == UA_HYPER_PAV_ALIAS) - return; if (dasd_nopav || MACHINE_IS_VM) enable_pav = 0; else @@ -1546,28 +1542,11 @@ static void dasd_eckd_validate_server(struct dasd_device *device) /* may be requested feature is not available on server, * therefore just report error and go ahead */ + private = (struct dasd_eckd_private *) device->private; DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x " "returned rc=%d", private->uid.ssid, rc); } -/* - * worker to do a validate server in case of a lost pathgroup - */ -static void dasd_eckd_do_validate_server(struct work_struct *work) -{ - struct dasd_device *device = container_of(work, struct dasd_device, - kick_validate); - dasd_eckd_validate_server(device); - dasd_put_device(device); -} - -static void dasd_eckd_kick_validate_server(struct dasd_device *device) -{ - dasd_get_device(device); - /* queue call to do_validate_server to the kernel event daemon. */ - schedule_work(&device->kick_validate); -} - static u32 get_fcx_max_data(struct dasd_device *device) { #if defined(CONFIG_64BIT) @@ -1609,13 +1588,10 @@ dasd_eckd_check_characteristics(struct dasd_device *device) struct dasd_eckd_private *private; struct dasd_block *block; struct dasd_uid temp_uid; - int rc, i; + int is_known, rc, i; int readonly; unsigned long value; - /* setup work queue for validate server*/ - INIT_WORK(&device->kick_validate, dasd_eckd_do_validate_server); - if (!ccw_device_is_pathgroup(device->cdev)) { dev_warn(&device->cdev->dev, "A channel path group could not be established\n"); @@ -1675,12 +1651,22 @@ dasd_eckd_check_characteristics(struct dasd_device *device) block->base = device; } - /* register lcu with alias handling, enable PAV */ - rc = dasd_alias_make_device_known_to_lcu(device); - if (rc) + /* register lcu with alias handling, enable PAV if this is a new lcu */ + is_known = dasd_alias_make_device_known_to_lcu(device); + if (is_known < 0) { + rc = is_known; goto out_err2; - - dasd_eckd_validate_server(device); + } + /* + * dasd_eckd_validate_server is done on the first device that + * is found for an LCU. All later other devices have to wait + * for it, so they will read the correct feature codes. + */ + if (!is_known) { + dasd_eckd_validate_server(device); + dasd_alias_lcu_setup_complete(device); + } else + dasd_alias_wait_for_lcu_setup(device); /* device may report different configuration data after LCU setup */ rc = dasd_eckd_read_conf(device); @@ -4112,7 +4098,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device) { struct dasd_eckd_private *private; struct dasd_eckd_characteristics temp_rdc_data; - int rc; + int is_known, rc; struct dasd_uid temp_uid; unsigned long flags; @@ -4135,10 +4121,14 @@ static int dasd_eckd_restore_device(struct dasd_device *device) goto out_err; /* register lcu with alias handling, enable PAV if this is a new lcu */ - rc = dasd_alias_make_device_known_to_lcu(device); - if (rc) - return rc; - dasd_eckd_validate_server(device); + is_known = dasd_alias_make_device_known_to_lcu(device); + if (is_known < 0) + return is_known; + if (!is_known) { + dasd_eckd_validate_server(device); + dasd_alias_lcu_setup_complete(device); + } else + dasd_alias_wait_for_lcu_setup(device); /* RE-Read Configuration Data */ rc = dasd_eckd_read_conf(device); @@ -4280,7 +4270,6 @@ static struct dasd_discipline dasd_eckd_discipline = { .restore = dasd_eckd_restore_device, .reload = dasd_eckd_reload_device, .get_uid = dasd_eckd_get_uid, - .kick_validate = dasd_eckd_kick_validate_server, }; static int __init diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index 33a6743ddc55..afe8c33422ed 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -355,7 +355,6 @@ struct dasd_discipline { int (*reload) (struct dasd_device *); int (*get_uid) (struct dasd_device *, struct dasd_uid *); - void (*kick_validate) (struct dasd_device *); }; extern struct dasd_discipline *dasd_diag_discipline_pointer; @@ -456,7 +455,6 @@ struct dasd_device { struct work_struct kick_work; struct work_struct restore_device; struct work_struct reload_device; - struct work_struct kick_validate; struct timer_list timer; debug_info_t *debug_area; diff --git a/trunk/drivers/scsi/mac_esp.c b/trunk/drivers/scsi/mac_esp.c index 70eb1f79b1ba..4ceeace80453 100644 --- a/trunk/drivers/scsi/mac_esp.c +++ b/trunk/drivers/scsi/mac_esp.c @@ -565,7 +565,8 @@ static int __devinit esp_mac_probe(struct platform_device *dev) esp_chips[dev->id] = esp; mb(); if (esp_chips[!dev->id] == NULL) { - err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL); + err = request_irq(host->irq, mac_scsi_esp_intr, 0, + "Mac ESP", NULL); if (err < 0) { esp_chips[dev->id] = NULL; goto fail_free_priv; diff --git a/trunk/drivers/scsi/mac_scsi.c b/trunk/drivers/scsi/mac_scsi.c index 2bccfbe5661e..ea2bde206f7f 100644 --- a/trunk/drivers/scsi/mac_scsi.c +++ b/trunk/drivers/scsi/mac_scsi.c @@ -339,6 +339,9 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance) printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." ); + /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ + disable_irq(IRQ_MAC_SCSI); + /* get in phase */ NCR5380_write( TARGET_COMMAND_REG, PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); @@ -354,6 +357,9 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance) for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) barrier(); + /* switch on SCSI IRQ again */ + enable_irq(IRQ_MAC_SCSI); + printk(KERN_INFO " done\n" ); } #endif diff --git a/trunk/drivers/staging/media/go7007/go7007-usb.c b/trunk/drivers/staging/media/go7007/go7007-usb.c index 5443e25086e9..70e006b50f29 100644 --- a/trunk/drivers/staging/media/go7007/go7007-usb.c +++ b/trunk/drivers/staging/media/go7007/go7007-usb.c @@ -1279,4 +1279,3 @@ static struct usb_driver go7007_usb_driver = { }; module_usb_driver(go7007_usb_driver); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/thermal/thermal_sys.c b/trunk/drivers/thermal/thermal_sys.c index 220ce7e31cf5..dd9a5743fa99 100644 --- a/trunk/drivers/thermal/thermal_sys.c +++ b/trunk/drivers/thermal/thermal_sys.c @@ -1304,7 +1304,7 @@ static struct genl_multicast_group thermal_event_mcgrp = { .name = THERMAL_GENL_MCAST_GROUP_NAME, }; -int thermal_generate_netlink_event(u32 orig, enum events event) +int generate_netlink_event(u32 orig, enum events event) { struct sk_buff *skb; struct nlattr *attr; @@ -1363,7 +1363,7 @@ int thermal_generate_netlink_event(u32 orig, enum events event) return result; } -EXPORT_SYMBOL(thermal_generate_netlink_event); +EXPORT_SYMBOL(generate_netlink_event); static int genetlink_init(void) { diff --git a/trunk/drivers/tty/serial/8250/8250.c b/trunk/drivers/tty/serial/8250.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250.c rename to trunk/drivers/tty/serial/8250.c diff --git a/trunk/drivers/tty/serial/8250/8250.h b/trunk/drivers/tty/serial/8250.h similarity index 100% rename from trunk/drivers/tty/serial/8250/8250.h rename to trunk/drivers/tty/serial/8250.h diff --git a/trunk/drivers/tty/serial/8250/Kconfig b/trunk/drivers/tty/serial/8250/Kconfig deleted file mode 100644 index 591f8018e7dd..000000000000 --- a/trunk/drivers/tty/serial/8250/Kconfig +++ /dev/null @@ -1,280 +0,0 @@ -# -# The 8250/16550 serial drivers. You shouldn't be in this list unless -# you somehow have an implicit or explicit dependency on SERIAL_8250. -# - -config SERIAL_8250 - tristate "8250/16550 and compatible serial support" - select SERIAL_CORE - ---help--- - This selects whether you want to include the driver for the standard - serial ports. The standard answer is Y. People who might say N - here are those that are setting up dedicated Ethernet WWW/FTP - servers, or users that have one of the various bus mice instead of a - serial mouse and don't intend to use their machine's standard serial - port for anything. (Note that the Cyclades and Stallion multi - serial port drivers do not need this driver built in for them to - work.) - - To compile this driver as a module, choose M here: the - module will be called 8250. - [WARNING: Do not compile this driver as a module if you are using - non-standard serial ports, since the configuration information will - be lost when the driver is unloaded. This limitation may be lifted - in the future.] - - BTW1: If you have a mouseman serial mouse which is not recognized by - the X window system, try running gpm first. - - BTW2: If you intend to use a software modem (also called Winmodem) - under Linux, forget it. These modems are crippled and require - proprietary drivers which are only available under Windows. - - Most people will say Y or M here, so that they can use serial mice, - modems and similar devices connecting to the standard serial ports. - -config SERIAL_8250_CONSOLE - bool "Console on 8250/16550 and compatible serial port" - depends on SERIAL_8250=y - select SERIAL_CORE_CONSOLE - ---help--- - If you say Y here, it will be possible to use a serial port as the - system console (the system console is the device which receives all - kernel messages and warnings and which allows logins in single user - mode). This could be useful if some terminal or printer is connected - to that serial port. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttyS1". (Try "man bootparam" or see the documentation of - your boot loader (grub or lilo or loadlin) about how to pass options - to the kernel at boot time.) - - If you don't have a VGA card installed and you say Y here, the - kernel will automatically use the first serial line, /dev/ttyS0, as - system console. - - You can set that using a kernel command line option such as - "console=uart8250,io,0x3f8,9600n8" - "console=uart8250,mmio,0xff5e0000,115200n8". - and it will switch to normal serial console when the corresponding - port is ready. - "earlycon=uart8250,io,0x3f8,9600n8" - "earlycon=uart8250,mmio,0xff5e0000,115200n8". - it will not only setup early console. - - If unsure, say N. - -config FIX_EARLYCON_MEM - bool - depends on X86 - default y - -config SERIAL_8250_GSC - tristate - depends on SERIAL_8250 && GSC - default SERIAL_8250 - -config SERIAL_8250_PCI - tristate "8250/16550 PCI device support" if EXPERT - depends on SERIAL_8250 && PCI - default SERIAL_8250 - help - This builds standard PCI serial support. You may be able to - disable this feature if you only need legacy serial support. - Saves about 9K. - -config SERIAL_8250_PNP - tristate "8250/16550 PNP device support" if EXPERT - depends on SERIAL_8250 && PNP - default SERIAL_8250 - help - This builds standard PNP serial support. You may be able to - disable this feature if you only need legacy serial support. - -config SERIAL_8250_HP300 - tristate - depends on SERIAL_8250 && HP300 - default SERIAL_8250 - -config SERIAL_8250_CS - tristate "8250/16550 PCMCIA device support" - depends on PCMCIA && SERIAL_8250 - ---help--- - Say Y here to enable support for 16-bit PCMCIA serial devices, - including serial port cards, modems, and the modem functions of - multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are - credit-card size devices often used with laptops.) - - To compile this driver as a module, choose M here: the - module will be called serial_cs. - - If unsure, say N. - -config SERIAL_8250_NR_UARTS - int "Maximum number of 8250/16550 serial ports" - depends on SERIAL_8250 - default "4" - help - Set this to the number of serial ports you want the driver - to support. This includes any ports discovered via ACPI or - PCI enumeration and any ports that may be added at run-time - via hot-plug, or any ISA multi-port serial cards. - -config SERIAL_8250_RUNTIME_UARTS - int "Number of 8250/16550 serial ports to register at runtime" - depends on SERIAL_8250 - range 0 SERIAL_8250_NR_UARTS - default "4" - help - Set this to the maximum number of serial ports you want - the kernel to register at boot time. This can be overridden - with the module parameter "nr_uarts", or boot-time parameter - 8250.nr_uarts - -config SERIAL_8250_EXTENDED - bool "Extended 8250/16550 serial driver options" - depends on SERIAL_8250 - help - If you wish to use any non-standard features of the standard "dumb" - driver, say Y here. This includes HUB6 support, shared serial - interrupts, special multiport support, support for more than the - four COM 1/2/3/4 boards, etc. - - Note that the answer to this question won't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about serial driver options. If unsure, say N. - -config SERIAL_8250_MANY_PORTS - bool "Support more than 4 legacy serial ports" - depends on SERIAL_8250_EXTENDED && !IA64 - help - Say Y here if you have dumb serial boards other than the four - standard COM 1/2/3/4 ports. This may happen if you have an AST - FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available - from ), or other custom - serial port hardware which acts similar to standard serial port - hardware. If you only use the standard COM 1/2/3/4 ports, you can - say N here to save some memory. You can also say Y if you have an - "intelligent" multiport card such as Cyclades, Digiboards, etc. - -# -# Multi-port serial cards -# - -config SERIAL_8250_FOURPORT - tristate "Support Fourport cards" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - Say Y here if you have an AST FourPort serial board. - - To compile this driver as a module, choose M here: the module - will be called 8250_fourport. - -config SERIAL_8250_ACCENT - tristate "Support Accent cards" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - Say Y here if you have an Accent Async serial board. - - To compile this driver as a module, choose M here: the module - will be called 8250_accent. - -config SERIAL_8250_BOCA - tristate "Support Boca cards" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - Say Y here if you have a Boca serial board. Please read the Boca - mini-HOWTO, available from - - To compile this driver as a module, choose M here: the module - will be called 8250_boca. - -config SERIAL_8250_EXAR_ST16C554 - tristate "Support Exar ST16C554/554D Quad UART" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - The Uplogix Envoy TU301 uses this Exar Quad UART. If you are - tinkering with your Envoy TU301, or have a machine with this UART, - say Y here. - - To compile this driver as a module, choose M here: the module - will be called 8250_exar_st16c554. - -config SERIAL_8250_HUB6 - tristate "Support Hub6 cards" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - Say Y here if you have a HUB6 serial board. - - To compile this driver as a module, choose M here: the module - will be called 8250_hub6. - -# -# Misc. options/drivers. -# - -config SERIAL_8250_SHARE_IRQ - bool "Support for sharing serial interrupts" - depends on SERIAL_8250_EXTENDED - help - Some serial boards have hardware support which allows multiple dumb - serial ports on the same board to share a single IRQ. To enable - support for this in the serial driver, say Y here. - -config SERIAL_8250_DETECT_IRQ - bool "Autodetect IRQ on standard ports (unsafe)" - depends on SERIAL_8250_EXTENDED - help - Say Y here if you want the kernel to try to guess which IRQ - to use for your serial port. - - This is considered unsafe; it is far better to configure the IRQ in - a boot script using the setserial command. - - If unsure, say N. - -config SERIAL_8250_RSA - bool "Support RSA serial ports" - depends on SERIAL_8250_EXTENDED - help - ::: To be written ::: - -config SERIAL_8250_MCA - tristate "Support 8250-type ports on MCA buses" - depends on SERIAL_8250 != n && MCA - help - Say Y here if you have a MCA serial ports. - - To compile this driver as a module, choose M here: the module - will be called 8250_mca. - -config SERIAL_8250_ACORN - tristate "Acorn expansion card serial port support" - depends on ARCH_ACORN && SERIAL_8250 - help - If you have an Atomwide Serial card or Serial Port card for an Acorn - system, say Y to this option. The driver can handle 1, 2, or 3 port - cards. If unsure, say N. - -config SERIAL_8250_RM9K - bool "Support for MIPS RM9xxx integrated serial port" - depends on SERIAL_8250 != n && SERIAL_RM9000 - select SERIAL_8250_SHARE_IRQ - help - Selecting this option will add support for the integrated serial - port hardware found on MIPS RM9122 and similar processors. - If unsure, say N. - -config SERIAL_8250_FSL - bool - depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 - default PPC - -config SERIAL_8250_DW - tristate "Support for Synopsys DesignWare 8250 quirks" - depends on SERIAL_8250 && OF - help - Selecting this option will enable handling of the extra features - present in the Synopsys DesignWare APB UART. diff --git a/trunk/drivers/tty/serial/8250/Makefile b/trunk/drivers/tty/serial/8250/Makefile deleted file mode 100644 index 867bba738908..000000000000 --- a/trunk/drivers/tty/serial/8250/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# Makefile for the 8250 serial device drivers. -# - -obj-$(CONFIG_SERIAL_8250) += 8250.o -obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o -obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o -obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o -obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o -obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o -obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o -obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o -obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o -obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o -obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o -obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o -obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o -obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o -obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o -obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o diff --git a/trunk/drivers/tty/serial/8250/8250_accent.c b/trunk/drivers/tty/serial/8250_accent.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_accent.c rename to trunk/drivers/tty/serial/8250_accent.c diff --git a/trunk/drivers/tty/serial/8250/8250_acorn.c b/trunk/drivers/tty/serial/8250_acorn.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_acorn.c rename to trunk/drivers/tty/serial/8250_acorn.c diff --git a/trunk/drivers/tty/serial/8250/8250_boca.c b/trunk/drivers/tty/serial/8250_boca.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_boca.c rename to trunk/drivers/tty/serial/8250_boca.c diff --git a/trunk/drivers/tty/serial/8250/8250_dw.c b/trunk/drivers/tty/serial/8250_dw.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_dw.c rename to trunk/drivers/tty/serial/8250_dw.c diff --git a/trunk/drivers/tty/serial/8250/8250_early.c b/trunk/drivers/tty/serial/8250_early.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_early.c rename to trunk/drivers/tty/serial/8250_early.c diff --git a/trunk/drivers/tty/serial/8250/8250_exar_st16c554.c b/trunk/drivers/tty/serial/8250_exar_st16c554.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_exar_st16c554.c rename to trunk/drivers/tty/serial/8250_exar_st16c554.c diff --git a/trunk/drivers/tty/serial/8250/8250_fourport.c b/trunk/drivers/tty/serial/8250_fourport.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_fourport.c rename to trunk/drivers/tty/serial/8250_fourport.c diff --git a/trunk/drivers/tty/serial/8250/8250_fsl.c b/trunk/drivers/tty/serial/8250_fsl.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_fsl.c rename to trunk/drivers/tty/serial/8250_fsl.c diff --git a/trunk/drivers/tty/serial/8250/8250_gsc.c b/trunk/drivers/tty/serial/8250_gsc.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_gsc.c rename to trunk/drivers/tty/serial/8250_gsc.c diff --git a/trunk/drivers/tty/serial/8250/8250_hp300.c b/trunk/drivers/tty/serial/8250_hp300.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_hp300.c rename to trunk/drivers/tty/serial/8250_hp300.c diff --git a/trunk/drivers/tty/serial/8250/8250_hub6.c b/trunk/drivers/tty/serial/8250_hub6.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_hub6.c rename to trunk/drivers/tty/serial/8250_hub6.c diff --git a/trunk/drivers/tty/serial/8250/8250_mca.c b/trunk/drivers/tty/serial/8250_mca.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_mca.c rename to trunk/drivers/tty/serial/8250_mca.c diff --git a/trunk/drivers/tty/serial/8250/8250_pci.c b/trunk/drivers/tty/serial/8250_pci.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_pci.c rename to trunk/drivers/tty/serial/8250_pci.c diff --git a/trunk/drivers/tty/serial/8250/8250_pnp.c b/trunk/drivers/tty/serial/8250_pnp.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_pnp.c rename to trunk/drivers/tty/serial/8250_pnp.c diff --git a/trunk/drivers/tty/serial/Kconfig b/trunk/drivers/tty/serial/Kconfig index 2de99248dfae..aca2386c5ef1 100644 --- a/trunk/drivers/tty/serial/Kconfig +++ b/trunk/drivers/tty/serial/Kconfig @@ -5,7 +5,279 @@ menu "Serial drivers" depends on HAS_IOMEM -source "drivers/tty/serial/8250/Kconfig" +# +# The new 8250/16550 serial drivers +config SERIAL_8250 + tristate "8250/16550 and compatible serial support" + select SERIAL_CORE + ---help--- + This selects whether you want to include the driver for the standard + serial ports. The standard answer is Y. People who might say N + here are those that are setting up dedicated Ethernet WWW/FTP + servers, or users that have one of the various bus mice instead of a + serial mouse and don't intend to use their machine's standard serial + port for anything. (Note that the Cyclades and Stallion multi + serial port drivers do not need this driver built in for them to + work.) + + To compile this driver as a module, choose M here: the + module will be called 8250. + [WARNING: Do not compile this driver as a module if you are using + non-standard serial ports, since the configuration information will + be lost when the driver is unloaded. This limitation may be lifted + in the future.] + + BTW1: If you have a mouseman serial mouse which is not recognized by + the X window system, try running gpm first. + + BTW2: If you intend to use a software modem (also called Winmodem) + under Linux, forget it. These modems are crippled and require + proprietary drivers which are only available under Windows. + + Most people will say Y or M here, so that they can use serial mice, + modems and similar devices connecting to the standard serial ports. + +config SERIAL_8250_CONSOLE + bool "Console on 8250/16550 and compatible serial port" + depends on SERIAL_8250=y + select SERIAL_CORE_CONSOLE + ---help--- + If you say Y here, it will be possible to use a serial port as the + system console (the system console is the device which receives all + kernel messages and warnings and which allows logins in single user + mode). This could be useful if some terminal or printer is connected + to that serial port. + + Even if you say Y here, the currently visible virtual console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttyS1". (Try "man bootparam" or see the documentation of + your boot loader (grub or lilo or loadlin) about how to pass options + to the kernel at boot time.) + + If you don't have a VGA card installed and you say Y here, the + kernel will automatically use the first serial line, /dev/ttyS0, as + system console. + + You can set that using a kernel command line option such as + "console=uart8250,io,0x3f8,9600n8" + "console=uart8250,mmio,0xff5e0000,115200n8". + and it will switch to normal serial console when the corresponding + port is ready. + "earlycon=uart8250,io,0x3f8,9600n8" + "earlycon=uart8250,mmio,0xff5e0000,115200n8". + it will not only setup early console. + + If unsure, say N. + +config FIX_EARLYCON_MEM + bool + depends on X86 + default y + +config SERIAL_8250_GSC + tristate + depends on SERIAL_8250 && GSC + default SERIAL_8250 + +config SERIAL_8250_PCI + tristate "8250/16550 PCI device support" if EXPERT + depends on SERIAL_8250 && PCI + default SERIAL_8250 + help + This builds standard PCI serial support. You may be able to + disable this feature if you only need legacy serial support. + Saves about 9K. + +config SERIAL_8250_PNP + tristate "8250/16550 PNP device support" if EXPERT + depends on SERIAL_8250 && PNP + default SERIAL_8250 + help + This builds standard PNP serial support. You may be able to + disable this feature if you only need legacy serial support. + +config SERIAL_8250_FSL + bool + depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 + default PPC + +config SERIAL_8250_HP300 + tristate + depends on SERIAL_8250 && HP300 + default SERIAL_8250 + +config SERIAL_8250_CS + tristate "8250/16550 PCMCIA device support" + depends on PCMCIA && SERIAL_8250 + ---help--- + Say Y here to enable support for 16-bit PCMCIA serial devices, + including serial port cards, modems, and the modem functions of + multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are + credit-card size devices often used with laptops.) + + To compile this driver as a module, choose M here: the + module will be called serial_cs. + + If unsure, say N. + +config SERIAL_8250_NR_UARTS + int "Maximum number of 8250/16550 serial ports" + depends on SERIAL_8250 + default "4" + help + Set this to the number of serial ports you want the driver + to support. This includes any ports discovered via ACPI or + PCI enumeration and any ports that may be added at run-time + via hot-plug, or any ISA multi-port serial cards. + +config SERIAL_8250_RUNTIME_UARTS + int "Number of 8250/16550 serial ports to register at runtime" + depends on SERIAL_8250 + range 0 SERIAL_8250_NR_UARTS + default "4" + help + Set this to the maximum number of serial ports you want + the kernel to register at boot time. This can be overridden + with the module parameter "nr_uarts", or boot-time parameter + 8250.nr_uarts + +config SERIAL_8250_EXTENDED + bool "Extended 8250/16550 serial driver options" + depends on SERIAL_8250 + help + If you wish to use any non-standard features of the standard "dumb" + driver, say Y here. This includes HUB6 support, shared serial + interrupts, special multiport support, support for more than the + four COM 1/2/3/4 boards, etc. + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about serial driver options. If unsure, say N. + +config SERIAL_8250_MANY_PORTS + bool "Support more than 4 legacy serial ports" + depends on SERIAL_8250_EXTENDED && !IA64 + help + Say Y here if you have dumb serial boards other than the four + standard COM 1/2/3/4 ports. This may happen if you have an AST + FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available + from ), or other custom + serial port hardware which acts similar to standard serial port + hardware. If you only use the standard COM 1/2/3/4 ports, you can + say N here to save some memory. You can also say Y if you have an + "intelligent" multiport card such as Cyclades, Digiboards, etc. + +# +# Multi-port serial cards +# + +config SERIAL_8250_FOURPORT + tristate "Support Fourport cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have an AST FourPort serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_fourport. + +config SERIAL_8250_ACCENT + tristate "Support Accent cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have an Accent Async serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_accent. + +config SERIAL_8250_BOCA + tristate "Support Boca cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have a Boca serial board. Please read the Boca + mini-HOWTO, available from + + To compile this driver as a module, choose M here: the module + will be called 8250_boca. + +config SERIAL_8250_EXAR_ST16C554 + tristate "Support Exar ST16C554/554D Quad UART" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + The Uplogix Envoy TU301 uses this Exar Quad UART. If you are + tinkering with your Envoy TU301, or have a machine with this UART, + say Y here. + + To compile this driver as a module, choose M here: the module + will be called 8250_exar_st16c554. + +config SERIAL_8250_HUB6 + tristate "Support Hub6 cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have a HUB6 serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_hub6. + +config SERIAL_8250_SHARE_IRQ + bool "Support for sharing serial interrupts" + depends on SERIAL_8250_EXTENDED + help + Some serial boards have hardware support which allows multiple dumb + serial ports on the same board to share a single IRQ. To enable + support for this in the serial driver, say Y here. + +config SERIAL_8250_DETECT_IRQ + bool "Autodetect IRQ on standard ports (unsafe)" + depends on SERIAL_8250_EXTENDED + help + Say Y here if you want the kernel to try to guess which IRQ + to use for your serial port. + + This is considered unsafe; it is far better to configure the IRQ in + a boot script using the setserial command. + + If unsure, say N. + +config SERIAL_8250_RSA + bool "Support RSA serial ports" + depends on SERIAL_8250_EXTENDED + help + ::: To be written ::: + +config SERIAL_8250_MCA + tristate "Support 8250-type ports on MCA buses" + depends on SERIAL_8250 != n && MCA + help + Say Y here if you have a MCA serial ports. + + To compile this driver as a module, choose M here: the module + will be called 8250_mca. + +config SERIAL_8250_ACORN + tristate "Acorn expansion card serial port support" + depends on ARCH_ACORN && SERIAL_8250 + help + If you have an Atomwide Serial card or Serial Port card for an Acorn + system, say Y to this option. The driver can handle 1, 2, or 3 port + cards. If unsure, say N. + +config SERIAL_8250_RM9K + bool "Support for MIPS RM9xxx integrated serial port" + depends on SERIAL_8250 != n && SERIAL_RM9000 + select SERIAL_8250_SHARE_IRQ + help + Selecting this option will add support for the integrated serial + port hardware found on MIPS RM9122 and similar processors. + If unsure, say N. + +config SERIAL_8250_DW + tristate "Support for Synopsys DesignWare 8250 quirks" + depends on SERIAL_8250 && OF + help + Selecting this option will enable handling of the extra features + present in the Synopsys DesignWare APB UART. comment "Non-8250 serial port support" @@ -264,6 +536,15 @@ config SERIAL_MAX3107 help MAX3107 chip support +config SERIAL_MAX3107_AAVA + tristate "MAX3107 AAVA platform support" + depends on X86_MRST && SERIAL_MAX3107 && GPIOLIB + select SERIAL_CORE + help + Support for the MAX3107 chip configuration found on the AAVA + platform. Includes the extra initialisation and GPIO support + neded for this device. + config SERIAL_DZ bool "DECstation DZ serial driver" depends on MACH_DECSTATION && 32BIT diff --git a/trunk/drivers/tty/serial/Makefile b/trunk/drivers/tty/serial/Makefile index fef32e10c851..f5b01f2ce525 100644 --- a/trunk/drivers/tty/serial/Makefile +++ b/trunk/drivers/tty/serial/Makefile @@ -14,9 +14,22 @@ obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o -# Now bring in any enabled 8250/16450/16550 type drivers. -obj-$(CONFIG_SERIAL_8250) += 8250/ - +obj-$(CONFIG_SERIAL_8250) += 8250.o +obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o +obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o +obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o +obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o +obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o +obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o +obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o +obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o +obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o +obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o +obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o +obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o +obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o +obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o @@ -29,6 +42,7 @@ obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o obj-$(CONFIG_SERIAL_MAX3100) += max3100.o obj-$(CONFIG_SERIAL_MAX3107) += max3107.o +obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o obj-$(CONFIG_SERIAL_MUX) += mux.o obj-$(CONFIG_SERIAL_68328) += 68328serial.o diff --git a/trunk/drivers/tty/serial/amba-pl011.c b/trunk/drivers/tty/serial/amba-pl011.c index 6800f5f26241..9ae024025ff3 100644 --- a/trunk/drivers/tty/serial/amba-pl011.c +++ b/trunk/drivers/tty/serial/amba-pl011.c @@ -159,7 +159,6 @@ struct uart_amba_port { unsigned int fifosize; /* vendor-specific */ unsigned int lcrh_tx; /* vendor-specific */ unsigned int lcrh_rx; /* vendor-specific */ - unsigned int old_cr; /* state during shutdown */ bool autorts; char type[12]; bool interrupt_may_hang; /* vendor-specific */ @@ -1412,9 +1411,7 @@ static int pl011_startup(struct uart_port *port) while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) barrier(); - /* restore RTS and DTR */ - cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); - cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; + cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; writew(cr, uap->port.membase + UART011_CR); /* Clear pending error interrupts */ @@ -1472,7 +1469,6 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap, static void pl011_shutdown(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; - unsigned int cr; /* * disable all interrupts @@ -1492,16 +1488,9 @@ static void pl011_shutdown(struct uart_port *port) /* * disable the port - * disable the port. It should not disable RTS and DTR. - * Also RTS and DTR state should be preserved to restore - * it during startup(). */ uap->autorts = false; - cr = readw(uap->port.membase + UART011_CR); - uap->old_cr = cr; - cr &= UART011_CR_RTS | UART011_CR_DTR; - cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - writew(cr, uap->port.membase + UART011_CR); + writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); /* * disable break condition and fifos @@ -1751,19 +1740,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) { struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr, new_cr; - unsigned long flags; - int locked = 1; clk_enable(uap->clk); - local_irq_save(flags); - if (uap->port.sysrq) - locked = 0; - else if (oops_in_progress) - locked = spin_trylock(&uap->port.lock); - else - spin_lock(&uap->port.lock); - /* * First save the CR then disable the interrupts */ @@ -1783,10 +1762,6 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) } while (status & UART01x_FR_BUSY); writew(old_cr, uap->port.membase + UART011_CR); - if (locked) - spin_unlock(&uap->port.lock); - local_irq_restore(flags); - clk_disable(uap->clk); } @@ -1930,7 +1905,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->vendor = vendor; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; - uap->old_cr = 0; uap->fifosize = vendor->fifosize; uap->interrupt_may_hang = vendor->interrupt_may_hang; uap->port.dev = &dev->dev; diff --git a/trunk/drivers/tty/serial/jsm/jsm_driver.c b/trunk/drivers/tty/serial/jsm/jsm_driver.c index 7545fe1b9925..7c867a046c97 100644 --- a/trunk/drivers/tty/serial/jsm/jsm_driver.c +++ b/trunk/drivers/tty/serial/jsm/jsm_driver.c @@ -251,7 +251,6 @@ static void jsm_io_resume(struct pci_dev *pdev) struct jsm_board *brd = pci_get_drvdata(pdev); pci_restore_state(pdev); - pci_save_state(pdev); jsm_uart_port_init(brd); } diff --git a/trunk/drivers/tty/serial/8250/m32r_sio.c b/trunk/drivers/tty/serial/m32r_sio.c similarity index 100% rename from trunk/drivers/tty/serial/8250/m32r_sio.c rename to trunk/drivers/tty/serial/m32r_sio.c diff --git a/trunk/drivers/tty/serial/8250/m32r_sio.h b/trunk/drivers/tty/serial/m32r_sio.h similarity index 100% rename from trunk/drivers/tty/serial/8250/m32r_sio.h rename to trunk/drivers/tty/serial/m32r_sio.h diff --git a/trunk/drivers/tty/serial/8250/m32r_sio_reg.h b/trunk/drivers/tty/serial/m32r_sio_reg.h similarity index 100% rename from trunk/drivers/tty/serial/8250/m32r_sio_reg.h rename to trunk/drivers/tty/serial/m32r_sio_reg.h diff --git a/trunk/drivers/tty/serial/max3107-aava.c b/trunk/drivers/tty/serial/max3107-aava.c new file mode 100644 index 000000000000..aae772a71de6 --- /dev/null +++ b/trunk/drivers/tty/serial/max3107-aava.c @@ -0,0 +1,344 @@ +/* + * max3107.c - spi uart protocol driver for Maxim 3107 + * Based on max3100.c + * by Christian Pellegrin + * and max3110.c + * by Feng Tang + * + * Copyright (C) Aavamobile 2009 + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "max3107.h" + +/* GPIO direction to input function */ +static int max3107_gpio_direction_in(struct gpio_chip *chip, unsigned offset) +{ + struct max3107_port *s = container_of(chip, struct max3107_port, chip); + u16 buf[1]; /* Buffer for SPI transfer */ + + if (offset >= MAX3107_GPIO_COUNT) { + dev_err(&s->spi->dev, "Invalid GPIO\n"); + return -EINVAL; + } + + /* Read current GPIO configuration register */ + buf[0] = MAX3107_GPIOCFG_REG; + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { + dev_err(&s->spi->dev, "SPI transfer GPIO read failed\n"); + return -EIO; + } + buf[0] &= MAX3107_SPI_RX_DATA_MASK; + + /* Set GPIO to input */ + buf[0] &= ~(0x0001 << offset); + + /* Write new GPIO configuration register value */ + buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, NULL, 2)) { + dev_err(&s->spi->dev, "SPI transfer GPIO write failed\n"); + return -EIO; + } + return 0; +} + +/* GPIO direction to output function */ +static int max3107_gpio_direction_out(struct gpio_chip *chip, unsigned offset, + int value) +{ + struct max3107_port *s = container_of(chip, struct max3107_port, chip); + u16 buf[2]; /* Buffer for SPI transfers */ + + if (offset >= MAX3107_GPIO_COUNT) { + dev_err(&s->spi->dev, "Invalid GPIO\n"); + return -EINVAL; + } + + /* Read current GPIO configuration and data registers */ + buf[0] = MAX3107_GPIOCFG_REG; + buf[1] = MAX3107_GPIODATA_REG; + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { + dev_err(&s->spi->dev, "SPI transfer gpio failed\n"); + return -EIO; + } + buf[0] &= MAX3107_SPI_RX_DATA_MASK; + buf[1] &= MAX3107_SPI_RX_DATA_MASK; + + /* Set GPIO to output */ + buf[0] |= (0x0001 << offset); + /* Set value */ + if (value) + buf[1] |= (0x0001 << offset); + else + buf[1] &= ~(0x0001 << offset); + + /* Write new GPIO configuration and data register values */ + buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); + buf[1] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, NULL, 4)) { + dev_err(&s->spi->dev, + "SPI transfer for GPIO conf data w failed\n"); + return -EIO; + } + return 0; +} + +/* GPIO value query function */ +static int max3107_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct max3107_port *s = container_of(chip, struct max3107_port, chip); + u16 buf[1]; /* Buffer for SPI transfer */ + + if (offset >= MAX3107_GPIO_COUNT) { + dev_err(&s->spi->dev, "Invalid GPIO\n"); + return -EINVAL; + } + + /* Read current GPIO data register */ + buf[0] = MAX3107_GPIODATA_REG; + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { + dev_err(&s->spi->dev, "SPI transfer GPIO data r failed\n"); + return -EIO; + } + buf[0] &= MAX3107_SPI_RX_DATA_MASK; + + /* Return value */ + return buf[0] & (0x0001 << offset); +} + +/* GPIO value set function */ +static void max3107_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct max3107_port *s = container_of(chip, struct max3107_port, chip); + u16 buf[2]; /* Buffer for SPI transfers */ + + if (offset >= MAX3107_GPIO_COUNT) { + dev_err(&s->spi->dev, "Invalid GPIO\n"); + return; + } + + /* Read current GPIO configuration registers*/ + buf[0] = MAX3107_GPIODATA_REG; + buf[1] = MAX3107_GPIOCFG_REG; + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { + dev_err(&s->spi->dev, + "SPI transfer for GPIO data and config read failed\n"); + return; + } + buf[0] &= MAX3107_SPI_RX_DATA_MASK; + buf[1] &= MAX3107_SPI_RX_DATA_MASK; + + if (!(buf[1] & (0x0001 << offset))) { + /* Configured as input, can't set value */ + dev_warn(&s->spi->dev, + "Trying to set value for input GPIO\n"); + return; + } + + /* Set value */ + if (value) + buf[0] |= (0x0001 << offset); + else + buf[0] &= ~(0x0001 << offset); + + /* Write new GPIO data register value */ + buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, NULL, 2)) + dev_err(&s->spi->dev, "SPI transfer GPIO data w failed\n"); +} + +/* GPIO chip data */ +static struct gpio_chip max3107_gpio_chip = { + .owner = THIS_MODULE, + .direction_input = max3107_gpio_direction_in, + .direction_output = max3107_gpio_direction_out, + .get = max3107_gpio_get, + .set = max3107_gpio_set, + .can_sleep = 1, + .base = MAX3107_GPIO_BASE, + .ngpio = MAX3107_GPIO_COUNT, +}; + +/** + * max3107_aava_reset - reset on AAVA systems + * @spi: The SPI device we are probing + * + * Reset the device ready for probing. + */ + +static int max3107_aava_reset(struct spi_device *spi) +{ + /* Reset the chip */ + if (gpio_request(MAX3107_RESET_GPIO, "max3107")) { + pr_err("Requesting RESET GPIO failed\n"); + return -EIO; + } + if (gpio_direction_output(MAX3107_RESET_GPIO, 0)) { + pr_err("Setting RESET GPIO to 0 failed\n"); + gpio_free(MAX3107_RESET_GPIO); + return -EIO; + } + msleep(MAX3107_RESET_DELAY); + if (gpio_direction_output(MAX3107_RESET_GPIO, 1)) { + pr_err("Setting RESET GPIO to 1 failed\n"); + gpio_free(MAX3107_RESET_GPIO); + return -EIO; + } + gpio_free(MAX3107_RESET_GPIO); + msleep(MAX3107_WAKEUP_DELAY); + return 0; +} + +static int max3107_aava_configure(struct max3107_port *s) +{ + int retval; + + /* Initialize GPIO chip data */ + s->chip = max3107_gpio_chip; + s->chip.label = s->spi->modalias; + s->chip.dev = &s->spi->dev; + + /* Add GPIO chip */ + retval = gpiochip_add(&s->chip); + if (retval) { + dev_err(&s->spi->dev, "Adding GPIO chip failed\n"); + return retval; + } + + /* Temporary fix for EV2 boot problems, set modem reset to 0 */ + max3107_gpio_direction_out(&s->chip, 3, 0); + return 0; +} + +#if 0 +/* This will get enabled once we have the board stuff merged for this + specific case */ + +static const struct baud_table brg13_ext[] = { + { 300, MAX3107_BRG13_B300 }, + { 600, MAX3107_BRG13_B600 }, + { 1200, MAX3107_BRG13_B1200 }, + { 2400, MAX3107_BRG13_B2400 }, + { 4800, MAX3107_BRG13_B4800 }, + { 9600, MAX3107_BRG13_B9600 }, + { 19200, MAX3107_BRG13_B19200 }, + { 57600, MAX3107_BRG13_B57600 }, + { 115200, MAX3107_BRG13_B115200 }, + { 230400, MAX3107_BRG13_B230400 }, + { 460800, MAX3107_BRG13_B460800 }, + { 921600, MAX3107_BRG13_B921600 }, + { 0, 0 } +}; + +static void max3107_aava_init(struct max3107_port *s) +{ + /*override for AAVA SC specific*/ + if (mrst_platform_id() == MRST_PLATFORM_AAVA_SC) { + if (get_koski_build_id() <= KOSKI_EV2) + if (s->ext_clk) { + s->brg_cfg = MAX3107_BRG13_B9600; + s->baud_tbl = (struct baud_table *)brg13_ext; + } + } +} +#endif + +static int __devexit max3107_aava_remove(struct spi_device *spi) +{ + struct max3107_port *s = dev_get_drvdata(&spi->dev); + + /* Remove GPIO chip */ + if (gpiochip_remove(&s->chip)) + dev_warn(&spi->dev, "Removing GPIO chip failed\n"); + + /* Then do the default remove */ + return max3107_remove(spi); +} + +/* Platform data */ +static struct max3107_plat aava_plat_data = { + .loopback = 0, + .ext_clk = 1, +/* .init = max3107_aava_init, */ + .configure = max3107_aava_configure, + .hw_suspend = max3107_hw_susp, + .polled_mode = 0, + .poll_time = 0, +}; + + +static int __devinit max3107_probe_aava(struct spi_device *spi) +{ + int err = max3107_aava_reset(spi); + if (err < 0) + return err; + return max3107_probe(spi, &aava_plat_data); +} + +/* Spi driver data */ +static struct spi_driver max3107_driver = { + .driver = { + .name = "aava-max3107", + .owner = THIS_MODULE, + }, + .probe = max3107_probe_aava, + .remove = __devexit_p(max3107_aava_remove), + .suspend = max3107_suspend, + .resume = max3107_resume, +}; + +/* Driver init function */ +static int __init max3107_init(void) +{ + return spi_register_driver(&max3107_driver); +} + +/* Driver exit function */ +static void __exit max3107_exit(void) +{ + spi_unregister_driver(&max3107_driver); +} + +module_init(max3107_init); +module_exit(max3107_exit); + +MODULE_DESCRIPTION("MAX3107 driver"); +MODULE_AUTHOR("Aavamobile"); +MODULE_ALIAS("spi:aava-max3107"); +MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/tty/serial/omap-serial.c b/trunk/drivers/tty/serial/omap-serial.c index 1c2426931484..d192dcbb82f5 100644 --- a/trunk/drivers/tty/serial/omap-serial.c +++ b/trunk/drivers/tty/serial/omap-serial.c @@ -1160,7 +1160,7 @@ static struct uart_driver serial_omap_reg = { .cons = OMAP_CONSOLE, }; -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_SUSPEND static int serial_omap_suspend(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); @@ -1521,7 +1521,6 @@ static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1) } } -#ifdef CONFIG_PM_RUNTIME static void serial_omap_restore_context(struct uart_omap_port *up) { if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) @@ -1551,6 +1550,7 @@ static void serial_omap_restore_context(struct uart_omap_port *up) serial_out(up, UART_OMAP_MDR1, up->mdr1); } +#ifdef CONFIG_PM_RUNTIME static int serial_omap_runtime_suspend(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); diff --git a/trunk/drivers/tty/serial/serial_core.c b/trunk/drivers/tty/serial/serial_core.c index 13056180adf5..c7bf31a6a7e7 100644 --- a/trunk/drivers/tty/serial/serial_core.c +++ b/trunk/drivers/tty/serial/serial_core.c @@ -2348,11 +2348,11 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) */ tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); if (likely(!IS_ERR(tty_dev))) { - device_set_wakeup_capable(tty_dev, 1); - } else { + device_init_wakeup(tty_dev, 1); + device_set_wakeup_enable(tty_dev, 0); + } else printk(KERN_ERR "Cannot register tty device on line %d\n", uport->line); - } /* * Ensure UPF_DEAD is not set. diff --git a/trunk/drivers/tty/serial/8250/serial_cs.c b/trunk/drivers/tty/serial/serial_cs.c similarity index 100% rename from trunk/drivers/tty/serial/8250/serial_cs.c rename to trunk/drivers/tty/serial/serial_cs.c diff --git a/trunk/drivers/tty/tty_port.c b/trunk/drivers/tty/tty_port.c index bf6e238146ae..ef9dd628ba0b 100644 --- a/trunk/drivers/tty/tty_port.c +++ b/trunk/drivers/tty/tty_port.c @@ -227,6 +227,7 @@ int tty_port_block_til_ready(struct tty_port *port, int do_clocal = 0, retval; unsigned long flags; DEFINE_WAIT(wait); + int cd; /* block if port is in the process of being closed */ if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { @@ -283,14 +284,11 @@ int tty_port_block_til_ready(struct tty_port *port, retval = -ERESTARTSYS; break; } - /* - * Probe the carrier. For devices with no carrier detect - * tty_port_carrier_raised will always return true. - * Never ask drivers if CLOCAL is set, this causes troubles - * on some hardware. - */ + /* Probe the carrier. For devices with no carrier detect this + will always return true */ + cd = tty_port_carrier_raised(port); if (!(port->flags & ASYNC_CLOSING) && - (do_clocal || tty_port_carrier_raised(port))) + (do_clocal || cd)) break; if (signal_pending(current)) { retval = -ERESTARTSYS; diff --git a/trunk/drivers/tty/vt/vt_ioctl.c b/trunk/drivers/tty/vt/vt_ioctl.c index 65447c5f91d7..5e096f43bcea 100644 --- a/trunk/drivers/tty/vt/vt_ioctl.c +++ b/trunk/drivers/tty/vt/vt_ioctl.c @@ -1463,6 +1463,7 @@ compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop, if (!perm && op->op != KD_FONT_OP_GET) return -EPERM; op->data = compat_ptr(((struct compat_console_font_op *)op)->data); + op->flags |= KD_FONT_FLAG_OLD; i = con_font_op(vc, op); if (i) return i; diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index d2b3cffca3f7..1c50baff7725 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -57,8 +57,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_MAX 16 -/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */ -#define WDM_DEFAULT_BUFSIZE 256 static DEFINE_MUTEX(wdm_mutex); @@ -90,8 +88,7 @@ struct wdm_device { int count; dma_addr_t shandle; dma_addr_t ihandle; - struct mutex wlock; - struct mutex rlock; + struct mutex lock; wait_queue_head_t wait; struct work_struct rxwork; int werr; @@ -326,7 +323,7 @@ static ssize_t wdm_write } /* concurrent writes and disconnect */ - r = mutex_lock_interruptible(&desc->wlock); + r = mutex_lock_interruptible(&desc->lock); rv = -ERESTARTSYS; if (r) { kfree(buf); @@ -389,7 +386,7 @@ static ssize_t wdm_write out: usb_autopm_put_interface(desc->intf); outnp: - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); outnl: return rv < 0 ? rv : count; } @@ -402,7 +399,7 @@ static ssize_t wdm_read struct wdm_device *desc = file->private_data; - rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ + rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ if (rv < 0) return -ERESTARTSYS; @@ -470,16 +467,14 @@ static ssize_t wdm_read for (i = 0; i < desc->length - cntr; i++) desc->ubuf[i] = desc->ubuf[i + cntr]; - spin_lock_irq(&desc->iuspin); desc->length -= cntr; - spin_unlock_irq(&desc->iuspin); /* in case we had outstanding data */ if (!desc->length) clear_bit(WDM_READ, &desc->flags); rv = cntr; err: - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); return rv; } @@ -545,8 +540,7 @@ static int wdm_open(struct inode *inode, struct file *file) } intf->needs_remote_wakeup = 1; - /* using write lock to protect desc->count */ - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); if (!desc->count++) { desc->werr = 0; desc->rerr = 0; @@ -559,7 +553,7 @@ static int wdm_open(struct inode *inode, struct file *file) } else { rv = 0; } - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); usb_autopm_put_interface(desc->intf); out: mutex_unlock(&wdm_mutex); @@ -571,11 +565,9 @@ static int wdm_release(struct inode *inode, struct file *file) struct wdm_device *desc = file->private_data; mutex_lock(&wdm_mutex); - - /* using write lock to protect desc->count */ - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); desc->count--; - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); if (!desc->count) { dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); @@ -638,7 +630,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_cdc_dmm_desc *dmhd; u8 *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; - u16 maxcom = WDM_DEFAULT_BUFSIZE; + u16 maxcom = 0; if (!buffer) goto out; @@ -673,8 +665,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); if (!desc) goto out; - mutex_init(&desc->rlock); - mutex_init(&desc->wlock); + mutex_init(&desc->lock); spin_lock_init(&desc->iuspin); init_waitqueue_head(&desc->wait); desc->wMaxCommand = maxcom; @@ -725,7 +716,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) goto err; desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->wMaxCommand, + desc->bMaxPacketSize0, GFP_KERNEL, &desc->response->transfer_dma); if (!desc->inbuf) @@ -788,13 +779,11 @@ static void wdm_disconnect(struct usb_interface *intf) /* to terminate pending flushes */ clear_bit(WDM_IN_USE, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); - wake_up_all(&desc->wait); - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); kill_urbs(desc); cancel_work_sync(&desc->rxwork); - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); + wake_up_all(&desc->wait); if (!desc->count) cleanup(desc); mutex_unlock(&wdm_mutex); @@ -809,10 +798,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); /* if this is an autosuspend the caller does the locking */ - if (!PMSG_IS_AUTO(message)) { - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); - } + if (!PMSG_IS_AUTO(message)) + mutex_lock(&desc->lock); spin_lock_irq(&desc->iuspin); if (PMSG_IS_AUTO(message) && @@ -828,10 +815,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) kill_urbs(desc); cancel_work_sync(&desc->rxwork); } - if (!PMSG_IS_AUTO(message)) { - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); - } + if (!PMSG_IS_AUTO(message)) + mutex_unlock(&desc->lock); return rv; } @@ -869,8 +854,7 @@ static int wdm_pre_reset(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); kill_urbs(desc); /* @@ -892,8 +876,7 @@ static int wdm_post_reset(struct usb_interface *intf) int rv; rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); return 0; } diff --git a/trunk/drivers/usb/dwc3/ep0.c b/trunk/drivers/usb/dwc3/ep0.c index c8df1dd967ef..2f51de57593a 100644 --- a/trunk/drivers/usb/dwc3/ep0.c +++ b/trunk/drivers/usb/dwc3/ep0.c @@ -126,6 +126,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, struct dwc3_request *req) { struct dwc3 *dwc = dep->dwc; + u32 type; int ret = 0; req->request.actual = 0; @@ -148,14 +149,20 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, direction = !!(dep->flags & DWC3_EP0_DIR_IN); - if (dwc->ep0state != EP0_DATA_PHASE) { - dev_WARN(dwc->dev, "Unexpected pending request\n"); + if (dwc->ep0state == EP0_STATUS_PHASE) { + type = dwc->three_stage_setup + ? DWC3_TRBCTL_CONTROL_STATUS3 + : DWC3_TRBCTL_CONTROL_STATUS2; + } else if (dwc->ep0state == EP0_DATA_PHASE) { + type = DWC3_TRBCTL_CONTROL_DATA; + } else { + /* should never happen */ + WARN_ON(1); return 0; } ret = dwc3_ep0_start_trans(dwc, direction, - req->request.dma, req->request.length, - DWC3_TRBCTL_CONTROL_DATA); + req->request.dma, req->request.length, type); dep->flags &= ~(DWC3_EP_PENDING_REQUEST | DWC3_EP0_DIR_IN); } else if (dwc->delayed_status) { diff --git a/trunk/drivers/usb/dwc3/gadget.c b/trunk/drivers/usb/dwc3/gadget.c index 064b6e2cd411..a696bde53222 100644 --- a/trunk/drivers/usb/dwc3/gadget.c +++ b/trunk/drivers/usb/dwc3/gadget.c @@ -101,7 +101,7 @@ void dwc3_unmap_buffer_from_dma(struct dwc3_request *req) if (req->request.num_mapped_sgs) { req->request.dma = DMA_ADDR_INVALID; dma_unmap_sg(dwc->dev, req->request.sg, - req->request.num_mapped_sgs, + req->request.num_sgs, req->direction ? DMA_TO_DEVICE : DMA_FROM_DEVICE); diff --git a/trunk/drivers/usb/gadget/composite.c b/trunk/drivers/usb/gadget/composite.c index baaebf2830fc..a95de6a4a134 100644 --- a/trunk/drivers/usb/gadget/composite.c +++ b/trunk/drivers/usb/gadget/composite.c @@ -175,13 +175,14 @@ int config_ep_by_speed(struct usb_gadget *g, _ep->comp_desc = comp_desc; if (g->speed == USB_SPEED_SUPER) { switch (usb_endpoint_type(_ep->desc)) { - case USB_ENDPOINT_XFER_ISOC: - /* mult: bits 1:0 of bmAttributes */ - _ep->mult = comp_desc->bmAttributes & 0x3; case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: _ep->maxburst = comp_desc->bMaxBurst; break; + case USB_ENDPOINT_XFER_ISOC: + /* mult: bits 1:0 of bmAttributes */ + _ep->mult = comp_desc->bmAttributes & 0x3; + break; default: /* Do nothing for control endpoints */ break; diff --git a/trunk/drivers/usb/gadget/epautoconf.c b/trunk/drivers/usb/gadget/epautoconf.c index e0e6375ef5dd..753aa0683ac1 100644 --- a/trunk/drivers/usb/gadget/epautoconf.c +++ b/trunk/drivers/usb/gadget/epautoconf.c @@ -126,7 +126,7 @@ ep_matches ( * descriptor and see if the EP matches it */ if (usb_endpoint_xfer_bulk(desc)) { - if (ep_comp && gadget->max_speed >= USB_SPEED_SUPER) { + if (ep_comp) { num_req_streams = ep_comp->bmAttributes & 0x1f; if (num_req_streams > ep->max_streams) return 0; diff --git a/trunk/drivers/usb/gadget/f_mass_storage.c b/trunk/drivers/usb/gadget/f_mass_storage.c index ee8ceec01560..6353eca1e852 100644 --- a/trunk/drivers/usb/gadget/f_mass_storage.c +++ b/trunk/drivers/usb/gadget/f_mass_storage.c @@ -3123,15 +3123,15 @@ fsg_add(struct usb_composite_dev *cdev, struct usb_configuration *c, struct fsg_module_parameters { char *file[FSG_MAX_LUNS]; - bool ro[FSG_MAX_LUNS]; - bool removable[FSG_MAX_LUNS]; - bool cdrom[FSG_MAX_LUNS]; - bool nofua[FSG_MAX_LUNS]; + int ro[FSG_MAX_LUNS]; + int removable[FSG_MAX_LUNS]; + int cdrom[FSG_MAX_LUNS]; + int nofua[FSG_MAX_LUNS]; unsigned int file_count, ro_count, removable_count, cdrom_count; unsigned int nofua_count; unsigned int luns; /* nluns */ - bool stall; /* can_stall */ + int stall; /* can_stall */ }; #define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ diff --git a/trunk/drivers/usb/gadget/fsl_udc_core.c b/trunk/drivers/usb/gadget/fsl_udc_core.c index b04712f19f1e..d7ea6c076ce9 100644 --- a/trunk/drivers/usb/gadget/fsl_udc_core.c +++ b/trunk/drivers/usb/gadget/fsl_udc_core.c @@ -1430,7 +1430,7 @@ static void setup_received_irq(struct fsl_udc *udc, int pipe = get_pipe_by_windex(wIndex); struct fsl_ep *ep; - if (wValue != 0 || wLength != 0 || pipe >= udc->max_ep) + if (wValue != 0 || wLength != 0 || pipe > udc->max_ep) break; ep = get_ep_by_pipe(udc, pipe); @@ -1673,7 +1673,7 @@ static void dtd_complete_irq(struct fsl_udc *udc) if (!bit_pos) return; - for (i = 0; i < udc->max_ep; i++) { + for (i = 0; i < udc->max_ep * 2; i++) { ep_num = i >> 1; direction = i % 2; diff --git a/trunk/drivers/usb/gadget/langwell_udc.c b/trunk/drivers/usb/gadget/langwell_udc.c index e2293c1588ee..fa0fcc11263f 100644 --- a/trunk/drivers/usb/gadget/langwell_udc.c +++ b/trunk/drivers/usb/gadget/langwell_udc.c @@ -11,6 +11,11 @@ /* #undef DEBUG */ /* #undef VERBOSE_DEBUG */ +#if defined(CONFIG_USB_LANGWELL_OTG) +#define OTG_TRANSCEIVER +#endif + + #include #include #include @@ -1517,7 +1522,8 @@ static void langwell_udc_stop(struct langwell_udc *dev) /* stop all USB activities */ -static void stop_activity(struct langwell_udc *dev) +static void stop_activity(struct langwell_udc *dev, + struct usb_gadget_driver *driver) { struct langwell_ep *ep; dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); @@ -1529,9 +1535,9 @@ static void stop_activity(struct langwell_udc *dev) } /* report disconnect; the driver is already quiesced */ - if (dev->driver) { + if (driver) { spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); + driver->disconnect(&dev->gadget); spin_lock(&dev->lock); } @@ -1919,10 +1925,11 @@ static int langwell_stop(struct usb_gadget *g, /* stop all usb activities */ dev->gadget.speed = USB_SPEED_UNKNOWN; + stop_activity(dev, driver); + spin_unlock_irqrestore(&dev->lock, flags); + dev->gadget.dev.driver = NULL; dev->driver = NULL; - stop_activity(dev); - spin_unlock_irqrestore(&dev->lock, flags); device_remove_file(&dev->pdev->dev, &dev_attr_function); @@ -2308,9 +2315,13 @@ static void handle_setup_packet(struct langwell_udc *dev, if (!gadget_is_otg(&dev->gadget)) break; - else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) + else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) { dev->gadget.b_hnp_enable = 1; - else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT) +#ifdef OTG_TRANSCEIVER + if (!dev->lotg->otg.default_a) + dev->lotg->hsm.b_hnp_enable = 1; +#endif + } else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT) dev->gadget.a_hnp_support = 1; else if (setup->bRequest == USB_DEVICE_A_ALT_HNP_SUPPORT) @@ -2722,7 +2733,7 @@ static void handle_usb_reset(struct langwell_udc *dev) dev->bus_reset = 1; /* reset all the queues, stop all USB activities */ - stop_activity(dev); + stop_activity(dev, dev->driver); dev->usb_state = USB_STATE_DEFAULT; } else { dev_vdbg(&dev->pdev->dev, "device controller reset\n"); @@ -2730,7 +2741,7 @@ static void handle_usb_reset(struct langwell_udc *dev) langwell_udc_reset(dev); /* reset all the queues, stop all USB activities */ - stop_activity(dev); + stop_activity(dev, dev->driver); /* reset ep0 dQH and endptctrl */ ep0_reset(dev); @@ -2741,6 +2752,12 @@ static void handle_usb_reset(struct langwell_udc *dev) dev->usb_state = USB_STATE_ATTACHED; } +#ifdef OTG_TRANSCEIVER + /* refer to USB OTG 6.6.2.3 b_hnp_en is cleared */ + if (!dev->lotg->otg.default_a) + dev->lotg->hsm.b_hnp_enable = 0; +#endif + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2753,6 +2770,29 @@ static void handle_bus_suspend(struct langwell_udc *dev) dev->resume_state = dev->usb_state; dev->usb_state = USB_STATE_SUSPENDED; +#ifdef OTG_TRANSCEIVER + if (dev->lotg->otg.default_a) { + if (dev->lotg->hsm.b_bus_suspend_vld == 1) { + dev->lotg->hsm.b_bus_suspend = 1; + /* notify transceiver the state changes */ + if (spin_trylock(&dev->lotg->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&dev->lotg->wq_lock); + } + } + dev->lotg->hsm.b_bus_suspend_vld++; + } else { + if (!dev->lotg->hsm.a_bus_suspend) { + dev->lotg->hsm.a_bus_suspend = 1; + /* notify transceiver the state changes */ + if (spin_trylock(&dev->lotg->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&dev->lotg->wq_lock); + } + } + } +#endif + /* report suspend to the driver */ if (dev->driver) { if (dev->driver->suspend) { @@ -2783,6 +2823,11 @@ static void handle_bus_resume(struct langwell_udc *dev) if (dev->pdev->device != 0x0829) langwell_phy_low_power(dev, 0); +#ifdef OTG_TRANSCEIVER + if (dev->lotg->otg.default_a == 0) + dev->lotg->hsm.a_bus_suspend = 0; +#endif + /* report resume to the driver */ if (dev->driver) { if (dev->driver->resume) { @@ -2975,6 +3020,7 @@ static void langwell_udc_remove(struct pci_dev *pdev) dev->done = &done; +#ifndef OTG_TRANSCEIVER /* free dTD dma_pool and dQH */ if (dev->dtd_pool) dma_pool_destroy(dev->dtd_pool); @@ -2986,6 +3032,7 @@ static void langwell_udc_remove(struct pci_dev *pdev) /* release SRAM caching */ if (dev->has_sram && dev->got_sram) sram_deinit(dev); +#endif if (dev->status_req) { kfree(dev->status_req->req.buf); @@ -2998,6 +3045,7 @@ static void langwell_udc_remove(struct pci_dev *pdev) if (dev->got_irq) free_irq(pdev->irq, dev); +#ifndef OTG_TRANSCEIVER if (dev->cap_regs) iounmap(dev->cap_regs); @@ -3007,6 +3055,13 @@ static void langwell_udc_remove(struct pci_dev *pdev) if (dev->enabled) pci_disable_device(pdev); +#else + if (dev->transceiver) { + otg_put_transceiver(dev->transceiver); + dev->transceiver = NULL; + dev->lotg = NULL; + } +#endif dev->cap_regs = NULL; @@ -3017,7 +3072,9 @@ static void langwell_udc_remove(struct pci_dev *pdev) device_remove_file(&pdev->dev, &dev_attr_langwell_udc); device_remove_file(&pdev->dev, &dev_attr_remote_wakeup); +#ifndef OTG_TRANSCEIVER pci_set_drvdata(pdev, NULL); +#endif /* free dev, wait for the release() finished */ wait_for_completion(&done); @@ -3032,7 +3089,9 @@ static int langwell_udc_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct langwell_udc *dev; +#ifndef OTG_TRANSCEIVER unsigned long resource, len; +#endif void __iomem *base = NULL; size_t size; int retval; @@ -3050,6 +3109,16 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->pdev = pdev; dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); +#ifdef OTG_TRANSCEIVER + /* PCI device is already enabled by otg_transceiver driver */ + dev->enabled = 1; + + /* mem region and register base */ + dev->region = 1; + dev->transceiver = otg_get_transceiver(); + dev->lotg = otg_to_langwell(dev->transceiver); + base = dev->lotg->regs; +#else pci_set_drvdata(pdev, dev); /* now all the pci goodies ... */ @@ -3070,6 +3139,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->region = 1; base = ioremap_nocache(resource, len); +#endif if (base == NULL) { dev_err(&dev->pdev->dev, "can't map memory\n"); retval = -EFAULT; @@ -3093,6 +3163,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->got_sram = 0; dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram); +#ifndef OTG_TRANSCEIVER /* enable SRAM caching if detected */ if (dev->has_sram && !dev->got_sram) sram_init(dev); @@ -3111,6 +3182,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, goto error; } dev->got_irq = 1; +#endif /* set stopped bit */ dev->stopped = 1; @@ -3185,8 +3257,10 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->remote_wakeup = 0; dev->dev_status = 1 << USB_DEVICE_SELF_POWERED; +#ifndef OTG_TRANSCEIVER /* reset device controller */ langwell_udc_reset(dev); +#endif /* initialize gadget structure */ dev->gadget.ops = &langwell_ops; /* usb_gadget_ops */ @@ -3194,6 +3268,9 @@ static int langwell_udc_probe(struct pci_dev *pdev, INIT_LIST_HEAD(&dev->gadget.ep_list); /* ep_list */ dev->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ dev->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ +#ifdef OTG_TRANSCEIVER + dev->gadget.is_otg = 1; /* support otg mode */ +#endif /* the "gadget" abstracts/virtualizes the controller */ dev_set_name(&dev->gadget.dev, "gadget"); @@ -3205,8 +3282,10 @@ static int langwell_udc_probe(struct pci_dev *pdev, /* controller endpoints reinit */ eps_reinit(dev); +#ifndef OTG_TRANSCEIVER /* reset ep0 dQH and endptctrl */ ep0_reset(dev); +#endif /* create dTD dma_pool resource */ dev->dtd_pool = dma_pool_create("langwell_dtd", @@ -3288,7 +3367,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) spin_lock_irq(&dev->lock); /* stop all usb activities */ - stop_activity(dev); + stop_activity(dev, dev->driver); spin_unlock_irq(&dev->lock); /* free dTD dma_pool and dQH */ @@ -3446,14 +3525,22 @@ static struct pci_driver langwell_pci_driver = { static int __init init(void) { +#ifdef OTG_TRANSCEIVER + return langwell_register_peripheral(&langwell_pci_driver); +#else return pci_register_driver(&langwell_pci_driver); +#endif } module_init(init); static void __exit cleanup(void) { +#ifdef OTG_TRANSCEIVER + return langwell_unregister_peripheral(&langwell_pci_driver); +#else pci_unregister_driver(&langwell_pci_driver); +#endif } module_exit(cleanup); diff --git a/trunk/drivers/usb/gadget/langwell_udc.h b/trunk/drivers/usb/gadget/langwell_udc.h index d6e78accaffe..ef79e242b7b0 100644 --- a/trunk/drivers/usb/gadget/langwell_udc.h +++ b/trunk/drivers/usb/gadget/langwell_udc.h @@ -8,6 +8,7 @@ */ #include +#include /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/gadget/storage_common.c b/trunk/drivers/usb/gadget/storage_common.c index 85ea14e2545e..c7f291a331df 100644 --- a/trunk/drivers/usb/gadget/storage_common.c +++ b/trunk/drivers/usb/gadget/storage_common.c @@ -598,16 +598,16 @@ static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = { | USB_5GBPS_OPERATION), .bFunctionalitySupport = USB_LOW_SPEED_OPERATION, .bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT, - .bU2DevExitLat = cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT), + .bU2DevExitLat = USB_DEFAULT_U2_DEV_EXIT_LAT, }; static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = { .bLength = USB_DT_BOS_SIZE, .bDescriptorType = USB_DT_BOS, - .wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE + .wTotalLength = USB_DT_BOS_SIZE + USB_DT_USB_EXT_CAP_SIZE - + USB_DT_USB_SS_CAP_SIZE), + + USB_DT_USB_SS_CAP_SIZE, .bNumDeviceCaps = 2, }; diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index b556a72264d1..e90344a17631 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -125,7 +125,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, */ if (pdata->init && pdata->init(pdev)) { retval = -ENODEV; - goto err4; + goto err3; } /* Enable USB controller, 83xx or 8536 */ diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index 01bb7241d6ef..f4b627d343ac 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -276,9 +276,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) /* Serial Bus Release Number is at PCI 0x60 offset */ pci_read_config_byte(pdev, 0x60, &ehci->sbrn); - if (pdev->vendor == PCI_VENDOR_ID_STMICRO - && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST) - ehci->sbrn = 0x20; /* ConneXT has no sbrn register */ /* Keep this around for a while just in case some EHCI * implementation uses legacy PCI PM support. This test @@ -529,9 +526,6 @@ static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), .driver_data = (unsigned long) &ehci_pci_hc_driver, - }, { - PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_HOST), - .driver_data = (unsigned long) &ehci_pci_hc_driver, }, { /* end: all zeroes */ } }; diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 77afabc77f9b..5df0b0e3392b 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -139,23 +139,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, } iclk = clk_get(&pdev->dev, "ohci_clk"); - if (IS_ERR(iclk)) { - dev_err(&pdev->dev, "failed to get ohci_clk\n"); - retval = PTR_ERR(iclk); - goto err3; - } fclk = clk_get(&pdev->dev, "uhpck"); - if (IS_ERR(fclk)) { - dev_err(&pdev->dev, "failed to get uhpck\n"); - retval = PTR_ERR(fclk); - goto err4; - } hclk = clk_get(&pdev->dev, "hclk"); - if (IS_ERR(hclk)) { - dev_err(&pdev->dev, "failed to get hclk\n"); - retval = PTR_ERR(hclk); - goto err5; - } at91_start_hc(pdev); ohci_hcd_init(hcd_to_ohci(hcd)); @@ -168,12 +153,9 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, at91_stop_hc(pdev); clk_put(hclk); - err5: clk_put(fclk); - err4: clk_put(iclk); - err3: iounmap(hcd->regs); err2: @@ -244,8 +226,7 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int if (!gpio_is_valid(pdata->vbus_pin[port])) return; - gpio_set_value(pdata->vbus_pin[port], - !pdata->vbus_pin_active_low[port] ^ enable); + gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable); } static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) @@ -256,8 +237,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) if (!gpio_is_valid(pdata->vbus_pin[port])) return -EINVAL; - return gpio_get_value(pdata->vbus_pin[port]) ^ - !pdata->vbus_pin_active_low[port]; + return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted; } /* diff --git a/trunk/drivers/usb/host/ohci-dbg.c b/trunk/drivers/usb/host/ohci-dbg.c index e4bcb62b930a..5179fcd73d8a 100644 --- a/trunk/drivers/usb/host/ohci-dbg.c +++ b/trunk/drivers/usb/host/ohci-dbg.c @@ -82,14 +82,6 @@ urb_print(struct urb * urb, char * str, int small, int status) ohci_dbg(ohci,format, ## arg ); \ } while (0); -/* Version for use where "next" is the address of a local variable */ -#define ohci_dbg_nosw(ohci, next, size, format, arg...) \ - do { \ - unsigned s_len; \ - s_len = scnprintf(*next, *size, format, ## arg); \ - *size -= s_len; *next += s_len; \ - } while (0); - static void ohci_dump_intr_mask ( struct ohci_hcd *ohci, @@ -661,7 +653,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) /* dump driver info, then registers in spec order */ - ohci_dbg_nosw(ohci, &next, &size, + ohci_dbg_sw (ohci, &next, &size, "bus %s, device %s\n" "%s\n" "%s\n", @@ -680,7 +672,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) /* hcca */ if (ohci->hcca) - ohci_dbg_nosw(ohci, &next, &size, + ohci_dbg_sw (ohci, &next, &size, "hcca frame 0x%04x\n", ohci_frame_no(ohci)); /* other registers mostly affect frame timings */ diff --git a/trunk/drivers/usb/host/ohci-pci.c b/trunk/drivers/usb/host/ohci-pci.c index 1843bb68ac7c..6109810cc2d3 100644 --- a/trunk/drivers/usb/host/ohci-pci.c +++ b/trunk/drivers/usb/host/ohci-pci.c @@ -397,10 +397,6 @@ static const struct pci_device_id pci_ids [] = { { /* handle any USB OHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0), .driver_data = (unsigned long) &ohci_pci_hc_driver, - }, { - /* The device in the ConneXT I/O hub has no class reg */ - PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_OHCI), - .driver_data = (unsigned long) &ohci_pci_hc_driver, }, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE (pci, pci_ids); diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index b62037bff688..b90e1386418b 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -1204,7 +1204,6 @@ static void handle_vendor_event(struct xhci_hcd *xhci, * * Returns a zero-based port number, which is suitable for indexing into each of * the split roothubs' port arrays and bus state arrays. - * Add one to it in order to call xhci_find_slot_id_by_port. */ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd, struct xhci_hcd *xhci, u32 port_id) @@ -1325,7 +1324,7 @@ static void handle_port_status(struct xhci_hcd *xhci, xhci_set_link_state(xhci, port_array, faked_port_index, XDEV_U0); slot_id = xhci_find_slot_id_by_port(hcd, xhci, - faked_port_index + 1); + faked_port_index); if (!slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); goto cleanup; @@ -3324,8 +3323,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Check TD length */ if (running_total != td_len) { xhci_err(xhci, "ISOC TD length unmatch\n"); - ret = -EINVAL; - goto cleanup; + return -EINVAL; } } diff --git a/trunk/drivers/usb/misc/emi26.c b/trunk/drivers/usb/misc/emi26.c index da97dcec1f32..d9b6a0355443 100644 --- a/trunk/drivers/usb/misc/emi26.c +++ b/trunk/drivers/usb/misc/emi26.c @@ -37,6 +37,9 @@ static int emi26_set_reset(struct usb_device *dev, unsigned char reset_bit); static int emi26_load_firmware (struct usb_device *dev); static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id); static void emi26_disconnect(struct usb_interface *intf); +static int __init emi26_init (void); +static void __exit emi26_exit (void); + /* thanks to drivers/usb/serial/keyspan_pda.c code */ static int emi26_writememory (struct usb_device *dev, int address, diff --git a/trunk/drivers/usb/misc/emi62.c b/trunk/drivers/usb/misc/emi62.c index 4e0f167a6c4e..9f39062ebb08 100644 --- a/trunk/drivers/usb/misc/emi62.c +++ b/trunk/drivers/usb/misc/emi62.c @@ -46,6 +46,9 @@ static int emi62_set_reset(struct usb_device *dev, unsigned char reset_bit); static int emi62_load_firmware (struct usb_device *dev); static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id); static void emi62_disconnect(struct usb_interface *intf); +static int __init emi62_init (void); +static void __exit emi62_exit (void); + /* thanks to drivers/usb/serial/keyspan_pda.c code */ static int emi62_writememory(struct usb_device *dev, int address, diff --git a/trunk/drivers/usb/misc/usbsevseg.c b/trunk/drivers/usb/misc/usbsevseg.c index b2d82b937392..107bf13b1cf1 100644 --- a/trunk/drivers/usb/misc/usbsevseg.c +++ b/trunk/drivers/usb/misc/usbsevseg.c @@ -24,7 +24,7 @@ #define VENDOR_ID 0x0fc5 #define PRODUCT_ID 0x1227 -#define MAXLEN 8 +#define MAXLEN 6 /* table of devices that work with this driver */ static const struct usb_device_id id_table[] = { diff --git a/trunk/drivers/usb/musb/davinci.c b/trunk/drivers/usb/musb/davinci.c index 7c569f51212a..f9a3f62a83b5 100644 --- a/trunk/drivers/usb/musb/davinci.c +++ b/trunk/drivers/usb/musb/davinci.c @@ -33,6 +33,9 @@ #include #include +#include +#include +#include #include #include diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index 3d11cf64ebd1..56cf0243979e 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -981,9 +981,6 @@ static void musb_shutdown(struct platform_device *pdev) unsigned long flags; pm_runtime_get_sync(musb->controller); - - musb_gadget_cleanup(musb); - spin_lock_irqsave(&musb->lock, flags); musb_platform_disable(musb); musb_generic_disable(musb); @@ -1830,6 +1827,8 @@ static void musb_free(struct musb *musb) sysfs_remove_group(&musb->controller->kobj, &musb_attr_group); #endif + musb_gadget_cleanup(musb); + if (musb->nIrq >= 0) { if (musb->irq_wake) disable_irq_wake(musb->nIrq); diff --git a/trunk/drivers/usb/musb/omap2430.c b/trunk/drivers/usb/musb/omap2430.c index df719eae3b03..c27bbbf32b52 100644 --- a/trunk/drivers/usb/musb/omap2430.c +++ b/trunk/drivers/usb/musb/omap2430.c @@ -222,6 +222,7 @@ static inline void omap2430_low_level_init(struct musb *musb) musb_writel(musb->mregs, OTG_FORCESTDBY, l); } +/* blocking notifier support */ static int musb_otg_notifications(struct notifier_block *nb, unsigned long event, void *unused) { @@ -230,7 +231,7 @@ static int musb_otg_notifications(struct notifier_block *nb, musb->xceiv_event = event; schedule_work(&musb->otg_notifier_work); - return NOTIFY_OK; + return 0; } static void musb_otg_notifier_work(struct work_struct *data_notifier_work) @@ -385,7 +386,6 @@ static void omap2430_musb_disable(struct musb *musb) static int omap2430_musb_exit(struct musb *musb) { del_timer_sync(&musb_idle_timer); - cancel_work_sync(&musb->otg_notifier_work); omap2430_low_level_exit(musb); otg_put_transceiver(musb->xceiv); diff --git a/trunk/drivers/usb/otg/Kconfig b/trunk/drivers/usb/otg/Kconfig index 76d629345418..2a25955881fc 100644 --- a/trunk/drivers/usb/otg/Kconfig +++ b/trunk/drivers/usb/otg/Kconfig @@ -86,6 +86,20 @@ config NOP_USB_XCEIV built-in with usb ip or which are autonomous and doesn't require any phy programming such as ISP1x04 etc. +config USB_LANGWELL_OTG + tristate "Intel Langwell USB OTG dual-role support" + depends on USB && PCI && INTEL_SCU_IPC + select USB_OTG + select USB_OTG_UTILS + help + Say Y here if you want to build Intel Langwell USB OTG + transciever driver in kernel. This driver implements role + switch between EHCI host driver and Langwell USB OTG + client driver. + + To compile this driver as a module, choose M here: the + module will be called langwell_otg. + config USB_MSM_OTG tristate "OTG support for Qualcomm on-chip USB controller" depends on (USB || USB_GADGET) && ARCH_MSM @@ -110,7 +124,7 @@ config AB8500_USB config FSL_USB2_OTG bool "Freescale USB OTG Transceiver Driver" - depends on USB_EHCI_FSL && USB_GADGET_FSL_USB2 && USB_SUSPEND + depends on USB_EHCI_FSL && USB_GADGET_FSL_USB2 select USB_OTG select USB_OTG_UTILS help @@ -118,7 +132,7 @@ config FSL_USB2_OTG config USB_MV_OTG tristate "Marvell USB OTG support" - depends on USB_MV_UDC && USB_SUSPEND + depends on USB_MV_UDC select USB_OTG select USB_OTG_UTILS help diff --git a/trunk/drivers/usb/otg/Makefile b/trunk/drivers/usb/otg/Makefile index 41aa5098b139..b2c5a9598637 100644 --- a/trunk/drivers/usb/otg/Makefile +++ b/trunk/drivers/usb/otg/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o +obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o obj-$(CONFIG_USB_ULPI) += ulpi.o obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o diff --git a/trunk/drivers/usb/otg/langwell_otg.c b/trunk/drivers/usb/otg/langwell_otg.c new file mode 100644 index 000000000000..f08f784086f7 --- /dev/null +++ b/trunk/drivers/usb/otg/langwell_otg.c @@ -0,0 +1,2347 @@ +/* + * Intel Langwell USB OTG transceiver driver + * Copyright (C) 2008 - 2010, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +/* This driver helps to switch Langwell OTG controller function between host + * and peripheral. It works with EHCI driver and Langwell client controller + * driver together. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_DESC "Intel Langwell USB OTG transceiver driver" +#define DRIVER_VERSION "July 10, 2010" + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Henry Yuan , Hao Wu "); +MODULE_VERSION(DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +static const char driver_name[] = "langwell_otg"; + +static int langwell_otg_probe(struct pci_dev *pdev, + const struct pci_device_id *id); +static void langwell_otg_remove(struct pci_dev *pdev); +static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message); +static int langwell_otg_resume(struct pci_dev *pdev); + +static int langwell_otg_set_host(struct otg_transceiver *otg, + struct usb_bus *host); +static int langwell_otg_set_peripheral(struct otg_transceiver *otg, + struct usb_gadget *gadget); +static int langwell_otg_start_srp(struct otg_transceiver *otg); + +static const struct pci_device_id pci_ids[] = {{ + .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class_mask = ~0, + .vendor = 0x8086, + .device = 0x0811, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, +}, { /* end: all zeroes */ } +}; + +static struct pci_driver otg_pci_driver = { + .name = (char *) driver_name, + .id_table = pci_ids, + + .probe = langwell_otg_probe, + .remove = langwell_otg_remove, + + .suspend = langwell_otg_suspend, + .resume = langwell_otg_resume, +}; + +/* HSM timers */ +static inline struct langwell_otg_timer *otg_timer_initializer +(void (*function)(unsigned long), unsigned long expires, unsigned long data) +{ + struct langwell_otg_timer *timer; + timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL); + if (timer == NULL) + return timer; + + timer->function = function; + timer->expires = expires; + timer->data = data; + return timer; +} + +static struct langwell_otg_timer *a_wait_vrise_tmr, *a_aidl_bdis_tmr, + *b_se0_srp_tmr, *b_srp_init_tmr; + +static struct list_head active_timers; + +static struct langwell_otg *the_transceiver; + +/* host/client notify transceiver when event affects HNP state */ +void langwell_update_transceiver(void) +{ + struct langwell_otg *lnw = the_transceiver; + + dev_dbg(lnw->dev, "transceiver is updated\n"); + + if (!lnw->qwork) + return ; + + queue_work(lnw->qwork, &lnw->work); +} +EXPORT_SYMBOL(langwell_update_transceiver); + +static int langwell_otg_set_host(struct otg_transceiver *otg, + struct usb_bus *host) +{ + otg->host = host; + + return 0; +} + +static int langwell_otg_set_peripheral(struct otg_transceiver *otg, + struct usb_gadget *gadget) +{ + otg->gadget = gadget; + + return 0; +} + +static int langwell_otg_set_power(struct otg_transceiver *otg, + unsigned mA) +{ + return 0; +} + +/* A-device drives vbus, controlled through IPC commands */ +static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled) +{ + struct langwell_otg *lnw = the_transceiver; + u8 sub_id; + + dev_dbg(lnw->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off"); + + if (enabled) + sub_id = 0x8; /* Turn on the VBus */ + else + sub_id = 0x9; /* Turn off the VBus */ + + if (intel_scu_ipc_simple_command(0xef, sub_id)) { + dev_dbg(lnw->dev, "Failed to set Vbus via IPC commands\n"); + return -EBUSY; + } + + dev_dbg(lnw->dev, "%s --->\n", __func__); + + return 0; +} + +/* charge vbus or discharge vbus through a resistor to ground */ +static void langwell_otg_chrg_vbus(int on) +{ + struct langwell_otg *lnw = the_transceiver; + u32 val; + + val = readl(lnw->iotg.base + CI_OTGSC); + + if (on) + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC, + lnw->iotg.base + CI_OTGSC); + else + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD, + lnw->iotg.base + CI_OTGSC); +} + +/* Start SRP */ +static int langwell_otg_start_srp(struct otg_transceiver *otg) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val; + + dev_dbg(lnw->dev, "%s --->\n", __func__); + + val = readl(iotg->base + CI_OTGSC); + + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP, + iotg->base + CI_OTGSC); + + /* Check if the data plus is finished or not */ + msleep(8); + val = readl(iotg->base + CI_OTGSC); + if (val & (OTGSC_HADP | OTGSC_DP)) + dev_dbg(lnw->dev, "DataLine SRP Error\n"); + + /* Disable interrupt - b_sess_vld */ + val = readl(iotg->base + CI_OTGSC); + val &= (~(OTGSC_BSVIE | OTGSC_BSEIE)); + writel(val, iotg->base + CI_OTGSC); + + /* Start VBus SRP, drive vbus to generate VBus pulse */ + iotg->otg.set_vbus(&iotg->otg, true); + msleep(15); + iotg->otg.set_vbus(&iotg->otg, false); + + /* Enable interrupt - b_sess_vld*/ + val = readl(iotg->base + CI_OTGSC); + dev_dbg(lnw->dev, "after VBUS pulse otgsc = %x\n", val); + + val |= (OTGSC_BSVIE | OTGSC_BSEIE); + writel(val, iotg->base + CI_OTGSC); + + /* If Vbus is valid, then update the hsm */ + if (val & OTGSC_BSV) { + dev_dbg(lnw->dev, "no b_sess_vld interrupt\n"); + + lnw->iotg.hsm.b_sess_vld = 1; + langwell_update_transceiver(); + } + + dev_dbg(lnw->dev, "%s <---\n", __func__); + return 0; +} + +/* stop SOF via bus_suspend */ +static void langwell_otg_loc_sof(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct usb_hcd *hcd; + int err; + + dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "suspend" : "resume"); + + hcd = bus_to_hcd(lnw->iotg.otg.host); + if (on) + err = hcd->driver->bus_resume(hcd); + else + err = hcd->driver->bus_suspend(hcd); + + if (err) + dev_dbg(lnw->dev, "Fail to resume/suspend USB bus - %d\n", err); + + dev_dbg(lnw->dev, "%s <---\n", __func__); +} + +static int langwell_otg_check_otgsc(void) +{ + struct langwell_otg *lnw = the_transceiver; + u32 otgsc, usbcfg; + + dev_dbg(lnw->dev, "check sync OTGSC and USBCFG registers\n"); + + otgsc = readl(lnw->iotg.base + CI_OTGSC); + usbcfg = readl(lnw->usbcfg); + + dev_dbg(lnw->dev, "OTGSC = %08x, USBCFG = %08x\n", + otgsc, usbcfg); + dev_dbg(lnw->dev, "OTGSC_AVV = %d\n", !!(otgsc & OTGSC_AVV)); + dev_dbg(lnw->dev, "USBCFG.VBUSVAL = %d\n", + !!(usbcfg & USBCFG_VBUSVAL)); + dev_dbg(lnw->dev, "OTGSC_ASV = %d\n", !!(otgsc & OTGSC_ASV)); + dev_dbg(lnw->dev, "USBCFG.AVALID = %d\n", + !!(usbcfg & USBCFG_AVALID)); + dev_dbg(lnw->dev, "OTGSC_BSV = %d\n", !!(otgsc & OTGSC_BSV)); + dev_dbg(lnw->dev, "USBCFG.BVALID = %d\n", + !!(usbcfg & USBCFG_BVALID)); + dev_dbg(lnw->dev, "OTGSC_BSE = %d\n", !!(otgsc & OTGSC_BSE)); + dev_dbg(lnw->dev, "USBCFG.SESEND = %d\n", + !!(usbcfg & USBCFG_SESEND)); + + /* Check USBCFG VBusValid/AValid/BValid/SessEnd */ + if (!!(otgsc & OTGSC_AVV) ^ !!(usbcfg & USBCFG_VBUSVAL)) { + dev_dbg(lnw->dev, "OTGSC.AVV != USBCFG.VBUSVAL\n"); + goto err; + } + if (!!(otgsc & OTGSC_ASV) ^ !!(usbcfg & USBCFG_AVALID)) { + dev_dbg(lnw->dev, "OTGSC.ASV != USBCFG.AVALID\n"); + goto err; + } + if (!!(otgsc & OTGSC_BSV) ^ !!(usbcfg & USBCFG_BVALID)) { + dev_dbg(lnw->dev, "OTGSC.BSV != USBCFG.BVALID\n"); + goto err; + } + if (!!(otgsc & OTGSC_BSE) ^ !!(usbcfg & USBCFG_SESEND)) { + dev_dbg(lnw->dev, "OTGSC.BSE != USBCFG.SESSEN\n"); + goto err; + } + + dev_dbg(lnw->dev, "OTGSC and USBCFG are synced\n"); + + return 0; + +err: + dev_warn(lnw->dev, "OTGSC isn't equal to USBCFG\n"); + return -EPIPE; +} + + +static void langwell_otg_phy_low_power(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u8 val, phcd; + int retval; + + dev_dbg(lnw->dev, "%s ---> %s mode\n", + __func__, on ? "Low power" : "Normal"); + + phcd = 0x40; + + val = readb(iotg->base + CI_HOSTPC1 + 2); + + if (on) { + /* Due to hardware issue, after set PHCD, sync will failed + * between USBCFG and OTGSC, so before set PHCD, check if + * sync is in process now. If the answer is "yes", then do + * not touch PHCD bit */ + retval = langwell_otg_check_otgsc(); + if (retval) { + dev_dbg(lnw->dev, "Skip PHCD programming..\n"); + return ; + } + + writeb(val | phcd, iotg->base + CI_HOSTPC1 + 2); + } else + writeb(val & ~phcd, iotg->base + CI_HOSTPC1 + 2); + + dev_dbg(lnw->dev, "%s <--- done\n", __func__); +} + +/* After drv vbus, add 5 ms delay to set PHCD */ +static void langwell_otg_phy_low_power_wait(int on) +{ + struct langwell_otg *lnw = the_transceiver; + + dev_dbg(lnw->dev, "add 5ms delay before programing PHCD\n"); + + mdelay(5); + langwell_otg_phy_low_power(on); +} + +/* Enable/Disable OTG interrupt */ +static void langwell_otg_intr(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val; + + dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); + + val = readl(iotg->base + CI_OTGSC); + + /* OTGSC_INT_MASK doesn't contains 1msInt */ + if (on) { + val = val | (OTGSC_INT_MASK); + writel(val, iotg->base + CI_OTGSC); + } else { + val = val & ~(OTGSC_INT_MASK); + writel(val, iotg->base + CI_OTGSC); + } + + dev_dbg(lnw->dev, "%s <---\n", __func__); +} + +/* set HAAR: Hardware Assist Auto-Reset */ +static void langwell_otg_HAAR(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val; + + dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); + + val = readl(iotg->base + CI_OTGSC); + if (on) + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR, + iotg->base + CI_OTGSC); + else + writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR, + iotg->base + CI_OTGSC); + + dev_dbg(lnw->dev, "%s <---\n", __func__); +} + +/* set HABA: Hardware Assist B-Disconnect to A-Connect */ +static void langwell_otg_HABA(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val; + + dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); + + val = readl(iotg->base + CI_OTGSC); + if (on) + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA, + iotg->base + CI_OTGSC); + else + writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA, + iotg->base + CI_OTGSC); + + dev_dbg(lnw->dev, "%s <---\n", __func__); +} + +static int langwell_otg_check_se0_srp(int on) +{ + struct langwell_otg *lnw = the_transceiver; + int delay_time = TB_SE0_SRP * 10; + u32 val; + + dev_dbg(lnw->dev, "%s --->\n", __func__); + + do { + udelay(100); + if (!delay_time--) + break; + val = readl(lnw->iotg.base + CI_PORTSC1); + val &= PORTSC_LS; + } while (!val); + + dev_dbg(lnw->dev, "%s <---\n", __func__); + return val; +} + +/* The timeout callback function to set time out bit */ +static void set_tmout(unsigned long indicator) +{ + *(int *)indicator = 1; +} + +void langwell_otg_nsf_msg(unsigned long indicator) +{ + struct langwell_otg *lnw = the_transceiver; + + switch (indicator) { + case 2: + case 4: + case 6: + case 7: + dev_warn(lnw->dev, + "OTG:NSF-%lu - deivce not responding\n", indicator); + break; + case 3: + dev_warn(lnw->dev, + "OTG:NSF-%lu - deivce not supported\n", indicator); + break; + default: + dev_warn(lnw->dev, "Do not have this kind of NSF\n"); + break; + } +} + +/* Initialize timers */ +static int langwell_otg_init_timers(struct otg_hsm *hsm) +{ + /* HSM used timers */ + a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, + (unsigned long)&hsm->a_wait_vrise_tmout); + if (a_wait_vrise_tmr == NULL) + return -ENOMEM; + a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, + (unsigned long)&hsm->a_aidl_bdis_tmout); + if (a_aidl_bdis_tmr == NULL) + return -ENOMEM; + b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, + (unsigned long)&hsm->b_se0_srp); + if (b_se0_srp_tmr == NULL) + return -ENOMEM; + b_srp_init_tmr = otg_timer_initializer(&set_tmout, TB_SRP_INIT, + (unsigned long)&hsm->b_srp_init_tmout); + if (b_srp_init_tmr == NULL) + return -ENOMEM; + + return 0; +} + +/* Free timers */ +static void langwell_otg_free_timers(void) +{ + kfree(a_wait_vrise_tmr); + kfree(a_aidl_bdis_tmr); + kfree(b_se0_srp_tmr); + kfree(b_srp_init_tmr); +} + +/* The timeout callback function to set time out bit */ +static void langwell_otg_timer_fn(unsigned long indicator) +{ + struct langwell_otg *lnw = the_transceiver; + + *(int *)indicator = 1; + + dev_dbg(lnw->dev, "kernel timer - timeout\n"); + + langwell_update_transceiver(); +} + +/* kernel timer used instead of HW based interrupt */ +static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + unsigned long j = jiffies; + unsigned long data, time; + + switch (timers) { + case TA_WAIT_VRISE_TMR: + iotg->hsm.a_wait_vrise_tmout = 0; + data = (unsigned long)&iotg->hsm.a_wait_vrise_tmout; + time = TA_WAIT_VRISE; + break; + case TA_WAIT_BCON_TMR: + iotg->hsm.a_wait_bcon_tmout = 0; + data = (unsigned long)&iotg->hsm.a_wait_bcon_tmout; + time = TA_WAIT_BCON; + break; + case TA_AIDL_BDIS_TMR: + iotg->hsm.a_aidl_bdis_tmout = 0; + data = (unsigned long)&iotg->hsm.a_aidl_bdis_tmout; + time = TA_AIDL_BDIS; + break; + case TB_ASE0_BRST_TMR: + iotg->hsm.b_ase0_brst_tmout = 0; + data = (unsigned long)&iotg->hsm.b_ase0_brst_tmout; + time = TB_ASE0_BRST; + break; + case TB_SRP_INIT_TMR: + iotg->hsm.b_srp_init_tmout = 0; + data = (unsigned long)&iotg->hsm.b_srp_init_tmout; + time = TB_SRP_INIT; + break; + case TB_SRP_FAIL_TMR: + iotg->hsm.b_srp_fail_tmout = 0; + data = (unsigned long)&iotg->hsm.b_srp_fail_tmout; + time = TB_SRP_FAIL; + break; + case TB_BUS_SUSPEND_TMR: + iotg->hsm.b_bus_suspend_tmout = 0; + data = (unsigned long)&iotg->hsm.b_bus_suspend_tmout; + time = TB_BUS_SUSPEND; + break; + default: + dev_dbg(lnw->dev, "unknown timer, cannot enable it\n"); + return; + } + + lnw->hsm_timer.data = data; + lnw->hsm_timer.function = langwell_otg_timer_fn; + lnw->hsm_timer.expires = j + time * HZ / 1000; /* milliseconds */ + + add_timer(&lnw->hsm_timer); + + dev_dbg(lnw->dev, "add timer successfully\n"); +} + +/* Add timer to timer list */ +static void langwell_otg_add_timer(void *gtimer) +{ + struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; + struct langwell_otg_timer *tmp_timer; + struct intel_mid_otg_xceiv *iotg = &the_transceiver->iotg; + u32 val32; + + /* Check if the timer is already in the active list, + * if so update timer count + */ + list_for_each_entry(tmp_timer, &active_timers, list) + if (tmp_timer == timer) { + timer->count = timer->expires; + return; + } + timer->count = timer->expires; + + if (list_empty(&active_timers)) { + val32 = readl(iotg->base + CI_OTGSC); + writel(val32 | OTGSC_1MSE, iotg->base + CI_OTGSC); + } + + list_add_tail(&timer->list, &active_timers); +} + +/* Remove timer from the timer list; clear timeout status */ +static void langwell_otg_del_timer(void *gtimer) +{ + struct langwell_otg *lnw = the_transceiver; + struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; + struct langwell_otg_timer *tmp_timer, *del_tmp; + u32 val32; + + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) + if (tmp_timer == timer) + list_del(&timer->list); + + if (list_empty(&active_timers)) { + val32 = readl(lnw->iotg.base + CI_OTGSC); + writel(val32 & ~OTGSC_1MSE, lnw->iotg.base + CI_OTGSC); + } +} + +/* Reduce timer count by 1, and find timeout conditions.*/ +static int langwell_otg_tick_timer(u32 *int_sts) +{ + struct langwell_otg *lnw = the_transceiver; + struct langwell_otg_timer *tmp_timer, *del_tmp; + int expired = 0; + + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { + tmp_timer->count--; + /* check if timer expires */ + if (!tmp_timer->count) { + list_del(&tmp_timer->list); + tmp_timer->function(tmp_timer->data); + expired = 1; + } + } + + if (list_empty(&active_timers)) { + dev_dbg(lnw->dev, "tick timer: disable 1ms int\n"); + *int_sts = *int_sts & ~OTGSC_1MSE; + } + return expired; +} + +static void reset_otg(void) +{ + struct langwell_otg *lnw = the_transceiver; + int delay_time = 1000; + u32 val; + + dev_dbg(lnw->dev, "reseting OTG controller ...\n"); + val = readl(lnw->iotg.base + CI_USBCMD); + writel(val | USBCMD_RST, lnw->iotg.base + CI_USBCMD); + do { + udelay(100); + if (!delay_time--) + dev_dbg(lnw->dev, "reset timeout\n"); + val = readl(lnw->iotg.base + CI_USBCMD); + val &= USBCMD_RST; + } while (val != 0); + dev_dbg(lnw->dev, "reset done.\n"); +} + +static void set_host_mode(void) +{ + struct langwell_otg *lnw = the_transceiver; + u32 val; + + reset_otg(); + val = readl(lnw->iotg.base + CI_USBMODE); + val = (val & (~USBMODE_CM)) | USBMODE_HOST; + writel(val, lnw->iotg.base + CI_USBMODE); +} + +static void set_client_mode(void) +{ + struct langwell_otg *lnw = the_transceiver; + u32 val; + + reset_otg(); + val = readl(lnw->iotg.base + CI_USBMODE); + val = (val & (~USBMODE_CM)) | USBMODE_DEVICE; + writel(val, lnw->iotg.base + CI_USBMODE); +} + +static void init_hsm(void) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val32; + + /* read OTGSC after reset */ + val32 = readl(lnw->iotg.base + CI_OTGSC); + dev_dbg(lnw->dev, "%s: OTGSC init value = 0x%x\n", __func__, val32); + + /* set init state */ + if (val32 & OTGSC_ID) { + iotg->hsm.id = 1; + iotg->otg.default_a = 0; + set_client_mode(); + iotg->otg.state = OTG_STATE_B_IDLE; + } else { + iotg->hsm.id = 0; + iotg->otg.default_a = 1; + set_host_mode(); + iotg->otg.state = OTG_STATE_A_IDLE; + } + + /* set session indicator */ + if (val32 & OTGSC_BSE) + iotg->hsm.b_sess_end = 1; + if (val32 & OTGSC_BSV) + iotg->hsm.b_sess_vld = 1; + if (val32 & OTGSC_ASV) + iotg->hsm.a_sess_vld = 1; + if (val32 & OTGSC_AVV) + iotg->hsm.a_vbus_vld = 1; + + /* defautly power the bus */ + iotg->hsm.a_bus_req = 1; + iotg->hsm.a_bus_drop = 0; + /* defautly don't request bus as B device */ + iotg->hsm.b_bus_req = 0; + /* no system error */ + iotg->hsm.a_clr_err = 0; + + langwell_otg_phy_low_power_wait(1); +} + +static void update_hsm(void) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val32; + + /* read OTGSC */ + val32 = readl(lnw->iotg.base + CI_OTGSC); + dev_dbg(lnw->dev, "%s: OTGSC value = 0x%x\n", __func__, val32); + + iotg->hsm.id = !!(val32 & OTGSC_ID); + iotg->hsm.b_sess_end = !!(val32 & OTGSC_BSE); + iotg->hsm.b_sess_vld = !!(val32 & OTGSC_BSV); + iotg->hsm.a_sess_vld = !!(val32 & OTGSC_ASV); + iotg->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV); +} + +static irqreturn_t otg_dummy_irq(int irq, void *_dev) +{ + struct langwell_otg *lnw = the_transceiver; + void __iomem *reg_base = _dev; + u32 val; + u32 int_mask = 0; + + val = readl(reg_base + CI_USBMODE); + if ((val & USBMODE_CM) != USBMODE_DEVICE) + return IRQ_NONE; + + val = readl(reg_base + CI_USBSTS); + int_mask = val & INTR_DUMMY_MASK; + + if (int_mask == 0) + return IRQ_NONE; + + /* clear hsm.b_conn here since host driver can't detect it + * otg_dummy_irq called means B-disconnect happened. + */ + if (lnw->iotg.hsm.b_conn) { + lnw->iotg.hsm.b_conn = 0; + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + } + + /* Clear interrupts */ + writel(int_mask, reg_base + CI_USBSTS); + return IRQ_HANDLED; +} + +static irqreturn_t otg_irq(int irq, void *_dev) +{ + struct langwell_otg *lnw = _dev; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 int_sts, int_en; + u32 int_mask = 0; + int flag = 0; + + int_sts = readl(lnw->iotg.base + CI_OTGSC); + int_en = (int_sts & OTGSC_INTEN_MASK) >> 8; + int_mask = int_sts & int_en; + if (int_mask == 0) + return IRQ_NONE; + + if (int_mask & OTGSC_IDIS) { + dev_dbg(lnw->dev, "%s: id change int\n", __func__); + iotg->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0; + dev_dbg(lnw->dev, "id = %d\n", iotg->hsm.id); + flag = 1; + } + if (int_mask & OTGSC_DPIS) { + dev_dbg(lnw->dev, "%s: data pulse int\n", __func__); + iotg->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0; + dev_dbg(lnw->dev, "data pulse = %d\n", iotg->hsm.a_srp_det); + flag = 1; + } + if (int_mask & OTGSC_BSEIS) { + dev_dbg(lnw->dev, "%s: b session end int\n", __func__); + iotg->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0; + dev_dbg(lnw->dev, "b_sess_end = %d\n", iotg->hsm.b_sess_end); + flag = 1; + } + if (int_mask & OTGSC_BSVIS) { + dev_dbg(lnw->dev, "%s: b session valid int\n", __func__); + iotg->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0; + dev_dbg(lnw->dev, "b_sess_vld = %d\n", iotg->hsm.b_sess_end); + flag = 1; + } + if (int_mask & OTGSC_ASVIS) { + dev_dbg(lnw->dev, "%s: a session valid int\n", __func__); + iotg->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0; + dev_dbg(lnw->dev, "a_sess_vld = %d\n", iotg->hsm.a_sess_vld); + flag = 1; + } + if (int_mask & OTGSC_AVVIS) { + dev_dbg(lnw->dev, "%s: a vbus valid int\n", __func__); + iotg->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0; + dev_dbg(lnw->dev, "a_vbus_vld = %d\n", iotg->hsm.a_vbus_vld); + flag = 1; + } + + if (int_mask & OTGSC_1MSS) { + /* need to schedule otg_work if any timer is expired */ + if (langwell_otg_tick_timer(&int_sts)) + flag = 1; + } + + writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask, + lnw->iotg.base + CI_OTGSC); + if (flag) + langwell_update_transceiver(); + + return IRQ_HANDLED; +} + +static int langwell_otg_iotg_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = data; + int flag = 0; + + if (iotg == NULL) + return NOTIFY_BAD; + + if (lnw == NULL) + return NOTIFY_BAD; + + switch (action) { + case MID_OTG_NOTIFY_CONNECT: + dev_dbg(lnw->dev, "Lnw OTG Notify Connect Event\n"); + if (iotg->otg.default_a == 1) + iotg->hsm.b_conn = 1; + else + iotg->hsm.a_conn = 1; + flag = 1; + break; + case MID_OTG_NOTIFY_DISCONN: + dev_dbg(lnw->dev, "Lnw OTG Notify Disconnect Event\n"); + if (iotg->otg.default_a == 1) + iotg->hsm.b_conn = 0; + else + iotg->hsm.a_conn = 0; + flag = 1; + break; + case MID_OTG_NOTIFY_HSUSPEND: + dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus suspend Event\n"); + if (iotg->otg.default_a == 1) + iotg->hsm.a_suspend_req = 1; + else + iotg->hsm.b_bus_req = 0; + flag = 1; + break; + case MID_OTG_NOTIFY_HRESUME: + dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus resume Event\n"); + if (iotg->otg.default_a == 1) + iotg->hsm.b_bus_resume = 1; + flag = 1; + break; + case MID_OTG_NOTIFY_CSUSPEND: + dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus suspend Event\n"); + if (iotg->otg.default_a == 1) { + if (iotg->hsm.b_bus_suspend_vld == 2) { + iotg->hsm.b_bus_suspend = 1; + iotg->hsm.b_bus_suspend_vld = 0; + flag = 1; + } else { + iotg->hsm.b_bus_suspend_vld++; + flag = 0; + } + } else { + if (iotg->hsm.a_bus_suspend == 0) { + iotg->hsm.a_bus_suspend = 1; + flag = 1; + } + } + break; + case MID_OTG_NOTIFY_CRESUME: + dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus resume Event\n"); + if (iotg->otg.default_a == 0) + iotg->hsm.a_bus_suspend = 0; + flag = 0; + break; + case MID_OTG_NOTIFY_HOSTADD: + dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver Add\n"); + flag = 1; + break; + case MID_OTG_NOTIFY_HOSTREMOVE: + dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver remove\n"); + flag = 1; + break; + case MID_OTG_NOTIFY_CLIENTADD: + dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver Add\n"); + flag = 1; + break; + case MID_OTG_NOTIFY_CLIENTREMOVE: + dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver remove\n"); + flag = 1; + break; + default: + dev_dbg(lnw->dev, "Lnw OTG Nofity unknown notify message\n"); + return NOTIFY_DONE; + } + + if (flag) + langwell_update_transceiver(); + + return NOTIFY_OK; +} + +static void langwell_otg_work(struct work_struct *work) +{ + struct langwell_otg *lnw; + struct intel_mid_otg_xceiv *iotg; + int retval; + struct pci_dev *pdev; + + lnw = container_of(work, struct langwell_otg, work); + iotg = &lnw->iotg; + pdev = to_pci_dev(lnw->dev); + + dev_dbg(lnw->dev, "%s: old state = %s\n", __func__, + otg_state_string(iotg->otg.state)); + + switch (iotg->otg.state) { + case OTG_STATE_UNDEFINED: + case OTG_STATE_B_IDLE: + if (!iotg->hsm.id) { + langwell_otg_del_timer(b_srp_init_tmr); + del_timer_sync(&lnw->hsm_timer); + + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + langwell_otg_chrg_vbus(0); + set_host_mode(); + langwell_otg_phy_low_power(1); + + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.b_sess_vld) { + langwell_otg_del_timer(b_srp_init_tmr); + del_timer_sync(&lnw->hsm_timer); + iotg->hsm.b_sess_end = 0; + iotg->hsm.a_bus_suspend = 0; + langwell_otg_chrg_vbus(0); + + if (lnw->iotg.start_peripheral) { + lnw->iotg.start_peripheral(&lnw->iotg); + iotg->otg.state = OTG_STATE_B_PERIPHERAL; + } else + dev_dbg(lnw->dev, "client driver not loaded\n"); + + } else if (iotg->hsm.b_srp_init_tmout) { + iotg->hsm.b_srp_init_tmout = 0; + dev_warn(lnw->dev, "SRP init timeout\n"); + } else if (iotg->hsm.b_srp_fail_tmout) { + iotg->hsm.b_srp_fail_tmout = 0; + iotg->hsm.b_bus_req = 0; + + /* No silence failure */ + langwell_otg_nsf_msg(6); + } else if (iotg->hsm.b_bus_req && iotg->hsm.b_sess_end) { + del_timer_sync(&lnw->hsm_timer); + /* workaround for b_se0_srp detection */ + retval = langwell_otg_check_se0_srp(0); + if (retval) { + iotg->hsm.b_bus_req = 0; + dev_dbg(lnw->dev, "LS isn't SE0, try later\n"); + } else { + /* clear the PHCD before start srp */ + langwell_otg_phy_low_power(0); + + /* Start SRP */ + langwell_otg_add_timer(b_srp_init_tmr); + iotg->otg.start_srp(&iotg->otg); + langwell_otg_del_timer(b_srp_init_tmr); + langwell_otg_add_ktimer(TB_SRP_FAIL_TMR); + + /* reset PHY low power mode here */ + langwell_otg_phy_low_power_wait(1); + } + } + break; + case OTG_STATE_B_SRP_INIT: + if (!iotg->hsm.id) { + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_chrg_vbus(0); + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.b_sess_vld) { + langwell_otg_chrg_vbus(0); + if (lnw->iotg.start_peripheral) { + lnw->iotg.start_peripheral(&lnw->iotg); + iotg->otg.state = OTG_STATE_B_PERIPHERAL; + } else + dev_dbg(lnw->dev, "client driver not loaded\n"); + } + break; + case OTG_STATE_B_PERIPHERAL: + if (!iotg->hsm.id) { + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + langwell_otg_chrg_vbus(0); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.b_sess_vld) { + iotg->hsm.b_hnp_enable = 0; + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + iotg->otg.state = OTG_STATE_B_IDLE; + } else if (iotg->hsm.b_bus_req && iotg->otg.gadget && + iotg->otg.gadget->b_hnp_enable && + iotg->hsm.a_bus_suspend) { + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + langwell_otg_HAAR(1); + iotg->hsm.a_conn = 0; + + if (lnw->iotg.start_host) { + lnw->iotg.start_host(&lnw->iotg); + iotg->otg.state = OTG_STATE_B_WAIT_ACON; + } else + dev_dbg(lnw->dev, + "host driver not loaded.\n"); + + iotg->hsm.a_bus_resume = 0; + langwell_otg_add_ktimer(TB_ASE0_BRST_TMR); + } + break; + + case OTG_STATE_B_WAIT_ACON: + if (!iotg->hsm.id) { + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + langwell_otg_chrg_vbus(0); + + langwell_otg_HAAR(0); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.b_sess_vld) { + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + iotg->hsm.b_hnp_enable = 0; + iotg->hsm.b_bus_req = 0; + + langwell_otg_chrg_vbus(0); + langwell_otg_HAAR(0); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + } else if (iotg->hsm.a_conn) { + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + langwell_otg_HAAR(0); + iotg->otg.state = OTG_STATE_B_HOST; + langwell_update_transceiver(); + } else if (iotg->hsm.a_bus_resume || + iotg->hsm.b_ase0_brst_tmout) { + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + langwell_otg_HAAR(0); + langwell_otg_nsf_msg(7); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + iotg->hsm.a_bus_suspend = 0; + iotg->hsm.b_bus_req = 0; + + if (lnw->iotg.start_peripheral) + lnw->iotg.start_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver not loaded.\n"); + + iotg->otg.state = OTG_STATE_B_PERIPHERAL; + } + break; + + case OTG_STATE_B_HOST: + if (!iotg->hsm.id) { + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + langwell_otg_chrg_vbus(0); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.b_sess_vld) { + iotg->hsm.b_hnp_enable = 0; + iotg->hsm.b_bus_req = 0; + + langwell_otg_chrg_vbus(0); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + } else if ((!iotg->hsm.b_bus_req) || + (!iotg->hsm.a_conn)) { + iotg->hsm.b_bus_req = 0; + langwell_otg_loc_sof(0); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + iotg->hsm.a_bus_suspend = 0; + + if (lnw->iotg.start_peripheral) + lnw->iotg.start_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver not loaded.\n"); + + iotg->otg.state = OTG_STATE_B_PERIPHERAL; + } + break; + + case OTG_STATE_A_IDLE: + iotg->otg.default_a = 1; + if (iotg->hsm.id) { + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + iotg->hsm.vbus_srp_up = 0; + + langwell_otg_chrg_vbus(0); + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_bus_drop && + (iotg->hsm.a_srp_det || iotg->hsm.a_bus_req)) { + langwell_otg_phy_low_power(0); + + /* Turn on VBus */ + iotg->otg.set_vbus(&iotg->otg, true); + + iotg->hsm.vbus_srp_up = 0; + iotg->hsm.a_wait_vrise_tmout = 0; + langwell_otg_add_timer(a_wait_vrise_tmr); + iotg->otg.state = OTG_STATE_A_WAIT_VRISE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_bus_drop && iotg->hsm.a_sess_vld) { + iotg->hsm.vbus_srp_up = 1; + } else if (!iotg->hsm.a_sess_vld && iotg->hsm.vbus_srp_up) { + msleep(10); + langwell_otg_phy_low_power(0); + + /* Turn on VBus */ + iotg->otg.set_vbus(&iotg->otg, true); + iotg->hsm.a_srp_det = 1; + iotg->hsm.vbus_srp_up = 0; + iotg->hsm.a_wait_vrise_tmout = 0; + langwell_otg_add_timer(a_wait_vrise_tmr); + iotg->otg.state = OTG_STATE_A_WAIT_VRISE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_sess_vld && + !iotg->hsm.vbus_srp_up) { + langwell_otg_phy_low_power(1); + } + break; + case OTG_STATE_A_WAIT_VRISE: + if (iotg->hsm.id) { + langwell_otg_del_timer(a_wait_vrise_tmr); + iotg->hsm.b_bus_req = 0; + iotg->otg.default_a = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_B_IDLE; + } else if (iotg->hsm.a_vbus_vld) { + langwell_otg_del_timer(a_wait_vrise_tmr); + iotg->hsm.b_conn = 0; + if (lnw->iotg.start_host) + lnw->iotg.start_host(&lnw->iotg); + else { + dev_dbg(lnw->dev, "host driver not loaded.\n"); + break; + } + + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } else if (iotg->hsm.a_wait_vrise_tmout) { + iotg->hsm.b_conn = 0; + if (iotg->hsm.a_vbus_vld) { + if (lnw->iotg.start_host) + lnw->iotg.start_host(&lnw->iotg); + else { + dev_dbg(lnw->dev, + "host driver not loaded.\n"); + break; + } + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } else { + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } + } + break; + case OTG_STATE_A_WAIT_BCON: + if (iotg->hsm.id) { + /* delete hsm timer for a_wait_bcon_tmr */ + del_timer_sync(&lnw->hsm_timer); + + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_vbus_vld) { + /* delete hsm timer for a_wait_bcon_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } else if (iotg->hsm.a_bus_drop || + (iotg->hsm.a_wait_bcon_tmout && + !iotg->hsm.a_bus_req)) { + /* delete hsm timer for a_wait_bcon_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } else if (iotg->hsm.b_conn) { + /* delete hsm timer for a_wait_bcon_tmr */ + del_timer_sync(&lnw->hsm_timer); + + iotg->hsm.a_suspend_req = 0; + iotg->otg.state = OTG_STATE_A_HOST; + if (iotg->hsm.a_srp_det && iotg->otg.host && + !iotg->otg.host->b_hnp_enable) { + /* SRP capable peripheral-only device */ + iotg->hsm.a_bus_req = 1; + iotg->hsm.a_srp_det = 0; + } else if (!iotg->hsm.a_bus_req && iotg->otg.host && + iotg->otg.host->b_hnp_enable) { + /* It is not safe enough to do a fast + * transition from A_WAIT_BCON to + * A_SUSPEND */ + msleep(10000); + if (iotg->hsm.a_bus_req) + break; + + if (request_irq(pdev->irq, + otg_dummy_irq, IRQF_SHARED, + driver_name, iotg->base) != 0) { + dev_dbg(lnw->dev, + "request interrupt %d fail\n", + pdev->irq); + } + + langwell_otg_HABA(1); + iotg->hsm.b_bus_resume = 0; + iotg->hsm.a_aidl_bdis_tmout = 0; + + langwell_otg_loc_sof(0); + /* clear PHCD to enable HW timer */ + langwell_otg_phy_low_power(0); + langwell_otg_add_timer(a_aidl_bdis_tmr); + iotg->otg.state = OTG_STATE_A_SUSPEND; + } else if (!iotg->hsm.a_bus_req && iotg->otg.host && + !iotg->otg.host->b_hnp_enable) { + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } + } + break; + case OTG_STATE_A_HOST: + if (iotg->hsm.id) { + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.a_bus_drop || + (iotg->otg.host && + !iotg->otg.host->b_hnp_enable && + !iotg->hsm.a_bus_req)) { + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } else if (!iotg->hsm.a_vbus_vld) { + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } else if (iotg->otg.host && + iotg->otg.host->b_hnp_enable && + !iotg->hsm.a_bus_req) { + /* Set HABA to enable hardware assistance to signal + * A-connect after receiver B-disconnect. Hardware + * will then set client mode and enable URE, SLE and + * PCE after the assistance. otg_dummy_irq is used to + * clean these ints when client driver is not resumed. + */ + if (request_irq(pdev->irq, otg_dummy_irq, IRQF_SHARED, + driver_name, iotg->base) != 0) { + dev_dbg(lnw->dev, + "request interrupt %d failed\n", + pdev->irq); + } + + /* set HABA */ + langwell_otg_HABA(1); + iotg->hsm.b_bus_resume = 0; + iotg->hsm.a_aidl_bdis_tmout = 0; + langwell_otg_loc_sof(0); + /* clear PHCD to enable HW timer */ + langwell_otg_phy_low_power(0); + langwell_otg_add_timer(a_aidl_bdis_tmr); + iotg->otg.state = OTG_STATE_A_SUSPEND; + } else if (!iotg->hsm.b_conn || !iotg->hsm.a_bus_req) { + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } + break; + case OTG_STATE_A_SUSPEND: + if (iotg->hsm.id) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.a_bus_req || + iotg->hsm.b_bus_resume) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + iotg->hsm.a_suspend_req = 0; + langwell_otg_loc_sof(1); + iotg->otg.state = OTG_STATE_A_HOST; + } else if (iotg->hsm.a_aidl_bdis_tmout || + iotg->hsm.a_bus_drop) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } else if (!iotg->hsm.b_conn && iotg->otg.host && + iotg->otg.host->b_hnp_enable) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + iotg->hsm.b_bus_suspend = 0; + iotg->hsm.b_bus_suspend_vld = 0; + + /* msleep(200); */ + if (lnw->iotg.start_peripheral) + lnw->iotg.start_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver not loaded.\n"); + + langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR); + iotg->otg.state = OTG_STATE_A_PERIPHERAL; + break; + } else if (!iotg->hsm.a_vbus_vld) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } + break; + case OTG_STATE_A_PERIPHERAL: + if (iotg->hsm.id) { + /* delete hsm timer for b_bus_suspend_tmr */ + del_timer_sync(&lnw->hsm_timer); + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_vbus_vld) { + /* delete hsm timer for b_bus_suspend_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } else if (iotg->hsm.a_bus_drop) { + /* delete hsm timer for b_bus_suspend_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } else if (iotg->hsm.b_bus_suspend) { + /* delete hsm timer for b_bus_suspend_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + if (lnw->iotg.start_host) + lnw->iotg.start_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver not loaded.\n"); + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } else if (iotg->hsm.b_bus_suspend_tmout) { + u32 val; + val = readl(lnw->iotg.base + CI_PORTSC1); + if (!(val & PORTSC_SUSP)) + break; + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + if (lnw->iotg.start_host) + lnw->iotg.start_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver not loaded.\n"); + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } + break; + case OTG_STATE_A_VBUS_ERR: + if (iotg->hsm.id) { + iotg->otg.default_a = 0; + iotg->hsm.a_clr_err = 0; + iotg->hsm.a_srp_det = 0; + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.a_clr_err) { + iotg->hsm.a_clr_err = 0; + iotg->hsm.a_srp_det = 0; + reset_otg(); + init_hsm(); + if (iotg->otg.state == OTG_STATE_A_IDLE) + langwell_update_transceiver(); + } else { + /* FW will clear PHCD bit when any VBus + * event detected. Reset PHCD to 1 again */ + langwell_otg_phy_low_power(1); + } + break; + case OTG_STATE_A_WAIT_VFALL: + if (iotg->hsm.id) { + iotg->otg.default_a = 0; + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.a_bus_req) { + + /* Turn on VBus */ + iotg->otg.set_vbus(&iotg->otg, true); + iotg->hsm.a_wait_vrise_tmout = 0; + langwell_otg_add_timer(a_wait_vrise_tmr); + iotg->otg.state = OTG_STATE_A_WAIT_VRISE; + } else if (!iotg->hsm.a_sess_vld) { + iotg->hsm.a_srp_det = 0; + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + } + break; + default: + ; + } + + dev_dbg(lnw->dev, "%s: new state = %s\n", __func__, + otg_state_string(iotg->otg.state)); +} + +static ssize_t +show_registers(struct device *_dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + t = scnprintf(next, size, + "\n" + "USBCMD = 0x%08x\n" + "USBSTS = 0x%08x\n" + "USBINTR = 0x%08x\n" + "ASYNCLISTADDR = 0x%08x\n" + "PORTSC1 = 0x%08x\n" + "HOSTPC1 = 0x%08x\n" + "OTGSC = 0x%08x\n" + "USBMODE = 0x%08x\n", + readl(lnw->iotg.base + 0x30), + readl(lnw->iotg.base + 0x34), + readl(lnw->iotg.base + 0x38), + readl(lnw->iotg.base + 0x48), + readl(lnw->iotg.base + 0x74), + readl(lnw->iotg.base + 0xb4), + readl(lnw->iotg.base + 0xf4), + readl(lnw->iotg.base + 0xf8) + ); + size -= t; + next += t; + + return PAGE_SIZE - size; +} +static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); + +static ssize_t +show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + if (iotg->otg.host) + iotg->hsm.a_set_b_hnp_en = iotg->otg.host->b_hnp_enable; + + if (iotg->otg.gadget) + iotg->hsm.b_hnp_enable = iotg->otg.gadget->b_hnp_enable; + + t = scnprintf(next, size, + "\n" + "current state = %s\n" + "a_bus_resume = \t%d\n" + "a_bus_suspend = \t%d\n" + "a_conn = \t%d\n" + "a_sess_vld = \t%d\n" + "a_srp_det = \t%d\n" + "a_vbus_vld = \t%d\n" + "b_bus_resume = \t%d\n" + "b_bus_suspend = \t%d\n" + "b_conn = \t%d\n" + "b_se0_srp = \t%d\n" + "b_sess_end = \t%d\n" + "b_sess_vld = \t%d\n" + "id = \t%d\n" + "a_set_b_hnp_en = \t%d\n" + "b_srp_done = \t%d\n" + "b_hnp_enable = \t%d\n" + "a_wait_vrise_tmout = \t%d\n" + "a_wait_bcon_tmout = \t%d\n" + "a_aidl_bdis_tmout = \t%d\n" + "b_ase0_brst_tmout = \t%d\n" + "a_bus_drop = \t%d\n" + "a_bus_req = \t%d\n" + "a_clr_err = \t%d\n" + "a_suspend_req = \t%d\n" + "b_bus_req = \t%d\n" + "b_bus_suspend_tmout = \t%d\n" + "b_bus_suspend_vld = \t%d\n", + otg_state_string(iotg->otg.state), + iotg->hsm.a_bus_resume, + iotg->hsm.a_bus_suspend, + iotg->hsm.a_conn, + iotg->hsm.a_sess_vld, + iotg->hsm.a_srp_det, + iotg->hsm.a_vbus_vld, + iotg->hsm.b_bus_resume, + iotg->hsm.b_bus_suspend, + iotg->hsm.b_conn, + iotg->hsm.b_se0_srp, + iotg->hsm.b_sess_end, + iotg->hsm.b_sess_vld, + iotg->hsm.id, + iotg->hsm.a_set_b_hnp_en, + iotg->hsm.b_srp_done, + iotg->hsm.b_hnp_enable, + iotg->hsm.a_wait_vrise_tmout, + iotg->hsm.a_wait_bcon_tmout, + iotg->hsm.a_aidl_bdis_tmout, + iotg->hsm.b_ase0_brst_tmout, + iotg->hsm.a_bus_drop, + iotg->hsm.a_bus_req, + iotg->hsm.a_clr_err, + iotg->hsm.a_suspend_req, + iotg->hsm.b_bus_req, + iotg->hsm.b_bus_suspend_tmout, + iotg->hsm.b_bus_suspend_vld + ); + size -= t; + next += t; + + return PAGE_SIZE - size; +} +static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL); + +static ssize_t +get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_req); + size -= t; + next += t; + + return PAGE_SIZE - size; +} + +static ssize_t +set_a_bus_req(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + + if (!iotg->otg.default_a) + return -1; + if (count > 2) + return -1; + + if (buf[0] == '0') { + iotg->hsm.a_bus_req = 0; + dev_dbg(lnw->dev, "User request: a_bus_req = 0\n"); + } else if (buf[0] == '1') { + /* If a_bus_drop is TRUE, a_bus_req can't be set */ + if (iotg->hsm.a_bus_drop) + return -1; + iotg->hsm.a_bus_req = 1; + dev_dbg(lnw->dev, "User request: a_bus_req = 1\n"); + } + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + return count; +} +static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req); + +static ssize_t +get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_drop); + size -= t; + next += t; + + return PAGE_SIZE - size; +} + +static ssize_t +set_a_bus_drop(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + + if (!iotg->otg.default_a) + return -1; + if (count > 2) + return -1; + + if (buf[0] == '0') { + iotg->hsm.a_bus_drop = 0; + dev_dbg(lnw->dev, "User request: a_bus_drop = 0\n"); + } else if (buf[0] == '1') { + iotg->hsm.a_bus_drop = 1; + iotg->hsm.a_bus_req = 0; + dev_dbg(lnw->dev, "User request: a_bus_drop = 1\n"); + dev_dbg(lnw->dev, "User request: and a_bus_req = 0\n"); + } + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + return count; +} +static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, set_a_bus_drop); + +static ssize_t +get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + t = scnprintf(next, size, "%d", lnw->iotg.hsm.b_bus_req); + size -= t; + next += t; + + return PAGE_SIZE - size; +} + +static ssize_t +set_b_bus_req(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + + if (iotg->otg.default_a) + return -1; + + if (count > 2) + return -1; + + if (buf[0] == '0') { + iotg->hsm.b_bus_req = 0; + dev_dbg(lnw->dev, "User request: b_bus_req = 0\n"); + } else if (buf[0] == '1') { + iotg->hsm.b_bus_req = 1; + dev_dbg(lnw->dev, "User request: b_bus_req = 1\n"); + } + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + return count; +} +static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req); + +static ssize_t +set_a_clr_err(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + + if (!iotg->otg.default_a) + return -1; + if (count > 2) + return -1; + + if (buf[0] == '1') { + iotg->hsm.a_clr_err = 1; + dev_dbg(lnw->dev, "User request: a_clr_err = 1\n"); + } + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + return count; +} +static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); + +static struct attribute *inputs_attrs[] = { + &dev_attr_a_bus_req.attr, + &dev_attr_a_bus_drop.attr, + &dev_attr_b_bus_req.attr, + &dev_attr_a_clr_err.attr, + NULL, +}; + +static struct attribute_group debug_dev_attr_group = { + .name = "inputs", + .attrs = inputs_attrs, +}; + +static int langwell_otg_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + unsigned long resource, len; + void __iomem *base = NULL; + int retval; + u32 val32; + struct langwell_otg *lnw; + char qname[] = "langwell_otg_queue"; + + retval = 0; + dev_dbg(&pdev->dev, "\notg controller is detected.\n"); + if (pci_enable_device(pdev) < 0) { + retval = -ENODEV; + goto done; + } + + lnw = kzalloc(sizeof *lnw, GFP_KERNEL); + if (lnw == NULL) { + retval = -ENOMEM; + goto done; + } + the_transceiver = lnw; + + /* control register: BAR 0 */ + resource = pci_resource_start(pdev, 0); + len = pci_resource_len(pdev, 0); + if (!request_mem_region(resource, len, driver_name)) { + retval = -EBUSY; + goto err; + } + lnw->region = 1; + + base = ioremap_nocache(resource, len); + if (base == NULL) { + retval = -EFAULT; + goto err; + } + lnw->iotg.base = base; + + if (!request_mem_region(USBCFG_ADDR, USBCFG_LEN, driver_name)) { + retval = -EBUSY; + goto err; + } + lnw->cfg_region = 1; + + /* For the SCCB.USBCFG register */ + base = ioremap_nocache(USBCFG_ADDR, USBCFG_LEN); + if (base == NULL) { + retval = -EFAULT; + goto err; + } + lnw->usbcfg = base; + + if (!pdev->irq) { + dev_dbg(&pdev->dev, "No IRQ.\n"); + retval = -ENODEV; + goto err; + } + + lnw->qwork = create_singlethread_workqueue(qname); + if (!lnw->qwork) { + dev_dbg(&pdev->dev, "cannot create workqueue %s\n", qname); + retval = -ENOMEM; + goto err; + } + INIT_WORK(&lnw->work, langwell_otg_work); + + /* OTG common part */ + lnw->dev = &pdev->dev; + lnw->iotg.otg.dev = lnw->dev; + lnw->iotg.otg.label = driver_name; + lnw->iotg.otg.set_host = langwell_otg_set_host; + lnw->iotg.otg.set_peripheral = langwell_otg_set_peripheral; + lnw->iotg.otg.set_power = langwell_otg_set_power; + lnw->iotg.otg.set_vbus = langwell_otg_set_vbus; + lnw->iotg.otg.start_srp = langwell_otg_start_srp; + lnw->iotg.otg.state = OTG_STATE_UNDEFINED; + + if (otg_set_transceiver(&lnw->iotg.otg)) { + dev_dbg(lnw->dev, "can't set transceiver\n"); + retval = -EBUSY; + goto err; + } + + reset_otg(); + init_hsm(); + + spin_lock_init(&lnw->lock); + spin_lock_init(&lnw->wq_lock); + INIT_LIST_HEAD(&active_timers); + retval = langwell_otg_init_timers(&lnw->iotg.hsm); + if (retval) { + dev_dbg(&pdev->dev, "Failed to init timers\n"); + goto err; + } + + init_timer(&lnw->hsm_timer); + ATOMIC_INIT_NOTIFIER_HEAD(&lnw->iotg.iotg_notifier); + + lnw->iotg_notifier.notifier_call = langwell_otg_iotg_notify; + + retval = intel_mid_otg_register_notifier(&lnw->iotg, + &lnw->iotg_notifier); + if (retval) { + dev_dbg(lnw->dev, "Failed to register notifier\n"); + goto err; + } + + if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, + driver_name, lnw) != 0) { + dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq); + retval = -EBUSY; + goto err; + } + + /* enable OTGSC int */ + val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE | + OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU; + writel(val32, lnw->iotg.base + CI_OTGSC); + + retval = device_create_file(&pdev->dev, &dev_attr_registers); + if (retval < 0) { + dev_dbg(lnw->dev, + "Can't register sysfs attribute: %d\n", retval); + goto err; + } + + retval = device_create_file(&pdev->dev, &dev_attr_hsm); + if (retval < 0) { + dev_dbg(lnw->dev, "Can't hsm sysfs attribute: %d\n", retval); + goto err; + } + + retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group); + if (retval < 0) { + dev_dbg(lnw->dev, + "Can't register sysfs attr group: %d\n", retval); + goto err; + } + + if (lnw->iotg.otg.state == OTG_STATE_A_IDLE) + langwell_update_transceiver(); + + return 0; + +err: + if (the_transceiver) + langwell_otg_remove(pdev); +done: + return retval; +} + +static void langwell_otg_remove(struct pci_dev *pdev) +{ + struct langwell_otg *lnw = the_transceiver; + + if (lnw->qwork) { + flush_workqueue(lnw->qwork); + destroy_workqueue(lnw->qwork); + } + intel_mid_otg_unregister_notifier(&lnw->iotg, &lnw->iotg_notifier); + langwell_otg_free_timers(); + + /* disable OTGSC interrupt as OTGSC doesn't change in reset */ + writel(0, lnw->iotg.base + CI_OTGSC); + + if (pdev->irq) + free_irq(pdev->irq, lnw); + if (lnw->usbcfg) + iounmap(lnw->usbcfg); + if (lnw->cfg_region) + release_mem_region(USBCFG_ADDR, USBCFG_LEN); + if (lnw->iotg.base) + iounmap(lnw->iotg.base); + if (lnw->region) + release_mem_region(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + + otg_set_transceiver(NULL); + pci_disable_device(pdev); + sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group); + device_remove_file(&pdev->dev, &dev_attr_hsm); + device_remove_file(&pdev->dev, &dev_attr_registers); + kfree(lnw); + lnw = NULL; +} + +static void transceiver_suspend(struct pci_dev *pdev) +{ + pci_save_state(pdev); + pci_set_power_state(pdev, PCI_D3hot); + langwell_otg_phy_low_power(1); +} + +static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + int ret = 0; + + /* Disbale OTG interrupts */ + langwell_otg_intr(0); + + if (pdev->irq) + free_irq(pdev->irq, lnw); + + /* Prevent more otg_work */ + flush_workqueue(lnw->qwork); + destroy_workqueue(lnw->qwork); + lnw->qwork = NULL; + + /* start actions */ + switch (iotg->otg.state) { + case OTG_STATE_A_WAIT_VFALL: + iotg->otg.state = OTG_STATE_A_IDLE; + case OTG_STATE_A_IDLE: + case OTG_STATE_B_IDLE: + case OTG_STATE_A_VBUS_ERR: + transceiver_suspend(pdev); + break; + case OTG_STATE_A_WAIT_VRISE: + langwell_otg_del_timer(a_wait_vrise_tmr); + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_A_WAIT_BCON: + del_timer_sync(&lnw->hsm_timer); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(&pdev->dev, "host driver has been removed.\n"); + + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_A_HOST: + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(&pdev->dev, "host driver has been removed.\n"); + + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_A_SUSPEND: + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, "host driver has been removed.\n"); + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_A_PERIPHERAL: + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(&pdev->dev, + "client driver has been removed.\n"); + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_B_HOST: + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(&pdev->dev, "host driver has been removed.\n"); + iotg->hsm.b_bus_req = 0; + iotg->otg.state = OTG_STATE_B_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_B_PERIPHERAL: + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(&pdev->dev, + "client driver has been removed.\n"); + iotg->otg.state = OTG_STATE_B_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_B_WAIT_ACON: + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + langwell_otg_HAAR(0); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(&pdev->dev, "host driver has been removed.\n"); + iotg->hsm.b_bus_req = 0; + iotg->otg.state = OTG_STATE_B_IDLE; + transceiver_suspend(pdev); + break; + default: + dev_dbg(lnw->dev, "error state before suspend\n"); + break; + } + + return ret; +} + +static void transceiver_resume(struct pci_dev *pdev) +{ + pci_restore_state(pdev); + pci_set_power_state(pdev, PCI_D0); +} + +static int langwell_otg_resume(struct pci_dev *pdev) +{ + struct langwell_otg *lnw = the_transceiver; + int ret = 0; + + transceiver_resume(pdev); + + lnw->qwork = create_singlethread_workqueue("langwell_otg_queue"); + if (!lnw->qwork) { + dev_dbg(&pdev->dev, "cannot create langwell otg workqueuen"); + ret = -ENOMEM; + goto error; + } + + if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, + driver_name, lnw) != 0) { + dev_dbg(&pdev->dev, "request interrupt %d failed\n", pdev->irq); + ret = -EBUSY; + goto error; + } + + /* enable OTG interrupts */ + langwell_otg_intr(1); + + update_hsm(); + + langwell_update_transceiver(); + + return ret; +error: + langwell_otg_intr(0); + transceiver_suspend(pdev); + return ret; +} + +static int __init langwell_otg_init(void) +{ + return pci_register_driver(&otg_pci_driver); +} +module_init(langwell_otg_init); + +static void __exit langwell_otg_cleanup(void) +{ + pci_unregister_driver(&otg_pci_driver); +} +module_exit(langwell_otg_cleanup); diff --git a/trunk/drivers/usb/otg/mv_otg.c b/trunk/drivers/usb/otg/mv_otg.c index b5fbe1452ab0..db0d4fcdc8e2 100644 --- a/trunk/drivers/usb/otg/mv_otg.c +++ b/trunk/drivers/usb/otg/mv_otg.c @@ -202,7 +202,6 @@ static void mv_otg_init_irq(struct mv_otg *mvotg) static void mv_otg_start_host(struct mv_otg *mvotg, int on) { -#ifdef CONFIG_USB struct otg_transceiver *otg = &mvotg->otg; struct usb_hcd *hcd; @@ -217,7 +216,6 @@ static void mv_otg_start_host(struct mv_otg *mvotg, int on) usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); else usb_remove_hcd(hcd); -#endif /* CONFIG_USB */ } static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) diff --git a/trunk/drivers/usb/renesas_usbhs/mod_gadget.c b/trunk/drivers/usb/renesas_usbhs/mod_gadget.c index 7542aa94a462..528691d5f3e2 100644 --- a/trunk/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/trunk/drivers/usb/renesas_usbhs/mod_gadget.c @@ -425,7 +425,7 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv, struct usbhs_pipe *pipe; int recip = ctrl->bRequestType & USB_RECIP_MASK; int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; - int ret = 0; + int ret; int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep, struct usb_ctrlrequest *ctrl); char *msg; diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index 8dbf51a43c45..fba1147ed916 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -39,8 +39,6 @@ static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *port); static void cp210x_get_termios_port(struct usb_serial_port *port, unsigned int *cflagp, unsigned int *baudp); -static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *, - struct ktermios *); static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, struct ktermios*); static int cp210x_tiocmget(struct tty_struct *); @@ -140,7 +138,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ - { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; @@ -204,8 +201,6 @@ static struct usb_serial_driver cp210x_device = { #define CP210X_EMBED_EVENTS 0x15 #define CP210X_GET_EVENTSTATE 0x16 #define CP210X_SET_CHARS 0x19 -#define CP210X_GET_BAUDRATE 0x1D -#define CP210X_SET_BAUDRATE 0x1E /* CP210X_IFC_ENABLE */ #define UART_ENABLE 0x0001 @@ -365,8 +360,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port, * Quantises the baud rate as per AN205 Table 1 */ static unsigned int cp210x_quantise_baudrate(unsigned int baud) { - if (baud <= 300) - baud = 300; + if (baud <= 56) baud = 0; + else if (baud <= 300) baud = 300; else if (baud <= 600) baud = 600; else if (baud <= 1200) baud = 1200; else if (baud <= 1800) baud = 1800; @@ -394,10 +389,10 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) { else if (baud <= 491520) baud = 460800; else if (baud <= 567138) baud = 500000; else if (baud <= 670254) baud = 576000; - else if (baud < 1000000) - baud = 921600; - else if (baud > 2000000) - baud = 2000000; + else if (baud <= 1053257) baud = 921600; + else if (baud <= 1474560) baud = 1228800; + else if (baud <= 2457600) baud = 1843200; + else baud = 3686400; return baud; } @@ -414,14 +409,13 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) return result; } + result = usb_serial_generic_open(tty, port); + if (result) + return result; + /* Configure the termios structure */ cp210x_get_termios(tty, port); - - /* The baud rate must be initialised on cp2104 */ - if (tty) - cp210x_change_speed(tty, port, NULL); - - return usb_serial_generic_open(tty, port); + return 0; } static void cp210x_close(struct usb_serial_port *port) @@ -473,7 +467,10 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, dbg("%s - port %d", __func__, port->number); - cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4); + cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); + /* Convert to baudrate */ + if (baud) + baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); dbg("%s - baud rate = %d", __func__, baud); *baudp = baud; @@ -582,64 +579,11 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, *cflagp = cflag; } -/* - * CP2101 supports the following baud rates: - * - * 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 28800, - * 38400, 56000, 57600, 115200, 128000, 230400, 460800, 921600 - * - * CP2102 and CP2103 support the following additional rates: - * - * 4000, 16000, 51200, 64000, 76800, 153600, 250000, 256000, 500000, - * 576000 - * - * The device will map a requested rate to a supported one, but the result - * of requests for rates greater than 1053257 is undefined (see AN205). - * - * CP2104, CP2105 and CP2110 support most rates up to 2M, 921k and 1M baud, - * respectively, with an error less than 1%. The actual rates are determined - * by - * - * div = round(freq / (2 x prescale x request)) - * actual = freq / (2 x prescale x div) - * - * For CP2104 and CP2105 freq is 48Mhz and prescale is 4 for request <= 365bps - * or 1 otherwise. - * For CP2110 freq is 24Mhz and prescale is 4 for request <= 300bps or 1 - * otherwise. - */ -static void cp210x_change_speed(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - u32 baud; - - baud = tty->termios->c_ospeed; - - /* This maps the requested rate to a rate valid on cp2102 or cp2103, - * or to an arbitrary rate in [1M,2M]. - * - * NOTE: B0 is not implemented. - */ - baud = cp210x_quantise_baudrate(baud); - - dbg("%s - setting baud rate to %u", __func__, baud); - if (cp210x_set_config(port, CP210X_SET_BAUDRATE, &baud, - sizeof(baud))) { - dev_warn(&port->dev, "failed to set baud rate to %u\n", baud); - if (old_termios) - baud = old_termios->c_ospeed; - else - baud = 9600; - } - - tty_encode_baud_rate(tty, baud, baud); -} - static void cp210x_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { unsigned int cflag, old_cflag; - unsigned int bits; + unsigned int baud = 0, bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __func__, port->number); @@ -649,9 +593,20 @@ static void cp210x_set_termios(struct tty_struct *tty, cflag = tty->termios->c_cflag; old_cflag = old_termios->c_cflag; - - if (tty->termios->c_ospeed != old_termios->c_ospeed) - cp210x_change_speed(tty, port, old_termios); + baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty)); + + /* If the baud rate is to be updated*/ + if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { + dbg("%s - Setting baud rate to %d baud", __func__, + baud); + if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, + ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { + dbg("Baud rate requested not supported by device"); + baud = tty_termios_baud_rate(old_termios); + } + } + /* Report back the resulting baud rate */ + tty_encode_baud_rate(tty, baud, baud); /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index ad654f8208ef..01b6404df395 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -797,7 +797,6 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) }, { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, @@ -806,8 +805,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) }, @@ -844,7 +841,6 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(ST_VID, ST_STMCLT1030_PID), .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, - { USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -1337,7 +1333,8 @@ static int set_serial_info(struct tty_struct *tty, goto check_and_exit; } - if (new_serial.baud_base != priv->baud_base) { + if ((new_serial.baud_base != priv->baud_base) && + (new_serial.baud_base < 9600)) { mutex_unlock(&priv->cfg_lock); return -EINVAL; } @@ -1827,7 +1824,6 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) { - struct ktermios dummy; struct usb_device *dev = port->serial->dev; struct ftdi_private *priv = usb_get_serial_port_data(port); int result; @@ -1846,10 +1842,8 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) This is same behaviour as serial.c/rs_open() - Kuba */ /* ftdi_set_termios will send usb control messages */ - if (tty) { - memset(&dummy, 0, sizeof(dummy)); - ftdi_set_termios(tty, port, &dummy); - } + if (tty) + ftdi_set_termios(tty, port, tty->termios); /* Start reading from the device */ result = usb_serial_generic_open(tty, port); diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index f994503df2dd..df1d7da933ec 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -39,13 +39,6 @@ /* www.candapter.com Ewert Energy Systems CANdapter device */ #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ -/* - * Texas Instruments XDS100v2 JTAG / BeagleBone A3 - * http://processors.wiki.ti.com/index.php/XDS100 - * http://beagleboard.org/bone - */ -#define TI_XDS100V2_PID 0xa6d0 - #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ /* US Interface Navigator (http://www.usinterface.com/) */ @@ -531,12 +524,6 @@ #define ADI_GNICE_PID 0xF000 #define ADI_GNICEPLUS_PID 0xF001 -/* - * Hornby Elite - */ -#define HORNBY_VID 0x04D8 -#define HORNBY_ELITE_PID 0x000A - /* * RATOC REX-USB60F */ @@ -1181,9 +1168,3 @@ */ /* TagTracer MIFARE*/ #define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0 - -/* - * Rainforest Automation - */ -/* ZigBee controller */ -#define FTDI_RF_R106 0x8A28 diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index 5818bfc3261e..65bf06aa591a 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -2657,7 +2657,15 @@ static int edge_startup(struct usb_serial *serial) static void edge_disconnect(struct usb_serial *serial) { + int i; + struct edgeport_port *edge_port; + dbg("%s", __func__); + + for (i = 0; i < serial->num_ports; ++i) { + edge_port = usb_get_serial_port_data(serial->port[i]); + edge_remove_sysfs_attrs(edge_port->port); + } } static void edge_release(struct usb_serial *serial) @@ -2736,7 +2744,6 @@ static struct usb_serial_driver edgeport_1port_device = { .disconnect = edge_disconnect, .release = edge_release, .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -2768,7 +2775,6 @@ static struct usb_serial_driver edgeport_2port_device = { .disconnect = edge_disconnect, .release = edge_release, .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, diff --git a/trunk/drivers/usb/serial/kobil_sct.c b/trunk/drivers/usb/serial/kobil_sct.c index a92a3efb507b..5d3beeeb5fd9 100644 --- a/trunk/drivers/usb/serial/kobil_sct.c +++ b/trunk/drivers/usb/serial/kobil_sct.c @@ -38,7 +38,7 @@ #include #include "kobil_sct.h" -static bool debug; +static int debug; /* Version Information */ #define DRIVER_VERSION "21/05/2004" diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index ea126a4490cd..420d9857394a 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -480,10 +480,6 @@ static void option_instat_callback(struct urb *urb); #define ZD_VENDOR_ID 0x0685 #define ZD_PRODUCT_7000 0x7000 -/* LG products */ -#define LG_VENDOR_ID 0x1004 -#define LG_PRODUCT_L02C 0x618f - /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -1187,7 +1183,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, - { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/trunk/drivers/usb/serial/qcaux.c b/trunk/drivers/usb/serial/qcaux.c index a34819884c1a..30b73e68a904 100644 --- a/trunk/drivers/usb/serial/qcaux.c +++ b/trunk/drivers/usb/serial/qcaux.c @@ -36,7 +36,6 @@ #define UTSTARCOM_PRODUCT_UM175_V1 0x3712 #define UTSTARCOM_PRODUCT_UM175_V2 0x3714 #define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715 -#define PANTECH_PRODUCT_UML190_VZW 0x3716 #define PANTECH_PRODUCT_UML290_VZW 0x3718 /* CMOTECH devices */ @@ -68,11 +67,7 @@ static struct usb_device_id id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xfe, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfd, 0xff) }, /* NMEA */ - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfe, 0xff) }, /* WMC */ - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, /* DIAG */ + { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/trunk/drivers/usb/storage/realtek_cr.c b/trunk/drivers/usb/storage/realtek_cr.c index d32f72061c09..1f62723ef1a8 100644 --- a/trunk/drivers/usb/storage/realtek_cr.c +++ b/trunk/drivers/usb/storage/realtek_cr.c @@ -789,7 +789,7 @@ static void rts51x_suspend_timer_fn(unsigned long data) rts51x_set_stat(chip, RTS51X_STAT_SS); /* ignore mass storage interface's children */ pm_suspend_ignore_children(&us->pusb_intf->dev, true); - usb_autopm_put_interface_async(us->pusb_intf); + usb_autopm_put_interface(us->pusb_intf); US_DEBUGP("%s: RTS51X_STAT_SS 01," "intf->pm_usage_cnt:%d, power.usage:%d\n", __func__, diff --git a/trunk/drivers/usb/usb-skeleton.c b/trunk/drivers/usb/usb-skeleton.c index b4a71679c933..8efeae24764f 100644 --- a/trunk/drivers/usb/usb-skeleton.c +++ b/trunk/drivers/usb/usb-skeleton.c @@ -27,6 +27,8 @@ #define USB_SKEL_VENDOR_ID 0xfff0 #define USB_SKEL_PRODUCT_ID 0xfff0 +static DEFINE_MUTEX(skel_mutex); + /* table of devices that work with this driver */ static const struct usb_device_id skel_table[] = { { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, @@ -99,18 +101,25 @@ static int skel_open(struct inode *inode, struct file *file) goto exit; } + mutex_lock(&skel_mutex); dev = usb_get_intfdata(interface); if (!dev) { + mutex_unlock(&skel_mutex); retval = -ENODEV; goto exit; } /* increment our usage count for the device */ kref_get(&dev->kref); + mutex_unlock(&skel_mutex); /* lock the device to allow correctly handling errors * in resumption */ mutex_lock(&dev->io_mutex); + if (!dev->interface) { + retval = -ENODEV; + goto out_err; + } retval = usb_autopm_get_interface(interface); if (retval) @@ -118,7 +127,11 @@ static int skel_open(struct inode *inode, struct file *file) /* save our object in the file's private structure */ file->private_data = dev; + +out_err: mutex_unlock(&dev->io_mutex); + if (retval) + kref_put(&dev->kref, skel_delete); exit: return retval; @@ -598,7 +611,6 @@ static void skel_disconnect(struct usb_interface *interface) int minor = interface->minor; dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); /* give back our minor */ usb_deregister_dev(interface, &skel_class); @@ -610,8 +622,12 @@ static void skel_disconnect(struct usb_interface *interface) usb_kill_anchored_urbs(&dev->submitted); + mutex_lock(&skel_mutex); + usb_set_intfdata(interface, NULL); + /* decrement our usage count */ kref_put(&dev->kref, skel_delete); + mutex_unlock(&skel_mutex); dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor); } diff --git a/trunk/drivers/usb/wusbcore/Kconfig b/trunk/drivers/usb/wusbcore/Kconfig index f29fdd7f6d75..0ead8826ec79 100644 --- a/trunk/drivers/usb/wusbcore/Kconfig +++ b/trunk/drivers/usb/wusbcore/Kconfig @@ -6,7 +6,7 @@ config USB_WUSB depends on EXPERIMENTAL depends on USB depends on PCI - depends on UWB + select UWB select CRYPTO select CRYPTO_BLKCIPHER select CRYPTO_CBC diff --git a/trunk/drivers/video/macfb.c b/trunk/drivers/video/macfb.c index fe01add3700e..43207cc6cc19 100644 --- a/trunk/drivers/video/macfb.c +++ b/trunk/drivers/video/macfb.c @@ -592,12 +592,12 @@ static int __init macfb_init(void) if (!fb_info.screen_base) return -ENODEV; - pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n", - macfb_fix.smem_start, fb_info.screen_base, - macfb_fix.smem_len / 1024); - pr_info("macfb: mode is %dx%dx%d, linelength=%d\n", - macfb_defined.xres, macfb_defined.yres, - macfb_defined.bits_per_pixel, macfb_fix.line_length); + printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n", + macfb_fix.smem_start, fb_info.screen_base, + macfb_fix.smem_len / 1024); + printk("macfb: mode is %dx%dx%d, linelength=%d\n", + macfb_defined.xres, macfb_defined.yres, + macfb_defined.bits_per_pixel, macfb_fix.line_length); /* Fill in the available video resolution */ macfb_defined.xres_virtual = macfb_defined.xres; @@ -613,10 +613,14 @@ static int __init macfb_init(void) switch (macfb_defined.bits_per_pixel) { case 1: + /* + * XXX: I think this will catch any program that tries + * to do FBIO_PUTCMAP when the visual is monochrome. + */ macfb_defined.red.length = macfb_defined.bits_per_pixel; macfb_defined.green.length = macfb_defined.bits_per_pixel; macfb_defined.blue.length = macfb_defined.bits_per_pixel; - video_cmap_len = 2; + video_cmap_len = 0; macfb_fix.visual = FB_VISUAL_MONO01; break; case 2: @@ -656,10 +660,11 @@ static int __init macfb_init(void) macfb_fix.visual = FB_VISUAL_TRUECOLOR; break; default: - pr_err("macfb: unknown or unsupported bit depth: %d\n", + video_cmap_len = 0; + macfb_fix.visual = FB_VISUAL_MONO01; + printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel); - err = -EINVAL; - goto fail_unmap; + break; } /* @@ -729,8 +734,8 @@ static int __init macfb_init(void) case MAC_MODEL_Q950: strcpy(macfb_fix.id, "DAFB"); macfb_setpalette = dafb_setpalette; - dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); macfb_defined.activate = FB_ACTIVATE_NOW; + dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); break; /* @@ -739,8 +744,8 @@ static int __init macfb_init(void) case MAC_MODEL_LCII: strcpy(macfb_fix.id, "V8"); macfb_setpalette = v8_brazil_setpalette; - v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); macfb_defined.activate = FB_ACTIVATE_NOW; + v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); break; /* @@ -753,8 +758,8 @@ static int __init macfb_init(void) case MAC_MODEL_P600: strcpy(macfb_fix.id, "Brazil"); macfb_setpalette = v8_brazil_setpalette; - v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); macfb_defined.activate = FB_ACTIVATE_NOW; + v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); break; /* @@ -768,10 +773,10 @@ static int __init macfb_init(void) case MAC_MODEL_P520: case MAC_MODEL_P550: case MAC_MODEL_P460: - strcpy(macfb_fix.id, "Sonora"); macfb_setpalette = v8_brazil_setpalette; - v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); macfb_defined.activate = FB_ACTIVATE_NOW; + strcpy(macfb_fix.id, "Sonora"); + v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); break; /* @@ -781,10 +786,10 @@ static int __init macfb_init(void) */ case MAC_MODEL_IICI: case MAC_MODEL_IISI: - strcpy(macfb_fix.id, "RBV"); macfb_setpalette = rbv_setpalette; - rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); macfb_defined.activate = FB_ACTIVATE_NOW; + strcpy(macfb_fix.id, "RBV"); + rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); break; /* @@ -792,10 +797,10 @@ static int __init macfb_init(void) */ case MAC_MODEL_Q840: case MAC_MODEL_C660: - strcpy(macfb_fix.id, "Civic"); macfb_setpalette = civic_setpalette; - civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000); macfb_defined.activate = FB_ACTIVATE_NOW; + strcpy(macfb_fix.id, "Civic"); + civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000); break; @@ -804,26 +809,26 @@ static int __init macfb_init(void) * We think this may be like the LC II */ case MAC_MODEL_LC: - strcpy(macfb_fix.id, "LC"); if (vidtest) { macfb_setpalette = v8_brazil_setpalette; + macfb_defined.activate = FB_ACTIVATE_NOW; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; } + strcpy(macfb_fix.id, "LC"); break; /* * We think this may be like the LC II */ case MAC_MODEL_CCL: - strcpy(macfb_fix.id, "Color Classic"); if (vidtest) { macfb_setpalette = v8_brazil_setpalette; + macfb_defined.activate = FB_ACTIVATE_NOW; v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); - macfb_defined.activate = FB_ACTIVATE_NOW; } + strcpy(macfb_fix.id, "Color Classic"); break; /* @@ -888,10 +893,10 @@ static int __init macfb_init(void) case MAC_MODEL_PB270C: case MAC_MODEL_PB280: case MAC_MODEL_PB280C: - strcpy(macfb_fix.id, "CSC"); macfb_setpalette = csc_setpalette; - csc_cmap_regs = ioremap(CSC_BASE, 0x1000); macfb_defined.activate = FB_ACTIVATE_NOW; + strcpy(macfb_fix.id, "CSC"); + csc_cmap_regs = ioremap(CSC_BASE, 0x1000); break; default: @@ -913,9 +918,8 @@ static int __init macfb_init(void) if (err) goto fail_dealloc; - pr_info("fb%d: %s frame buffer device\n", - fb_info.node, fb_info.fix.id); - + printk("fb%d: %s frame buffer device\n", + fb_info.node, fb_info.fix.id); return 0; fail_dealloc: diff --git a/trunk/drivers/virtio/virtio_ring.c b/trunk/drivers/virtio/virtio_ring.c index 5aa43c3392a2..79e1b292c030 100644 --- a/trunk/drivers/virtio/virtio_ring.c +++ b/trunk/drivers/virtio/virtio_ring.c @@ -35,7 +35,7 @@ #define virtio_rmb(vq) \ do { if ((vq)->weak_barriers) smp_rmb(); else rmb(); } while(0) #define virtio_wmb(vq) \ - do { if ((vq)->weak_barriers) smp_wmb(); else wmb(); } while(0) + do { if ((vq)->weak_barriers) smp_rmb(); else rmb(); } while(0) #else /* We must force memory ordering even if guest is UP since host could be * running on another CPU, but SMP barriers are defined to barrier() in that @@ -308,9 +308,9 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq) bool needs_kick; START_USE(vq); - /* We need to expose available array entries before checking avail - * event. */ - virtio_mb(vq); + /* Descriptors and available array need to be set before we expose the + * new available array entries. */ + virtio_wmb(vq); old = vq->vring.avail->idx - vq->num_added; new = vq->vring.avail->idx; diff --git a/trunk/drivers/watchdog/dw_wdt.c b/trunk/drivers/watchdog/dw_wdt.c index 63d7b58f1c7d..1b0e3dd81c1a 100644 --- a/trunk/drivers/watchdog/dw_wdt.c +++ b/trunk/drivers/watchdog/dw_wdt.c @@ -300,7 +300,11 @@ static int __devinit dw_wdt_drv_probe(struct platform_device *pdev) if (!mem) return -EINVAL; - dw_wdt.regs = devm_request_and_ioremap(&pdev->dev, mem); + if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), + "dw_wdt")) + return -ENOMEM; + + dw_wdt.regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!dw_wdt.regs) return -ENOMEM; diff --git a/trunk/drivers/watchdog/iTCO_wdt.c b/trunk/drivers/watchdog/iTCO_wdt.c index bdf401b240b5..99796c5d913d 100644 --- a/trunk/drivers/watchdog/iTCO_wdt.c +++ b/trunk/drivers/watchdog/iTCO_wdt.c @@ -36,7 +36,6 @@ * document number TBD : Patsburg (PBG) * document number TBD : DH89xxCC * document number TBD : Panther Point - * document number TBD : Lynx Point */ /* @@ -127,7 +126,6 @@ enum iTCO_chipsets { TCO_PBG, /* Patsburg */ TCO_DH89XXCC, /* DH89xxCC */ TCO_PPT, /* Panther Point */ - TCO_LPT, /* Lynx Point */ }; static struct { @@ -191,7 +189,6 @@ static struct { {"Patsburg", 2}, {"DH89xxCC", 2}, {"Panther Point", 2}, - {"Lynx Point", 2}, {NULL, 0} }; @@ -334,38 +331,6 @@ static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = { { PCI_VDEVICE(INTEL, 0x1e5d), TCO_PPT}, { PCI_VDEVICE(INTEL, 0x1e5e), TCO_PPT}, { PCI_VDEVICE(INTEL, 0x1e5f), TCO_PPT}, - { PCI_VDEVICE(INTEL, 0x8c40), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c41), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c42), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c43), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c44), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c45), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c46), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c47), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c48), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c49), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4a), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4b), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4c), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4d), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4e), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4f), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c50), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c51), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c52), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c53), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c54), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c55), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c56), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c57), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c58), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c59), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5a), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5b), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5c), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5d), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5e), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5f), TCO_LPT}, { 0, }, /* End of list */ }; MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); diff --git a/trunk/drivers/watchdog/imx2_wdt.c b/trunk/drivers/watchdog/imx2_wdt.c index c44c3334003a..b8ef2c6dca7c 100644 --- a/trunk/drivers/watchdog/imx2_wdt.c +++ b/trunk/drivers/watchdog/imx2_wdt.c @@ -247,6 +247,7 @@ static struct miscdevice imx2_wdt_miscdev = { static int __init imx2_wdt_probe(struct platform_device *pdev) { int ret; + int res_size; struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -255,7 +256,15 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) return -ENODEV; } - imx2_wdt.base = devm_request_and_ioremap(&pdev->dev, res); + res_size = resource_size(res); + if (!devm_request_mem_region(&pdev->dev, res->start, res_size, + res->name)) { + dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n", + res_size, res->start); + return -ENOMEM; + } + + imx2_wdt.base = devm_ioremap_nocache(&pdev->dev, res->start, res_size); if (!imx2_wdt.base) { dev_err(&pdev->dev, "ioremap failed\n"); return -ENOMEM; diff --git a/trunk/drivers/watchdog/nuc900_wdt.c b/trunk/drivers/watchdog/nuc900_wdt.c index 529085b8b8fb..50359bad9177 100644 --- a/trunk/drivers/watchdog/nuc900_wdt.c +++ b/trunk/drivers/watchdog/nuc900_wdt.c @@ -72,7 +72,7 @@ struct nuc900_wdt { }; static unsigned long nuc900wdt_busy; -static struct nuc900_wdt *nuc900_wdt; +struct nuc900_wdt *nuc900_wdt; static inline void nuc900_wdt_keepalive(void) { @@ -287,8 +287,7 @@ static int __devinit nuc900wdt_probe(struct platform_device *pdev) setup_timer(&nuc900_wdt->timer, nuc900_wdt_timer_ping, 0); - ret = misc_register(&nuc900wdt_miscdev); - if (ret) { + if (misc_register(&nuc900wdt_miscdev)) { dev_err(&pdev->dev, "err register miscdev on minor=%d (%d)\n", WATCHDOG_MINOR, ret); goto err_clk; diff --git a/trunk/drivers/watchdog/omap_wdt.c b/trunk/drivers/watchdog/omap_wdt.c index d19ff5145e82..4b33e3fd726b 100644 --- a/trunk/drivers/watchdog/omap_wdt.c +++ b/trunk/drivers/watchdog/omap_wdt.c @@ -339,7 +339,6 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) return 0; err_misc: - pm_runtime_disable(wdev->dev); platform_set_drvdata(pdev, NULL); iounmap(wdev->base); @@ -372,7 +371,6 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev) struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pm_runtime_disable(wdev->dev); if (!res) return -ENOENT; diff --git a/trunk/drivers/watchdog/pnx4008_wdt.c b/trunk/drivers/watchdog/pnx4008_wdt.c index 8e210aafdfd0..bd143c9dd3e6 100644 --- a/trunk/drivers/watchdog/pnx4008_wdt.c +++ b/trunk/drivers/watchdog/pnx4008_wdt.c @@ -226,7 +226,7 @@ static long pnx4008_wdt_ioctl(struct file *file, unsigned int cmd, static int pnx4008_wdt_release(struct inode *inode, struct file *file) { if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status)) - printk(KERN_WARNING "WATCHDOG: Device closed unexpectedly\n"); + printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); wdt_disable(); clk_disable(wdt_clk); diff --git a/trunk/drivers/watchdog/stmp3xxx_wdt.c b/trunk/drivers/watchdog/stmp3xxx_wdt.c index e37d81178b9e..4c2a4e8698f9 100644 --- a/trunk/drivers/watchdog/stmp3xxx_wdt.c +++ b/trunk/drivers/watchdog/stmp3xxx_wdt.c @@ -174,7 +174,7 @@ static int stmp3xxx_wdt_release(struct inode *inode, struct file *file) if (!nowayout) { if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { wdt_ping(); - pr_debug("%s: Device closed unexpectedly\n", __func__); + pr_debug("%s: Device closed unexpectdly\n", __func__); ret = -EINVAL; } else { wdt_disable(); diff --git a/trunk/drivers/watchdog/via_wdt.c b/trunk/drivers/watchdog/via_wdt.c index 8f07dd4bd94a..026b4bbfa0aa 100644 --- a/trunk/drivers/watchdog/via_wdt.c +++ b/trunk/drivers/watchdog/via_wdt.c @@ -124,6 +124,8 @@ static int wdt_stop(struct watchdog_device *wdd) static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int new_timeout) { + if (new_timeout < 1 || new_timeout > WDT_TIMEOUT_MAX) + return -EINVAL; writel(new_timeout, wdt_mem + VIA_WDT_COUNT); timeout = new_timeout; return 0; @@ -148,8 +150,6 @@ static const struct watchdog_ops wdt_ops = { static struct watchdog_device wdt_dev = { .info = &wdt_info, .ops = &wdt_ops, - .min_timeout = 1, - .max_timeout = WDT_TIMEOUT_MAX, }; static int __devinit wdt_probe(struct pci_dev *pdev, @@ -233,7 +233,7 @@ static void __devexit wdt_remove(struct pci_dev *pdev) pci_disable_device(pdev); } -static DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = { +DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700) }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800) }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, diff --git a/trunk/drivers/watchdog/wafer5823wdt.c b/trunk/drivers/watchdog/wafer5823wdt.c index c3c3188c34d7..42e940c23891 100644 --- a/trunk/drivers/watchdog/wafer5823wdt.c +++ b/trunk/drivers/watchdog/wafer5823wdt.c @@ -152,12 +152,12 @@ static long wafwdt_ioctl(struct file *file, unsigned int cmd, return -EFAULT; if (options & WDIOS_DISABLECARD) { - wafwdt_stop(); + wafwdt_start(); retval = 0; } if (options & WDIOS_ENABLECARD) { - wafwdt_start(); + wafwdt_stop(); retval = 0; } diff --git a/trunk/drivers/watchdog/wm8350_wdt.c b/trunk/drivers/watchdog/wm8350_wdt.c index 5d7113c7e501..909c78650d3e 100644 --- a/trunk/drivers/watchdog/wm8350_wdt.c +++ b/trunk/drivers/watchdog/wm8350_wdt.c @@ -212,10 +212,10 @@ static long wm8350_wdt_ioctl(struct file *file, unsigned int cmd, /* Setting both simultaneously means at least one must fail */ if (options == WDIOS_DISABLECARD) - ret = wm8350_wdt_stop(wm8350); + ret = wm8350_wdt_start(wm8350); if (options == WDIOS_ENABLECARD) - ret = wm8350_wdt_start(wm8350); + ret = wm8350_wdt_stop(wm8350); break; } diff --git a/trunk/drivers/xen/grant-table.c b/trunk/drivers/xen/grant-table.c index b4d4eac761db..1cd94daa71db 100644 --- a/trunk/drivers/xen/grant-table.c +++ b/trunk/drivers/xen/grant-table.c @@ -948,12 +948,9 @@ static void gnttab_request_version(void) int rc; struct gnttab_set_version gsv; - if (xen_hvm_domain()) - gsv.version = 1; - else - gsv.version = 2; + gsv.version = 2; rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1); - if (rc == 0 && gsv.version == 2) { + if (rc == 0) { grant_table_version = 2; gnttab_interface = &gnttab_v2_ops; } else if (grant_table_version == 2) { diff --git a/trunk/fs/btrfs/backref.c b/trunk/fs/btrfs/backref.c index 633c701a287d..b9a843226de8 100644 --- a/trunk/fs/btrfs/backref.c +++ b/trunk/fs/btrfs/backref.c @@ -297,7 +297,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, struct btrfs_delayed_extent_op *extent_op = head->extent_op; struct rb_node *n = &head->node.rb_node; int sgn; - int ret = 0; + int ret; if (extent_op && extent_op->update_key) btrfs_disk_key_to_cpu(info_key, &extent_op->key); @@ -392,7 +392,7 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info, struct btrfs_key *info_key, int *info_level, struct list_head *prefs) { - int ret = 0; + int ret; int slot; struct extent_buffer *leaf; struct btrfs_key key; diff --git a/trunk/fs/btrfs/check-integrity.c b/trunk/fs/btrfs/check-integrity.c index b669a7d8e499..ad0b3ba735b7 100644 --- a/trunk/fs/btrfs/check-integrity.c +++ b/trunk/fs/btrfs/check-integrity.c @@ -1662,7 +1662,7 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, block = btrfsic_block_hashtable_lookup(bdev, dev_bytenr, &state->block_hashtable); if (NULL != block) { - u64 bytenr = 0; + u64 bytenr; struct list_head *elem_ref_to; struct list_head *tmp_ref_to; @@ -2777,10 +2777,9 @@ int btrfsic_submit_bh(int rw, struct buffer_head *bh) printk(KERN_INFO "submit_bh(rw=0x%x, blocknr=%lu (bytenr %llu)," " size=%lu, data=%p, bdev=%p)\n", - rw, (unsigned long)bh->b_blocknr, - (unsigned long long)dev_bytenr, - (unsigned long)bh->b_size, bh->b_data, - bh->b_bdev); + rw, bh->b_blocknr, + (unsigned long long)dev_bytenr, bh->b_size, + bh->b_data, bh->b_bdev); btrfsic_process_written_block(dev_state, dev_bytenr, bh->b_data, bh->b_size, NULL, NULL, bh, rw); @@ -2845,7 +2844,7 @@ void btrfsic_submit_bio(int rw, struct bio *bio) printk(KERN_INFO "submit_bio(rw=0x%x, bi_vcnt=%u," " bi_sector=%lu (bytenr %llu), bi_bdev=%p)\n", - rw, bio->bi_vcnt, (unsigned long)bio->bi_sector, + rw, bio->bi_vcnt, bio->bi_sector, (unsigned long long)dev_bytenr, bio->bi_bdev); diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index 811d9f918b1c..7aa9cd36bf1b 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -962,13 +962,6 @@ static int btree_releasepage(struct page *page, gfp_t gfp_flags) tree = &BTRFS_I(page->mapping->host)->io_tree; map = &BTRFS_I(page->mapping->host)->extent_tree; - /* - * We need to mask out eg. __GFP_HIGHMEM and __GFP_DMA32 as we're doing - * slab allocation from alloc_extent_state down the callchain where - * it'd hit a BUG_ON as those flags are not allowed. - */ - gfp_flags &= ~GFP_SLAB_BUG_MASK; - ret = try_release_extent_state(map, tree, page, gfp_flags); if (!ret) return 0; diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 283af7a676a3..700879ed64cf 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -34,24 +34,23 @@ #include "locking.h" #include "free-space-cache.h" -/* - * control flags for do_chunk_alloc's force field +/* control flags for do_chunk_alloc's force field * CHUNK_ALLOC_NO_FORCE means to only allocate a chunk * if we really need one. * + * CHUNK_ALLOC_FORCE means it must try to allocate one + * * CHUNK_ALLOC_LIMITED means to only try and allocate one * if we have very few chunks already allocated. This is * used as part of the clustering code to help make sure * we have a good pool of storage to cluster in, without * filling the FS with empty chunks * - * CHUNK_ALLOC_FORCE means it must try to allocate one - * */ enum { CHUNK_ALLOC_NO_FORCE = 0, - CHUNK_ALLOC_LIMITED = 1, - CHUNK_ALLOC_FORCE = 2, + CHUNK_ALLOC_FORCE = 1, + CHUNK_ALLOC_LIMITED = 2, }; /* @@ -3415,7 +3414,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, again: spin_lock(&space_info->lock); - if (force < space_info->force_alloc) + if (space_info->force_alloc) force = space_info->force_alloc; if (space_info->full) { spin_unlock(&space_info->lock); @@ -5795,7 +5794,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, u64 search_end, struct btrfs_key *ins, u64 data) { - bool final_tried = false; int ret; u64 search_start = 0; @@ -5815,25 +5813,22 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, search_start, search_end, hint_byte, ins, data); - if (ret == -ENOSPC) { - if (!final_tried) { - num_bytes = num_bytes >> 1; - num_bytes = num_bytes & ~(root->sectorsize - 1); - num_bytes = max(num_bytes, min_alloc_size); - do_chunk_alloc(trans, root->fs_info->extent_root, - num_bytes, data, CHUNK_ALLOC_FORCE); - if (num_bytes == min_alloc_size) - final_tried = true; - goto again; - } else if (btrfs_test_opt(root, ENOSPC_DEBUG)) { - struct btrfs_space_info *sinfo; - - sinfo = __find_space_info(root->fs_info, data); - printk(KERN_ERR "btrfs allocation failed flags %llu, " - "wanted %llu\n", (unsigned long long)data, - (unsigned long long)num_bytes); - dump_space_info(sinfo, num_bytes, 1); - } + if (ret == -ENOSPC && num_bytes > min_alloc_size) { + num_bytes = num_bytes >> 1; + num_bytes = num_bytes & ~(root->sectorsize - 1); + num_bytes = max(num_bytes, min_alloc_size); + do_chunk_alloc(trans, root->fs_info->extent_root, + num_bytes, data, CHUNK_ALLOC_FORCE); + goto again; + } + if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) { + struct btrfs_space_info *sinfo; + + sinfo = __find_space_info(root->fs_info, data); + printk(KERN_ERR "btrfs allocation failed flags %llu, " + "wanted %llu\n", (unsigned long long)data, + (unsigned long long)num_bytes); + dump_space_info(sinfo, num_bytes, 1); } trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index fcf77e1ded40..9d09a4f81875 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -3909,8 +3909,6 @@ int extent_range_uptodate(struct extent_io_tree *tree, while (start <= end) { index = start >> PAGE_CACHE_SHIFT; page = find_get_page(tree->mapping, index); - if (!page) - return 1; uptodate = PageUptodate(page); page_cache_release(page); if (!uptodate) { diff --git a/trunk/fs/btrfs/free-space-cache.c b/trunk/fs/btrfs/free-space-cache.c index c2f20594c9f7..d20ff87ca603 100644 --- a/trunk/fs/btrfs/free-space-cache.c +++ b/trunk/fs/btrfs/free-space-cache.c @@ -2242,7 +2242,7 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, if (entry->bitmap) { ret = btrfs_alloc_from_bitmap(block_group, cluster, entry, bytes, - cluster->window_start); + min_start); if (ret == 0) { node = rb_next(&entry->offset_index); if (!node) @@ -2251,7 +2251,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, offset_index); continue; } - cluster->window_start += bytes; } else { ret = entry->offset; @@ -2476,7 +2475,7 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, } list_for_each_entry(entry, bitmaps, list) { - if (entry->bytes < bytes) + if (entry->bytes < min_bytes) continue; ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset, bytes, cont1_bytes, min_bytes); diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 32214fe0f7e3..0da19a0ea00d 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -6401,23 +6401,18 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) unsigned long zero_start; loff_t size; int ret; - int reserved = 0; u64 page_start; u64 page_end; ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); - if (!ret) { + if (!ret) ret = btrfs_update_time(vma->vm_file); - reserved = 1; - } if (ret) { if (ret == -ENOMEM) ret = VM_FAULT_OOM; else /* -ENOSPC, -EIO, etc */ ret = VM_FAULT_SIGBUS; - if (reserved) - goto out; - goto out_noreserve; + goto out; } ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ @@ -6500,7 +6495,6 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) unlock_page(page); out: btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); -out_noreserve: return ret; } diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 03bb62a9ee24..ab620014bcc3 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -1065,7 +1065,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, i = range->start >> PAGE_CACHE_SHIFT; } if (!max_to_defrag) - max_to_defrag = last_index + 1; + max_to_defrag = last_index; /* * make writeback starts from i, so the defrag range can be diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index 966cc74f5d6c..cb877e0886a7 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -1957,8 +1957,7 @@ static int wait_log_commit(struct btrfs_trans_handle *trans, finish_wait(&root->log_commit_wait[index], &wait); mutex_lock(&root->log_mutex); - } while (root->fs_info->last_trans_log_full_commit != - trans->transid && root->log_transid < transid + 2 && + } while (root->log_transid < transid + 2 && atomic_read(&root->log_commit[index])); return 0; } @@ -1967,8 +1966,7 @@ static int wait_for_writer(struct btrfs_trans_handle *trans, struct btrfs_root *root) { DEFINE_WAIT(wait); - while (root->fs_info->last_trans_log_full_commit != - trans->transid && atomic_read(&root->log_writers)) { + while (atomic_read(&root->log_writers)) { prepare_to_wait(&root->log_writer_wait, &wait, TASK_UNINTERRUPTIBLE); mutex_unlock(&root->log_mutex); diff --git a/trunk/fs/ceph/caps.c b/trunk/fs/ceph/caps.c index 620daad201db..b60fc8bfb3e9 100644 --- a/trunk/fs/ceph/caps.c +++ b/trunk/fs/ceph/caps.c @@ -641,10 +641,10 @@ static int __cap_is_valid(struct ceph_cap *cap) unsigned long ttl; u32 gen; - spin_lock(&cap->session->s_gen_ttl_lock); + spin_lock(&cap->session->s_cap_lock); gen = cap->session->s_cap_gen; ttl = cap->session->s_cap_ttl; - spin_unlock(&cap->session->s_gen_ttl_lock); + spin_unlock(&cap->session->s_cap_lock); if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) { dout("__cap_is_valid %p cap %p issued %s " diff --git a/trunk/fs/ceph/dir.c b/trunk/fs/ceph/dir.c index 3e8094be4604..618246bc2196 100644 --- a/trunk/fs/ceph/dir.c +++ b/trunk/fs/ceph/dir.c @@ -975,10 +975,10 @@ static int dentry_lease_is_valid(struct dentry *dentry) di = ceph_dentry(dentry); if (di->lease_session) { s = di->lease_session; - spin_lock(&s->s_gen_ttl_lock); + spin_lock(&s->s_cap_lock); gen = s->s_cap_gen; ttl = s->s_cap_ttl; - spin_unlock(&s->s_gen_ttl_lock); + spin_unlock(&s->s_cap_lock); if (di->lease_gen == gen && time_before(jiffies, dentry->d_time) && diff --git a/trunk/fs/ceph/mds_client.c b/trunk/fs/ceph/mds_client.c index 866e8d7ca37d..23ab6a3f1825 100644 --- a/trunk/fs/ceph/mds_client.c +++ b/trunk/fs/ceph/mds_client.c @@ -262,7 +262,6 @@ static int parse_reply_info(struct ceph_msg *msg, /* trace */ ceph_decode_32_safe(&p, end, len, bad); if (len > 0) { - ceph_decode_need(&p, end, len, bad); err = parse_reply_info_trace(&p, p+len, info, features); if (err < 0) goto out_bad; @@ -271,7 +270,6 @@ static int parse_reply_info(struct ceph_msg *msg, /* extra */ ceph_decode_32_safe(&p, end, len, bad); if (len > 0) { - ceph_decode_need(&p, end, len, bad); err = parse_reply_info_extra(&p, p+len, info, features); if (err < 0) goto out_bad; @@ -400,11 +398,9 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS; s->s_con.peer_name.num = cpu_to_le64(mds); - spin_lock_init(&s->s_gen_ttl_lock); + spin_lock_init(&s->s_cap_lock); s->s_cap_gen = 0; s->s_cap_ttl = 0; - - spin_lock_init(&s->s_cap_lock); s->s_renew_requested = 0; s->s_renew_seq = 0; INIT_LIST_HEAD(&s->s_caps); @@ -2330,10 +2326,10 @@ static void handle_session(struct ceph_mds_session *session, case CEPH_SESSION_STALE: pr_info("mds%d caps went stale, renewing\n", session->s_mds); - spin_lock(&session->s_gen_ttl_lock); + spin_lock(&session->s_cap_lock); session->s_cap_gen++; session->s_cap_ttl = 0; - spin_unlock(&session->s_gen_ttl_lock); + spin_unlock(&session->s_cap_lock); send_renew_caps(mdsc, session); break; diff --git a/trunk/fs/ceph/mds_client.h b/trunk/fs/ceph/mds_client.h index 8c7c04ebb595..a50ca0e39475 100644 --- a/trunk/fs/ceph/mds_client.h +++ b/trunk/fs/ceph/mds_client.h @@ -117,13 +117,10 @@ struct ceph_mds_session { void *s_authorizer_buf, *s_authorizer_reply_buf; size_t s_authorizer_buf_len, s_authorizer_reply_buf_len; - /* protected by s_gen_ttl_lock */ - spinlock_t s_gen_ttl_lock; - u32 s_cap_gen; /* inc each time we get mds stale msg */ - unsigned long s_cap_ttl; /* when session caps expire */ - /* protected by s_cap_lock */ spinlock_t s_cap_lock; + u32 s_cap_gen; /* inc each time we get mds stale msg */ + unsigned long s_cap_ttl; /* when session caps expire */ struct list_head s_caps; /* all caps issued by this session */ int s_nr_caps, s_trim_caps; int s_num_cap_releases; diff --git a/trunk/fs/ceph/xattr.c b/trunk/fs/ceph/xattr.c index a76f697303d9..857214ae8c08 100644 --- a/trunk/fs/ceph/xattr.c +++ b/trunk/fs/ceph/xattr.c @@ -111,10 +111,8 @@ static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, } static struct ceph_vxattr_cb ceph_file_vxattrs[] = { - { true, "ceph.file.layout", ceph_vxattrcb_layout}, - /* The following extended attribute name is deprecated */ { true, "ceph.layout", ceph_vxattrcb_layout}, - { true, NULL, NULL } + { NULL, NULL } }; static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode) diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 986709a8d903..026d6464335b 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -3857,10 +3857,8 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) struct smb_vol *vol_info; vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL); - if (vol_info == NULL) { - tcon = ERR_PTR(-ENOMEM); - goto out; - } + if (vol_info == NULL) + return ERR_PTR(-ENOMEM); vol_info->local_nls = cifs_sb->local_nls; vol_info->linux_uid = fsuid; diff --git a/trunk/fs/ecryptfs/crypto.c b/trunk/fs/ecryptfs/crypto.c index 63ab24510649..2a834255c75d 100644 --- a/trunk/fs/ecryptfs/crypto.c +++ b/trunk/fs/ecryptfs/crypto.c @@ -417,6 +417,17 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, (unsigned long long)(extent_base + extent_offset), rc); goto out; } + if (unlikely(ecryptfs_verbosity > 0)) { + ecryptfs_printk(KERN_DEBUG, "Encrypting extent " + "with iv:\n"); + ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); + ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " + "encryption:\n"); + ecryptfs_dump_hex((char *) + (page_address(page) + + (extent_offset * crypt_stat->extent_size)), + 8); + } rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0, page, (extent_offset * crypt_stat->extent_size), @@ -429,6 +440,14 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, goto out; } rc = 0; + if (unlikely(ecryptfs_verbosity > 0)) { + ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; " + "rc = [%d]\n", + (unsigned long long)(extent_base + extent_offset), rc); + ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " + "encryption:\n"); + ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8); + } out: return rc; } @@ -524,6 +543,17 @@ static int ecryptfs_decrypt_extent(struct page *page, (unsigned long long)(extent_base + extent_offset), rc); goto out; } + if (unlikely(ecryptfs_verbosity > 0)) { + ecryptfs_printk(KERN_DEBUG, "Decrypting extent " + "with iv:\n"); + ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); + ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " + "decryption:\n"); + ecryptfs_dump_hex((char *) + (page_address(enc_extent_page) + + (extent_offset * crypt_stat->extent_size)), + 8); + } rc = ecryptfs_decrypt_page_offset(crypt_stat, page, (extent_offset * crypt_stat->extent_size), @@ -537,6 +567,16 @@ static int ecryptfs_decrypt_extent(struct page *page, goto out; } rc = 0; + if (unlikely(ecryptfs_verbosity > 0)) { + ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; " + "rc = [%d]\n", + (unsigned long long)(extent_base + extent_offset), rc); + ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " + "decryption:\n"); + ecryptfs_dump_hex((char *)(page_address(page) + + (extent_offset + * crypt_stat->extent_size)), 8); + } out: return rc; } @@ -1550,8 +1590,8 @@ int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry, */ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) { - int rc; - char *page_virt; + int rc = 0; + char *page_virt = NULL; struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; @@ -1576,13 +1616,11 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) ecryptfs_dentry, ECRYPTFS_VALIDATE_HEADER_SIZE); if (rc) { - /* metadata is not in the file header, so try xattrs */ memset(page_virt, 0, PAGE_CACHE_SIZE); rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); if (rc) { printk(KERN_DEBUG "Valid eCryptfs headers not found in " - "file header region or xattr region, inode %lu\n", - ecryptfs_inode->i_ino); + "file header region or xattr region\n"); rc = -EINVAL; goto out; } @@ -1591,8 +1629,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) ECRYPTFS_DONT_VALIDATE_HEADER_SIZE); if (rc) { printk(KERN_DEBUG "Valid eCryptfs headers not found in " - "file xattr region either, inode %lu\n", - ecryptfs_inode->i_ino); + "file xattr region either\n"); rc = -EINVAL; } if (crypt_stat->mount_crypt_stat->flags @@ -1603,8 +1640,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) "crypto metadata only in the extended attribute " "region, but eCryptfs was mounted without " "xattr support enabled. eCryptfs will not treat " - "this like an encrypted file, inode %lu\n", - ecryptfs_inode->i_ino); + "this like an encrypted file.\n"); rc = -EINVAL; } } diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index a2362df58ae8..a9f29b12fbf2 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -151,11 +151,6 @@ ecryptfs_get_key_payload_data(struct key *key) * dentry name */ #define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as * metadata */ -#define ECRYPTFS_MIN_PKT_LEN_SIZE 1 /* Min size to specify packet length */ -#define ECRYPTFS_MAX_PKT_LEN_SIZE 2 /* Pass at least this many bytes to - * ecryptfs_parse_packet_length() and - * ecryptfs_write_packet_length() - */ /* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >= * ECRYPTFS_MAX_IV_BYTES */ #define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16 diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 19892d7d2ed1..19a8ca4ab1dd 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -822,6 +822,18 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, size_t num_zeros = (PAGE_CACHE_SIZE - (ia->ia_size & ~PAGE_CACHE_MASK)); + + /* + * XXX(truncate) this should really happen at the begginning + * of ->setattr. But the code is too messy to that as part + * of a larger patch. ecryptfs is also totally missing out + * on the inode_change_ok check at the beginning of + * ->setattr while would include this. + */ + rc = inode_newsize_ok(inode, ia->ia_size); + if (rc) + goto out; + if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { truncate_setsize(inode, ia->ia_size); lower_ia->ia_size = ia->ia_size; @@ -871,28 +883,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, return rc; } -static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset) -{ - struct ecryptfs_crypt_stat *crypt_stat; - loff_t lower_oldsize, lower_newsize; - - crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; - lower_oldsize = upper_size_to_lower_size(crypt_stat, - i_size_read(inode)); - lower_newsize = upper_size_to_lower_size(crypt_stat, offset); - if (lower_newsize > lower_oldsize) { - /* - * The eCryptfs inode and the new *lower* size are mixed here - * because we may not have the lower i_mutex held and/or it may - * not be appropriate to call inode_newsize_ok() with inodes - * from other filesystems. - */ - return inode_newsize_ok(inode, lower_newsize); - } - - return 0; -} - /** * ecryptfs_truncate * @dentry: The ecryptfs layer dentry @@ -909,10 +899,6 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) struct iattr lower_ia = { .ia_valid = 0 }; int rc; - rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length); - if (rc) - return rc; - rc = truncate_upper(dentry, &ia, &lower_ia); if (!rc && lower_ia.ia_valid & ATTR_SIZE) { struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); @@ -992,16 +978,6 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) } } mutex_unlock(&crypt_stat->cs_mutex); - - rc = inode_change_ok(inode, ia); - if (rc) - goto out; - if (ia->ia_valid & ATTR_SIZE) { - rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size); - if (rc) - goto out; - } - if (S_ISREG(inode->i_mode)) { rc = filemap_write_and_wait(inode->i_mapping); if (rc) diff --git a/trunk/fs/ecryptfs/keystore.c b/trunk/fs/ecryptfs/keystore.c index 8e3b943e330f..ac1ad48c2376 100644 --- a/trunk/fs/ecryptfs/keystore.c +++ b/trunk/fs/ecryptfs/keystore.c @@ -109,7 +109,7 @@ int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, (*size) += ((unsigned char)(data[1]) + 192); (*length_size) = 2; } else if (data[0] == 255) { - /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */ + /* Five-byte length; we're not supposed to see this */ ecryptfs_printk(KERN_ERR, "Five-byte packet length not " "supported\n"); rc = -EINVAL; @@ -126,7 +126,7 @@ int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, /** * ecryptfs_write_packet_length * @dest: The byte array target into which to write the length. Must - * have at least ECRYPTFS_MAX_PKT_LEN_SIZE bytes allocated. + * have at least 5 bytes allocated. * @size: The length to write. * @packet_size_length: The number of bytes used to encode the packet * length is written to this address. @@ -146,7 +146,6 @@ int ecryptfs_write_packet_length(char *dest, size_t size, dest[1] = ((size - 192) % 256); (*packet_size_length) = 2; } else { - /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */ rc = -EINVAL; ecryptfs_printk(KERN_WARNING, "Unsupported packet size: [%zd]\n", size); diff --git a/trunk/fs/ecryptfs/miscdev.c b/trunk/fs/ecryptfs/miscdev.c index 349209dc6a91..940a82e63dc3 100644 --- a/trunk/fs/ecryptfs/miscdev.c +++ b/trunk/fs/ecryptfs/miscdev.c @@ -218,29 +218,6 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, return rc; } -/* - * miscdevfs packet format: - * Octet 0: Type - * Octets 1-4: network byte order msg_ctx->counter - * Octets 5-N0: Size of struct ecryptfs_message to follow - * Octets N0-N1: struct ecryptfs_message (including data) - * - * Octets 5-N1 not written if the packet type does not include a message - */ -#define PKT_TYPE_SIZE 1 -#define PKT_CTR_SIZE 4 -#define MIN_NON_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE) -#define MIN_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE \ - + ECRYPTFS_MIN_PKT_LEN_SIZE) -/* 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES comes from tag 65 packet format */ -#define MAX_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE \ - + ECRYPTFS_MAX_PKT_LEN_SIZE \ - + sizeof(struct ecryptfs_message) \ - + 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) -#define PKT_TYPE_OFFSET 0 -#define PKT_CTR_OFFSET PKT_TYPE_SIZE -#define PKT_LEN_OFFSET (PKT_TYPE_SIZE + PKT_CTR_SIZE) - /** * ecryptfs_miscdev_read - format and send message from queue * @file: fs/ecryptfs/euid miscdevfs handle (ignored) @@ -260,7 +237,7 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, struct ecryptfs_daemon *daemon; struct ecryptfs_msg_ctx *msg_ctx; size_t packet_length_size; - char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE]; + char packet_length[3]; size_t i; size_t total_length; uid_t euid = current_euid(); @@ -328,8 +305,15 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, packet_length_size = 0; msg_ctx->msg_size = 0; } - total_length = (PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_length_size - + msg_ctx->msg_size); + /* miscdevfs packet format: + * Octet 0: Type + * Octets 1-4: network byte order msg_ctx->counter + * Octets 5-N0: Size of struct ecryptfs_message to follow + * Octets N0-N1: struct ecryptfs_message (including data) + * + * Octets 5-N1 not written if the packet type does not + * include a message */ + total_length = (1 + 4 + packet_length_size + msg_ctx->msg_size); if (count < total_length) { rc = 0; printk(KERN_WARNING "%s: Only given user buffer of " @@ -340,10 +324,9 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, rc = -EFAULT; if (put_user(msg_ctx->type, buf)) goto out_unlock_msg_ctx; - if (put_user(cpu_to_be32(msg_ctx->counter), - (__be32 __user *)(&buf[PKT_CTR_OFFSET]))) + if (put_user(cpu_to_be32(msg_ctx->counter), (__be32 __user *)(buf + 1))) goto out_unlock_msg_ctx; - i = PKT_TYPE_SIZE + PKT_CTR_SIZE; + i = 5; if (msg_ctx->msg) { if (copy_to_user(&buf[i], packet_length, packet_length_size)) goto out_unlock_msg_ctx; @@ -408,6 +391,12 @@ static int ecryptfs_miscdev_response(char *data, size_t data_size, * @count: Amount of data in @buf * @ppos: Pointer to offset in file (ignored) * + * miscdevfs packet format: + * Octet 0: Type + * Octets 1-4: network byte order msg_ctx->counter (0's for non-response) + * Octets 5-N0: Size of struct ecryptfs_message to follow + * Octets N0-N1: struct ecryptfs_message (including data) + * * Returns the number of bytes read from @buf */ static ssize_t @@ -416,78 +405,60 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, { __be32 counter_nbo; u32 seq; - size_t packet_size, packet_size_length; + size_t packet_size, packet_size_length, i; + ssize_t sz = 0; char *data; uid_t euid = current_euid(); - unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE]; - ssize_t rc; - - if (count == 0) { - return 0; - } else if (count == MIN_NON_MSG_PKT_SIZE) { - /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */ - goto memdup; - } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) { - printk(KERN_WARNING "%s: Acceptable packet size range is " - "[%d-%lu], but amount of data written is [%zu].", - __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count); - return -EINVAL; - } - - if (copy_from_user(packet_size_peek, &buf[PKT_LEN_OFFSET], - sizeof(packet_size_peek))) { - printk(KERN_WARNING "%s: Error while inspecting packet size\n", - __func__); - return -EFAULT; - } - - rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size, - &packet_size_length); - if (rc) { - printk(KERN_WARNING "%s: Error parsing packet length; " - "rc = [%zd]\n", __func__, rc); - return rc; - } + int rc; - if ((PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_size_length + packet_size) - != count) { - printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__, - packet_size); - return -EINVAL; - } + if (count == 0) + goto out; -memdup: data = memdup_user(buf, count); if (IS_ERR(data)) { printk(KERN_ERR "%s: memdup_user returned error [%ld]\n", __func__, PTR_ERR(data)); - return PTR_ERR(data); + goto out; } - switch (data[PKT_TYPE_OFFSET]) { + sz = count; + i = 0; + switch (data[i++]) { case ECRYPTFS_MSG_RESPONSE: - if (count < (MIN_MSG_PKT_SIZE - + sizeof(struct ecryptfs_message))) { + if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) { printk(KERN_WARNING "%s: Minimum acceptable packet " "size is [%zd], but amount of data written is " "only [%zd]. Discarding response packet.\n", __func__, - (MIN_MSG_PKT_SIZE - + sizeof(struct ecryptfs_message)), count); - rc = -EINVAL; + (1 + 4 + 1 + sizeof(struct ecryptfs_message)), + count); goto out_free; } - memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE); + memcpy(&counter_nbo, &data[i], 4); seq = be32_to_cpu(counter_nbo); - rc = ecryptfs_miscdev_response( - &data[PKT_LEN_OFFSET + packet_size_length], - packet_size, euid, current_user_ns(), - task_pid(current), seq); + i += 4; + rc = ecryptfs_parse_packet_length(&data[i], &packet_size, + &packet_size_length); if (rc) { - printk(KERN_WARNING "%s: Failed to deliver miscdev " - "response to requesting operation; rc = [%zd]\n", - __func__, rc); + printk(KERN_WARNING "%s: Error parsing packet length; " + "rc = [%d]\n", __func__, rc); goto out_free; } + i += packet_size_length; + if ((1 + 4 + packet_size_length + packet_size) != count) { + printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])" + " + packet_size([%zd]))([%zd]) != " + "count([%zd]). Invalid packet format.\n", + __func__, packet_size_length, packet_size, + (1 + packet_size_length + packet_size), count); + goto out_free; + } + rc = ecryptfs_miscdev_response(&data[i], packet_size, + euid, current_user_ns(), + task_pid(current), seq); + if (rc) + printk(KERN_WARNING "%s: Failed to deliver miscdev " + "response to requesting operation; rc = [%d]\n", + __func__, rc); break; case ECRYPTFS_MSG_HELO: case ECRYPTFS_MSG_QUIT: @@ -496,13 +467,12 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, ecryptfs_printk(KERN_WARNING, "Dropping miscdev " "message of unrecognized type [%d]\n", data[0]); - rc = -EINVAL; - goto out_free; + break; } - rc = count; out_free: kfree(data); - return rc; +out: + return sz; } diff --git a/trunk/fs/ecryptfs/mmap.c b/trunk/fs/ecryptfs/mmap.c index 10ec695ccd68..6a44148c5fb9 100644 --- a/trunk/fs/ecryptfs/mmap.c +++ b/trunk/fs/ecryptfs/mmap.c @@ -57,10 +57,6 @@ struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index) * @page: Page that is locked before this call is made * * Returns zero on success; non-zero otherwise - * - * This is where we encrypt the data and pass the encrypted data to - * the lower filesystem. In OpenPGP-compatible mode, we operate on - * entire underlying packets. */ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) { @@ -485,6 +481,10 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode) * @copied: The amount of data copied * @page: The eCryptfs page * @fsdata: The fsdata (unused) + * + * This is where we encrypt the data and pass the encrypted data to + * the lower filesystem. In OpenPGP-compatible mode, we operate on + * entire underlying packets. */ static int ecryptfs_write_end(struct file *file, struct address_space *mapping, diff --git a/trunk/fs/ecryptfs/read_write.c b/trunk/fs/ecryptfs/read_write.c index 5c0106f75775..3745f7c2b9c2 100644 --- a/trunk/fs/ecryptfs/read_write.c +++ b/trunk/fs/ecryptfs/read_write.c @@ -130,18 +130,13 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); - loff_t total_remaining_bytes = ((offset + size) - pos); - - if (fatal_signal_pending(current)) { - rc = -EINTR; - break; - } + size_t total_remaining_bytes = ((offset + size) - pos); if (num_bytes > total_remaining_bytes) num_bytes = total_remaining_bytes; if (pos < offset) { /* remaining zeros to write, up to destination offset */ - loff_t total_remaining_zeros = (offset - pos); + size_t total_remaining_zeros = (offset - pos); if (num_bytes > total_remaining_zeros) num_bytes = total_remaining_zeros; @@ -198,19 +193,15 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, } pos += num_bytes; } - if (pos > ecryptfs_file_size) { - i_size_write(ecryptfs_inode, pos); + if ((offset + size) > ecryptfs_file_size) { + i_size_write(ecryptfs_inode, (offset + size)); if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { - int rc2; - - rc2 = ecryptfs_write_inode_size_to_metadata( + rc = ecryptfs_write_inode_size_to_metadata( ecryptfs_inode); - if (rc2) { + if (rc) { printk(KERN_ERR "Problem with " "ecryptfs_write_inode_size_to_metadata; " - "rc = [%d]\n", rc2); - if (!rc) - rc = rc2; + "rc = [%d]\n", rc); goto out; } } @@ -282,3 +273,76 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, flush_dcache_page(page_for_ecryptfs); return rc; } + +#if 0 +/** + * ecryptfs_read + * @data: The virtual address into which to write the data read (and + * possibly decrypted) from the lower file + * @offset: The offset in the decrypted view of the file from which to + * read into @data + * @size: The number of bytes to read into @data + * @ecryptfs_file: The eCryptfs file from which to read + * + * Read an arbitrary amount of data from an arbitrary location in the + * eCryptfs page cache. This is done on an extent-by-extent basis; + * individual extents are decrypted and read from the lower page + * cache (via VFS reads). This function takes care of all the + * address translation to locations in the lower filesystem. + * + * Returns zero on success; non-zero otherwise + */ +int ecryptfs_read(char *data, loff_t offset, size_t size, + struct file *ecryptfs_file) +{ + struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; + struct page *ecryptfs_page; + char *ecryptfs_page_virt; + loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); + loff_t data_offset = 0; + loff_t pos; + int rc = 0; + + if ((offset + size) > ecryptfs_file_size) { + rc = -EINVAL; + printk(KERN_ERR "%s: Attempt to read data past the end of the " + "file; offset = [%lld]; size = [%td]; " + "ecryptfs_file_size = [%lld]\n", + __func__, offset, size, ecryptfs_file_size); + goto out; + } + pos = offset; + while (pos < (offset + size)) { + pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); + size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); + size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); + size_t total_remaining_bytes = ((offset + size) - pos); + + if (num_bytes > total_remaining_bytes) + num_bytes = total_remaining_bytes; + ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, + ecryptfs_page_idx); + if (IS_ERR(ecryptfs_page)) { + rc = PTR_ERR(ecryptfs_page); + printk(KERN_ERR "%s: Error getting page at " + "index [%ld] from eCryptfs inode " + "mapping; rc = [%d]\n", __func__, + ecryptfs_page_idx, rc); + goto out; + } + ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); + memcpy((data + data_offset), + ((char *)ecryptfs_page_virt + start_offset_in_page), + num_bytes); + kunmap_atomic(ecryptfs_page_virt, KM_USER0); + flush_dcache_page(ecryptfs_page); + SetPageUptodate(ecryptfs_page); + unlock_page(ecryptfs_page); + page_cache_release(ecryptfs_page); + pos += num_bytes; + data_offset += num_bytes; + } +out: + return rc; +} +#endif /* 0 */ diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 92ce83a11e90..aeb135c7ff5c 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1071,21 +1071,6 @@ void set_task_comm(struct task_struct *tsk, char *buf) perf_event_comm(tsk); } -static void filename_to_taskname(char *tcomm, const char *fn, unsigned int len) -{ - int i, ch; - - /* Copies the binary name from after last slash */ - for (i = 0; (ch = *(fn++)) != '\0';) { - if (ch == '/') - i = 0; /* overwrite what we wrote */ - else - if (i < len - 1) - tcomm[i++] = ch; - } - tcomm[i] = '\0'; -} - int flush_old_exec(struct linux_binprm * bprm) { int retval; @@ -1100,7 +1085,6 @@ int flush_old_exec(struct linux_binprm * bprm) set_mm_exe_file(bprm->mm, bprm->file); - filename_to_taskname(bprm->tcomm, bprm->filename, sizeof(bprm->tcomm)); /* * Release all of the old mmap stuff */ @@ -1132,6 +1116,10 @@ EXPORT_SYMBOL(would_dump); void setup_new_exec(struct linux_binprm * bprm) { + int i, ch; + const char *name; + char tcomm[sizeof(current->comm)]; + arch_pick_mmap_layout(current->mm); /* This is the point of no return */ @@ -1142,7 +1130,18 @@ void setup_new_exec(struct linux_binprm * bprm) else set_dumpable(current->mm, suid_dumpable); - set_task_comm(current, bprm->tcomm); + name = bprm->filename; + + /* Copies the binary name from after last slash */ + for (i=0; (ch = *(name++)) != '\0';) { + if (ch == '/') + i = 0; /* overwrite what we wrote */ + else + if (i < (sizeof(tcomm) - 1)) + tcomm[i++] = ch; + } + tcomm[i] = '\0'; + set_task_comm(current, tcomm); /* Set the new mm task size. We have to do that late because it may * depend on TIF_32BIT which is only updated in flush_thread() on diff --git a/trunk/fs/ext2/ioctl.c b/trunk/fs/ext2/ioctl.c index 2de655f5d625..1089f760c847 100644 --- a/trunk/fs/ext2/ioctl.c +++ b/trunk/fs/ext2/ioctl.c @@ -77,11 +77,10 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) flags = flags & EXT2_FL_USER_MODIFIABLE; flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; ei->i_flags = flags; + mutex_unlock(&inode->i_mutex); ext2_set_inode_flags(inode); inode->i_ctime = CURRENT_TIME_SEC; - mutex_unlock(&inode->i_mutex); - mark_inode_dirty(inode); setflags_out: mnt_drop_write_file(filp); @@ -89,29 +88,20 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } case EXT2_IOC_GETVERSION: return put_user(inode->i_generation, (int __user *) arg); - case EXT2_IOC_SETVERSION: { - __u32 generation; - + case EXT2_IOC_SETVERSION: if (!inode_owner_or_capable(inode)) return -EPERM; ret = mnt_want_write_file(filp); if (ret) return ret; - if (get_user(generation, (int __user *) arg)) { + if (get_user(inode->i_generation, (int __user *) arg)) { ret = -EFAULT; - goto setversion_out; + } else { + inode->i_ctime = CURRENT_TIME_SEC; + mark_inode_dirty(inode); } - - mutex_lock(&inode->i_mutex); - inode->i_ctime = CURRENT_TIME_SEC; - inode->i_generation = generation; - mutex_unlock(&inode->i_mutex); - - mark_inode_dirty(inode); -setversion_out: mnt_drop_write_file(filp); return ret; - } case EXT2_IOC_GETRSVSZ: if (test_opt(inode->i_sb, RESERVATION) && S_ISREG(inode->i_mode) diff --git a/trunk/fs/jbd/checkpoint.c b/trunk/fs/jbd/checkpoint.c index 05f0754f2b46..5d1a00a5041b 100644 --- a/trunk/fs/jbd/checkpoint.c +++ b/trunk/fs/jbd/checkpoint.c @@ -453,6 +453,8 @@ int log_do_checkpoint(journal_t *journal) * * Return <0 on error, 0 on success, 1 if there was nothing to clean up. * + * Called with the journal lock held. + * * This is the only part of the journaling code which really needs to be * aware of transaction aborts. Checkpointing involves writing to the * main filesystem area rather than to the journal, so it can proceed @@ -470,14 +472,13 @@ int cleanup_journal_tail(journal_t *journal) if (is_journal_aborted(journal)) return 1; - /* - * OK, work out the oldest transaction remaining in the log, and + /* OK, work out the oldest transaction remaining in the log, and * the log block it starts at. * * If the log is now empty, we need to work out which is the * next transaction ID we will write, and where it will - * start. - */ + * start. */ + spin_lock(&journal->j_state_lock); spin_lock(&journal->j_list_lock); transaction = journal->j_checkpoint_transactions; @@ -503,25 +504,7 @@ int cleanup_journal_tail(journal_t *journal) spin_unlock(&journal->j_state_lock); return 1; } - spin_unlock(&journal->j_state_lock); - - /* - * We need to make sure that any blocks that were recently written out - * --- perhaps by log_do_checkpoint() --- are flushed out before we - * drop the transactions from the journal. It's unlikely this will be - * necessary, especially with an appropriately sized journal, but we - * need this to guarantee correctness. Fortunately - * cleanup_journal_tail() doesn't get called all that often. - */ - if (journal->j_flags & JFS_BARRIER) - blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); - spin_lock(&journal->j_state_lock); - if (!tid_gt(first_tid, journal->j_tail_sequence)) { - spin_unlock(&journal->j_state_lock); - /* Someone else cleaned up journal so return 0 */ - return 0; - } /* OK, update the superblock to recover the freed space. * Physical blocks come first: have we wrapped beyond the end of * the log? */ diff --git a/trunk/fs/jbd/recovery.c b/trunk/fs/jbd/recovery.c index 008bf062fd26..5b43e96788e6 100644 --- a/trunk/fs/jbd/recovery.c +++ b/trunk/fs/jbd/recovery.c @@ -20,7 +20,6 @@ #include #include #include -#include #endif /* @@ -264,9 +263,6 @@ int journal_recover(journal_t *journal) err2 = sync_blockdev(journal->j_fs_dev); if (!err) err = err2; - /* Flush disk caches to get replayed data on the permanent storage */ - if (journal->j_flags & JFS_BARRIER) - blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); return err; } diff --git a/trunk/fs/jffs2/erase.c b/trunk/fs/jffs2/erase.c index eafb8d37a6fb..a01cdad6aad1 100644 --- a/trunk/fs/jffs2/erase.c +++ b/trunk/fs/jffs2/erase.c @@ -335,7 +335,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl void *ebuf; uint32_t ofs; size_t retlen; - int ret; + int ret = -EIO; unsigned long *wordebuf; ret = mtd_point(c->mtd, jeb->offset, c->sector_size, &retlen, diff --git a/trunk/fs/logfs/dev_mtd.c b/trunk/fs/logfs/dev_mtd.c index 9c501449450d..e97404d611e0 100644 --- a/trunk/fs/logfs/dev_mtd.c +++ b/trunk/fs/logfs/dev_mtd.c @@ -152,6 +152,9 @@ static struct page *logfs_mtd_find_first_sb(struct super_block *sb, u64 *ofs) filler_t *filler = logfs_mtd_readpage; struct mtd_info *mtd = super->s_mtd; + if (!mtd_can_have_bb(mtd)) + return NULL; + *ofs = 0; while (mtd_block_isbad(mtd, *ofs)) { *ofs += mtd->erasesize; @@ -169,6 +172,9 @@ static struct page *logfs_mtd_find_last_sb(struct super_block *sb, u64 *ofs) filler_t *filler = logfs_mtd_readpage; struct mtd_info *mtd = super->s_mtd; + if (!mtd_can_have_bb(mtd)) + return NULL; + *ofs = mtd->size - mtd->erasesize; while (mtd_block_isbad(mtd, *ofs)) { *ofs -= mtd->erasesize; diff --git a/trunk/fs/logfs/dir.c b/trunk/fs/logfs/dir.c index 3de7a32cadbe..501043e8966c 100644 --- a/trunk/fs/logfs/dir.c +++ b/trunk/fs/logfs/dir.c @@ -71,7 +71,7 @@ static int write_dir(struct inode *dir, struct logfs_disk_dentry *dd, static int write_inode(struct inode *inode) { - return __logfs_write_inode(inode, NULL, WF_LOCK); + return __logfs_write_inode(inode, WF_LOCK); } static s64 dir_seek_data(struct inode *inode, s64 pos) diff --git a/trunk/fs/logfs/file.c b/trunk/fs/logfs/file.c index 3886cded283c..b548c87a86f1 100644 --- a/trunk/fs/logfs/file.c +++ b/trunk/fs/logfs/file.c @@ -230,9 +230,7 @@ int logfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) return ret; mutex_lock(&inode->i_mutex); - logfs_get_wblocks(sb, NULL, WF_LOCK); logfs_write_anchor(sb); - logfs_put_wblocks(sb, NULL, WF_LOCK); mutex_unlock(&inode->i_mutex); return 0; diff --git a/trunk/fs/logfs/gc.c b/trunk/fs/logfs/gc.c index d4efb061bdc5..caa4419285dc 100644 --- a/trunk/fs/logfs/gc.c +++ b/trunk/fs/logfs/gc.c @@ -367,7 +367,7 @@ static struct gc_candidate *get_candidate(struct super_block *sb) int i, max_dist; struct gc_candidate *cand = NULL, *this; - max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS - 1); + max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS); for (i = max_dist; i >= 0; i--) { this = first_in_list(&super->s_low_list[i]); diff --git a/trunk/fs/logfs/inode.c b/trunk/fs/logfs/inode.c index a422f42238b2..388df1aa35e5 100644 --- a/trunk/fs/logfs/inode.c +++ b/trunk/fs/logfs/inode.c @@ -286,7 +286,7 @@ static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc) if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN) return 0; - ret = __logfs_write_inode(inode, NULL, flags); + ret = __logfs_write_inode(inode, flags); LOGFS_BUG_ON(ret, inode->i_sb); return ret; } @@ -363,9 +363,7 @@ static void logfs_init_once(void *_li) static int logfs_sync_fs(struct super_block *sb, int wait) { - logfs_get_wblocks(sb, NULL, WF_LOCK); logfs_write_anchor(sb); - logfs_put_wblocks(sb, NULL, WF_LOCK); return 0; } diff --git a/trunk/fs/logfs/journal.c b/trunk/fs/logfs/journal.c index 1e1c369df22b..9da29706f91c 100644 --- a/trunk/fs/logfs/journal.c +++ b/trunk/fs/logfs/journal.c @@ -612,6 +612,7 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type, if (len == 0) return logfs_write_header(super, header, 0, type); + BUG_ON(len > sb->s_blocksize); compr_len = logfs_compress(buf, data, len, sb->s_blocksize); if (compr_len < 0 || type == JE_ANCHOR) { memcpy(data, buf, len); diff --git a/trunk/fs/logfs/logfs.h b/trunk/fs/logfs/logfs.h index 5f0937609465..926373866a55 100644 --- a/trunk/fs/logfs/logfs.h +++ b/trunk/fs/logfs/logfs.h @@ -528,7 +528,7 @@ void logfs_destroy_inode_cache(void); void logfs_set_blocks(struct inode *inode, u64 no); /* these logically belong into inode.c but actually reside in readwrite.c */ int logfs_read_inode(struct inode *inode); -int __logfs_write_inode(struct inode *inode, struct page *, long flags); +int __logfs_write_inode(struct inode *inode, long flags); void logfs_evict_inode(struct inode *inode); /* journal.c */ @@ -577,8 +577,6 @@ void initialize_block_counters(struct page *page, struct logfs_block *block, __be64 *array, int page_is_empty); int logfs_exist_block(struct inode *inode, u64 bix); int get_page_reserve(struct inode *inode, struct page *page); -void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock); -void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock); extern struct logfs_block_ops indirect_block_ops; /* segment.c */ @@ -596,7 +594,6 @@ int logfs_init_mapping(struct super_block *sb); void logfs_sync_area(struct logfs_area *area); void logfs_sync_segments(struct super_block *sb); void freeseg(struct super_block *sb, u32 segno); -void free_areas(struct super_block *sb); /* area handling */ int logfs_init_areas(struct super_block *sb); diff --git a/trunk/fs/logfs/readwrite.c b/trunk/fs/logfs/readwrite.c index 4153e65b0148..2ac4217b7901 100644 --- a/trunk/fs/logfs/readwrite.c +++ b/trunk/fs/logfs/readwrite.c @@ -244,7 +244,8 @@ static void preunlock_page(struct super_block *sb, struct page *page, int lock) * is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked * in addition to PG_locked. */ -void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock) +static void logfs_get_wblocks(struct super_block *sb, struct page *page, + int lock) { struct logfs_super *super = logfs_super(sb); @@ -259,7 +260,8 @@ void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock) } } -void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock) +static void logfs_put_wblocks(struct super_block *sb, struct page *page, + int lock) { struct logfs_super *super = logfs_super(sb); @@ -422,7 +424,7 @@ static void inode_write_block(struct logfs_block *block) if (inode->i_ino == LOGFS_INO_MASTER) logfs_write_anchor(inode->i_sb); else { - ret = __logfs_write_inode(inode, NULL, 0); + ret = __logfs_write_inode(inode, 0); /* see indirect_write_block comment */ BUG_ON(ret); } @@ -558,13 +560,8 @@ static void inode_free_block(struct super_block *sb, struct logfs_block *block) static void indirect_free_block(struct super_block *sb, struct logfs_block *block) { - struct page *page = block->page; - - if (PagePrivate(page)) { - ClearPagePrivate(page); - page_cache_release(page); - set_page_private(page, 0); - } + ClearPagePrivate(block->page); + block->page->private = 0; __free_block(sb, block); } @@ -653,11 +650,8 @@ static void alloc_data_block(struct inode *inode, struct page *page) logfs_unpack_index(page->index, &bix, &level); block = __alloc_block(inode->i_sb, inode->i_ino, bix, level); block->page = page; - SetPagePrivate(page); - page_cache_get(page); - set_page_private(page, (unsigned long) block); - + page->private = (unsigned long)block; block->ops = &indirect_block_ops; } @@ -1576,15 +1570,11 @@ int logfs_write_buf(struct inode *inode, struct page *page, long flags) static int __logfs_delete(struct inode *inode, struct page *page) { long flags = WF_DELETE; - int err; inode->i_ctime = inode->i_mtime = CURRENT_TIME; if (page->index < I0_BLOCKS) return logfs_write_direct(inode, page, flags); - err = grow_inode(inode, page->index, 0); - if (err) - return err; return logfs_write_rec(inode, page, page->index, 0, flags); } @@ -1633,7 +1623,7 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs, if (inode->i_ino == LOGFS_INO_MASTER) logfs_write_anchor(inode->i_sb); else { - err = __logfs_write_inode(inode, page, flags); + err = __logfs_write_inode(inode, flags); } } } @@ -1883,7 +1873,7 @@ int logfs_truncate(struct inode *inode, u64 target) logfs_get_wblocks(sb, NULL, 1); err = __logfs_truncate(inode, size); if (!err) - err = __logfs_write_inode(inode, NULL, 0); + err = __logfs_write_inode(inode, 0); logfs_put_wblocks(sb, NULL, 1); } @@ -1911,11 +1901,8 @@ static void move_page_to_inode(struct inode *inode, struct page *page) li->li_block = block; block->page = NULL; - if (PagePrivate(page)) { - ClearPagePrivate(page); - page_cache_release(page); - set_page_private(page, 0); - } + page->private = 0; + ClearPagePrivate(page); } static void move_inode_to_page(struct page *page, struct inode *inode) @@ -1931,12 +1918,8 @@ static void move_inode_to_page(struct page *page, struct inode *inode) BUG_ON(PagePrivate(page)); block->ops = &indirect_block_ops; block->page = page; - - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - set_page_private(page, (unsigned long) block); - } + page->private = (unsigned long)block; + SetPagePrivate(page); block->inode = NULL; li->li_block = NULL; @@ -2123,14 +2106,14 @@ void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec) ec_level); } -int __logfs_write_inode(struct inode *inode, struct page *page, long flags) +int __logfs_write_inode(struct inode *inode, long flags) { struct super_block *sb = inode->i_sb; int ret; - logfs_get_wblocks(sb, page, flags & WF_LOCK); + logfs_get_wblocks(sb, NULL, flags & WF_LOCK); ret = do_write_inode(inode); - logfs_put_wblocks(sb, page, flags & WF_LOCK); + logfs_put_wblocks(sb, NULL, flags & WF_LOCK); return ret; } diff --git a/trunk/fs/logfs/segment.c b/trunk/fs/logfs/segment.c index ab798ed1cc88..9d5187353255 100644 --- a/trunk/fs/logfs/segment.c +++ b/trunk/fs/logfs/segment.c @@ -86,11 +86,7 @@ int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, BUG_ON(!page); /* FIXME: reserve a pool */ SetPageUptodate(page); memcpy(page_address(page) + offset, buf, copylen); - - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - } + SetPagePrivate(page); page_cache_release(page); buf += copylen; @@ -114,10 +110,7 @@ static void pad_partial_page(struct logfs_area *area) page = get_mapping_page(sb, index, 0); BUG_ON(!page); /* FIXME: reserve a pool */ memset(page_address(page) + offset, 0xff, len); - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - } + SetPagePrivate(page); page_cache_release(page); } } @@ -137,10 +130,7 @@ static void pad_full_pages(struct logfs_area *area) BUG_ON(!page); /* FIXME: reserve a pool */ SetPageUptodate(page); memset(page_address(page), 0xff, PAGE_CACHE_SIZE); - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - } + SetPagePrivate(page); page_cache_release(page); index++; no_indizes--; @@ -495,12 +485,8 @@ static void move_btree_to_page(struct inode *inode, struct page *page, mempool_free(item, super->s_alias_pool); } block->page = page; - - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - set_page_private(page, (unsigned long) block); - } + SetPagePrivate(page); + page->private = (unsigned long)block; block->ops = &indirect_block_ops; initialize_block_counters(page, block, data, 0); } @@ -550,12 +536,8 @@ void move_page_to_btree(struct page *page) list_add(&item->list, &block->item_list); } block->page = NULL; - - if (PagePrivate(page)) { - ClearPagePrivate(page); - page_cache_release(page); - set_page_private(page, 0); - } + ClearPagePrivate(page); + page->private = 0; block->ops = &btree_block_ops; err = alias_tree_insert(block->sb, block->ino, block->bix, block->level, block); @@ -720,10 +702,7 @@ void freeseg(struct super_block *sb, u32 segno) page = find_get_page(mapping, ofs >> PAGE_SHIFT); if (!page) continue; - if (PagePrivate(page)) { - ClearPagePrivate(page); - page_cache_release(page); - } + ClearPagePrivate(page); page_cache_release(page); } } @@ -862,16 +841,6 @@ static void free_area(struct logfs_area *area) kfree(area); } -void free_areas(struct super_block *sb) -{ - struct logfs_super *super = logfs_super(sb); - int i; - - for_each_area(i) - free_area(super->s_area[i]); - free_area(super->s_journal_area); -} - static struct logfs_area *alloc_area(struct super_block *sb) { struct logfs_area *area; @@ -954,6 +923,10 @@ int logfs_init_areas(struct super_block *sb) void logfs_cleanup_areas(struct super_block *sb) { struct logfs_super *super = logfs_super(sb); + int i; btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias); + for_each_area(i) + free_area(super->s_area[i]); + free_area(super->s_journal_area); } diff --git a/trunk/fs/logfs/super.c b/trunk/fs/logfs/super.c index c9ee7f5d1caf..e795c234ea33 100644 --- a/trunk/fs/logfs/super.c +++ b/trunk/fs/logfs/super.c @@ -486,15 +486,14 @@ static void logfs_kill_sb(struct super_block *sb) /* Alias entries slow down mount, so evict as many as possible */ sync_filesystem(sb); logfs_write_anchor(sb); - free_areas(sb); /* * From this point on alias entries are simply dropped - and any * writes to the object store are considered bugs. */ + super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN; log_super("LogFS: Now in shutdown\n"); generic_shutdown_super(sb); - super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN; BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes); diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index d4548dd49b02..9cde9edf9c4d 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -198,6 +198,26 @@ static int proc_root_link(struct dentry *dentry, struct path *path) return result; } +static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) +{ + struct mm_struct *mm; + int err; + + err = mutex_lock_killable(&task->signal->cred_guard_mutex); + if (err) + return ERR_PTR(err); + + mm = get_task_mm(task); + if (mm && mm != current->mm && + !ptrace_may_access(task, mode)) { + mmput(mm); + mm = ERR_PTR(-EACCES); + } + mutex_unlock(&task->signal->cred_guard_mutex); + + return mm; +} + struct mm_struct *mm_for_maps(struct task_struct *task) { return mm_access(task, PTRACE_MODE_READ); @@ -691,13 +711,6 @@ static int mem_open(struct inode* inode, struct file* file) if (IS_ERR(mm)) return PTR_ERR(mm); - if (mm) { - /* ensure this mm_struct can't be freed */ - atomic_inc(&mm->mm_count); - /* but do not pin its memory */ - mmput(mm); - } - /* OK to pass negative loff_t, we can catch out-of-range */ file->f_mode |= FMODE_UNSIGNED_OFFSET; file->private_data = mm; @@ -705,13 +718,13 @@ static int mem_open(struct inode* inode, struct file* file) return 0; } -static ssize_t mem_rw(struct file *file, char __user *buf, - size_t count, loff_t *ppos, int write) +static ssize_t mem_read(struct file * file, char __user * buf, + size_t count, loff_t *ppos) { - struct mm_struct *mm = file->private_data; - unsigned long addr = *ppos; - ssize_t copied; + int ret; char *page; + unsigned long src = *ppos; + struct mm_struct *mm = file->private_data; if (!mm) return 0; @@ -720,55 +733,76 @@ static ssize_t mem_rw(struct file *file, char __user *buf, if (!page) return -ENOMEM; - copied = 0; - if (!atomic_inc_not_zero(&mm->mm_users)) - goto free; - + ret = 0; + while (count > 0) { - int this_len = min_t(int, count, PAGE_SIZE); + int this_len, retval; - if (write && copy_from_user(page, buf, this_len)) { - copied = -EFAULT; + this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; + retval = access_remote_vm(mm, src, page, this_len, 0); + if (!retval) { + if (!ret) + ret = -EIO; break; } - this_len = access_remote_vm(mm, addr, page, this_len, write); - if (!this_len) { - if (!copied) - copied = -EIO; + if (copy_to_user(buf, page, retval)) { + ret = -EFAULT; break; } + + ret += retval; + src += retval; + buf += retval; + count -= retval; + } + *ppos = src; - if (!write && copy_to_user(buf, page, this_len)) { + free_page((unsigned long) page); + return ret; +} + +static ssize_t mem_write(struct file * file, const char __user *buf, + size_t count, loff_t *ppos) +{ + int copied; + char *page; + unsigned long dst = *ppos; + struct mm_struct *mm = file->private_data; + + if (!mm) + return 0; + + page = (char *)__get_free_page(GFP_TEMPORARY); + if (!page) + return -ENOMEM; + + copied = 0; + while (count > 0) { + int this_len, retval; + + this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; + if (copy_from_user(page, buf, this_len)) { copied = -EFAULT; break; } - - buf += this_len; - addr += this_len; - copied += this_len; - count -= this_len; + retval = access_remote_vm(mm, dst, page, this_len, 1); + if (!retval) { + if (!copied) + copied = -EIO; + break; + } + copied += retval; + buf += retval; + dst += retval; + count -= retval; } - *ppos = addr; + *ppos = dst; - mmput(mm); -free: free_page((unsigned long) page); return copied; } -static ssize_t mem_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - return mem_rw(file, buf, count, ppos, 0); -} - -static ssize_t mem_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - return mem_rw(file, (char __user*)buf, count, ppos, 1); -} - loff_t mem_lseek(struct file *file, loff_t offset, int orig) { switch (orig) { @@ -788,8 +822,8 @@ loff_t mem_lseek(struct file *file, loff_t offset, int orig) static int mem_release(struct inode *inode, struct file *file) { struct mm_struct *mm = file->private_data; - if (mm) - mmdrop(mm); + + mmput(mm); return 0; } diff --git a/trunk/fs/quota/dquot.c b/trunk/fs/quota/dquot.c index 46741970371b..5ec59b20cf76 100644 --- a/trunk/fs/quota/dquot.c +++ b/trunk/fs/quota/dquot.c @@ -2125,8 +2125,6 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, mutex_unlock(&dqopt->dqio_mutex); goto out_file_init; } - if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) - dqopt->info[type].dqi_flags |= DQF_SYS_FILE; mutex_unlock(&dqopt->dqio_mutex); spin_lock(&dq_state_lock); dqopt->flags |= dquot_state_flag(flags, type); @@ -2466,7 +2464,7 @@ int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) spin_lock(&dq_data_lock); ii->dqi_bgrace = mi->dqi_bgrace; ii->dqi_igrace = mi->dqi_igrace; - ii->dqi_flags = mi->dqi_flags & DQF_GETINFO_MASK; + ii->dqi_flags = mi->dqi_flags & DQF_MASK; ii->dqi_valid = IIF_ALL; spin_unlock(&dq_data_lock); mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); @@ -2492,8 +2490,8 @@ int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) if (ii->dqi_valid & IIF_IGRACE) mi->dqi_igrace = ii->dqi_igrace; if (ii->dqi_valid & IIF_FLAGS) - mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) | - (ii->dqi_flags & DQF_SETINFO_MASK); + mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | + (ii->dqi_flags & DQF_MASK); spin_unlock(&dq_data_lock); mark_info_dirty(sb, type); /* Force write to disk */ diff --git a/trunk/fs/sysfs/file.c b/trunk/fs/sysfs/file.c index 00012e31829d..62f4fb37789e 100644 --- a/trunk/fs/sysfs/file.c +++ b/trunk/fs/sysfs/file.c @@ -493,12 +493,6 @@ int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr, const void *ns = NULL; int err; - if (!dir_sd) { - WARN(1, KERN_ERR "sysfs: kobject %s without dirent\n", - kobject_name(kobj)); - return -ENOENT; - } - err = 0; if (!sysfs_ns_type(dir_sd)) goto out; diff --git a/trunk/fs/sysfs/inode.c b/trunk/fs/sysfs/inode.c index 85eb81683a29..4a802b4a9056 100644 --- a/trunk/fs/sysfs/inode.c +++ b/trunk/fs/sysfs/inode.c @@ -318,11 +318,8 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const cha struct sysfs_addrm_cxt acxt; struct sysfs_dirent *sd; - if (!dir_sd) { - WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n", - name); + if (!dir_sd) return -ENOENT; - } sysfs_addrm_start(&acxt, dir_sd); diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index ebdb88840a47..0cf52da9d246 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -131,8 +131,7 @@ xfs_readlink( __func__, (unsigned long long) ip->i_ino, (long long) pathlen); ASSERT(0); - error = XFS_ERROR(EFSCORRUPTED); - goto out; + return XFS_ERROR(EFSCORRUPTED); } diff --git a/trunk/include/acpi/acpiosxf.h b/trunk/include/acpi/acpiosxf.h index 7c9aebe8a7aa..2fe8639b3ae7 100644 --- a/trunk/include/acpi/acpiosxf.h +++ b/trunk/include/acpi/acpiosxf.h @@ -218,13 +218,9 @@ acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width); */ acpi_status acpi_os_read_memory(acpi_physical_address address, u32 * value, u32 width); -acpi_status -acpi_os_read_memory64(acpi_physical_address address, u64 *value, u32 width); acpi_status acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width); -acpi_status -acpi_os_write_memory64(acpi_physical_address address, u64 value, u32 width); /* * Platform and hardware-independent PCI configuration space access diff --git a/trunk/include/acpi/atomicio.h b/trunk/include/acpi/atomicio.h new file mode 100644 index 000000000000..8b9fb4b0b9ce --- /dev/null +++ b/trunk/include/acpi/atomicio.h @@ -0,0 +1,10 @@ +#ifndef ACPI_ATOMIC_IO_H +#define ACPI_ATOMIC_IO_H + +int acpi_pre_map_gar(struct acpi_generic_address *reg); +int acpi_post_unmap_gar(struct acpi_generic_address *reg); + +int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg); +int acpi_atomic_write(u64 val, struct acpi_generic_address *reg); + +#endif diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 8cf7e98a2c7b..610f6fb1bbc2 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -195,7 +195,6 @@ struct acpi_processor_flags { u8 has_cst:1; u8 power_setup_done:1; u8 bm_rld_set:1; - u8 need_hotplug_init:1; }; struct acpi_processor { diff --git a/trunk/include/drm/drmP.h b/trunk/include/drm/drmP.h index 92f0981b5fb8..76caa67c22e2 100644 --- a/trunk/include/drm/drmP.h +++ b/trunk/include/drm/drmP.h @@ -1328,7 +1328,6 @@ extern int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic); /* Cache management (drm_cache.c) */ void drm_clflush_pages(struct page *pages[], unsigned long num_pages); diff --git a/trunk/include/linux/binfmts.h b/trunk/include/linux/binfmts.h index 0092102db2de..fd88a3945aa1 100644 --- a/trunk/include/linux/binfmts.h +++ b/trunk/include/linux/binfmts.h @@ -18,7 +18,7 @@ struct pt_regs; #define BINPRM_BUF_SIZE 128 #ifdef __KERNEL__ -#include +#include #define CORENAME_MAX_SIZE 128 @@ -58,7 +58,6 @@ struct linux_binprm { unsigned interp_flags; unsigned interp_data; unsigned long loader, exec; - char tcomm[TASK_COMM_LEN]; }; #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 diff --git a/trunk/include/linux/freezer.h b/trunk/include/linux/freezer.h index d09af4b67cf1..0ab54e16a91f 100644 --- a/trunk/include/linux/freezer.h +++ b/trunk/include/linux/freezer.h @@ -39,7 +39,6 @@ extern bool __refrigerator(bool check_kthr_stop); extern int freeze_processes(void); extern int freeze_kernel_threads(void); extern void thaw_processes(void); -extern void thaw_kernel_threads(void); static inline bool try_to_freeze(void) { @@ -175,7 +174,6 @@ static inline bool __refrigerator(bool check_kthr_stop) { return false; } static inline int freeze_processes(void) { return -ENOSYS; } static inline int freeze_kernel_threads(void) { return -ENOSYS; } static inline void thaw_processes(void) {} -static inline void thaw_kernel_threads(void) {} static inline bool try_to_freeze(void) { return false; } diff --git a/trunk/include/linux/gpio_keys.h b/trunk/include/linux/gpio_keys.h index 004ff33ab38e..b5ca4b2c08ec 100644 --- a/trunk/include/linux/gpio_keys.h +++ b/trunk/include/linux/gpio_keys.h @@ -1,8 +1,6 @@ #ifndef _GPIO_KEYS_H #define _GPIO_KEYS_H -struct device; - struct gpio_keys_button { /* Configuration parameters */ unsigned int code; /* input event code (KEY_*, SW_*) */ diff --git a/trunk/include/linux/if_team.h b/trunk/include/linux/if_team.h index 58404b0c5010..828181fbad5d 100644 --- a/trunk/include/linux/if_team.h +++ b/trunk/include/linux/if_team.h @@ -46,10 +46,6 @@ struct team_port { u32 speed; u8 duplex; - /* Custom gennetlink interface related flags */ - bool changed; - bool removed; - struct rcu_head rcu; }; @@ -76,10 +72,6 @@ struct team_option { enum team_option_type type; int (*getter)(struct team *team, void *arg); int (*setter)(struct team *team, void *arg); - - /* Custom gennetlink interface related flags */ - bool changed; - bool removed; }; struct team_mode { @@ -215,7 +207,6 @@ enum { TEAM_ATTR_OPTION_CHANGED, /* flag */ TEAM_ATTR_OPTION_TYPE, /* u8 */ TEAM_ATTR_OPTION_DATA, /* dynamic */ - TEAM_ATTR_OPTION_REMOVED, /* flag */ __TEAM_ATTR_OPTION_MAX, TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1, @@ -236,7 +227,6 @@ enum { TEAM_ATTR_PORT_LINKUP, /* flag */ TEAM_ATTR_PORT_SPEED, /* u32 */ TEAM_ATTR_PORT_DUPLEX, /* u8 */ - TEAM_ATTR_PORT_REMOVED, /* flag */ __TEAM_ATTR_PORT_MAX, TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1, diff --git a/trunk/include/linux/lp8727.h b/trunk/include/linux/lp8727.h old mode 100644 new mode 100755 diff --git a/trunk/include/linux/mfd/mcp.h b/trunk/include/linux/mfd/mcp.h index f88c1cc0cb0f..1515e64e3663 100644 --- a/trunk/include/linux/mfd/mcp.h +++ b/trunk/include/linux/mfd/mcp.h @@ -10,6 +10,7 @@ #ifndef MCP_H #define MCP_H +#include #include struct mcp_ops; @@ -26,7 +27,7 @@ struct mcp { dma_device_t dma_telco_rd; dma_device_t dma_telco_wr; struct device attached_device; - int gpio_base; + const char *codec; }; struct mcp_ops { @@ -44,10 +45,11 @@ void mcp_reg_write(struct mcp *, unsigned int, unsigned int); unsigned int mcp_reg_read(struct mcp *, unsigned int); void mcp_enable(struct mcp *); void mcp_disable(struct mcp *); +const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp); #define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) struct mcp *mcp_host_alloc(struct device *, size_t); -int mcp_host_register(struct mcp *); +int mcp_host_register(struct mcp *, void *); void mcp_host_unregister(struct mcp *); struct mcp_driver { @@ -56,6 +58,7 @@ struct mcp_driver { void (*remove)(struct mcp *); int (*suspend)(struct mcp *, pm_message_t); int (*resume)(struct mcp *); + const struct mcp_device_id *id_table; }; int mcp_driver_register(struct mcp_driver *); @@ -64,9 +67,6 @@ void mcp_driver_unregister(struct mcp_driver *); #define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device) #define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d) -static inline void *mcp_priv(struct mcp *mcp) -{ - return mcp + 1; -} +#define mcp_priv(mcp) ((void *)((mcp)+1)) #endif diff --git a/trunk/include/linux/mfd/twl6040.h b/trunk/include/linux/mfd/twl6040.h index 9bc9ac651dad..2463c2619596 100644 --- a/trunk/include/linux/mfd/twl6040.h +++ b/trunk/include/linux/mfd/twl6040.h @@ -187,10 +187,8 @@ struct twl6040 { int rev; u8 vibra_ctrl_cache[2]; - /* PLL configuration */ int pll; unsigned int sysclk; - unsigned int mclk; unsigned int irq; unsigned int irq_base; diff --git a/trunk/include/linux/mfd/ucb1x00.h b/trunk/include/linux/mfd/ucb1x00.h index 4321f044d1e4..bc19e5fb7ea8 100644 --- a/trunk/include/linux/mfd/ucb1x00.h +++ b/trunk/include/linux/mfd/ucb1x00.h @@ -104,6 +104,9 @@ #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) #define UCB_MODE_AUD_OFF_CAN (1 << 13) +struct ucb1x00_plat_data { + int gpio_base; +}; struct ucb1x00_irq { void *devid; @@ -116,7 +119,7 @@ struct ucb1x00 { unsigned int irq; struct semaphore adc_sem; spinlock_t io_lock; - u16 id; + const struct mcp_device_id *id; u16 io_dir; u16 io_out; u16 adc_cr; diff --git a/trunk/include/linux/mlx4/device.h b/trunk/include/linux/mlx4/device.h index aea61905499b..5c4fe8e5bfe5 100644 --- a/trunk/include/linux/mlx4/device.h +++ b/trunk/include/linux/mlx4/device.h @@ -621,7 +621,6 @@ void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac); int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac); int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn); void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn); -void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap); int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx); int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); diff --git a/trunk/include/linux/mod_devicetable.h b/trunk/include/linux/mod_devicetable.h index 83ac0713ed0a..b29e7f6f8fa5 100644 --- a/trunk/include/linux/mod_devicetable.h +++ b/trunk/include/linux/mod_devicetable.h @@ -436,6 +436,17 @@ struct spi_device_id { __attribute__((aligned(sizeof(kernel_ulong_t)))); }; +/* mcp */ + +#define MCP_NAME_SIZE 20 +#define MCP_MODULE_PREFIX "mcp:" + +struct mcp_device_id { + char name[MCP_NAME_SIZE]; + kernel_ulong_t driver_data /* Data private to the driver */ + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + /* dmi */ enum dmi_field { DMI_NONE, diff --git a/trunk/include/linux/mpi.h b/trunk/include/linux/mpi.h index d02cca6cc8ce..06f88994ccaa 100644 --- a/trunk/include/linux/mpi.h +++ b/trunk/include/linux/mpi.h @@ -57,6 +57,8 @@ struct gcry_mpi { typedef struct gcry_mpi *MPI; +#define MPI_NULL NULL + #define mpi_get_nlimbs(a) ((a)->nlimbs) #define mpi_is_neg(a) ((a)->sign) diff --git a/trunk/include/linux/mtd/mtd.h b/trunk/include/linux/mtd/mtd.h index d43dc25af82e..1a81fde8f333 100644 --- a/trunk/include/linux/mtd/mtd.h +++ b/trunk/include/linux/mtd/mtd.h @@ -427,7 +427,9 @@ static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) static inline int mtd_suspend(struct mtd_info *mtd) { - return mtd->suspend ? mtd->suspend(mtd) : 0; + if (!mtd->suspend) + return -EOPNOTSUPP; + return mtd->suspend(mtd); } static inline void mtd_resume(struct mtd_info *mtd) @@ -439,7 +441,7 @@ static inline void mtd_resume(struct mtd_info *mtd) static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) { if (!mtd->block_isbad) - return 0; + return -EOPNOTSUPP; return mtd->block_isbad(mtd, ofs); } diff --git a/trunk/include/linux/perf_event.h b/trunk/include/linux/perf_event.h index abb2776be1ba..08855613ceb3 100644 --- a/trunk/include/linux/perf_event.h +++ b/trunk/include/linux/perf_event.h @@ -587,7 +587,6 @@ struct hw_perf_event { u64 sample_period; u64 last_period; local64_t period_left; - u64 interrupts_seq; u64 interrupts; u64 freq_time_stamp; diff --git a/trunk/include/linux/pm_qos.h b/trunk/include/linux/pm_qos.h index 4d99e4e6ef83..e5bbcbaa6f57 100644 --- a/trunk/include/linux/pm_qos.h +++ b/trunk/include/linux/pm_qos.h @@ -110,19 +110,7 @@ static inline void pm_qos_remove_request(struct pm_qos_request *req) { return; } static inline int pm_qos_request(int pm_qos_class) -{ - switch (pm_qos_class) { - case PM_QOS_CPU_DMA_LATENCY: - return PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; - case PM_QOS_NETWORK_LATENCY: - return PM_QOS_NETWORK_LAT_DEFAULT_VALUE; - case PM_QOS_NETWORK_THROUGHPUT: - return PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE; - default: - return PM_QOS_DEFAULT_VALUE; - } -} - + { return 0; } static inline int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) { return 0; } diff --git a/trunk/include/linux/quota.h b/trunk/include/linux/quota.h index c09fa042b5ea..cb7855699037 100644 --- a/trunk/include/linux/quota.h +++ b/trunk/include/linux/quota.h @@ -230,11 +230,7 @@ struct mem_dqinfo { struct super_block; #define DQF_MASK 0xffff /* Mask for format specific flags */ -#define DQF_GETINFO_MASK 0x1ffff /* Mask for flags passed to userspace */ -#define DQF_SETINFO_MASK 0xffff /* Mask for flags modifiable from userspace */ -#define DQF_SYS_FILE_B 16 -#define DQF_SYS_FILE (1 << DQF_SYS_FILE_B) /* Quota file stored as system file */ -#define DQF_INFO_DIRTY_B 31 +#define DQF_INFO_DIRTY_B 16 #define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */ extern void mark_info_dirty(struct super_block *sb, int type); diff --git a/trunk/include/linux/res_counter.h b/trunk/include/linux/res_counter.h index da81af086eaf..c9d625ca659e 100644 --- a/trunk/include/linux/res_counter.h +++ b/trunk/include/linux/res_counter.h @@ -109,18 +109,12 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent); * * returns 0 on success and <0 if the counter->usage will exceed the * counter->limit _locked call expects the counter->lock to be taken - * - * charge_nofail works the same, except that it charges the resource - * counter unconditionally, and returns < 0 if the after the current - * charge we are over limit. */ int __must_check res_counter_charge_locked(struct res_counter *counter, unsigned long val); int __must_check res_counter_charge(struct res_counter *counter, unsigned long val, struct res_counter **limit_fail_at); -int __must_check res_counter_charge_nofail(struct res_counter *counter, - unsigned long val, struct res_counter **limit_fail_at); /* * uncharge - tell that some portion of the resource is released @@ -148,10 +142,7 @@ static inline unsigned long long res_counter_margin(struct res_counter *cnt) unsigned long flags; spin_lock_irqsave(&cnt->lock, flags); - if (cnt->limit > cnt->usage) - margin = cnt->limit - cnt->usage; - else - margin = 0; + margin = cnt->limit - cnt->usage; spin_unlock_irqrestore(&cnt->lock, flags); return margin; } diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 7d379a6bfd88..513f52459872 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -2090,7 +2090,7 @@ extern struct task_struct *idle_task(int cpu); * is_idle_task - is the specified task an idle task? * @p: the task in question. */ -static inline bool is_idle_task(const struct task_struct *p) +static inline bool is_idle_task(struct task_struct *p) { return p->pid == 0; } @@ -2259,12 +2259,6 @@ static inline void mmdrop(struct mm_struct * mm) extern void mmput(struct mm_struct *); /* Grab a reference to a task's mm, if it is not already going away */ extern struct mm_struct *get_task_mm(struct task_struct *task); -/* - * Grab a reference to a task's mm, if it is not already going away - * and ptrace_may_access with the mode parameter passed to it - * succeeds. - */ -extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode); /* Remove the current tasks stale references to the old mm_struct */ extern void mm_release(struct task_struct *, struct mm_struct *); /* Allocate a new mm structure and copy contents from tsk->mm */ diff --git a/trunk/include/linux/sh_dma.h b/trunk/include/linux/sh_dma.h index 425450b980b8..8cd7fe59cf1a 100644 --- a/trunk/include/linux/sh_dma.h +++ b/trunk/include/linux/sh_dma.h @@ -70,7 +70,6 @@ struct sh_dmae_pdata { unsigned int needs_tend_set:1; unsigned int no_dmars:1; unsigned int chclr_present:1; - unsigned int slave_only:1; }; /* DMA register */ diff --git a/trunk/include/linux/snmp.h b/trunk/include/linux/snmp.h index c1241c428179..e16557a357e5 100644 --- a/trunk/include/linux/snmp.h +++ b/trunk/include/linux/snmp.h @@ -192,6 +192,7 @@ enum LINUX_MIB_TCPPARTIALUNDO, /* TCPPartialUndo */ LINUX_MIB_TCPDSACKUNDO, /* TCPDSACKUndo */ LINUX_MIB_TCPLOSSUNDO, /* TCPLossUndo */ + LINUX_MIB_TCPLOSS, /* TCPLoss */ LINUX_MIB_TCPLOSTRETRANSMIT, /* TCPLostRetransmit */ LINUX_MIB_TCPRENOFAILURES, /* TCPRenoFailures */ LINUX_MIB_TCPSACKFAILURES, /* TCPSackFailures */ diff --git a/trunk/include/linux/sysdev.h b/trunk/include/linux/sysdev.h new file mode 100644 index 000000000000..20f63d3e6144 --- /dev/null +++ b/trunk/include/linux/sysdev.h @@ -0,0 +1,164 @@ +/** + * System devices follow a slightly different driver model. + * They don't need to do dynammic driver binding, can't be probed, + * and don't reside on any type of peripheral bus. + * So, we represent and treat them a little differently. + * + * We still have a notion of a driver for a system device, because we still + * want to perform basic operations on these devices. + * + * We also support auxiliary drivers binding to devices of a certain class. + * + * This allows configurable drivers to register themselves for devices of + * a certain type. And, it allows class definitions to reside in generic + * code while arch-specific code can register specific drivers. + * + * Auxiliary drivers registered with a NULL cls are registered as drivers + * for all system devices, and get notification calls for each device. + */ + + +#ifndef _SYSDEV_H_ +#define _SYSDEV_H_ + +#include +#include + + +struct sys_device; +struct sysdev_class_attribute; + +struct sysdev_class { + const char *name; + struct list_head drivers; + struct sysdev_class_attribute **attrs; + struct kset kset; +}; + +struct sysdev_class_attribute { + struct attribute attr; + ssize_t (*show)(struct sysdev_class *, struct sysdev_class_attribute *, + char *); + ssize_t (*store)(struct sysdev_class *, struct sysdev_class_attribute *, + const char *, size_t); +}; + +#define _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \ +{ \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +} + +#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \ + struct sysdev_class_attribute attr_##_name = \ + _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) + + +extern int sysdev_class_register(struct sysdev_class *); +extern void sysdev_class_unregister(struct sysdev_class *); + +extern int sysdev_class_create_file(struct sysdev_class *, + struct sysdev_class_attribute *); +extern void sysdev_class_remove_file(struct sysdev_class *, + struct sysdev_class_attribute *); +/** + * Auxiliary system device drivers. + */ + +struct sysdev_driver { + struct list_head entry; + int (*add)(struct sys_device *); + int (*remove)(struct sys_device *); +}; + + +extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *); +extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *); + + +/** + * sys_devices can be simplified a lot from regular devices, because they're + * simply not as versatile. + */ + +struct sys_device { + u32 id; + struct sysdev_class * cls; + struct kobject kobj; +}; + +extern int sysdev_register(struct sys_device *); +extern void sysdev_unregister(struct sys_device *); + + +struct sysdev_attribute { + struct attribute attr; + ssize_t (*show)(struct sys_device *, struct sysdev_attribute *, char *); + ssize_t (*store)(struct sys_device *, struct sysdev_attribute *, + const char *, size_t); +}; + + +#define _SYSDEV_ATTR(_name, _mode, _show, _store) \ +{ \ + .attr = { .name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +} + +#define SYSDEV_ATTR(_name, _mode, _show, _store) \ + struct sysdev_attribute attr_##_name = \ + _SYSDEV_ATTR(_name, _mode, _show, _store); + +extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *); +extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *); + +/* Create/remove NULL terminated attribute list */ +static inline int +sysdev_create_files(struct sys_device *d, struct sysdev_attribute **a) +{ + return sysfs_create_files(&d->kobj, (const struct attribute **)a); +} + +static inline void +sysdev_remove_files(struct sys_device *d, struct sysdev_attribute **a) +{ + return sysfs_remove_files(&d->kobj, (const struct attribute **)a); +} + +struct sysdev_ext_attribute { + struct sysdev_attribute attr; + void *var; +}; + +/* + * Support for simple variable sysdev attributes. + * The pointer to the variable is stored in a sysdev_ext_attribute + */ + +/* Add more types as needed */ + +extern ssize_t sysdev_show_ulong(struct sys_device *, struct sysdev_attribute *, + char *); +extern ssize_t sysdev_store_ulong(struct sys_device *, + struct sysdev_attribute *, const char *, size_t); +extern ssize_t sysdev_show_int(struct sys_device *, struct sysdev_attribute *, + char *); +extern ssize_t sysdev_store_int(struct sys_device *, + struct sysdev_attribute *, const char *, size_t); + +#define _SYSDEV_ULONG_ATTR(_name, _mode, _var) \ + { _SYSDEV_ATTR(_name, _mode, sysdev_show_ulong, sysdev_store_ulong), \ + &(_var) } +#define SYSDEV_ULONG_ATTR(_name, _mode, _var) \ + struct sysdev_ext_attribute attr_##_name = \ + _SYSDEV_ULONG_ATTR(_name, _mode, _var); +#define _SYSDEV_INT_ATTR(_name, _mode, _var) \ + { _SYSDEV_ATTR(_name, _mode, sysdev_show_int, sysdev_store_int), \ + &(_var) } +#define SYSDEV_INT_ATTR(_name, _mode, _var) \ + struct sysdev_ext_attribute attr_##_name = \ + _SYSDEV_INT_ATTR(_name, _mode, _var); + +#endif /* _SYSDEV_H_ */ diff --git a/trunk/include/linux/thermal.h b/trunk/include/linux/thermal.h index 796f1ff0388c..47b4a27e6e97 100644 --- a/trunk/include/linux/thermal.h +++ b/trunk/include/linux/thermal.h @@ -152,9 +152,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, void thermal_cooling_device_unregister(struct thermal_cooling_device *); #ifdef CONFIG_NET -extern int thermal_generate_netlink_event(u32 orig, enum events event); +extern int generate_netlink_event(u32 orig, enum events event); #else -static inline int thermal_generate_netlink_event(u32 orig, enum events event) +static inline int generate_netlink_event(u32 orig, enum events event) { return 0; } diff --git a/trunk/include/linux/usb/langwell_otg.h b/trunk/include/linux/usb/langwell_otg.h new file mode 100644 index 000000000000..51f17b16d312 --- /dev/null +++ b/trunk/include/linux/usb/langwell_otg.h @@ -0,0 +1,139 @@ +/* + * Intel Langwell USB OTG transceiver driver + * Copyright (C) 2008 - 2010, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef __LANGWELL_OTG_H +#define __LANGWELL_OTG_H + +#include + +#define CI_USBCMD 0x30 +# define USBCMD_RST BIT(1) +# define USBCMD_RS BIT(0) +#define CI_USBSTS 0x34 +# define USBSTS_SLI BIT(8) +# define USBSTS_URI BIT(6) +# define USBSTS_PCI BIT(2) +#define CI_PORTSC1 0x74 +# define PORTSC_PP BIT(12) +# define PORTSC_LS (BIT(11) | BIT(10)) +# define PORTSC_SUSP BIT(7) +# define PORTSC_CCS BIT(0) +#define CI_HOSTPC1 0xb4 +# define HOSTPC1_PHCD BIT(22) +#define CI_OTGSC 0xf4 +# define OTGSC_DPIE BIT(30) +# define OTGSC_1MSE BIT(29) +# define OTGSC_BSEIE BIT(28) +# define OTGSC_BSVIE BIT(27) +# define OTGSC_ASVIE BIT(26) +# define OTGSC_AVVIE BIT(25) +# define OTGSC_IDIE BIT(24) +# define OTGSC_DPIS BIT(22) +# define OTGSC_1MSS BIT(21) +# define OTGSC_BSEIS BIT(20) +# define OTGSC_BSVIS BIT(19) +# define OTGSC_ASVIS BIT(18) +# define OTGSC_AVVIS BIT(17) +# define OTGSC_IDIS BIT(16) +# define OTGSC_DPS BIT(14) +# define OTGSC_1MST BIT(13) +# define OTGSC_BSE BIT(12) +# define OTGSC_BSV BIT(11) +# define OTGSC_ASV BIT(10) +# define OTGSC_AVV BIT(9) +# define OTGSC_ID BIT(8) +# define OTGSC_HABA BIT(7) +# define OTGSC_HADP BIT(6) +# define OTGSC_IDPU BIT(5) +# define OTGSC_DP BIT(4) +# define OTGSC_OT BIT(3) +# define OTGSC_HAAR BIT(2) +# define OTGSC_VC BIT(1) +# define OTGSC_VD BIT(0) +# define OTGSC_INTEN_MASK (0x7f << 24) +# define OTGSC_INT_MASK (0x5f << 24) +# define OTGSC_INTSTS_MASK (0x7f << 16) +#define CI_USBMODE 0xf8 +# define USBMODE_CM (BIT(1) | BIT(0)) +# define USBMODE_IDLE 0 +# define USBMODE_DEVICE 0x2 +# define USBMODE_HOST 0x3 +#define USBCFG_ADDR 0xff10801c +#define USBCFG_LEN 4 +# define USBCFG_VBUSVAL BIT(14) +# define USBCFG_AVALID BIT(13) +# define USBCFG_BVALID BIT(12) +# define USBCFG_SESEND BIT(11) + +#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI) + +enum langwell_otg_timer_type { + TA_WAIT_VRISE_TMR, + TA_WAIT_BCON_TMR, + TA_AIDL_BDIS_TMR, + TB_ASE0_BRST_TMR, + TB_SE0_SRP_TMR, + TB_SRP_INIT_TMR, + TB_SRP_FAIL_TMR, + TB_BUS_SUSPEND_TMR +}; + +#define TA_WAIT_VRISE 100 +#define TA_WAIT_BCON 30000 +#define TA_AIDL_BDIS 15000 +#define TB_ASE0_BRST 5000 +#define TB_SE0_SRP 2 +#define TB_SRP_INIT 100 +#define TB_SRP_FAIL 5500 +#define TB_BUS_SUSPEND 500 + +struct langwell_otg_timer { + unsigned long expires; /* Number of count increase to timeout */ + unsigned long count; /* Tick counter */ + void (*function)(unsigned long); /* Timeout function */ + unsigned long data; /* Data passed to function */ + struct list_head list; +}; + +struct langwell_otg { + struct intel_mid_otg_xceiv iotg; + struct device *dev; + + void __iomem *usbcfg; /* SCCBUSB config Reg */ + + unsigned region; + unsigned cfg_region; + + struct work_struct work; + struct workqueue_struct *qwork; + struct timer_list hsm_timer; + + spinlock_t lock; + spinlock_t wq_lock; + + struct notifier_block iotg_notifier; +}; + +static inline +struct langwell_otg *mid_xceiv_to_lnw(struct intel_mid_otg_xceiv *iotg) +{ + return container_of(iotg, struct langwell_otg, iotg); +} + +#endif /* __LANGWELL_OTG_H__ */ diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index 00596e816b4d..5b2fed5eebf2 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -1388,6 +1388,6 @@ struct hci_inquiry_req { }; #define IREQ_CACHE_FLUSH 0x0001 -extern bool enable_hs; +extern int enable_hs; #endif /* __HCI_H */ diff --git a/trunk/include/net/netns/generic.h b/trunk/include/net/netns/generic.h index d55f43443335..3419bf5cd154 100644 --- a/trunk/include/net/netns/generic.h +++ b/trunk/include/net/netns/generic.h @@ -41,7 +41,6 @@ static inline void *net_generic(const struct net *net, int id) ptr = ng->ptr[id - 1]; rcu_read_unlock(); - BUG_ON(!ptr); return ptr; } #endif diff --git a/trunk/include/net/netprio_cgroup.h b/trunk/include/net/netprio_cgroup.h index 7b2d43139c8e..e503b87c4c1b 100644 --- a/trunk/include/net/netprio_cgroup.h +++ b/trunk/include/net/netprio_cgroup.h @@ -13,6 +13,7 @@ #ifndef _NETPRIO_CGROUP_H #define _NETPRIO_CGROUP_H +#include #include #include #include diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 91c1c8baf020..bb972d254dff 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -55,7 +55,6 @@ #include #include #include -#include #include #include @@ -227,7 +226,6 @@ struct cg_proto; * @sk_ack_backlog: current listen backlog * @sk_max_ack_backlog: listen backlog set in listen() * @sk_priority: %SO_PRIORITY setting - * @sk_cgrp_prioidx: socket group's priority map index * @sk_type: socket type (%SOCK_STREAM, etc) * @sk_protocol: which protocol this socket belongs in this network family * @sk_peer_pid: &struct pid for this socket's peer @@ -923,7 +921,7 @@ inline void sk_refcnt_debug_release(const struct sock *sk) #define sk_refcnt_debug_release(sk) do { } while (0) #endif /* SOCK_REFCNT_DEBUG */ -#if defined(CONFIG_CGROUP_MEM_RES_CTLR_KMEM) && defined(CONFIG_NET) +#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM extern struct jump_label_key memcg_socket_limit_enabled; static inline struct cg_proto *parent_cg_proto(struct proto *proto, struct cg_proto *cg_proto) @@ -1009,8 +1007,9 @@ static inline void memcg_memory_allocated_add(struct cg_proto *prot, struct res_counter *fail; int ret; - ret = res_counter_charge_nofail(prot->memory_allocated, - amt << PAGE_SHIFT, &fail); + ret = res_counter_charge(prot->memory_allocated, + amt << PAGE_SHIFT, &fail); + if (ret < 0) *parent_status = OVER_LIMIT; } @@ -1054,11 +1053,12 @@ sk_memory_allocated_add(struct sock *sk, int amt, int *parent_status) } static inline void -sk_memory_allocated_sub(struct sock *sk, int amt) +sk_memory_allocated_sub(struct sock *sk, int amt, int parent_status) { struct proto *prot = sk->sk_prot; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + if (mem_cgroup_sockets_enabled && sk->sk_cgrp && + parent_status != OVER_LIMIT) /* Otherwise was uncharged already */ memcg_memory_allocated_sub(sk->sk_cgrp, amt); atomic_long_sub(amt, prot->memory_allocated); diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index d49db0113a06..0118ea999f67 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -311,8 +311,6 @@ extern struct proto tcp_prot; #define TCP_ADD_STATS_USER(net, field, val) SNMP_ADD_STATS_USER((net)->mib.tcp_statistics, field, val) #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) -extern void tcp_init_mem(struct net *net); - extern void tcp_v4_err(struct sk_buff *skb, u32); extern void tcp_shutdown (struct sock *sk, int how); diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index cea1b5426dfa..5ab255f196cc 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -417,7 +417,6 @@ static inline int __snd_bug_on(int cond) #define gameport_get_port_data(gp) (gp)->port_data #endif -#ifdef CONFIG_PCI /* PCI quirk list helper */ struct snd_pci_quirk { unsigned short subvendor; /* PCI subvendor ID */ @@ -457,6 +456,5 @@ snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list); const struct snd_pci_quirk * snd_pci_quirk_lookup_id(u16 vendor, u16 device, const struct snd_pci_quirk *list); -#endif #endif /* __SOUND_CORE_H */ diff --git a/trunk/kernel/events/callchain.c b/trunk/kernel/events/callchain.c index 6581a040f399..057e24b665cf 100644 --- a/trunk/kernel/events/callchain.c +++ b/trunk/kernel/events/callchain.c @@ -115,6 +115,8 @@ int get_callchain_buffers(void) } err = alloc_callchain_buffers(); + if (err) + release_callchain_buffers(); exit: mutex_unlock(&callchain_mutex); diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index ba36013cfb21..a8f4ac001a00 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -815,7 +815,7 @@ static void update_event_times(struct perf_event *event) * here. */ if (is_cgroup_event(event)) - run_end = perf_cgroup_event_time(event); + run_end = perf_event_time(event); else if (ctx->is_active) run_end = ctx->time; else @@ -2300,9 +2300,6 @@ do { \ return div64_u64(dividend, divisor); } -static DEFINE_PER_CPU(int, perf_throttled_count); -static DEFINE_PER_CPU(u64, perf_throttled_seq); - static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) { struct hw_perf_event *hwc = &event->hw; @@ -2328,29 +2325,16 @@ static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) } } -/* - * combine freq adjustment with unthrottling to avoid two passes over the - * events. At the same time, make sure, having freq events does not change - * the rate of unthrottling as that would introduce bias. - */ -static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx, - int needs_unthr) +static void perf_ctx_adjust_freq(struct perf_event_context *ctx, u64 period) { struct perf_event *event; struct hw_perf_event *hwc; - u64 now, period = TICK_NSEC; + u64 interrupts, now; s64 delta; - /* - * only need to iterate over all events iff: - * - context have events in frequency mode (needs freq adjust) - * - there are events to unthrottle on this cpu - */ - if (!(ctx->nr_freq || needs_unthr)) + if (!ctx->nr_freq) return; - raw_spin_lock(&ctx->lock); - list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { if (event->state != PERF_EVENT_STATE_ACTIVE) continue; @@ -2360,8 +2344,13 @@ static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx, hwc = &event->hw; - if (needs_unthr && hwc->interrupts == MAX_INTERRUPTS) { - hwc->interrupts = 0; + interrupts = hwc->interrupts; + hwc->interrupts = 0; + + /* + * unthrottle events on the tick + */ + if (interrupts == MAX_INTERRUPTS) { perf_log_throttle(event, 1); event->pmu->start(event, 0); } @@ -2369,26 +2358,14 @@ static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx, if (!event->attr.freq || !event->attr.sample_freq) continue; - /* - * stop the event and update event->count - */ - event->pmu->stop(event, PERF_EF_UPDATE); - + event->pmu->read(event); now = local64_read(&event->count); delta = now - hwc->freq_count_stamp; hwc->freq_count_stamp = now; - /* - * restart the event - * reload only if value has changed - */ if (delta > 0) perf_adjust_period(event, period, delta); - - event->pmu->start(event, delta > 0 ? PERF_EF_RELOAD : 0); } - - raw_spin_unlock(&ctx->lock); } /* @@ -2411,13 +2388,16 @@ static void rotate_ctx(struct perf_event_context *ctx) */ static void perf_rotate_context(struct perf_cpu_context *cpuctx) { + u64 interval = (u64)cpuctx->jiffies_interval * TICK_NSEC; struct perf_event_context *ctx = NULL; - int rotate = 0, remove = 1; + int rotate = 0, remove = 1, freq = 0; if (cpuctx->ctx.nr_events) { remove = 0; if (cpuctx->ctx.nr_events != cpuctx->ctx.nr_active) rotate = 1; + if (cpuctx->ctx.nr_freq) + freq = 1; } ctx = cpuctx->task_ctx; @@ -2425,26 +2405,37 @@ static void perf_rotate_context(struct perf_cpu_context *cpuctx) remove = 0; if (ctx->nr_events != ctx->nr_active) rotate = 1; + if (ctx->nr_freq) + freq = 1; } - if (!rotate) + if (!rotate && !freq) goto done; perf_ctx_lock(cpuctx, cpuctx->task_ctx); perf_pmu_disable(cpuctx->ctx.pmu); - cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); - if (ctx) - ctx_sched_out(ctx, cpuctx, EVENT_FLEXIBLE); + if (freq) { + perf_ctx_adjust_freq(&cpuctx->ctx, interval); + if (ctx) + perf_ctx_adjust_freq(ctx, interval); + } - rotate_ctx(&cpuctx->ctx); - if (ctx) - rotate_ctx(ctx); + if (rotate) { + cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); + if (ctx) + ctx_sched_out(ctx, cpuctx, EVENT_FLEXIBLE); - perf_event_sched_in(cpuctx, ctx, current); + rotate_ctx(&cpuctx->ctx); + if (ctx) + rotate_ctx(ctx); + + perf_event_sched_in(cpuctx, ctx, current); + } perf_pmu_enable(cpuctx->ctx.pmu); perf_ctx_unlock(cpuctx, cpuctx->task_ctx); + done: if (remove) list_del_init(&cpuctx->rotation_list); @@ -2454,22 +2445,10 @@ void perf_event_task_tick(void) { struct list_head *head = &__get_cpu_var(rotation_list); struct perf_cpu_context *cpuctx, *tmp; - struct perf_event_context *ctx; - int throttled; WARN_ON(!irqs_disabled()); - __this_cpu_inc(perf_throttled_seq); - throttled = __this_cpu_xchg(perf_throttled_count, 0); - list_for_each_entry_safe(cpuctx, tmp, head, rotation_list) { - ctx = &cpuctx->ctx; - perf_adjust_freq_unthr_context(ctx, throttled); - - ctx = cpuctx->task_ctx; - if (ctx) - perf_adjust_freq_unthr_context(ctx, throttled); - if (cpuctx->jiffies_interval == 1 || !(jiffies % cpuctx->jiffies_interval)) perf_rotate_context(cpuctx); @@ -4530,7 +4509,6 @@ static int __perf_event_overflow(struct perf_event *event, { int events = atomic_read(&event->event_limit); struct hw_perf_event *hwc = &event->hw; - u64 seq; int ret = 0; /* @@ -4540,20 +4518,14 @@ static int __perf_event_overflow(struct perf_event *event, if (unlikely(!is_sampling_event(event))) return 0; - seq = __this_cpu_read(perf_throttled_seq); - if (seq != hwc->interrupts_seq) { - hwc->interrupts_seq = seq; - hwc->interrupts = 1; - } else { - hwc->interrupts++; - if (unlikely(throttle - && hwc->interrupts >= max_samples_per_tick)) { - __this_cpu_inc(perf_throttled_count); + if (unlikely(hwc->interrupts >= max_samples_per_tick)) { + if (throttle) { hwc->interrupts = MAX_INTERRUPTS; perf_log_throttle(event, 0); ret = 1; } - } + } else + hwc->interrupts++; if (event->attr.freq) { u64 now = perf_clock(); diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 4b4042f9bc6a..294b1709170d 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -1038,22 +1038,6 @@ void do_exit(long code) if (tsk->nr_dirtied) __this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied); exit_rcu(); - - /* - * The setting of TASK_RUNNING by try_to_wake_up() may be delayed - * when the following two conditions become true. - * - There is race condition of mmap_sem (It is acquired by - * exit_mm()), and - * - SMI occurs before setting TASK_RUNINNG. - * (or hypervisor of virtual machine switches to other guest) - * As a result, we may become TASK_RUNNING after becoming TASK_DEAD - * - * To avoid it, we have to wait for releasing tsk->pi_lock which - * is held by try_to_wake_up() - */ - smp_mb(); - raw_spin_unlock_wait(&tsk->pi_lock); - /* causes final put_task_struct in finish_task_switch(). */ tsk->state = TASK_DEAD; tsk->flags |= PF_NOFREEZE; /* tell freezer to ignore us */ diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 1b2ef3c23ae4..051f090d40c1 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -647,26 +647,6 @@ struct mm_struct *get_task_mm(struct task_struct *task) } EXPORT_SYMBOL_GPL(get_task_mm); -struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) -{ - struct mm_struct *mm; - int err; - - err = mutex_lock_killable(&task->signal->cred_guard_mutex); - if (err) - return ERR_PTR(err); - - mm = get_task_mm(task); - if (mm && mm != current->mm && - !ptrace_may_access(task, mode)) { - mmput(mm); - mm = ERR_PTR(-EACCES); - } - mutex_unlock(&task->signal->cred_guard_mutex); - - return mm; -} - /* Please note the differences between mmput and mm_release. * mmput is called whenever we stop holding onto a mm_struct, * error success whatever. diff --git a/trunk/kernel/kprobes.c b/trunk/kernel/kprobes.c index 9788c0ec6f43..29f5b65bee29 100644 --- a/trunk/kernel/kprobes.c +++ b/trunk/kernel/kprobes.c @@ -1673,12 +1673,8 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p, ri->rp = rp; ri->task = current; - if (rp->entry_handler && rp->entry_handler(ri, regs)) { - raw_spin_lock_irqsave(&rp->lock, flags); - hlist_add_head(&ri->hlist, &rp->free_instances); - raw_spin_unlock_irqrestore(&rp->lock, flags); + if (rp->entry_handler && rp->entry_handler(ri, regs)) return 0; - } arch_prepare_kretprobe(ri, regs); diff --git a/trunk/kernel/power/power.h b/trunk/kernel/power/power.h index 21724eee5206..0c4defe6d3b8 100644 --- a/trunk/kernel/power/power.h +++ b/trunk/kernel/power/power.h @@ -231,28 +231,8 @@ extern int pm_test_level; #ifdef CONFIG_SUSPEND_FREEZER static inline int suspend_freeze_processes(void) { - int error; - - error = freeze_processes(); - - /* - * freeze_processes() automatically thaws every task if freezing - * fails. So we need not do anything extra upon error. - */ - if (error) - goto Finish; - - error = freeze_kernel_threads(); - - /* - * freeze_kernel_threads() thaws only kernel threads upon freezing - * failure. So we have to thaw the userspace tasks ourselves. - */ - if (error) - thaw_processes(); - - Finish: - return error; + int error = freeze_processes(); + return error ? : freeze_kernel_threads(); } static inline void suspend_thaw_processes(void) diff --git a/trunk/kernel/power/process.c b/trunk/kernel/power/process.c index 7e426459e60a..77274c9ba2f1 100644 --- a/trunk/kernel/power/process.c +++ b/trunk/kernel/power/process.c @@ -143,10 +143,7 @@ int freeze_processes(void) /** * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator. * - * On success, returns 0. On failure, -errno and only the kernel threads are - * thawed, so as to give a chance to the caller to do additional cleanups - * (if any) before thawing the userspace tasks. So, it is the responsibility - * of the caller to thaw the userspace tasks, when the time is right. + * On success, returns 0. On failure, -errno and system is fully thawed. */ int freeze_kernel_threads(void) { @@ -162,7 +159,7 @@ int freeze_kernel_threads(void) BUG_ON(in_atomic()); if (error) - thaw_kernel_threads(); + thaw_processes(); return error; } @@ -191,22 +188,3 @@ void thaw_processes(void) printk("done.\n"); } -void thaw_kernel_threads(void) -{ - struct task_struct *g, *p; - - pm_nosig_freezing = false; - printk("Restarting kernel threads ... "); - - thaw_workqueues(); - - read_lock(&tasklist_lock); - do_each_thread(g, p) { - if (p->flags & (PF_KTHREAD | PF_WQ_WORKER)) - __thaw_task(p); - } while_each_thread(g, p); - read_unlock(&tasklist_lock); - - schedule(); - printk("done.\n"); -} diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index 3e100075b13c..6b1ab7a88522 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -249,15 +249,13 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, } pm_restore_gfp_mask(); error = hibernation_snapshot(data->platform_support); - if (error) { - thaw_kernel_threads(); - } else { + if (!error) { error = put_user(in_suspend, (int __user *)arg); if (!error && !freezer_test_done) data->ready = 1; if (freezer_test_done) { freezer_test_done = false; - thaw_kernel_threads(); + thaw_processes(); } } break; @@ -276,15 +274,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, swsusp_free(); memset(&data->handle, 0, sizeof(struct snapshot_handle)); data->ready = 0; - /* - * It is necessary to thaw kernel threads here, because - * SNAPSHOT_CREATE_IMAGE may be invoked directly after - * SNAPSHOT_FREE. In that case, if kernel threads were not - * thawed, the preallocation of memory carried out by - * hibernation_snapshot() might run into problems (i.e. it - * might fail or even deadlock). - */ - thaw_kernel_threads(); break; case SNAPSHOT_PREF_IMAGE_SIZE: diff --git a/trunk/kernel/rcutorture.c b/trunk/kernel/rcutorture.c index a58ac285fc69..88f17b8a3b1d 100644 --- a/trunk/kernel/rcutorture.c +++ b/trunk/kernel/rcutorture.c @@ -56,8 +56,8 @@ static int nreaders = -1; /* # reader threads, defaults to 2*ncpus */ static int nfakewriters = 4; /* # fake writer threads */ static int stat_interval; /* Interval between stats, in seconds. */ /* Defaults to "only at end of test". */ -static bool verbose; /* Print more debug info. */ -static bool test_no_idle_hz; /* Test RCU's support for tickless idle CPUs. */ +static int verbose; /* Print more debug info. */ +static int test_no_idle_hz; /* Test RCU's support for tickless idle CPUs. */ static int shuffle_interval = 3; /* Interval between shuffles (in sec)*/ static int stutter = 5; /* Start/stop testing interval (in sec) */ static int irqreader = 1; /* RCU readers from irq (timers). */ @@ -1399,7 +1399,7 @@ rcu_torture_shutdown(void *arg) * Execute random CPU-hotplug operations at the interval specified * by the onoff_interval. */ -static int __cpuinit +static int rcu_torture_onoff(void *arg) { int cpu; @@ -1447,7 +1447,7 @@ rcu_torture_onoff(void *arg) return 0; } -static int __cpuinit +static int rcu_torture_onoff_init(void) { if (onoff_interval <= 0) diff --git a/trunk/kernel/res_counter.c b/trunk/kernel/res_counter.c index d508363858b3..6d269cce7aa1 100644 --- a/trunk/kernel/res_counter.c +++ b/trunk/kernel/res_counter.c @@ -66,31 +66,6 @@ int res_counter_charge(struct res_counter *counter, unsigned long val, return ret; } -int res_counter_charge_nofail(struct res_counter *counter, unsigned long val, - struct res_counter **limit_fail_at) -{ - int ret, r; - unsigned long flags; - struct res_counter *c; - - r = ret = 0; - *limit_fail_at = NULL; - local_irq_save(flags); - for (c = counter; c != NULL; c = c->parent) { - spin_lock(&c->lock); - r = res_counter_charge_locked(c, val); - if (r) - c->usage += val; - spin_unlock(&c->lock); - if (r < 0 && ret == 0) { - *limit_fail_at = c; - ret = r; - } - } - local_irq_restore(flags); - - return ret; -} void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val) { if (WARN_ON(counter->usage < val)) diff --git a/trunk/kernel/sched/core.c b/trunk/kernel/sched/core.c index 5255c9d2e053..df00cb09263e 100644 --- a/trunk/kernel/sched/core.c +++ b/trunk/kernel/sched/core.c @@ -74,7 +74,6 @@ #include #include -#include #ifdef CONFIG_PARAVIRT #include #endif @@ -724,6 +723,9 @@ static void dequeue_task(struct rq *rq, struct task_struct *p, int flags) p->sched_class->dequeue_task(rq, p, flags); } +/* + * activate_task - move a task to the runqueue. + */ void activate_task(struct rq *rq, struct task_struct *p, int flags) { if (task_contributes_to_load(p)) @@ -732,6 +734,9 @@ void activate_task(struct rq *rq, struct task_struct *p, int flags) enqueue_task(rq, p, flags); } +/* + * deactivate_task - remove a task from the runqueue. + */ void deactivate_task(struct rq *rq, struct task_struct *p, int flags) { if (task_contributes_to_load(p)) @@ -4129,7 +4134,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy, on_rq = p->on_rq; running = task_current(rq, p); if (on_rq) - dequeue_task(rq, p, 0); + deactivate_task(rq, p, 0); if (running) p->sched_class->put_prev_task(rq, p); @@ -4142,7 +4147,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy, if (running) p->sched_class->set_curr_task(rq); if (on_rq) - enqueue_task(rq, p, 0); + activate_task(rq, p, 0); check_class_changed(rq, p, prev_class, oldprio); task_rq_unlock(rq, p, &flags); @@ -4993,9 +4998,9 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) * placed properly. */ if (p->on_rq) { - dequeue_task(rq_src, p, 0); + deactivate_task(rq_src, p, 0); set_task_cpu(p, dest_cpu); - enqueue_task(rq_dest, p, 0); + activate_task(rq_dest, p, 0); check_preempt_curr(rq_dest, p, 0); } done: @@ -7027,10 +7032,10 @@ static void normalize_task(struct rq *rq, struct task_struct *p) on_rq = p->on_rq; if (on_rq) - dequeue_task(rq, p, 0); + deactivate_task(rq, p, 0); __setscheduler(rq, p, SCHED_NORMAL, 0); if (on_rq) { - enqueue_task(rq, p, 0); + activate_task(rq, p, 0); resched_task(rq->curr); } diff --git a/trunk/kernel/sched/fair.c b/trunk/kernel/sched/fair.c index 7c6414fc669d..84adb2d66cbd 100644 --- a/trunk/kernel/sched/fair.c +++ b/trunk/kernel/sched/fair.c @@ -4866,15 +4866,6 @@ static void nohz_balancer_kick(int cpu) return; } -static inline void clear_nohz_tick_stopped(int cpu) -{ - if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) { - cpumask_clear_cpu(cpu, nohz.idle_cpus_mask); - atomic_dec(&nohz.nr_cpus); - clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)); - } -} - static inline void set_cpu_sd_state_busy(void) { struct sched_domain *sd; @@ -4913,12 +4904,6 @@ void select_nohz_load_balancer(int stop_tick) { int cpu = smp_processor_id(); - /* - * If this cpu is going down, then nothing needs to be done. - */ - if (!cpu_active(cpu)) - return; - if (stop_tick) { if (test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu))) return; @@ -4929,18 +4914,6 @@ void select_nohz_load_balancer(int stop_tick) } return; } - -static int __cpuinit sched_ilb_notifier(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_DYING: - clear_nohz_tick_stopped(smp_processor_id()); - return NOTIFY_OK; - default: - return NOTIFY_DONE; - } -} #endif static DEFINE_SPINLOCK(balancing); @@ -5097,7 +5070,11 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) * busy tick after returning from idle, we will update the busy stats. */ set_cpu_sd_state_busy(); - clear_nohz_tick_stopped(cpu); + if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) { + clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)); + cpumask_clear_cpu(cpu, nohz.idle_cpus_mask); + atomic_dec(&nohz.nr_cpus); + } /* * None are in tickless mode and hence no need for NOHZ idle load @@ -5613,7 +5590,6 @@ __init void init_sched_fair_class(void) #ifdef CONFIG_NO_HZ zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT); - cpu_notifier(sched_ilb_notifier, 0); #endif #endif /* SMP */ diff --git a/trunk/kernel/sched/rt.c b/trunk/kernel/sched/rt.c index f42ae7fb5ec5..3640ebbb466b 100644 --- a/trunk/kernel/sched/rt.c +++ b/trunk/kernel/sched/rt.c @@ -1587,11 +1587,6 @@ static int push_rt_task(struct rq *rq) if (!next_task) return 0; -#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW - if (unlikely(task_running(rq, next_task))) - return 0; -#endif - retry: if (unlikely(next_task == rq->curr)) { WARN_ON(1); diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index d117262deba3..1d7bca7f4f52 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -296,7 +296,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) if (__this_cpu_read(soft_watchdog_warn) == true) return HRTIMER_RESTART; - printk(KERN_EMERG "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n", + printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n", smp_processor_id(), duration, current->comm, task_pid_nr(current)); print_modules(); diff --git a/trunk/lib/Kconfig b/trunk/lib/Kconfig index d69d321a0997..169eb7c598e5 100644 --- a/trunk/lib/Kconfig +++ b/trunk/lib/Kconfig @@ -279,9 +279,6 @@ config AVERAGE If unsure, say N. -config CLZ_TAB - bool - config CORDIC tristate "CORDIC algorithm" help @@ -290,7 +287,6 @@ config CORDIC config MPILIB tristate - select CLZ_TAB help Multiprecision maths library from GnuPG. It is used to implement RSA digital signature verification, diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index 18515f0267c4..d71aae1b01b3 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -121,8 +121,6 @@ obj-$(CONFIG_DQL) += dynamic_queue_limits.o obj-$(CONFIG_MPILIB) += mpi/ obj-$(CONFIG_SIGNATURE) += digsig.o -obj-$(CONFIG_CLZ_TAB) += clz_tab.o - hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/trunk/lib/bug.c b/trunk/lib/bug.c index a28c1415357c..19552096d16b 100644 --- a/trunk/lib/bug.c +++ b/trunk/lib/bug.c @@ -169,7 +169,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) return BUG_TRAP_TYPE_WARN; } - printk(KERN_DEFAULT "------------[ cut here ]------------\n"); + printk(KERN_EMERG "------------[ cut here ]------------\n"); if (file) printk(KERN_CRIT "kernel BUG at %s:%u!\n", diff --git a/trunk/lib/clz_tab.c b/trunk/lib/clz_tab.c deleted file mode 100644 index 7287b4a991a7..000000000000 --- a/trunk/lib/clz_tab.c +++ /dev/null @@ -1,18 +0,0 @@ -const unsigned char __clz_tab[] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, -}; diff --git a/trunk/lib/digsig.c b/trunk/lib/digsig.c index 286d558033e2..fd2402f67f89 100644 --- a/trunk/lib/digsig.c +++ b/trunk/lib/digsig.c @@ -34,9 +34,14 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, unsigned long msglen, unsigned long modulus_bitlen, unsigned char *out, - unsigned long *outlen) + unsigned long *outlen, + int *is_valid) { unsigned long modulus_len, ps_len, i; + int result; + + /* default to invalid packet */ + *is_valid = 0; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); @@ -45,30 +50,39 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, return -EINVAL; /* separate encoded message */ - if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) - return -EINVAL; + if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) { + result = -EINVAL; + goto bail; + } for (i = 2; i < modulus_len - 1; i++) if (msg[i] != 0xFF) break; /* separator check */ - if (msg[i] != 0) + if (msg[i] != 0) { /* There was no octet with hexadecimal value 0x00 to separate ps from m. */ - return -EINVAL; + result = -EINVAL; + goto bail; + } ps_len = i - 2; if (*outlen < (msglen - (2 + ps_len + 1))) { *outlen = msglen - (2 + ps_len + 1); - return -EOVERFLOW; + result = -EOVERFLOW; + goto bail; } *outlen = (msglen - (2 + ps_len + 1)); memcpy(out, &msg[2 + ps_len + 1], *outlen); - return 0; + /* valid packet */ + *is_valid = 1; + result = 0; +bail: + return result; } /* @@ -82,7 +96,7 @@ static int digsig_verify_rsa(struct key *key, unsigned long len; unsigned long mlen, mblen; unsigned nret, l; - int head, i; + int valid, head, i; unsigned char *out1 = NULL, *out2 = NULL; MPI in = NULL, res = NULL, pkey[2]; uint8_t *p, *datap, *endp; @@ -91,10 +105,6 @@ static int digsig_verify_rsa(struct key *key, down_read(&key->sem); ukp = key->payload.data; - - if (ukp->datalen < sizeof(*pkh)) - goto err1; - pkh = (struct pubkey_hdr *)ukp->data; if (pkh->version != 1) @@ -107,23 +117,18 @@ static int digsig_verify_rsa(struct key *key, goto err1; datap = pkh->mpi; - endp = ukp->data + ukp->datalen; - - err = -ENOMEM; + endp = datap + ukp->datalen; for (i = 0; i < pkh->nmpi; i++) { unsigned int remaining = endp - datap; pkey[i] = mpi_read_from_buffer(datap, &remaining); - if (!pkey[i]) - goto err; datap += remaining; } mblen = mpi_get_nbits(pkey[0]); mlen = (mblen + 7)/8; - if (mlen == 0) - goto err; + err = -ENOMEM; out1 = kzalloc(mlen, GFP_KERNEL); if (!out1) @@ -162,9 +167,10 @@ static int digsig_verify_rsa(struct key *key, memset(out1, 0, head); memcpy(out1 + head, p, l); - err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); + err = -EINVAL; + pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len, &valid); - if (!err && len == hlen) + if (valid && len == hlen) err = memcmp(out2, h, hlen); err: @@ -172,8 +178,8 @@ static int digsig_verify_rsa(struct key *key, mpi_free(res); kfree(out1); kfree(out2); - while (--i >= 0) - mpi_free(pkey[i]); + mpi_free(pkey[0]); + mpi_free(pkey[1]); err1: up_read(&key->sem); diff --git a/trunk/lib/mpi/longlong.h b/trunk/lib/mpi/longlong.h index 29f98624ef93..b87487b40a8b 100644 --- a/trunk/lib/mpi/longlong.h +++ b/trunk/lib/mpi/longlong.h @@ -1200,40 +1200,18 @@ do { \ "r" ((USItype)(v)) \ : "%g1", "%g2" __AND_CLOBBER_CC) #define UMUL_TIME 39 /* 39 instructions */ -/* It's quite necessary to add this much assembler for the sparc. - The default udiv_qrnnd (in C) is more than 10 times slower! */ -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("! Inlined udiv_qrnnd\n\t" \ - "mov 32,%%g1\n\t" \ - "subcc %1,%2,%%g0\n\t" \ - "1: bcs 5f\n\t" \ - "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \ - "sub %1,%2,%1 ! this kills msb of n\n\t" \ - "addx %1,%1,%1 ! so this can't give carry\n\t" \ - "subcc %%g1,1,%%g1\n\t" \ - "2: bne 1b\n\t" \ - "subcc %1,%2,%%g0\n\t" \ - "bcs 3f\n\t" \ - "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \ - "b 3f\n\t" \ - "sub %1,%2,%1 ! this kills msb of n\n\t" \ - "4: sub %1,%2,%1\n\t" \ - "5: addxcc %1,%1,%1\n\t" \ - "bcc 2b\n\t" \ - "subcc %%g1,1,%%g1\n\t" \ - "! Got carry from n. Subtract next step to cancel this carry.\n\t" \ - "bne 4b\n\t" \ - "addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n\t" \ - "sub %1,%2,%1\n\t" \ - "3: xnor %0,0,%0\n\t" \ - "! End of inline udiv_qrnnd\n" \ - : "=&r" ((USItype)(q)), \ - "=&r" ((USItype)(r)) \ - : "r" ((USItype)(d)), \ - "1" ((USItype)(n1)), \ - "0" ((USItype)(n0)) : "%g1", "cc") -#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ #endif +#ifndef udiv_qrnnd +#ifndef LONGLONG_STANDALONE +#define udiv_qrnnd(q, r, n1, n0, d) \ +do { USItype __r; \ + (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \ + (r) = __r; \ +} while (0) + extern USItype __udiv_qrnnd(); +#define UDIV_TIME 140 +#endif /* LONGLONG_STANDALONE */ +#endif /* udiv_qrnnd */ #endif /* __sparc__ */ /*************************************** diff --git a/trunk/lib/mpi/mpi-bit.c b/trunk/lib/mpi/mpi-bit.c index 2f526627e4f5..854c9c6da025 100644 --- a/trunk/lib/mpi/mpi-bit.c +++ b/trunk/lib/mpi/mpi-bit.c @@ -21,6 +21,25 @@ #include "mpi-internal.h" #include "longlong.h" +const unsigned char __clz_tab[] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, +}; + #define A_LIMB_1 ((mpi_limb_t) 1) /**************** diff --git a/trunk/lib/mpi/mpi-div.c b/trunk/lib/mpi/mpi-div.c index f68cbbb4d4a4..c3087d1390ce 100644 --- a/trunk/lib/mpi/mpi-div.c +++ b/trunk/lib/mpi/mpi-div.c @@ -149,9 +149,6 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) mpi_ptr_t marker[5]; int markidx = 0; - if (!dsize) - return -EINVAL; - memset(marker, 0, sizeof(marker)); /* Ensure space is enough for quotient and remainder. @@ -210,8 +207,6 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) * numerator would be gradually overwritten by the quotient limbs. */ if (qp == np) { /* Copy NP object to temporary space. */ np = marker[markidx++] = mpi_alloc_limb_space(nsize); - if (!np) - goto nomem; MPN_COPY(np, qp, nsize); } } else /* Put quotient at top of remainder. */ diff --git a/trunk/lib/mpi/mpi-pow.c b/trunk/lib/mpi/mpi-pow.c index 67f3e79af914..b04a3cf80080 100644 --- a/trunk/lib/mpi/mpi-pow.c +++ b/trunk/lib/mpi/mpi-pow.c @@ -59,7 +59,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod) ep = exp->d; if (!msize) - return -EINVAL; + msize = 1 / msize; /* provoke a signal */ if (!esize) { /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 diff --git a/trunk/lib/mpi/mpicoder.c b/trunk/lib/mpi/mpicoder.c index f26b41fcb48c..716802b774ea 100644 --- a/trunk/lib/mpi/mpicoder.c +++ b/trunk/lib/mpi/mpicoder.c @@ -20,15 +20,78 @@ #include "mpi-internal.h" +#define DIM(v) (sizeof(v)/sizeof((v)[0])) #define MAX_EXTERN_MPI_BITS 16384 +static uint8_t asn[15] = /* Object ID is 1.3.14.3.2.26 */ +{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, + 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 +}; + +MPI do_encode_md(const void *sha_buffer, unsigned nbits) +{ + int nframe = (nbits + 7) / 8; + uint8_t *frame, *fr_pt; + int i = 0, n; + size_t asnlen = DIM(asn); + MPI a = MPI_NULL; + + if (SHA1_DIGEST_LENGTH + asnlen + 4 > nframe) + pr_info("MPI: can't encode a %d bit MD into a %d bits frame\n", + (int)(SHA1_DIGEST_LENGTH * 8), (int)nbits); + + /* We encode the MD in this way: + * + * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) + * + * PAD consists of FF bytes. + */ + frame = kmalloc(nframe, GFP_KERNEL); + if (!frame) + return MPI_NULL; + n = 0; + frame[n++] = 0; + frame[n++] = 1; /* block type */ + i = nframe - SHA1_DIGEST_LENGTH - asnlen - 3; + + if (i <= 1) { + pr_info("MPI: message digest encoding failed\n"); + kfree(frame); + return a; + } + + memset(frame + n, 0xff, i); + n += i; + frame[n++] = 0; + memcpy(frame + n, &asn, asnlen); + n += asnlen; + memcpy(frame + n, sha_buffer, SHA1_DIGEST_LENGTH); + n += SHA1_DIGEST_LENGTH; + + i = nframe; + fr_pt = frame; + + if (n != nframe) { + printk + ("MPI: message digest encoding failed, frame length is wrong\n"); + kfree(frame); + return a; + } + + a = mpi_alloc((nframe + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB); + mpi_set_buffer(a, frame, nframe, 0); + kfree(frame); + + return a; +} + MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) { const uint8_t *buffer = xbuffer; int i, j; unsigned nbits, nbytes, nlimbs, nread = 0; mpi_limb_t a; - MPI val = NULL; + MPI val = MPI_NULL; if (*ret_nread < 2) goto leave; @@ -45,7 +108,7 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; val = mpi_alloc(nlimbs); if (!val) - return NULL; + return MPI_NULL; i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; i %= BYTES_PER_MPI_LIMB; val->nbits = nbits; @@ -148,6 +211,30 @@ int mpi_fromstr(MPI val, const char *str) } EXPORT_SYMBOL_GPL(mpi_fromstr); +/**************** + * Special function to get the low 8 bytes from an mpi. + * This can be used as a keyid; KEYID is an 2 element array. + * Return the low 4 bytes. + */ +u32 mpi_get_keyid(const MPI a, u32 *keyid) +{ +#if BYTES_PER_MPI_LIMB == 4 + if (keyid) { + keyid[0] = a->nlimbs >= 2 ? a->d[1] : 0; + keyid[1] = a->nlimbs >= 1 ? a->d[0] : 0; + } + return a->nlimbs >= 1 ? a->d[0] : 0; +#elif BYTES_PER_MPI_LIMB == 8 + if (keyid) { + keyid[0] = a->nlimbs ? (u32) (a->d[0] >> 32) : 0; + keyid[1] = a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0; + } + return a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0; +#else +#error Make this function work with other LIMB sizes +#endif +} + /**************** * Return an allocated buffer with the MPI (msb first). * NBYTES receives the length of this buffer. Caller must free the diff --git a/trunk/lib/mpi/mpih-div.c b/trunk/lib/mpi/mpih-div.c index cde1aaec18da..87ede162dfab 100644 --- a/trunk/lib/mpi/mpih-div.c +++ b/trunk/lib/mpi/mpih-div.c @@ -217,10 +217,6 @@ mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs, case 0: /* We are asked to divide by zero, so go ahead and do it! (To make the compiler not remove this statement, return the value.) */ - /* - * existing clients of this function have been modified - * not to call it with dsize == 0, so this should not happen - */ return 1 / dsize; case 1: diff --git a/trunk/lib/mpi/mpiutil.c b/trunk/lib/mpi/mpiutil.c index 26e4ed31e256..eefc55d6b7f5 100644 --- a/trunk/lib/mpi/mpiutil.c +++ b/trunk/lib/mpi/mpiutil.c @@ -58,9 +58,6 @@ mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs) { size_t len = nlimbs * sizeof(mpi_limb_t); - if (!len) - return NULL; - return kmalloc(len, GFP_KERNEL); } @@ -138,7 +135,7 @@ int mpi_copy(MPI *copied, const MPI a) size_t i; MPI b; - *copied = NULL; + *copied = MPI_NULL; if (a) { b = mpi_alloc(a->nlimbs); diff --git a/trunk/mm/compaction.c b/trunk/mm/compaction.c index bd939a574b84..71a58f67f481 100644 --- a/trunk/mm/compaction.c +++ b/trunk/mm/compaction.c @@ -313,19 +313,6 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, } else if (!locked) spin_lock_irq(&zone->lru_lock); - /* - * migrate_pfn does not necessarily start aligned to a - * pageblock. Ensure that pfn_valid is called when moving - * into a new MAX_ORDER_NR_PAGES range in case of large - * memory holes within the zone - */ - if ((low_pfn & (MAX_ORDER_NR_PAGES - 1)) == 0) { - if (!pfn_valid(low_pfn)) { - low_pfn += MAX_ORDER_NR_PAGES - 1; - continue; - } - } - if (!pfn_valid_within(low_pfn)) continue; nr_scanned++; diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index b66275757c28..97f49ed35bd2 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -1400,12 +1400,15 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long seg = 0; size_t count; loff_t *ppos = &iocb->ki_pos; + struct blk_plug plug; count = 0; retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE); if (retval) return retval; + blk_start_plug(&plug); + /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ if (filp->f_flags & O_DIRECT) { loff_t size; @@ -1421,12 +1424,8 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, retval = filemap_write_and_wait_range(mapping, pos, pos + iov_length(iov, nr_segs) - 1); if (!retval) { - struct blk_plug plug; - - blk_start_plug(&plug); retval = mapping->a_ops->direct_IO(READ, iocb, iov, pos, nr_segs); - blk_finish_plug(&plug); } if (retval > 0) { *ppos = pos + retval; @@ -1482,6 +1481,7 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, break; } out: + blk_finish_plug(&plug); return retval; } EXPORT_SYMBOL(generic_file_aio_read); diff --git a/trunk/mm/filemap_xip.c b/trunk/mm/filemap_xip.c index a4eb31132229..f91b2f687343 100644 --- a/trunk/mm/filemap_xip.c +++ b/trunk/mm/filemap_xip.c @@ -263,12 +263,7 @@ static int xip_file_fault(struct vm_area_struct *vma, struct vm_fault *vmf) xip_pfn); if (err == -ENOMEM) return VM_FAULT_OOM; - /* - * err == -EBUSY is fine, we've raced against another thread - * that faulted-in the same page - */ - if (err != -EBUSY) - BUG_ON(err); + BUG_ON(err); return VM_FAULT_NOPAGE; } else { int err, ret = VM_FAULT_OOM; diff --git a/trunk/mm/kmemleak.c b/trunk/mm/kmemleak.c index 45eb6217bf38..c833addd94d7 100644 --- a/trunk/mm/kmemleak.c +++ b/trunk/mm/kmemleak.c @@ -1036,7 +1036,7 @@ void __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) { pr_debug("%s(0x%p)\n", __func__, ptr); - if (atomic_read(&kmemleak_enabled) && ptr && size && !IS_ERR(ptr)) + if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) add_scan_area((unsigned long)ptr, size, gfp); else if (atomic_read(&kmemleak_early_log)) log_early(KMEMLEAK_SCAN_AREA, ptr, size, 0); @@ -1757,7 +1757,6 @@ void __init kmemleak_init(void) #ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF if (!kmemleak_skip_disable) { - atomic_set(&kmemleak_early_log, 0); kmemleak_disable(); return; } diff --git a/trunk/mm/memblock.c b/trunk/mm/memblock.c index 77b5f227e1d8..2f55f19b7c86 100644 --- a/trunk/mm/memblock.c +++ b/trunk/mm/memblock.c @@ -106,17 +106,14 @@ phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t start, if (end == MEMBLOCK_ALLOC_ACCESSIBLE) end = memblock.current_limit; - /* avoid allocating the first page */ - start = max_t(phys_addr_t, start, PAGE_SIZE); + /* adjust @start to avoid underflow and allocating the first page */ + start = max3(start, size, (phys_addr_t)PAGE_SIZE); end = max(start, end); for_each_free_mem_range_reverse(i, nid, &this_start, &this_end, NULL) { this_start = clamp(this_start, start, end); this_end = clamp(this_end, start, end); - if (this_end < size) - continue; - cand = round_down(this_end - size, align); if (cand >= this_start) return cand; diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 6728a7ae6f2d..4baddbae94cc 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -379,7 +379,7 @@ static void mem_cgroup_put(struct mem_cgroup *memcg); static bool mem_cgroup_is_root(struct mem_cgroup *memcg); void sock_update_memcg(struct sock *sk) { - if (mem_cgroup_sockets_enabled) { + if (static_branch(&memcg_socket_limit_enabled)) { struct mem_cgroup *memcg; BUG_ON(!sk->sk_prot->proto_cgroup); @@ -411,7 +411,7 @@ EXPORT_SYMBOL(sock_update_memcg); void sock_release_memcg(struct sock *sk) { - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { + if (static_branch(&memcg_socket_limit_enabled) && sk->sk_cgrp) { struct mem_cgroup *memcg; WARN_ON(!sk->sk_cgrp->memcg); memcg = sk->sk_cgrp->memcg; @@ -776,8 +776,7 @@ static void memcg_check_events(struct mem_cgroup *memcg, struct page *page) /* threshold event is triggered in finer grain than soft limit */ if (unlikely(mem_cgroup_event_ratelimit(memcg, MEM_CGROUP_TARGET_THRESH))) { - bool do_softlimit; - bool do_numainfo __maybe_unused; + bool do_softlimit, do_numainfo; do_softlimit = mem_cgroup_event_ratelimit(memcg, MEM_CGROUP_TARGET_SOFTLIMIT); diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index df141f60289e..9871a56d82c3 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -445,6 +445,7 @@ void migrate_page_copy(struct page *newpage, struct page *page) ClearPageSwapCache(page); ClearPagePrivate(page); set_page_private(page, 0); + page->mapping = NULL; /* * If any waiters have accumulated on the new page then @@ -666,7 +667,6 @@ static int move_to_new_page(struct page *newpage, struct page *page, } else { if (remap_swapcache) remove_migration_ptes(page, newpage); - page->mapping = NULL; } unlock_page(newpage); diff --git a/trunk/mm/process_vm_access.c b/trunk/mm/process_vm_access.c index c20ff48994c2..e920aa3ce104 100644 --- a/trunk/mm/process_vm_access.c +++ b/trunk/mm/process_vm_access.c @@ -298,18 +298,23 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec, goto free_proc_pages; } - mm = mm_access(task, PTRACE_MODE_ATTACH); - if (!mm || IS_ERR(mm)) { - rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH; - /* - * Explicitly map EACCES to EPERM as EPERM is a more a - * appropriate error code for process_vw_readv/writev - */ - if (rc == -EACCES) - rc = -EPERM; + task_lock(task); + if (__ptrace_may_access(task, PTRACE_MODE_ATTACH)) { + task_unlock(task); + rc = -EPERM; + goto put_task_struct; + } + mm = task->mm; + + if (!mm || (task->flags & PF_KTHREAD)) { + task_unlock(task); + rc = -EINVAL; goto put_task_struct; } + atomic_inc(&mm->mm_users); + task_unlock(task); + for (i = 0; i < riovcnt && iov_l_curr_idx < liovcnt; i++) { rc = process_vm_rw_single_vec( (unsigned long)rvec[i].iov_base, rvec[i].iov_len, diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 9de93714213a..845da3ee56a0 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -55,7 +55,7 @@ #define AUTO_OFF_TIMEOUT 2000 -bool enable_hs; +int enable_hs; static void hci_rx_work(struct work_struct *work); static void hci_cmd_work(struct work_struct *work); diff --git a/trunk/net/caif/caif_dev.c b/trunk/net/caif/caif_dev.c index 82c57069415f..673728add60b 100644 --- a/trunk/net/caif/caif_dev.c +++ b/trunk/net/caif/caif_dev.c @@ -59,6 +59,8 @@ struct cfcnfg *get_cfcnfg(struct net *net) { struct caif_net *caifn; caifn = net_generic(net, caif_net_id); + if (!caifn) + return NULL; return caifn->cfg; } EXPORT_SYMBOL(get_cfcnfg); @@ -67,6 +69,8 @@ static struct caif_device_entry_list *caif_device_list(struct net *net) { struct caif_net *caifn; caifn = net_generic(net, caif_net_id); + if (!caifn) + return NULL; return &caifn->caifdevs; } @@ -95,6 +99,8 @@ static struct caif_device_entry *caif_device_alloc(struct net_device *dev) struct caif_device_entry *caifd; caifdevs = caif_device_list(dev_net(dev)); + if (!caifdevs) + return NULL; caifd = kzalloc(sizeof(*caifd), GFP_KERNEL); if (!caifd) @@ -114,6 +120,8 @@ static struct caif_device_entry *caif_get(struct net_device *dev) struct caif_device_entry_list *caifdevs = caif_device_list(dev_net(dev)); struct caif_device_entry *caifd; + if (!caifdevs) + return NULL; list_for_each_entry_rcu(caifd, &caifdevs->list, list) { if (caifd->netdev == dev) @@ -313,6 +321,8 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, struct caif_device_entry_list *caifdevs; caifdevs = caif_device_list(dev_net(dev)); + if (!cfg || !caifdevs) + return; caifd = caif_device_alloc(dev); if (!caifd) return; @@ -364,6 +374,8 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, cfg = get_cfcnfg(dev_net(dev)); caifdevs = caif_device_list(dev_net(dev)); + if (!cfg || !caifdevs) + return 0; caifd = caif_get(dev); if (caifd == NULL && dev->type != ARPHRD_CAIF) @@ -495,6 +507,9 @@ static struct notifier_block caif_device_notifier = { static int caif_init_net(struct net *net) { struct caif_net *caifn = net_generic(net, caif_net_id); + if (WARN_ON(!caifn)) + return -EINVAL; + INIT_LIST_HEAD(&caifn->caifdevs.list); mutex_init(&caifn->caifdevs.lock); @@ -512,6 +527,9 @@ static void caif_exit_net(struct net *net) caif_device_list(net); struct cfcnfg *cfg = get_cfcnfg(net); + if (!cfg || !caifdevs) + return; + rtnl_lock(); mutex_lock(&caifdevs->lock); @@ -551,7 +569,7 @@ static int __init caif_device_init(void) { int result; - result = register_pernet_subsys(&caif_net_ops); + result = register_pernet_device(&caif_net_ops); if (result) return result; @@ -564,7 +582,7 @@ static int __init caif_device_init(void) static void __exit caif_device_exit(void) { - unregister_pernet_subsys(&caif_net_ops); + unregister_pernet_device(&caif_net_ops); unregister_netdevice_notifier(&caif_device_notifier); dev_remove_pack(&caif_packet_type); } diff --git a/trunk/net/caif/cfcnfg.c b/trunk/net/caif/cfcnfg.c index ba9cfd47778a..598aafb4cb51 100644 --- a/trunk/net/caif/cfcnfg.c +++ b/trunk/net/caif/cfcnfg.c @@ -309,6 +309,7 @@ int caif_connect_client(struct net *net, struct caif_connect_request *conn_req, int err; struct cfctrl_link_param param; struct cfcnfg *cfg = get_cfcnfg(net); + caif_assert(cfg != NULL); rcu_read_lock(); err = caif_connect_req_to_link_param(cfg, conn_req, ¶m); diff --git a/trunk/net/ceph/ceph_common.c b/trunk/net/ceph/ceph_common.c index 761ad9d6cc3b..97f70e50ad3b 100644 --- a/trunk/net/ceph/ceph_common.c +++ b/trunk/net/ceph/ceph_common.c @@ -85,6 +85,8 @@ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid) } else { pr_info("client%lld fsid %pU\n", ceph_client_id(client), fsid); memcpy(&client->fsid, fsid, sizeof(*fsid)); + ceph_debugfs_client_init(client); + client->have_fsid = true; } return 0; } diff --git a/trunk/net/ceph/mon_client.c b/trunk/net/ceph/mon_client.c index 1845cde26227..0b62deae42bd 100644 --- a/trunk/net/ceph/mon_client.c +++ b/trunk/net/ceph/mon_client.c @@ -8,8 +8,8 @@ #include #include -#include #include + #include /* @@ -340,19 +340,8 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc, client->monc.monmap = monmap; kfree(old); - if (!client->have_fsid) { - client->have_fsid = true; - mutex_unlock(&monc->mutex); - /* - * do debugfs initialization without mutex to avoid - * creating a locking dependency - */ - ceph_debugfs_client_init(client); - goto out_unlocked; - } out: mutex_unlock(&monc->mutex); -out_unlocked: wake_up_all(&client->auth_wq); } diff --git a/trunk/net/core/ethtool.c b/trunk/net/core/ethtool.c index 369b41894527..921aa2b4b415 100644 --- a/trunk/net/core/ethtool.c +++ b/trunk/net/core/ethtool.c @@ -1311,7 +1311,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GRXCSUM: case ETHTOOL_GTXCSUM: case ETHTOOL_GSG: - case ETHTOOL_GSSET_INFO: case ETHTOOL_GSTRINGS: case ETHTOOL_GTSO: case ETHTOOL_GPERMADDR: diff --git a/trunk/net/core/flow_dissector.c b/trunk/net/core/flow_dissector.c index a225089df5b6..0985b9b14b80 100644 --- a/trunk/net/core/flow_dissector.c +++ b/trunk/net/core/flow_dissector.c @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/trunk/net/core/net_namespace.c b/trunk/net/core/net_namespace.c index 0e950fda9a0a..aefcd7acbffa 100644 --- a/trunk/net/core/net_namespace.c +++ b/trunk/net/core/net_namespace.c @@ -30,20 +30,6 @@ EXPORT_SYMBOL(init_net); #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ -static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS; - -static struct net_generic *net_alloc_generic(void) -{ - struct net_generic *ng; - size_t generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]); - - ng = kzalloc(generic_size, GFP_KERNEL); - if (ng) - ng->len = max_gen_ptrs; - - return ng; -} - static int net_assign_generic(struct net *net, int id, void *data) { struct net_generic *ng, *old_ng; @@ -57,7 +43,8 @@ static int net_assign_generic(struct net *net, int id, void *data) if (old_ng->len >= id) goto assign; - ng = net_alloc_generic(); + ng = kzalloc(sizeof(struct net_generic) + + id * sizeof(void *), GFP_KERNEL); if (ng == NULL) return -ENOMEM; @@ -72,6 +59,7 @@ static int net_assign_generic(struct net *net, int id, void *data) * the old copy for kfree after a grace period. */ + ng->len = id; memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); rcu_assign_pointer(net->gen, ng); @@ -173,6 +161,18 @@ static __net_init int setup_net(struct net *net) goto out; } +static struct net_generic *net_alloc_generic(void) +{ + struct net_generic *ng; + size_t generic_size = sizeof(struct net_generic) + + INITIAL_NET_GEN_PTRS * sizeof(void *); + + ng = kzalloc(generic_size, GFP_KERNEL); + if (ng) + ng->len = INITIAL_NET_GEN_PTRS; + + return ng; +} #ifdef CONFIG_NET_NS static struct kmem_cache *net_cachep; @@ -483,7 +483,6 @@ static int register_pernet_operations(struct list_head *list, } return error; } - max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id); } error = __register_pernet_operations(list, ops); if (error) { diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index 4d8ce93cd503..65f80c7b1656 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -767,8 +767,8 @@ static int count_trail_chars(const char __user * user_buffer, return i; } -static long num_arg(const char __user *user_buffer, unsigned long maxlen, - unsigned long *num) +static unsigned long num_arg(const char __user * user_buffer, + unsigned long maxlen, unsigned long *num) { int i; *num = 0; diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 65aebd450027..f16444bc6cbb 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -1509,9 +1509,6 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, if (send_addr_notify) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - min_ifinfo_dump_size = max_t(u16, if_nlmsg_size(dev), - min_ifinfo_dump_size); - return err; } diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 3e81fd2e3c75..5c5af9988f94 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -1827,7 +1827,7 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) /* Alas. Undo changes. */ sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; - sk_memory_allocated_sub(sk, amt); + sk_memory_allocated_sub(sk, amt, parent_status); return 0; } @@ -1840,7 +1840,7 @@ EXPORT_SYMBOL(__sk_mem_schedule); void __sk_mem_reclaim(struct sock *sk) { sk_memory_allocated_sub(sk, - sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT); + sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, 0); sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1; if (sk_under_memory_pressure(sk) && diff --git a/trunk/net/ipv4/inet_connection_sock.c b/trunk/net/ipv4/inet_connection_sock.c index 19d66cefd7d3..2e4e24476c4c 100644 --- a/trunk/net/ipv4/inet_connection_sock.c +++ b/trunk/net/ipv4/inet_connection_sock.c @@ -123,14 +123,11 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) smallest_size = tb->num_owners; smallest_rover = rover; if (atomic_read(&hashinfo->bsockets) > (high - low) + 1) { + spin_unlock(&head->lock); snum = smallest_rover; - goto tb_found; + goto have_snum; } } - if (!inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb)) { - snum = rover; - goto tb_found; - } goto next; } break; diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 6b3ca5ba4450..2b53a1f7abf6 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -422,10 +422,6 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net, if (register_netdevice(dev) < 0) goto failed_free; - /* Can use a lockless transmit, unless we generate output sequences */ - if (!(nt->parms.o_flags & GRE_SEQ)) - dev->features |= NETIF_F_LLTX; - dev_hold(dev); ipgre_tunnel_link(ign, nt); return nt; diff --git a/trunk/net/ipv4/proc.c b/trunk/net/ipv4/proc.c index 6afc807ee2ad..3569d8ecaeac 100644 --- a/trunk/net/ipv4/proc.c +++ b/trunk/net/ipv4/proc.c @@ -216,6 +216,7 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPPartialUndo", LINUX_MIB_TCPPARTIALUNDO), SNMP_MIB_ITEM("TCPDSACKUndo", LINUX_MIB_TCPDSACKUNDO), SNMP_MIB_ITEM("TCPLossUndo", LINUX_MIB_TCPLOSSUNDO), + SNMP_MIB_ITEM("TCPLoss", LINUX_MIB_TCPLOSS), SNMP_MIB_ITEM("TCPLostRetransmit", LINUX_MIB_TCPLOSTRETRANSMIT), SNMP_MIB_ITEM("TCPRenoFailures", LINUX_MIB_TCPRENOFAILURES), SNMP_MIB_ITEM("TCPSackFailures", LINUX_MIB_TCPSACKFAILURES), diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index 4cb9cd2f2c39..4aa7e9dc0cbb 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -814,7 +814,6 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) net->ipv4.sysctl_rt_cache_rebuild_count = 4; - tcp_init_mem(net); limit = nr_free_buffer_pages() / 8; limit = max(limit, 128UL); net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3; diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 06373b4a449a..9bcdec3ad772 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -3216,16 +3216,6 @@ static int __init set_thash_entries(char *str) } __setup("thash_entries=", set_thash_entries); -void tcp_init_mem(struct net *net) -{ - /* Set per-socket limits to no more than 1/128 the pressure threshold */ - unsigned long limit = nr_free_buffer_pages() / 8; - limit = max(limit, 128UL); - net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3; - net->ipv4.sysctl_tcp_mem[1] = limit; - net->ipv4.sysctl_tcp_mem[2] = net->ipv4.sysctl_tcp_mem[0] * 2; -} - void __init tcp_init(void) { struct sk_buff *skb = NULL; @@ -3286,9 +3276,9 @@ void __init tcp_init(void) sysctl_tcp_max_orphans = cnt / 2; sysctl_max_syn_backlog = max(128, cnt / 256); - tcp_init_mem(&init_net); - limit = nr_free_buffer_pages() / 8; - limit = max(limit, 128UL); + /* Set per-socket limits to no more than 1/128 the pressure threshold */ + limit = ((unsigned long)init_net.ipv4.sysctl_tcp_mem[1]) + << (PAGE_SHIFT - 7); max_share = min(4UL*1024*1024, limit); sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; diff --git a/trunk/net/ipv4/tcp_bic.c b/trunk/net/ipv4/tcp_bic.c index f45e1c242440..6187eb4d1dcf 100644 --- a/trunk/net/ipv4/tcp_bic.c +++ b/trunk/net/ipv4/tcp_bic.c @@ -63,6 +63,7 @@ static inline void bictcp_reset(struct bictcp *ca) { ca->cnt = 0; ca->last_max_cwnd = 0; + ca->loss_cwnd = 0; ca->last_cwnd = 0; ca->last_time = 0; ca->epoch_start = 0; @@ -71,11 +72,7 @@ static inline void bictcp_reset(struct bictcp *ca) static void bictcp_init(struct sock *sk) { - struct bictcp *ca = inet_csk_ca(sk); - - bictcp_reset(ca); - ca->loss_cwnd = 0; - + bictcp_reset(inet_csk_ca(sk)); if (initial_ssthresh) tcp_sk(sk)->snd_ssthresh = initial_ssthresh; } @@ -130,7 +127,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) } /* if in slow start or link utilization is very low */ - if (ca->last_max_cwnd == 0) { + if (ca->loss_cwnd == 0) { if (ca->cnt > 20) /* increase cwnd 5% per RTT */ ca->cnt = 20; } @@ -188,7 +185,7 @@ static u32 bictcp_undo_cwnd(struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); const struct bictcp *ca = inet_csk_ca(sk); - return max(tp->snd_cwnd, ca->loss_cwnd); + return max(tp->snd_cwnd, ca->last_max_cwnd); } static void bictcp_state(struct sock *sk, u8 new_state) diff --git a/trunk/net/ipv4/tcp_cubic.c b/trunk/net/ipv4/tcp_cubic.c index a9077f441cb2..f376b05cca81 100644 --- a/trunk/net/ipv4/tcp_cubic.c +++ b/trunk/net/ipv4/tcp_cubic.c @@ -107,6 +107,7 @@ static inline void bictcp_reset(struct bictcp *ca) { ca->cnt = 0; ca->last_max_cwnd = 0; + ca->loss_cwnd = 0; ca->last_cwnd = 0; ca->last_time = 0; ca->bic_origin_point = 0; @@ -141,10 +142,7 @@ static inline void bictcp_hystart_reset(struct sock *sk) static void bictcp_init(struct sock *sk) { - struct bictcp *ca = inet_csk_ca(sk); - - bictcp_reset(ca); - ca->loss_cwnd = 0; + bictcp_reset(inet_csk_ca(sk)); if (hystart) bictcp_hystart_reset(sk); @@ -277,7 +275,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) * The initial growth of cubic function may be too conservative * when the available bandwidth is still unknown. */ - if (ca->last_max_cwnd == 0 && ca->cnt > 20) + if (ca->loss_cwnd == 0 && ca->cnt > 20) ca->cnt = 20; /* increase cwnd 5% per RTT */ /* TCP Friendly */ @@ -344,7 +342,7 @@ static u32 bictcp_undo_cwnd(struct sock *sk) { struct bictcp *ca = inet_csk_ca(sk); - return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd); + return max(tcp_sk(sk)->snd_cwnd, ca->last_max_cwnd); } static void bictcp_state(struct sock *sk, u8 new_state) diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 976034f82320..2877c3e09587 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -105,6 +105,7 @@ int sysctl_tcp_abc __read_mostly; #define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ #define FLAG_DATA_SACKED 0x20 /* New SACK. */ #define FLAG_ECE 0x40 /* ECE in this ACK */ +#define FLAG_DATA_LOST 0x80 /* SACK detected data lossage. */ #define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ #define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */ #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ @@ -1039,11 +1040,13 @@ static void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, * These 6 states form finite state machine, controlled by the following events: * 1. New ACK (+SACK) arrives. (tcp_sacktag_write_queue()) * 2. Retransmission. (tcp_retransmit_skb(), tcp_xmit_retransmit_queue()) - * 3. Loss detection event of two flavors: + * 3. Loss detection event of one of three flavors: * A. Scoreboard estimator decided the packet is lost. * A'. Reno "three dupacks" marks head of queue lost. - * A''. Its FACK modification, head until snd.fack is lost. - * B. SACK arrives sacking SND.NXT at the moment, when the + * A''. Its FACK modfication, head until snd.fack is lost. + * B. SACK arrives sacking data transmitted after never retransmitted + * hole was sent out. + * C. SACK arrives sacking SND.NXT at the moment, when the * segment was retransmitted. * 4. D-SACK added new rule: D-SACK changes any tag to S. * @@ -1150,7 +1153,7 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack, } /* Check for lost retransmit. This superb idea is borrowed from "ratehalving". - * Event "B". Later note: FACK people cheated me again 8), we have to account + * Event "C". Later note: FACK people cheated me again 8), we have to account * for reordering! Ugly, but should help. * * Search retransmitted skbs from write_queue that were sent when snd_nxt was @@ -1841,6 +1844,10 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb, if (found_dup_sack && ((i + 1) == first_sack_index)) next_dup = &sp[i + 1]; + /* Event "B" in the comment above. */ + if (after(end_seq, tp->high_seq)) + state.flag |= FLAG_DATA_LOST; + /* Skip too early cached blocks */ while (tcp_sack_cache_ok(tp, cache) && !before(start_seq, cache->end_seq)) @@ -2508,11 +2515,8 @@ static void tcp_timeout_skbs(struct sock *sk) tcp_verify_left_out(tp); } -/* Detect loss in event "A" above by marking head of queue up as lost. - * For FACK or non-SACK(Reno) senders, the first "packets" number of segments - * are considered lost. For RFC3517 SACK, a segment is considered lost if it - * has at least tp->reordering SACKed seqments above it; "packets" refers to - * the maximum SACKed segments to pass before reaching this limit. +/* Mark head of queue up as lost. With RFC3517 SACK, the packets is + * is against sacked "cnt", otherwise it's against facked "cnt" */ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) { @@ -2521,8 +2525,6 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) int cnt, oldcnt; int err; unsigned int mss; - /* Use SACK to deduce losses of new sequences sent during recovery */ - const u32 loss_high = tcp_is_sack(tp) ? tp->snd_nxt : tp->high_seq; WARN_ON(packets > tp->packets_out); if (tp->lost_skb_hint) { @@ -2544,7 +2546,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) tp->lost_skb_hint = skb; tp->lost_cnt_hint = cnt; - if (after(TCP_SKB_CB(skb)->end_seq, loss_high)) + if (after(TCP_SKB_CB(skb)->end_seq, tp->high_seq)) break; oldcnt = cnt; @@ -3031,10 +3033,19 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, if (tcp_check_sack_reneging(sk, flag)) return; - /* C. Check consistency of the current state. */ + /* C. Process data loss notification, provided it is valid. */ + if (tcp_is_fack(tp) && (flag & FLAG_DATA_LOST) && + before(tp->snd_una, tp->high_seq) && + icsk->icsk_ca_state != TCP_CA_Open && + tp->fackets_out > tp->reordering) { + tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0); + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS); + } + + /* D. Check consistency of the current state. */ tcp_verify_left_out(tp); - /* D. Check state exit conditions. State can be terminated + /* E. Check state exit conditions. State can be terminated * when high_seq is ACKed. */ if (icsk->icsk_ca_state == TCP_CA_Open) { WARN_ON(tp->retrans_out != 0); @@ -3066,7 +3077,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, } } - /* E. Process state. */ + /* F. Process state. */ switch (icsk->icsk_ca_state) { case TCP_CA_Recovery: if (!(flag & FLAG_SND_UNA_ADVANCED)) { diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 337ba4cca052..1eb4ad57670e 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -631,7 +631,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) arg.iov[0].iov_len = sizeof(rep.th); #ifdef CONFIG_TCP_MD5SIG - key = sk ? tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->saddr) : NULL; + key = sk ? tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr) : NULL; if (key) { rep.opt[0] = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 4ff3b6dc74fc..8c8de2780c7a 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -1141,9 +1141,11 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) sk_mem_uncharge(sk, len); sock_set_flag(sk, SOCK_QUEUE_SHRUNK); - /* Any change of skb->len requires recalculation of tso factor. */ + /* Any change of skb->len requires recalculation of tso + * factor and mss. + */ if (tcp_skb_pcount(skb) > 1) - tcp_set_skb_tso_segs(sk, skb, tcp_skb_mss(skb)); + tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk)); return 0; } diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index c02280a4d126..a225d5ee3c2f 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -502,31 +502,29 @@ static void addrconf_forward_change(struct net *net, __s32 newf) rcu_read_unlock(); } -static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) +static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) { struct net *net; - int old; - - if (!rtnl_trylock()) - return restart_syscall(); net = (struct net *)table->extra2; - old = *p; - *p = newf; - - if (p == &net->ipv6.devconf_dflt->forwarding) { - rtnl_unlock(); + if (p == &net->ipv6.devconf_dflt->forwarding) return 0; + + if (!rtnl_trylock()) { + /* Restore the original values before restarting */ + *p = old; + return restart_syscall(); } if (p == &net->ipv6.devconf_all->forwarding) { + __s32 newf = net->ipv6.devconf_all->forwarding; net->ipv6.devconf_dflt->forwarding = newf; addrconf_forward_change(net, newf); - } else if ((!newf) ^ (!old)) + } else if ((!*p) ^ (!old)) dev_forward_change((struct inet6_dev *)table->extra1); rtnl_unlock(); - if (newf) + if (*p) rt6_purge_dflt_routers(net); return 1; } @@ -4262,17 +4260,9 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; - ctl_table lctl; int ret; - /* - * ctl->data points to idev->cnf.forwarding, we should - * not modify it until we get the rtnl lock. - */ - lctl = *ctl; - lctl.data = &val; - - ret = proc_dointvec(&lctl, write, buffer, lenp, ppos); + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); if (write) ret = addrconf_fixup_forwarding(ctl, valp, val); @@ -4310,27 +4300,26 @@ static void addrconf_disable_change(struct net *net, __s32 newf) rcu_read_unlock(); } -static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int newf) +static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old) { struct net *net; - int old; - - if (!rtnl_trylock()) - return restart_syscall(); net = (struct net *)table->extra2; - old = *p; - *p = newf; - if (p == &net->ipv6.devconf_dflt->disable_ipv6) { - rtnl_unlock(); + if (p == &net->ipv6.devconf_dflt->disable_ipv6) return 0; + + if (!rtnl_trylock()) { + /* Restore the original values before restarting */ + *p = old; + return restart_syscall(); } if (p == &net->ipv6.devconf_all->disable_ipv6) { + __s32 newf = net->ipv6.devconf_all->disable_ipv6; net->ipv6.devconf_dflt->disable_ipv6 = newf; addrconf_disable_change(net, newf); - } else if ((!newf) ^ (!old)) + } else if ((!*p) ^ (!old)) dev_disable_change((struct inet6_dev *)table->extra1); rtnl_unlock(); @@ -4344,17 +4333,9 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; - ctl_table lctl; int ret; - /* - * ctl->data points to idev->cnf.disable_ipv6, we should - * not modify it until we get the rtnl lock. - */ - lctl = *ctl; - lctl.data = &val; - - ret = proc_dointvec(&lctl, write, buffer, lenp, ppos); + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); if (write) ret = addrconf_disable_ipv6(ctl, valp, val); diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 3edd05ae4388..906c7ca43542 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -1083,7 +1083,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) #ifdef CONFIG_TCP_MD5SIG if (sk) - key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr); + key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr); #endif if (th->ack) diff --git a/trunk/net/l2tp/l2tp_ip.c b/trunk/net/l2tp/l2tp_ip.c index 55670ec3cd0f..d21e7ebd91ca 100644 --- a/trunk/net/l2tp/l2tp_ip.c +++ b/trunk/net/l2tp/l2tp_ip.c @@ -393,6 +393,11 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb) { int rc; + if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) + goto drop; + + nf_reset(skb); + /* Charge it to the socket, dropping if the queue is full. */ rc = sock_queue_rcv_skb(sk, skb); if (rc < 0) diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index b9bef2c75026..a18e6c3d36e3 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -713,7 +713,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb = NULL; struct sock *sk = sock->sk; struct llc_sock *llc = llc_sk(sk); - unsigned long cpu_flags; size_t copied = 0; u32 peek_seq = 0; u32 *seq; @@ -839,9 +838,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, goto copy_uaddr; if (!(flags & MSG_PEEK)) { - spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags); sk_eat_skb(sk, skb, 0); - spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags); *seq = 0; } @@ -862,9 +859,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, llc_cmsg_rcv(msg, skb); if (!(flags & MSG_PEEK)) { - spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags); sk_eat_skb(sk, skb, 0); - spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags); *seq = 0; } diff --git a/trunk/net/mac80211/debugfs_key.c b/trunk/net/mac80211/debugfs_key.c index 59edcd95a58d..38e6101190d9 100644 --- a/trunk/net/mac80211/debugfs_key.c +++ b/trunk/net/mac80211/debugfs_key.c @@ -225,9 +225,9 @@ KEY_OPS(key); key, &key_##name##_ops); void ieee80211_debugfs_key_add(struct ieee80211_key *key) -{ + { static int keycount; - char buf[100]; + char buf[50]; struct sta_info *sta; if (!key->local->debugfs.keys) @@ -244,8 +244,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key) sta = key->sta; if (sta) { - sprintf(buf, "../../netdev:%s/stations/%pM", - sta->sdata->name, sta->sta.addr); + sprintf(buf, "../../stations/%pM", sta->sta.addr); key->debugfs.stalink = debugfs_create_symlink("station", key->debugfs.dir, buf); } diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index a4643969a13b..b3d76b756cd5 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -106,7 +106,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; - local->oper_channel = chan; channel_type = ifibss->channel_type; if (channel_type > NL80211_CHAN_HT20 && !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 01a21c2f6ab3..e47768cb8cb3 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -1314,7 +1314,6 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) continue; } /* count everything else */ - sdata->vif.bss_conf.idle = false; count++; } diff --git a/trunk/net/mac80211/mesh_hwmp.c b/trunk/net/mac80211/mesh_hwmp.c index 54df1b2bafd2..73abb7524b2c 100644 --- a/trunk/net/mac80211/mesh_hwmp.c +++ b/trunk/net/mac80211/mesh_hwmp.c @@ -119,12 +119,12 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + sizeof(mgmt->u.action.u.mesh_action); - skb = dev_alloc_skb(local->tx_headroom + + skb = dev_alloc_skb(local->hw.extra_tx_headroom + hdr_len + 2 + 37); /* max HWMP IE */ if (!skb) return -1; - skb_reserve(skb, local->tx_headroom); + skb_reserve(skb, local->hw.extra_tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); memset(mgmt, 0, hdr_len); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | @@ -250,12 +250,12 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, if (time_before(jiffies, ifmsh->next_perr)) return -EAGAIN; - skb = dev_alloc_skb(local->tx_headroom + + skb = dev_alloc_skb(local->hw.extra_tx_headroom + hdr_len + 2 + 15 /* PERR IE */); if (!skb) return -1; - skb_reserve(skb, local->tx_headroom); + skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); memset(mgmt, 0, hdr_len); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | diff --git a/trunk/net/mac80211/mesh_plink.c b/trunk/net/mac80211/mesh_plink.c index a17251730b9e..41ef1b476442 100644 --- a/trunk/net/mac80211/mesh_plink.c +++ b/trunk/net/mac80211/mesh_plink.c @@ -172,7 +172,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + sizeof(mgmt->u.action.u.self_prot); - skb = dev_alloc_skb(local->tx_headroom + + skb = dev_alloc_skb(local->hw.extra_tx_headroom + hdr_len + 2 + /* capability info */ 2 + /* AID */ @@ -186,7 +186,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, sdata->u.mesh.ie_len); if (!skb) return -1; - skb_reserve(skb, local->tx_headroom); + skb_reserve(skb, local->hw.extra_tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); memset(mgmt, 0, hdr_len); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 295be92f7c77..ecb4c84c1bb3 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -2750,6 +2750,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_work *wk; u8 bssid[ETH_ALEN]; bool assoc_bss = false; @@ -2762,47 +2763,30 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, assoc_bss = true; } else { bool not_auth_yet = false; - struct ieee80211_work *tmp, *wk = NULL; mutex_unlock(&ifmgd->mtx); mutex_lock(&local->mtx); - list_for_each_entry(tmp, &local->work_list, list) { - if (tmp->sdata != sdata) + list_for_each_entry(wk, &local->work_list, list) { + if (wk->sdata != sdata) continue; - if (tmp->type != IEEE80211_WORK_DIRECT_PROBE && - tmp->type != IEEE80211_WORK_AUTH && - tmp->type != IEEE80211_WORK_ASSOC && - tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) + if (wk->type != IEEE80211_WORK_DIRECT_PROBE && + wk->type != IEEE80211_WORK_AUTH && + wk->type != IEEE80211_WORK_ASSOC && + wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) continue; - if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN)) + if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) continue; - not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE; - list_del_rcu(&tmp->list); - synchronize_rcu(); - wk = tmp; + not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE; + list_del_rcu(&wk->list); + free_work(wk); break; } mutex_unlock(&local->mtx); - if (wk && wk->type == IEEE80211_WORK_ASSOC) { - /* clean up dummy sta & TX sync */ - sta_info_destroy_addr(wk->sdata, wk->filter_ta); - if (wk->assoc.synced) - drv_finish_tx_sync(local, wk->sdata, - wk->filter_ta, - IEEE80211_TX_SYNC_ASSOC); - } else if (wk && wk->type == IEEE80211_WORK_AUTH) { - if (wk->probe_auth.synced) - drv_finish_tx_sync(local, wk->sdata, - wk->filter_ta, - IEEE80211_TX_SYNC_AUTH); - } - kfree(wk); - /* * If somebody requests authentication and we haven't * sent out an auth frame yet there's no need to send diff --git a/trunk/net/rds/af_rds.c b/trunk/net/rds/af_rds.c index 424ff622ab5f..bb6ad81b671d 100644 --- a/trunk/net/rds/af_rds.c +++ b/trunk/net/rds/af_rds.c @@ -68,6 +68,7 @@ static int rds_release(struct socket *sock) { struct sock *sk = sock->sk; struct rds_sock *rs; + unsigned long flags; if (!sk) goto out; @@ -93,10 +94,10 @@ static int rds_release(struct socket *sock) rds_rdma_drop_keys(rs); rds_notify_queue_get(rs, NULL); - spin_lock_bh(&rds_sock_lock); + spin_lock_irqsave(&rds_sock_lock, flags); list_del_init(&rs->rs_item); rds_sock_count--; - spin_unlock_bh(&rds_sock_lock); + spin_unlock_irqrestore(&rds_sock_lock, flags); rds_trans_put(rs->rs_transport); @@ -408,6 +409,7 @@ static const struct proto_ops rds_proto_ops = { static int __rds_create(struct socket *sock, struct sock *sk, int protocol) { + unsigned long flags; struct rds_sock *rs; sock_init_data(sock, sk); @@ -424,10 +426,10 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol) spin_lock_init(&rs->rs_rdma_lock); rs->rs_rdma_keys = RB_ROOT; - spin_lock_bh(&rds_sock_lock); + spin_lock_irqsave(&rds_sock_lock, flags); list_add_tail(&rs->rs_item, &rds_sock_list); rds_sock_count++; - spin_unlock_bh(&rds_sock_lock); + spin_unlock_irqrestore(&rds_sock_lock, flags); return 0; } @@ -469,11 +471,12 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len, { struct rds_sock *rs; struct rds_incoming *inc; + unsigned long flags; unsigned int total = 0; len /= sizeof(struct rds_info_message); - spin_lock_bh(&rds_sock_lock); + spin_lock_irqsave(&rds_sock_lock, flags); list_for_each_entry(rs, &rds_sock_list, rs_item) { read_lock(&rs->rs_recv_lock); @@ -489,7 +492,7 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len, read_unlock(&rs->rs_recv_lock); } - spin_unlock_bh(&rds_sock_lock); + spin_unlock_irqrestore(&rds_sock_lock, flags); lens->nr = total; lens->each = sizeof(struct rds_info_message); @@ -501,10 +504,11 @@ static void rds_sock_info(struct socket *sock, unsigned int len, { struct rds_info_socket sinfo; struct rds_sock *rs; + unsigned long flags; len /= sizeof(struct rds_info_socket); - spin_lock_bh(&rds_sock_lock); + spin_lock_irqsave(&rds_sock_lock, flags); if (len < rds_sock_count) goto out; @@ -525,7 +529,7 @@ static void rds_sock_info(struct socket *sock, unsigned int len, lens->nr = rds_sock_count; lens->each = sizeof(struct rds_info_socket); - spin_unlock_bh(&rds_sock_lock); + spin_unlock_irqrestore(&rds_sock_lock, flags); } static void rds_exit(void) diff --git a/trunk/net/sched/sch_netem.c b/trunk/net/sched/sch_netem.c index 2776012132ea..e7e1d0b57b3d 100644 --- a/trunk/net/sched/sch_netem.c +++ b/trunk/net/sched/sch_netem.c @@ -419,7 +419,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) cb = netem_skb_cb(skb); if (q->gap == 0 || /* not doing reordering */ - q->counter < q->gap - 1 || /* inside last reordering gap */ + q->counter < q->gap || /* inside last reordering gap */ q->reorder < get_crandom(&q->reorder_cor)) { psched_time_t now; psched_tdiff_t delay; diff --git a/trunk/net/sunrpc/auth_generic.c b/trunk/net/sunrpc/auth_generic.c index 75762f346975..1426ec3d0a53 100644 --- a/trunk/net/sunrpc/auth_generic.c +++ b/trunk/net/sunrpc/auth_generic.c @@ -92,7 +92,6 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) if (gcred->acred.group_info != NULL) get_group_info(gcred->acred.group_info); gcred->acred.machine_cred = acred->machine_cred; - gcred->acred.principal = acred->principal; dprintk("RPC: allocated %s cred %p for uid %d gid %d\n", gcred->acred.machine_cred ? "machine" : "generic", @@ -124,17 +123,6 @@ generic_destroy_cred(struct rpc_cred *cred) call_rcu(&cred->cr_rcu, generic_free_cred_callback); } -static int -machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flags) -{ - if (!gcred->acred.machine_cred || - gcred->acred.principal != acred->principal || - gcred->acred.uid != acred->uid || - gcred->acred.gid != acred->gid) - return 0; - return 1; -} - /* * Match credentials against current process creds. */ @@ -144,12 +132,9 @@ generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags) struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base); int i; - if (acred->machine_cred) - return machine_cred_match(acred, gcred, flags); - if (gcred->acred.uid != acred->uid || gcred->acred.gid != acred->gid || - gcred->acred.machine_cred != 0) + gcred->acred.machine_cred != acred->machine_cred) goto out_nomatch; /* Optimisation in the case where pointers are identical... */ diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 85d3bb7490aa..aad8fb699989 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -1918,7 +1918,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; unix_state_lock(sk); - skb = skb_peek(&sk->sk_receive_queue); + skb = skb_dequeue(&sk->sk_receive_queue); if (skb == NULL) { unix_sk(sk)->recursion_level = 0; if (copied >= target) @@ -1958,8 +1958,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (check_creds) { /* Never glue messages from different writers */ if ((UNIXCB(skb).pid != siocb->scm->pid) || - (UNIXCB(skb).cred != siocb->scm->cred)) + (UNIXCB(skb).cred != siocb->scm->cred)) { + skb_queue_head(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); break; + } } else { /* Copy credentials */ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); @@ -1974,6 +1977,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, chunk = min_t(unsigned int, skb->len, size); if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { + skb_queue_head(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); if (copied == 0) copied = -EFAULT; break; @@ -1988,10 +1993,13 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (UNIXCB(skb).fp) unix_detach_fds(siocb->scm, skb); - if (skb->len) + /* put the skb back if we didn't use it up.. */ + if (skb->len) { + skb_queue_head(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); break; + } - skb_unlink(skb, &sk->sk_receive_queue); consume_skb(skb); if (siocb->scm->fp) @@ -2002,6 +2010,9 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (UNIXCB(skb).fp) siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); + /* put message back and return */ + skb_queue_head(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); break; } } while (size); diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index e8c969577768..c0e14b3f2306 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -823,6 +823,16 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, } ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry); +/* Looks like: mcp:S */ +static int do_mcp_entry(const char *filename, struct mcp_device_id *id, + char *alias) +{ + sprintf(alias, MCP_MODULE_PREFIX "%s", id->name); + + return 1; +} +ADD_TO_DEVTABLE("mcp", struct mcp_device_id, do_mcp_entry); + static const struct dmifield { const char *prefix; int field; diff --git a/trunk/sound/core/compress_offload.c b/trunk/sound/core/compress_offload.c index a68aed7fce02..dac3633507c9 100644 --- a/trunk/sound/core/compress_offload.c +++ b/trunk/sound/core/compress_offload.c @@ -441,22 +441,19 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) params = kmalloc(sizeof(*params), GFP_KERNEL); if (!params) return -ENOMEM; - if (copy_from_user(params, (void __user *)arg, sizeof(*params))) { - retval = -EFAULT; - goto out; - } + if (copy_from_user(params, (void __user *)arg, sizeof(*params))) + return -EFAULT; retval = snd_compr_allocate_buffer(stream, params); if (retval) { - retval = -ENOMEM; - goto out; + kfree(params); + return -ENOMEM; } retval = stream->ops->set_params(stream, params); if (retval) goto out; stream->runtime->state = SNDRV_PCM_STATE_SETUP; - } else { + } else return -EPERM; - } out: kfree(params); return retval; diff --git a/trunk/sound/pci/hda/alc880_quirks.c b/trunk/sound/pci/hda/alc880_quirks.c index 501501ef36a9..5b68435d195b 100644 --- a/trunk/sound/pci/hda/alc880_quirks.c +++ b/trunk/sound/pci/hda/alc880_quirks.c @@ -762,22 +762,16 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, /* Looks like the unsol event is incompatible with the standard * definition. 4bit tag is placed at 28 bit! */ - res >>= 28; - switch (res) { + switch (res >> 28) { case ALC_MIC_EVENT: alc88x_simple_mic_automute(codec); break; default: - alc_exec_unsol_event(codec, res); + alc_sku_unsol_event(codec, res); break; } } -static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) -{ - alc_exec_unsol_event(codec, res >> 28); -} - static void alc880_uniwill_p53_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -806,11 +800,10 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, /* Looks like the unsol event is incompatible with the standard * definition. 4bit tag is placed at 28 bit! */ - res >>= 28; - if (res == ALC_DCVOL_EVENT) + if ((res >> 28) == ALC_DCVOL_EVENT) alc880_uniwill_p53_dcvol_automute(codec); else - alc_exec_unsol_event(codec, res); + alc_sku_unsol_event(codec, res); } /* @@ -1684,7 +1677,7 @@ static const struct alc_config_preset alc880_presets[] = { .channel_mode = alc880_lg_ch_modes, .need_dac_fix = 1, .input_mux = &alc880_lg_capture_source, - .unsol_event = alc880_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc880_lg_setup, .init_hook = alc_hp_automute, #ifdef CONFIG_SND_HDA_POWER_SAVE diff --git a/trunk/sound/pci/hda/alc882_quirks.c b/trunk/sound/pci/hda/alc882_quirks.c index bb364a53f546..bdf0ed4ab3e2 100644 --- a/trunk/sound/pci/hda/alc882_quirks.c +++ b/trunk/sound/pci/hda/alc882_quirks.c @@ -730,11 +730,6 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) alc889A_mb31_automute(codec); } -static void alc882_unsol_event(struct hda_codec *codec, unsigned int res) -{ - alc_exec_unsol_event(codec, res >> 26); -} - /* * configuration and preset */ @@ -780,7 +775,7 @@ static const struct alc_config_preset alc882_presets[] = { .channel_mode = alc885_mba21_ch_modes, .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), .input_mux = &alc882_capture_source, - .unsol_event = alc882_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_mba21_setup, .init_hook = alc_hp_automute, }, @@ -796,7 +791,7 @@ static const struct alc_config_preset alc882_presets[] = { .input_mux = &alc882_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, - .unsol_event = alc882_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_mbp3_setup, .init_hook = alc_hp_automute, }, @@ -811,7 +806,7 @@ static const struct alc_config_preset alc882_presets[] = { .input_mux = &mb5_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, - .unsol_event = alc882_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_mb5_setup, .init_hook = alc_hp_automute, }, @@ -826,7 +821,7 @@ static const struct alc_config_preset alc882_presets[] = { .input_mux = &macmini3_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, - .unsol_event = alc882_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_macmini3_setup, .init_hook = alc_hp_automute, }, @@ -841,7 +836,7 @@ static const struct alc_config_preset alc882_presets[] = { .input_mux = &alc889A_imac91_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, - .unsol_event = alc882_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_imac91_setup, .init_hook = alc_hp_automute, }, diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index c2c65f63bf06..4df72c0e8c37 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -1447,7 +1447,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, for (i = 0; i < c->cvt_setups.used; i++) { p = snd_array_elem(&c->cvt_setups, i); if (!p->active && p->stream_tag == stream_tag && - get_wcaps_type(get_wcaps(c, p->nid)) == type) + get_wcaps_type(get_wcaps(codec, p->nid)) == type) p->dirty = 1; } } diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 95dfb6874941..fb35474c1203 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -469,7 +469,6 @@ struct azx { unsigned int irq_pending_warned :1; unsigned int probing :1; /* codec probing phase */ unsigned int snoop:1; - unsigned int align_buffer_size:1; /* for debugging */ unsigned int last_cmd[AZX_MAX_CODECS]; @@ -1691,7 +1690,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) runtime->hw.rates = hinfo->rates; snd_pcm_limit_hw_rates(runtime); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - if (chip->align_buffer_size) + if (align_buffer_size) /* constrain buffer sizes to be multiple of 128 bytes. This is more efficient in terms of memory access but isn't required by the HDA spec and @@ -2774,9 +2773,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, } /* disable buffer size rounding to 128-byte multiples if supported */ - chip->align_buffer_size = align_buffer_size; if (chip->driver_caps & AZX_DCAPS_BUFSIZE) - chip->align_buffer_size = 0; + align_buffer_size = 0; /* allow 64bit DMA address if supported by H/W */ if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) diff --git a/trunk/sound/pci/hda/hda_jack.c b/trunk/sound/pci/hda/hda_jack.c index 9d819c4b4923..d8a35da0803f 100644 --- a/trunk/sound/pci/hda/hda_jack.c +++ b/trunk/sound/pci/hda/hda_jack.c @@ -282,8 +282,7 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, - const struct auto_pin_cfg *cfg, - char *lastname, int *lastidx) + const struct auto_pin_cfg *cfg) { unsigned int def_conf, conn; char name[44]; @@ -299,10 +298,6 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, return 0; snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); - if (!strcmp(name, lastname) && idx == *lastidx) - idx++; - strncpy(lastname, name, 44); - *lastidx = idx; err = snd_hda_jack_add_kctl(codec, nid, name, idx); if (err < 0) return err; @@ -316,42 +311,41 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { const hda_nid_t *p; - int i, err, lastidx = 0; - char lastname[44] = ""; + int i, err; for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { - err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); + err = add_jack_kctl(codec, *p, cfg); if (err < 0) return err; } for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { if (*p == *cfg->line_out_pins) /* might be duplicated */ break; - err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); + err = add_jack_kctl(codec, *p, cfg); if (err < 0) return err; } for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { if (*p == *cfg->line_out_pins) /* might be duplicated */ break; - err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); + err = add_jack_kctl(codec, *p, cfg); if (err < 0) return err; } for (i = 0; i < cfg->num_inputs; i++) { - err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); + err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); if (err < 0) return err; } for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { - err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); + err = add_jack_kctl(codec, *p, cfg); if (err < 0) return err; } - err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); + err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); if (err < 0) return err; - err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); + err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); if (err < 0) return err; return 0; diff --git a/trunk/sound/pci/hda/patch_cirrus.c b/trunk/sound/pci/hda/patch_cirrus.c index bc5a993d1146..0e99357e822c 100644 --- a/trunk/sound/pci/hda/patch_cirrus.c +++ b/trunk/sound/pci/hda/patch_cirrus.c @@ -988,10 +988,8 @@ static void cs_automic(struct hda_codec *codec) change_cur_input(codec, !spec->automic_idx, 0); } else { if (present) { - if (spec->cur_input != spec->automic_idx) { - spec->last_input = spec->cur_input; - spec->cur_input = spec->automic_idx; - } + spec->last_input = spec->cur_input; + spec->cur_input = spec->automic_idx; } else { spec->cur_input = spec->last_input; } diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index a7a5733aa4d2..8a32a69c83c3 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -3027,7 +3027,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), - SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO), + SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO), SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index a8e82be3d2fc..5e82acf77c5a 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -177,7 +177,6 @@ struct alc_spec { unsigned int detect_lo:1; /* Line-out detection enabled */ unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ unsigned int automute_lo_possible:1; /* there are line outs and HP */ - unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ /* other flags */ unsigned int no_analog :1; /* digital I/O only */ @@ -186,6 +185,7 @@ struct alc_spec { unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ + unsigned int use_jack_tbl:1; /* 1 for model=auto */ /* auto-mute control */ int automute_mode; @@ -496,24 +496,13 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, for (i = 0; i < num_pins; i++) { hda_nid_t nid = pins[i]; - unsigned int val; if (!nid) break; switch (spec->automute_mode) { case ALC_AUTOMUTE_PIN: - /* don't reset VREF value in case it's controlling - * the amp (see alc861_fixup_asus_amp_vref_0f()) - */ - if (spec->keep_vref_in_automute) { - val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PIN_WIDGET_CONTROL, 0); - val &= ~PIN_HP; - } else - val = 0; - val |= pin_bits; snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - val); + pin_bits); break; case ALC_AUTOMUTE_AMP: snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, @@ -632,10 +621,17 @@ static void alc_mic_automute(struct hda_codec *codec) alc_mux_select(codec, 0, spec->int_mic_idx, false); } -/* handle the specified unsol action (ALC_XXX_EVENT) */ -static void alc_exec_unsol_event(struct hda_codec *codec, int action) +/* unsolicited event for HP jack sensing */ +static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) { - switch (action) { + struct alc_spec *spec = codec->spec; + if (codec->vendor_id == 0x10ec0880) + res >>= 28; + else + res >>= 26; + if (spec->use_jack_tbl) + res = snd_hda_jack_get_action(codec, res); + switch (res) { case ALC_HP_EVENT: alc_hp_automute(codec); break; @@ -649,17 +645,6 @@ static void alc_exec_unsol_event(struct hda_codec *codec, int action) snd_hda_jack_report_sync(codec); } -/* unsolicited event for HP jack sensing */ -static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) -{ - if (codec->vendor_id == 0x10ec0880) - res >>= 28; - else - res >>= 26; - res = snd_hda_jack_get_action(codec, res); - alc_exec_unsol_event(codec, res); -} - /* call init functions of standard auto-mute helpers */ static void alc_inithook(struct hda_codec *codec) { @@ -1898,7 +1883,7 @@ static const struct snd_kcontrol_new alc_beep_mixer[] = { }; #endif -static int __alc_build_controls(struct hda_codec *codec) +static int alc_build_controls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct snd_kcontrol *kctl = NULL; @@ -2044,16 +2029,11 @@ static int __alc_build_controls(struct hda_codec *codec) alc_free_kctls(codec); /* no longer needed */ - return 0; -} - -static int alc_build_controls(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - int err = __alc_build_controls(codec); + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); if (err < 0) return err; - return snd_hda_jack_add_kctls(codec, &spec->autocfg); + + return 0; } @@ -3253,7 +3233,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, int i, err, noutputs; noutputs = cfg->line_outs; - if (spec->multi_ios > 0 && cfg->line_outs < 3) + if (spec->multi_ios > 0) noutputs += spec->multi_ios; for (i = 0; i < noutputs; i++) { @@ -3924,6 +3904,7 @@ static void set_capture_mixer(struct hda_codec *codec) static void alc_auto_init_std(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + spec->use_jack_tbl = 1; alc_auto_init_multi_out(codec); alc_auto_init_extra_out(codec); alc_auto_init_analog_input(codec); @@ -4187,8 +4168,6 @@ static int patch_alc880(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; - else - codec->patch_ops.build_controls = __alc_build_controls; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc880_loopbacks; @@ -4318,8 +4297,6 @@ static int patch_alc260(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; - else - codec->patch_ops.build_controls = __alc_build_controls; spec->shutup = alc_eapd_shutup; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) @@ -4714,8 +4691,6 @@ static int patch_alc882(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; - else - codec->patch_ops.build_controls = __alc_build_controls; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) @@ -4747,6 +4722,7 @@ enum { ALC262_FIXUP_FSC_H270, ALC262_FIXUP_HP_Z200, ALC262_FIXUP_TYAN, + ALC262_FIXUP_TOSHIBA_RX1, ALC262_FIXUP_LENOVO_3000, ALC262_FIXUP_BENQ, ALC262_FIXUP_BENQ_T31, @@ -4776,6 +4752,16 @@ static const struct alc_fixup alc262_fixups[] = { { } } }, + [ALC262_FIXUP_TOSHIBA_RX1] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x90170110 }, /* speaker */ + { 0x15, 0x0421101f }, /* HP */ + { 0x1a, 0x40f000f0 }, /* N/A */ + { 0x1b, 0x40f000f0 }, /* N/A */ + { 0x1e, 0x40f000f0 }, /* N/A */ + } + }, [ALC262_FIXUP_LENOVO_3000] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { @@ -4808,6 +4794,8 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), + SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", + ALC262_FIXUP_TOSHIBA_RX1), SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), @@ -5376,6 +5364,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), + SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), @@ -5584,28 +5573,8 @@ static const struct hda_amp_list alc861_loopbacks[] = { /* Pin config fixes */ enum { PINFIX_FSC_AMILO_PI1505, - PINFIX_ASUS_A6RP, }; -/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ -static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, - const struct alc_fixup *fix, int action) -{ - struct alc_spec *spec = codec->spec; - unsigned int val; - - if (action != ALC_FIXUP_ACT_INIT) - return; - val = snd_hda_codec_read(codec, 0x0f, 0, - AC_VERB_GET_PIN_WIDGET_CONTROL, 0); - if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) - val |= AC_PINCTL_IN_EN; - val |= AC_PINCTL_VREF_50; - snd_hda_codec_write(codec, 0x0f, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, val); - spec->keep_vref_in_automute = 1; -} - static const struct alc_fixup alc861_fixups[] = { [PINFIX_FSC_AMILO_PI1505] = { .type = ALC_FIXUP_PINS, @@ -5615,15 +5584,9 @@ static const struct alc_fixup alc861_fixups[] = { { } } }, - [PINFIX_ASUS_A6RP] = { - .type = ALC_FIXUP_FUNC, - .v.func = alc861_fixup_asus_amp_vref_0f, - }, }; static const struct snd_pci_quirk alc861_fixup_tbl[] = { - SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), - SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), {} }; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 948f0be2f4f3..3556408d6ece 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -1608,7 +1608,7 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, "Alienware M17x", STAC_ALIENWARE_M17X), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, - "Alienware M17x R3", STAC_DELL_EQ), + "Alienware M17x", STAC_ALIENWARE_M17X), {} /* terminator */ }; @@ -4163,15 +4163,13 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, return 1; } -static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) +static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) { int i; for (i = 0; i < cfg->hp_outs; i++) if (cfg->hp_pins[i] == nid) return 1; /* nid is a HP-Out */ - for (i = 0; i < cfg->line_outs; i++) - if (cfg->line_out_pins[i] == nid) - return 1; /* nid is a line-Out */ + return 0; /* nid is not a HP-Out */ }; @@ -4377,7 +4375,7 @@ static int stac92xx_init(struct hda_codec *codec) continue; } - if (is_nid_out_jack_pin(cfg, nid)) + if (is_nid_hp_pin(cfg, nid)) continue; /* already has an unsol event */ pinctl = snd_hda_codec_read(codec, nid, 0, @@ -4870,14 +4868,7 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) /* BIOS bug: unfilled OEM string */ if (strstr(dev->name, "HP_Mute_LED_P_G")) { set_hp_led_gpio(codec); - switch (codec->subsystem_id) { - case 0x103c148a: - spec->gpio_led_polarity = 0; - break; - default: - spec->gpio_led_polarity = 1; - break; - } + spec->gpio_led_polarity = 1; return 1; } } diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index 284e311040fe..03e63fed9caf 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -199,9 +199,6 @@ struct via_spec { unsigned int no_pin_power_ctl; enum VIA_HDA_CODEC codec_type; - /* analog low-power control */ - bool alc_mode; - /* smart51 setup */ unsigned int smart51_nums; hda_nid_t smart51_pins[2]; @@ -690,15 +687,6 @@ static void via_auto_init_analog_input(struct hda_codec *codec) } } -static void update_power_state(struct hda_codec *codec, hda_nid_t nid, - unsigned int parm) -{ - if (snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_POWER_STATE, 0) == parm) - return; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); -} - static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, unsigned int *affected_parm) { @@ -721,7 +709,7 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, } else parm = AC_PWRST_D3; - update_power_state(codec, nid, parm); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); } static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol, @@ -761,7 +749,6 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol, return 0; spec->no_pin_power_ctl = val; set_widgets_power_state(codec); - analog_low_current_mode(codec); return 1; } @@ -1049,19 +1036,13 @@ static bool is_aa_path_mute(struct hda_codec *codec) } /* enter/exit analog low-current mode */ -static void __analog_low_current_mode(struct hda_codec *codec, bool force) +static void analog_low_current_mode(struct hda_codec *codec) { struct via_spec *spec = codec->spec; bool enable; unsigned int verb, parm; - if (spec->no_pin_power_ctl) - enable = false; - else - enable = is_aa_path_mute(codec) && !spec->opened_streams; - if (enable == spec->alc_mode && !force) - return; - spec->alc_mode = enable; + enable = is_aa_path_mute(codec) && (spec->opened_streams != 0); /* decide low current mode's verb & parameter */ switch (spec->codec_type) { @@ -1093,11 +1074,6 @@ static void __analog_low_current_mode(struct hda_codec *codec, bool force) snd_hda_codec_write(codec, codec->afg, 0, verb, parm); } -static void analog_low_current_mode(struct hda_codec *codec) -{ - return __analog_low_current_mode(codec, false); -} - /* * generic initialization of ADC, input mixers and output mixers */ @@ -1470,7 +1446,6 @@ static int via_build_controls(struct hda_codec *codec) struct snd_kcontrol *kctl; int err, i; - spec->no_pin_power_ctl = 1; if (spec->set_widgets_power_state) if (!via_clone_control(spec, &via_pin_power_ctl_enum)) return -ENOMEM; @@ -1524,6 +1499,10 @@ static int via_build_controls(struct hda_codec *codec) return err; } + /* init power states */ + set_widgets_power_state(codec); + analog_low_current_mode(codec); + via_free_kctls(codec); /* no longer needed */ err = snd_hda_jack_add_kctls(codec, &spec->autocfg); @@ -2316,7 +2295,10 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, if (mux) { /* switch to D0 beofre change index */ - update_power_state(codec, mux, AC_PWRST_D0); + if (snd_hda_codec_read(codec, mux, 0, + AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) + snd_hda_codec_write(codec, mux, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); snd_hda_codec_write(codec, mux, 0, AC_VERB_SET_CONNECT_SEL, spec->inputs[cur].mux_idx); @@ -2794,10 +2776,6 @@ static int via_init(struct hda_codec *codec) for (i = 0; i < spec->num_iverbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); - /* init power states */ - set_widgets_power_state(codec); - __analog_low_current_mode(codec, true); - via_auto_init_multi_out(codec); via_auto_init_hp_out(codec); via_auto_init_speaker_out(codec); @@ -2944,9 +2922,9 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) if (imux_is_smixer) parm = AC_PWRST_D0; /* SW0 (17h), AIW 0/1 (13h/14h) */ - update_power_state(codec, 0x17, parm); - update_power_state(codec, 0x13, parm); - update_power_state(codec, 0x14, parm); + snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); /* outputs */ /* PW0 (19h), SW1 (18h), AOW1 (11h) */ @@ -2954,8 +2932,8 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) set_pin_power_state(codec, 0x19, &parm); if (spec->smart51_enabled) set_pin_power_state(codec, 0x1b, &parm); - update_power_state(codec, 0x18, parm); - update_power_state(codec, 0x11, parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); /* PW6 (22h), SW2 (26h), AOW2 (24h) */ if (is_8ch) { @@ -2963,16 +2941,20 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) set_pin_power_state(codec, 0x22, &parm); if (spec->smart51_enabled) set_pin_power_state(codec, 0x1a, &parm); - update_power_state(codec, 0x26, parm); - update_power_state(codec, 0x24, parm); + snd_hda_codec_write(codec, 0x26, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x24, 0, + AC_VERB_SET_POWER_STATE, parm); } else if (codec->vendor_id == 0x11064397) { /* PW7(23h), SW2(27h), AOW2(25h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x23, &parm); if (spec->smart51_enabled) set_pin_power_state(codec, 0x1a, &parm); - update_power_state(codec, 0x27, parm); - update_power_state(codec, 0x25, parm); + snd_hda_codec_write(codec, 0x27, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); } /* PW 3/4/7 (1ch/1dh/23h) */ @@ -2984,13 +2966,17 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) set_pin_power_state(codec, 0x23, &parm); /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ - update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm); - update_power_state(codec, 0x10, parm); + snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); if (is_8ch) { - update_power_state(codec, 0x25, parm); - update_power_state(codec, 0x27, parm); + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x27, 0, + AC_VERB_SET_POWER_STATE, parm); } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) - update_power_state(codec, 0x25, parm); + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); } static int patch_vt1708S(struct hda_codec *codec); @@ -3163,10 +3149,10 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec) if (imux_is_smixer) parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ - update_power_state(codec, 0x13, parm); - update_power_state(codec, 0x12, parm); - update_power_state(codec, 0x1f, parm); - update_power_state(codec, 0x20, parm); + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm); /* outputs */ /* PW 3/4 (16h/17h) */ @@ -3174,9 +3160,10 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec) set_pin_power_state(codec, 0x17, &parm); set_pin_power_state(codec, 0x16, &parm); /* MW0 (1ah), AOW 0/1 (10h/1dh) */ - update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm); - update_power_state(codec, 0x10, parm); - update_power_state(codec, 0x1d, parm); + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); } static int patch_vt1702(struct hda_codec *codec) @@ -3241,48 +3228,52 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) if (imux_is_smixer) parm = AC_PWRST_D0; /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ - update_power_state(codec, 0x1e, parm); - update_power_state(codec, 0x1f, parm); - update_power_state(codec, 0x10, parm); - update_power_state(codec, 0x11, parm); + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); /* outputs */ /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x27, &parm); - update_power_state(codec, 0x1a, parm); - update_power_state(codec, 0xb, parm); + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); /* PW2 (26h), AOW2 (ah) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x26, &parm); if (spec->smart51_enabled) set_pin_power_state(codec, 0x2b, &parm); - update_power_state(codec, 0xa, parm); + snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm); /* PW0 (24h), AOW0 (8h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x24, &parm); if (!spec->hp_independent_mode) /* check for redirected HP */ set_pin_power_state(codec, 0x28, &parm); - update_power_state(codec, 0x8, parm); + snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ - update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); /* PW1 (25h), AOW1 (9h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x25, &parm); if (spec->smart51_enabled) set_pin_power_state(codec, 0x2a, &parm); - update_power_state(codec, 0x9, parm); + snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm); if (spec->hp_independent_mode) { /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x28, &parm); - update_power_state(codec, 0x1b, parm); - update_power_state(codec, 0x34, parm); - update_power_state(codec, 0xc, parm); + snd_hda_codec_write(codec, 0x1b, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0xc, 0, + AC_VERB_SET_POWER_STATE, parm); } } @@ -3442,8 +3433,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) if (imux_is_smixer) parm = AC_PWRST_D0; /* SW0 (17h), AIW0(13h) */ - update_power_state(codec, 0x17, parm); - update_power_state(codec, 0x13, parm); + snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); parm = AC_PWRST_D3; set_pin_power_state(codec, 0x1e, &parm); @@ -3451,11 +3442,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) if (spec->dmic_enabled) set_pin_power_state(codec, 0x22, &parm); else - update_power_state(codec, 0x22, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x22, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); /* SW2(26h), AIW1(14h) */ - update_power_state(codec, 0x26, parm); - update_power_state(codec, 0x14, parm); + snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); /* outputs */ /* PW0 (19h), SW1 (18h), AOW1 (11h) */ @@ -3464,8 +3456,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) /* Smart 5.1 PW2(1bh) */ if (spec->smart51_enabled) set_pin_power_state(codec, 0x1b, &parm); - update_power_state(codec, 0x18, parm); - update_power_state(codec, 0x11, parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); /* PW7 (23h), SW3 (27h), AOW3 (25h) */ parm = AC_PWRST_D3; @@ -3473,12 +3465,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) /* Smart 5.1 PW1(1ah) */ if (spec->smart51_enabled) set_pin_power_state(codec, 0x1a, &parm); - update_power_state(codec, 0x27, parm); + snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm); /* Smart 5.1 PW5(1eh) */ if (spec->smart51_enabled) set_pin_power_state(codec, 0x1e, &parm); - update_power_state(codec, 0x25, parm); + snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm); /* Mono out */ /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ @@ -3494,9 +3486,9 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) mono_out = 1; } parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; - update_power_state(codec, 0x28, parm); - update_power_state(codec, 0x29, parm); - update_power_state(codec, 0x2a, parm); + snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm); /* PW 3/4 (1ch/1dh) */ parm = AC_PWRST_D3; @@ -3504,12 +3496,15 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) set_pin_power_state(codec, 0x1d, &parm); /* HP Independent Mode, power on AOW3 */ if (spec->hp_independent_mode) - update_power_state(codec, 0x25, parm); + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); /* force to D0 for internal Speaker */ /* MW0 (16h), AOW0 (10h) */ - update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm); - update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, + mono_out ? AC_PWRST_D0 : parm); } static int patch_vt1716S(struct hda_codec *codec) @@ -3585,45 +3580,54 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) set_pin_power_state(codec, 0x2b, &parm); parm = AC_PWRST_D0; /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ - update_power_state(codec, 0x1e, parm); - update_power_state(codec, 0x1f, parm); - update_power_state(codec, 0x10, parm); - update_power_state(codec, 0x11, parm); + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); /* outputs */ /* AOW0 (8h)*/ - update_power_state(codec, 0x8, parm); + snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); if (spec->codec_type == VT1802) { /* PW4 (28h), MW4 (18h), MUX4(38h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x28, &parm); - update_power_state(codec, 0x18, parm); - update_power_state(codec, 0x38, parm); + snd_hda_codec_write(codec, 0x18, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x38, 0, + AC_VERB_SET_POWER_STATE, parm); } else { /* PW4 (26h), MW4 (1ch), MUX4(37h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x26, &parm); - update_power_state(codec, 0x1c, parm); - update_power_state(codec, 0x37, parm); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x37, 0, + AC_VERB_SET_POWER_STATE, parm); } if (spec->codec_type == VT1802) { /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x25, &parm); - update_power_state(codec, 0x15, parm); - update_power_state(codec, 0x35, parm); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, + AC_VERB_SET_POWER_STATE, parm); } else { /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x25, &parm); - update_power_state(codec, 0x19, parm); - update_power_state(codec, 0x35, parm); + snd_hda_codec_write(codec, 0x19, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, + AC_VERB_SET_POWER_STATE, parm); } if (spec->hp_independent_mode) - update_power_state(codec, 0x9, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x9, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); /* Class-D */ /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ @@ -3633,10 +3637,12 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) set_pin_power_state(codec, 0x24, &parm); parm = present ? AC_PWRST_D3 : AC_PWRST_D0; if (spec->codec_type == VT1802) - update_power_state(codec, 0x14, parm); + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, parm); else - update_power_state(codec, 0x18, parm); - update_power_state(codec, 0x34, parm); + snd_hda_codec_write(codec, 0x18, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm); /* Mono Out */ present = snd_hda_jack_detect(codec, 0x26); @@ -3644,20 +3650,28 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) parm = present ? AC_PWRST_D3 : AC_PWRST_D0; if (spec->codec_type == VT1802) { /* PW15 (33h), MW8(1ch), MUX8(3ch) */ - update_power_state(codec, 0x33, parm); - update_power_state(codec, 0x1c, parm); - update_power_state(codec, 0x3c, parm); + snd_hda_codec_write(codec, 0x33, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, parm); } else { /* PW15 (31h), MW8(17h), MUX8(3bh) */ - update_power_state(codec, 0x31, parm); - update_power_state(codec, 0x17, parm); - update_power_state(codec, 0x3b, parm); + snd_hda_codec_write(codec, 0x31, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x17, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3b, 0, + AC_VERB_SET_POWER_STATE, parm); } /* MW9 (21h) */ if (imux_is_smixer || !is_aa_path_mute(codec)) - update_power_state(codec, 0x21, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); else - update_power_state(codec, 0x21, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); } /* patch for vt2002P */ @@ -3717,28 +3731,30 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) set_pin_power_state(codec, 0x2b, &parm); parm = AC_PWRST_D0; /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ - update_power_state(codec, 0x1e, parm); - update_power_state(codec, 0x1f, parm); - update_power_state(codec, 0x10, parm); - update_power_state(codec, 0x11, parm); + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); /* outputs */ /* AOW0 (8h)*/ - update_power_state(codec, 0x8, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x8, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); /* PW4 (28h), MW4 (18h), MUX4(38h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x28, &parm); - update_power_state(codec, 0x18, parm); - update_power_state(codec, 0x38, parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm); /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x25, &parm); - update_power_state(codec, 0x15, parm); - update_power_state(codec, 0x35, parm); + snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm); if (spec->hp_independent_mode) - update_power_state(codec, 0x9, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x9, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); /* Internal Speaker */ /* PW0 (24h), MW0(14h), MUX0(34h) */ @@ -3747,11 +3763,15 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) parm = AC_PWRST_D3; set_pin_power_state(codec, 0x24, &parm); if (present) { - update_power_state(codec, 0x14, AC_PWRST_D3); - update_power_state(codec, 0x34, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); } else { - update_power_state(codec, 0x14, AC_PWRST_D0); - update_power_state(codec, 0x34, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); } @@ -3762,20 +3782,26 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) parm = AC_PWRST_D3; set_pin_power_state(codec, 0x31, &parm); if (present) { - update_power_state(codec, 0x1c, AC_PWRST_D3); - update_power_state(codec, 0x3c, AC_PWRST_D3); - update_power_state(codec, 0x3e, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x3e, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); } else { - update_power_state(codec, 0x1c, AC_PWRST_D0); - update_power_state(codec, 0x3c, AC_PWRST_D0); - update_power_state(codec, 0x3e, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x3e, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); } /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ parm = AC_PWRST_D3; set_pin_power_state(codec, 0x33, &parm); - update_power_state(codec, 0x1d, parm); - update_power_state(codec, 0x3d, parm); + snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm); } diff --git a/trunk/sound/pci/ymfpci/ymfpci.c b/trunk/sound/pci/ymfpci/ymfpci.c index 94ab728f5ca8..e57b89e8aa89 100644 --- a/trunk/sound/pci/ymfpci/ymfpci.c +++ b/trunk/sound/pci/ymfpci/ymfpci.c @@ -286,22 +286,17 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, snd_card_free(card); return err; } - err = snd_ymfpci_mixer(chip, rear_switch[dev]); - if (err < 0) { + if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) { snd_card_free(card); return err; } - if (chip->ac97->ext_id & AC97_EI_SDAC) { - err = snd_ymfpci_pcm_4ch(chip, 2, NULL); - if (err < 0) { - snd_card_free(card); - return err; - } - err = snd_ymfpci_pcm2(chip, 3, NULL); - if (err < 0) { - snd_card_free(card); - return err; - } + if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) { + snd_card_free(card); + return err; + } + if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) { + snd_card_free(card); + return err; } if ((err = snd_ymfpci_timer(chip, 0)) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/ymfpci/ymfpci_main.c b/trunk/sound/pci/ymfpci/ymfpci_main.c index 12a9a2b03387..03ee4e365311 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_main.c +++ b/trunk/sound/pci/ymfpci/ymfpci_main.c @@ -1614,14 +1614,6 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } -static struct snd_kcontrol_new snd_ymfpci_dup4ch __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "4ch Duplication", - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .info = snd_ymfpci_info_dup4ch, - .get = snd_ymfpci_get_dup4ch, - .put = snd_ymfpci_put_dup4ch, -}; static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { { @@ -1650,6 +1642,13 @@ YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4), +{ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "4ch Duplication", + .info = snd_ymfpci_info_dup4ch, + .get = snd_ymfpci_get_dup4ch, + .put = snd_ymfpci_put_dup4ch, +}, }; @@ -1839,12 +1838,6 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0) return err; } - if (chip->ac97->ext_id & AC97_EI_SDAC) { - kctl = snd_ctl_new1(&snd_ymfpci_dup4ch, chip); - err = snd_ctl_add(chip->card, kctl); - if (err < 0) - return err; - } /* add S/PDIF control */ if (snd_BUG_ON(!chip->pcm_spdif)) diff --git a/trunk/sound/soc/codecs/sgtl5000.c b/trunk/sound/soc/codecs/sgtl5000.c index 7f4ba819a9f6..f8863ebb4304 100644 --- a/trunk/sound/soc/codecs/sgtl5000.c +++ b/trunk/sound/soc/codecs/sgtl5000.c @@ -987,12 +987,12 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) /* restore regular registers */ for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { - /* These regs should restore in particular order */ + /* this regs depends on the others */ if (reg == SGTL5000_CHIP_ANA_POWER || reg == SGTL5000_CHIP_CLK_CTRL || reg == SGTL5000_CHIP_LINREG_CTRL || reg == SGTL5000_CHIP_LINE_OUT_CTRL || - reg == SGTL5000_CHIP_REF_CTRL) + reg == SGTL5000_CHIP_CLK_CTRL) continue; snd_soc_write(codec, reg, cache[reg]); @@ -1003,17 +1003,8 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) snd_soc_write(codec, reg, cache[reg]); /* - * restore these regs according to the power setting sequence in - * sgtl5000_set_power_regs() and clock setting sequence in - * sgtl5000_set_clock(). - * - * The order of restore is: - * 1. SGTL5000_CHIP_CLK_CTRL MCLK_FREQ bits (1:0) should be restore after - * SGTL5000_CHIP_ANA_POWER PLL bits set - * 2. SGTL5000_CHIP_LINREG_CTRL should be set before - * SGTL5000_CHIP_ANA_POWER LINREG_D restored - * 3. SGTL5000_CHIP_REF_CTRL controls Analog Ground Voltage, - * prefer to resotre it after SGTL5000_CHIP_ANA_POWER restored + * restore power and other regs according + * to set_power() and set_clock() */ snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, cache[SGTL5000_CHIP_LINREG_CTRL]); diff --git a/trunk/sound/soc/codecs/tlv320aic32x4.c b/trunk/sound/soc/codecs/tlv320aic32x4.c index 372b0b83bd9f..eb401ef021fb 100644 --- a/trunk/sound/soc/codecs/tlv320aic32x4.c +++ b/trunk/sound/soc/codecs/tlv320aic32x4.c @@ -60,6 +60,7 @@ struct aic32x4_rate_divs { struct aic32x4_priv { u32 sysclk; + s32 master; u8 page_no; void *control_data; u32 power_cfg; @@ -368,6 +369,7 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; + struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); u8 iface_reg_1; u8 iface_reg_2; u8 iface_reg_3; @@ -382,9 +384,11 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: + aic32x4->master = 1; iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER; break; case SND_SOC_DAIFMT_CBS_CFS: + aic32x4->master = 0; break; default: printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n"); @@ -522,58 +526,64 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute) static int aic32x4_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); + switch (level) { case SND_SOC_BIAS_ON: - /* Switch on PLL */ - snd_soc_update_bits(codec, AIC32X4_PLLPR, - AIC32X4_PLLEN, AIC32X4_PLLEN); - - /* Switch on NDAC Divider */ - snd_soc_update_bits(codec, AIC32X4_NDAC, - AIC32X4_NDACEN, AIC32X4_NDACEN); - - /* Switch on MDAC Divider */ - snd_soc_update_bits(codec, AIC32X4_MDAC, - AIC32X4_MDACEN, AIC32X4_MDACEN); - - /* Switch on NADC Divider */ - snd_soc_update_bits(codec, AIC32X4_NADC, - AIC32X4_NADCEN, AIC32X4_NADCEN); - - /* Switch on MADC Divider */ - snd_soc_update_bits(codec, AIC32X4_MADC, - AIC32X4_MADCEN, AIC32X4_MADCEN); - - /* Switch on BCLK_N Divider */ - snd_soc_update_bits(codec, AIC32X4_BCLKN, - AIC32X4_BCLKEN, AIC32X4_BCLKEN); + if (aic32x4->master) { + /* Switch on PLL */ + snd_soc_update_bits(codec, AIC32X4_PLLPR, + AIC32X4_PLLEN, AIC32X4_PLLEN); + + /* Switch on NDAC Divider */ + snd_soc_update_bits(codec, AIC32X4_NDAC, + AIC32X4_NDACEN, AIC32X4_NDACEN); + + /* Switch on MDAC Divider */ + snd_soc_update_bits(codec, AIC32X4_MDAC, + AIC32X4_MDACEN, AIC32X4_MDACEN); + + /* Switch on NADC Divider */ + snd_soc_update_bits(codec, AIC32X4_NADC, + AIC32X4_NADCEN, AIC32X4_NADCEN); + + /* Switch on MADC Divider */ + snd_soc_update_bits(codec, AIC32X4_MADC, + AIC32X4_MADCEN, AIC32X4_MADCEN); + + /* Switch on BCLK_N Divider */ + snd_soc_update_bits(codec, AIC32X4_BCLKN, + AIC32X4_BCLKEN, AIC32X4_BCLKEN); + } break; case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - /* Switch off PLL */ - snd_soc_update_bits(codec, AIC32X4_PLLPR, - AIC32X4_PLLEN, 0); - - /* Switch off NDAC Divider */ - snd_soc_update_bits(codec, AIC32X4_NDAC, - AIC32X4_NDACEN, 0); - - /* Switch off MDAC Divider */ - snd_soc_update_bits(codec, AIC32X4_MDAC, - AIC32X4_MDACEN, 0); - - /* Switch off NADC Divider */ - snd_soc_update_bits(codec, AIC32X4_NADC, - AIC32X4_NADCEN, 0); - - /* Switch off MADC Divider */ - snd_soc_update_bits(codec, AIC32X4_MADC, - AIC32X4_MADCEN, 0); - - /* Switch off BCLK_N Divider */ - snd_soc_update_bits(codec, AIC32X4_BCLKN, - AIC32X4_BCLKEN, 0); + if (aic32x4->master) { + /* Switch off PLL */ + snd_soc_update_bits(codec, AIC32X4_PLLPR, + AIC32X4_PLLEN, 0); + + /* Switch off NDAC Divider */ + snd_soc_update_bits(codec, AIC32X4_NDAC, + AIC32X4_NDACEN, 0); + + /* Switch off MDAC Divider */ + snd_soc_update_bits(codec, AIC32X4_MDAC, + AIC32X4_MDACEN, 0); + + /* Switch off NADC Divider */ + snd_soc_update_bits(codec, AIC32X4_NADC, + AIC32X4_NADCEN, 0); + + /* Switch off MADC Divider */ + snd_soc_update_bits(codec, AIC32X4_MADC, + AIC32X4_MADCEN, 0); + + /* Switch off BCLK_N Divider */ + snd_soc_update_bits(codec, AIC32X4_BCLKN, + AIC32X4_BCLKEN, 0); + } break; case SND_SOC_BIAS_OFF: break; @@ -641,11 +651,9 @@ static int aic32x4_probe(struct snd_soc_codec *codec) if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) { snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); } - - tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ? - AIC32X4_LDOCTLEN : 0; - snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg); - + if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) { + snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN); + } tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE); if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) { tmp_reg |= AIC32X4_LDOIN_18_36; diff --git a/trunk/sound/soc/codecs/wm2000.c b/trunk/sound/soc/codecs/wm2000.c index a75c3766aede..c2880907fced 100644 --- a/trunk/sound/soc/codecs/wm2000.c +++ b/trunk/sound/soc/codecs/wm2000.c @@ -733,9 +733,8 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, struct wm2000_priv *wm2000; struct wm2000_platform_data *pdata; const char *filename; - const struct firmware *fw = NULL; - int ret; - int reg; + const struct firmware *fw; + int reg, ret; u16 id; wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), @@ -752,7 +751,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, ret = PTR_ERR(wm2000->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); - goto out; + goto err; } /* Verify that this is a WM2000 */ @@ -764,7 +763,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (id != 0x2000) { dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); ret = -ENODEV; - goto out_regmap_exit; + goto err_regmap; } reg = wm2000_read(i2c, WM2000_REG_REVISON); @@ -783,7 +782,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, ret = request_firmware(&fw, filename, &i2c->dev); if (ret != 0) { dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); - goto out_regmap_exit; + goto err_regmap; } /* Pre-cook the concatenation of the register address onto the image */ @@ -794,13 +793,15 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (wm2000->anc_download == NULL) { dev_err(&i2c->dev, "Out of memory\n"); ret = -ENOMEM; - goto out_regmap_exit; + goto err_fw; } wm2000->anc_download[0] = 0x80; wm2000->anc_download[1] = 0x00; memcpy(wm2000->anc_download + 2, fw->data, fw->size); + release_firmware(fw); + wm2000->anc_eng_ena = 1; wm2000->anc_active = 1; wm2000->spk_ena = 1; @@ -808,14 +809,18 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, wm2000_reset(wm2000); - ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); - if (!ret) - goto out; + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, + NULL, 0); + if (ret != 0) + goto err_fw; -out_regmap_exit: - regmap_exit(wm2000->regmap); -out: + return 0; + +err_fw: release_firmware(fw); +err_regmap: + regmap_exit(wm2000->regmap); +err: return ret; } diff --git a/trunk/sound/soc/codecs/wm5100.c b/trunk/sound/soc/codecs/wm5100.c index 89f2af77b1c3..8b24323d6b2c 100644 --- a/trunk/sound/soc/codecs/wm5100.c +++ b/trunk/sound/soc/codecs/wm5100.c @@ -1377,7 +1377,6 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, switch (wm5100->rev) { case 0: - regcache_cache_bypass(wm5100->regmap, true); snd_soc_write(codec, 0x11, 0x3); snd_soc_write(codec, 0x203, 0xc); snd_soc_write(codec, 0x206, 0); @@ -1393,7 +1392,6 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, wm5100_reva_patches[i].reg, wm5100_reva_patches[i].val); - regcache_cache_bypass(wm5100->regmap, false); break; default: break; @@ -1404,8 +1402,6 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_OFF: - regcache_cache_only(wm5100->regmap, true); - regcache_mark_dirty(wm5100->regmap); if (wm5100->pdata.ldo_ena) gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), @@ -2184,7 +2180,6 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) if (wm5100->jack_detecting) { dev_dbg(codec->dev, "Microphone detected\n"); wm5100->jack_mic = true; - wm5100->jack_detecting = false; snd_soc_jack_report(wm5100->jack, SND_JACK_HEADSET, SND_JACK_HEADSET | SND_JACK_BTN_0); @@ -2223,7 +2218,6 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) SND_JACK_BTN_0); } else if (wm5100->jack_detecting) { dev_dbg(codec->dev, "Headphone detected\n"); - wm5100->jack_detecting = false; snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, SND_JACK_HEADPHONE); @@ -2613,13 +2607,6 @@ static const struct regmap_config wm5100_regmap = { .cache_type = REGCACHE_RBTREE, }; -static const unsigned int wm5100_mic_ctrl_reg[] = { - WM5100_IN1L_CONTROL, - WM5100_IN2L_CONTROL, - WM5100_IN3L_CONTROL, - WM5100_IN4L_CONTROL, -}; - static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2752,7 +2739,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, } for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { - regmap_update_bits(wm5100->regmap, wm5100_mic_ctrl_reg[i], + regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL, WM5100_IN1_MODE_MASK | WM5100_IN1_DMIC_SUP_MASK, (wm5100->pdata.in_mode[i] << diff --git a/trunk/sound/soc/codecs/wm8958-dsp2.c b/trunk/sound/soc/codecs/wm8958-dsp2.c index 40ac888faf3d..8d4ea43d40a3 100644 --- a/trunk/sound/soc/codecs/wm8958-dsp2.c +++ b/trunk/sound/soc/codecs/wm8958-dsp2.c @@ -55,7 +55,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, return 0; if (fw->size < 32) { - dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n", + dev_err(codec->dev, "%s: firmware too short (%d bytes)\n", name, fw->size); goto err; } diff --git a/trunk/sound/soc/codecs/wm8962.c b/trunk/sound/soc/codecs/wm8962.c index bda3da887d7e..296de4e30d26 100644 --- a/trunk/sound/soc/codecs/wm8962.c +++ b/trunk/sound/soc/codecs/wm8962.c @@ -96,7 +96,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \ struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - regcache_mark_dirty(wm8962->regmap); \ + regcache_cache_only(wm8962->regmap, true); \ } \ return 0; \ } diff --git a/trunk/sound/soc/codecs/wm8996.c b/trunk/sound/soc/codecs/wm8996.c index 61f7daa4d0e6..d8da10fe5b52 100644 --- a/trunk/sound/soc/codecs/wm8996.c +++ b/trunk/sound/soc/codecs/wm8996.c @@ -108,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \ struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - regcache_mark_dirty(wm8996->regmap); \ + regcache_cache_only(wm8996->regmap, true); \ } \ return 0; \ } @@ -1120,8 +1120,7 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), @@ -2008,7 +2007,6 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); int lfclk = 0; int ratediv = 0; - int sync = WM8996_REG_SYNC; int src; int old; @@ -2053,7 +2051,6 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, case 32000: case 32768: lfclk = WM8996_LFCLK_ENA; - sync = 0; break; default: dev_warn(codec->dev, "Unsupported clock rate %dHz\n", @@ -2067,8 +2064,6 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK, src << WM8996_SYSCLK_SRC_SHIFT | ratediv); snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk); - snd_soc_update_bits(codec, WM8996_CONTROL_INTERFACE_1, - WM8996_REG_SYNC, sync); snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1, WM8996_SYSCLK_ENA, old); diff --git a/trunk/sound/soc/codecs/wm8996.h b/trunk/sound/soc/codecs/wm8996.h index de9ac3e44aec..0fde643194ce 100644 --- a/trunk/sound/soc/codecs/wm8996.h +++ b/trunk/sound/soc/codecs/wm8996.h @@ -1567,10 +1567,6 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, /* * R257 (0x101) - Control Interface (1) */ -#define WM8996_REG_SYNC 0x8000 /* REG_SYNC */ -#define WM8996_REG_SYNC_MASK 0x8000 /* REG_SYNC */ -#define WM8996_REG_SYNC_SHIFT 15 /* REG_SYNC */ -#define WM8996_REG_SYNC_WIDTH 1 /* REG_SYNC */ #define WM8996_AUTO_INC 0x0004 /* AUTO_INC */ #define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */ #define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */ diff --git a/trunk/sound/soc/codecs/wm_hubs.c b/trunk/sound/soc/codecs/wm_hubs.c index ea2672455d07..2a61094075f8 100644 --- a/trunk/sound/soc/codecs/wm_hubs.c +++ b/trunk/sound/soc/codecs/wm_hubs.c @@ -592,8 +592,8 @@ SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0), }; static const struct snd_kcontrol_new line2n_mix[] = { -SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), -SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), +SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), +SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), }; static const struct snd_kcontrol_new line2p_mix[] = { @@ -613,8 +613,6 @@ SND_SOC_DAPM_INPUT("IN2RP:VXRP"), SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("LINEOUT_VMID_BUF", WM8993_ANTIPOP1, 7, 0, NULL, 0), - SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, in1l_pga, ARRAY_SIZE(in1l_pga)), SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0, @@ -836,11 +834,9 @@ static const struct snd_soc_dapm_route lineout1_diff_routes[] = { }; static const struct snd_soc_dapm_route lineout1_se_routes[] = { - { "LINEOUT1N Mixer", NULL, "LINEOUT_VMID_BUF" }, { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, - { "LINEOUT1P Mixer", NULL, "LINEOUT_VMID_BUF" }, { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, @@ -857,11 +853,9 @@ static const struct snd_soc_dapm_route lineout2_diff_routes[] = { }; static const struct snd_soc_dapm_route lineout2_se_routes[] = { - { "LINEOUT2N Mixer", NULL, "LINEOUT_VMID_BUF" }, { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, - { "LINEOUT2P Mixer", NULL, "LINEOUT_VMID_BUF" }, { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, diff --git a/trunk/sound/soc/mxs/mxs-saif.c b/trunk/sound/soc/mxs/mxs-saif.c index f204dbac11d4..dccfb37a9626 100644 --- a/trunk/sound/soc/mxs/mxs-saif.c +++ b/trunk/sound/soc/mxs/mxs-saif.c @@ -124,8 +124,6 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, * * If MCLK is not used, we just set saif clk to 512*fs. */ - clk_prepare_enable(master_saif->clk); - if (master_saif->mclk_in_use) { if (mclk % 32 == 0) { scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; @@ -135,7 +133,6 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, ret = clk_set_rate(master_saif->clk, 384 * rate); } else { /* SAIF MCLK should be either 32x or 48x */ - clk_disable_unprepare(master_saif->clk); return -EINVAL; } } else { @@ -143,8 +140,6 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; } - clk_disable_unprepare(master_saif->clk); - if (ret) return ret; diff --git a/trunk/sound/soc/samsung/neo1973_wm8753.c b/trunk/sound/soc/samsung/neo1973_wm8753.c index c6012ff5bd3e..7ac0ba2025c3 100644 --- a/trunk/sound/soc/samsung/neo1973_wm8753.c +++ b/trunk/sound/soc/samsung/neo1973_wm8753.c @@ -230,6 +230,8 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { /* GTA02 specific routes and controls */ +#ifdef CONFIG_MACH_NEO1973_GTA02 + static int gta02_speaker_enabled; static int lm4853_set_spk(struct snd_kcontrol *kcontrol, @@ -309,6 +311,10 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) return 0; } +#else +static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; } +#endif + static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; @@ -316,6 +322,10 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) int ret; /* set up NC codec pins */ + if (machine_is_neo1973_gta01()) { + snd_soc_dapm_nc_pin(dapm, "LOUT2"); + snd_soc_dapm_nc_pin(dapm, "ROUT2"); + } snd_soc_dapm_nc_pin(dapm, "OUT3"); snd_soc_dapm_nc_pin(dapm, "OUT4"); snd_soc_dapm_nc_pin(dapm, "LINE1"); @@ -360,6 +370,50 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) return 0; } +/* GTA01 specific controls */ + +#ifdef CONFIG_MACH_NEO1973_GTA01 + +static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = { + {"Amp IN", NULL, "ROUT1"}, + {"Amp IN", NULL, "LOUT1"}, + + {"Handset Spk", NULL, "Amp EP"}, + {"Stereo Out", NULL, "Amp LS"}, + {"Headphone", NULL, "Amp HP"}, +}; + +static const struct snd_soc_dapm_widget neo1973_lm4857_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Handset Spk", NULL), + SND_SOC_DAPM_SPK("Stereo Out", NULL), + SND_SOC_DAPM_HP("Headphone", NULL), +}; + +static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) +{ + int ret; + + ret = snd_soc_dapm_new_controls(dapm, neo1973_lm4857_dapm_widgets, + ARRAY_SIZE(neo1973_lm4857_dapm_widgets)); + if (ret) + return ret; + + ret = snd_soc_dapm_add_routes(dapm, neo1973_lm4857_routes, + ARRAY_SIZE(neo1973_lm4857_routes)); + if (ret) + return ret; + + snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); + snd_soc_dapm_ignore_suspend(dapm, "Headphone"); + + return 0; +} + +#else +static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; }; +#endif + static struct snd_soc_dai_link neo1973_dai[] = { { /* Hifi Playback - for similatious use with voice below */ .name = "WM8753", @@ -386,6 +440,11 @@ static struct snd_soc_aux_dev neo1973_aux_devs[] = { .name = "dfbmcs320", .codec_name = "dfbmcs320.0", }, + { + .name = "lm4857", + .codec_name = "lm4857.0-007c", + .init = neo1973_lm4857_init, + }, }; static struct snd_soc_codec_conf neo1973_codec_conf[] = { @@ -395,10 +454,14 @@ static struct snd_soc_codec_conf neo1973_codec_conf[] = { }, }; +#ifdef CONFIG_MACH_NEO1973_GTA02 static const struct gpio neo1973_gta02_gpios[] = { { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, }; +#else +static const struct gpio neo1973_gta02_gpios[] = {}; +#endif static struct snd_soc_card neo1973 = { .name = "neo1973", @@ -417,7 +480,7 @@ static int __init neo1973_init(void) { int ret; - if (!machine_is_neo1973_gta02()) + if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02()) return -ENODEV; if (machine_is_neo1973_gta02()) { diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 7c12650165ae..ac86d67b636e 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -104,7 +104,7 @@ endif CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) EXTLIBS = -lpthread -lrt -lelf -lm -ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 ALL_LDFLAGS = $(LDFLAGS) STRIP ?= strip @@ -168,7 +168,10 @@ endif ### --- END CONFIGURATION SECTION --- -BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +# Those must not be GNU-specific; they are shared with perl/ which may +# be built by a different compiler. (Note that this is an artifact now +# but it still might be nice to keep that distinction.) +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include BASIC_LDFLAGS = # Guard against environment variables diff --git a/trunk/tools/perf/builtin-probe.c b/trunk/tools/perf/builtin-probe.c index fb8566181f27..59d43abfbfec 100644 --- a/trunk/tools/perf/builtin-probe.c +++ b/trunk/tools/perf/builtin-probe.c @@ -20,6 +20,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +#define _GNU_SOURCE #include #include #include @@ -30,6 +31,7 @@ #include #include +#undef _GNU_SOURCE #include "perf.h" #include "builtin.h" #include "util/util.h" diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index dd162aa24baa..8f80df896038 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -89,6 +89,8 @@ void get_term_dimensions(struct winsize *ws) static void perf_top__update_print_entries(struct perf_top *top) { + top->print_entries = top->winsize.ws_row; + if (top->print_entries > 9) top->print_entries -= 9; } @@ -98,13 +100,6 @@ static void perf_top__sig_winch(int sig __used, siginfo_t *info __used, void *ar struct perf_top *top = arg; get_term_dimensions(&top->winsize); - if (!top->print_entries - || (top->print_entries+4) > top->winsize.ws_row) { - top->print_entries = top->winsize.ws_row; - } else { - top->print_entries += 4; - top->winsize.ws_row = top->print_entries; - } perf_top__update_print_entries(top); } @@ -458,10 +453,8 @@ static void perf_top__handle_keypress(struct perf_top *top, int c) }; perf_top__sig_winch(SIGWINCH, NULL, top); sigaction(SIGWINCH, &act, NULL); - } else { - perf_top__sig_winch(SIGWINCH, NULL, top); + } else signal(SIGWINCH, SIG_DFL); - } break; case 'E': if (top->evlist->nr_entries > 1) { diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index ecd7f4dd7eea..3e7e0b09c12c 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -2105,7 +2105,7 @@ int perf_event__synthesize_event_type(struct perf_tool *tool, strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1); ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE; - size = strlen(ev.event_type.event_type.name); + size = strlen(name); size = ALIGN(size, sizeof(u64)); ev.event_type.header.size = sizeof(ev.event_type) - (sizeof(ev.event_type.event_type.name) - size); diff --git a/trunk/tools/perf/util/probe-event.c b/trunk/tools/perf/util/probe-event.c index 29cb65459811..eb25900e2211 100644 --- a/trunk/tools/perf/util/probe-event.c +++ b/trunk/tools/perf/util/probe-event.c @@ -19,6 +19,7 @@ * */ +#define _GNU_SOURCE #include #include #include @@ -32,6 +33,7 @@ #include #include +#undef _GNU_SOURCE #include "util.h" #include "event.h" #include "string.h" diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index 0975438c3e72..215d50f2042e 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include #include #include diff --git a/trunk/tools/perf/util/trace-event-parse.c b/trunk/tools/perf/util/trace-event-parse.c index 1a8d4dc4f386..6c164dc9ee95 100644 --- a/trunk/tools/perf/util/trace-event-parse.c +++ b/trunk/tools/perf/util/trace-event-parse.c @@ -21,13 +21,14 @@ * The parts for function graph printing was taken and modified from the * Linux Kernel that were written by Frederic Weisbecker. */ - +#define _GNU_SOURCE #include #include #include #include #include +#undef _GNU_SOURCE #include "../perf.h" #include "util.h" #include "trace-event.h" diff --git a/trunk/tools/perf/util/ui/browsers/hists.c b/trunk/tools/perf/util/ui/browsers/hists.c index e81aef1f2569..1212a386a033 100644 --- a/trunk/tools/perf/util/ui/browsers/hists.c +++ b/trunk/tools/perf/util/ui/browsers/hists.c @@ -1,4 +1,6 @@ +#define _GNU_SOURCE #include +#undef _GNU_SOURCE #include "../libslang.h" #include #include diff --git a/trunk/tools/perf/util/ui/helpline.c b/trunk/tools/perf/util/ui/helpline.c index 4f48f5901b30..6ef3c5691762 100644 --- a/trunk/tools/perf/util/ui/helpline.c +++ b/trunk/tools/perf/util/ui/helpline.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include #include #include diff --git a/trunk/tools/perf/util/util.h b/trunk/tools/perf/util/util.h index ecf9898169c8..b9c530cce79a 100644 --- a/trunk/tools/perf/util/util.h +++ b/trunk/tools/perf/util/util.h @@ -40,6 +40,7 @@ #define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) #define _ALL_SOURCE 1 +#define _GNU_SOURCE 1 #define _BSD_SOURCE 1 #define HAS_BOOL diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index a91f980077d8..7287bf5d1c9e 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -1543,7 +1543,7 @@ void mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot, if (memslot && memslot->dirty_bitmap) { unsigned long rel_gfn = gfn - memslot->base_gfn; - if (!test_and_set_bit_le(rel_gfn, memslot->dirty_bitmap)) + if (!__test_and_set_bit_le(rel_gfn, memslot->dirty_bitmap)) memslot->nr_dirty_pages++; } }