From 9b996cc3f73214cf766f72e636177a219b3e4c33 Mon Sep 17 00:00:00 2001 From: Manoj Iyer Date: Tue, 10 Jul 2012 14:07:38 -0500 Subject: [PATCH] --- yaml --- r: 321990 b: refs/heads/master c: 61c964ba1748e984cb232b431582815899bf10fe h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/filesystems.tmpl | 4 +- .../devicetree/bindings/arm/mrvl/intc.txt | 20 - .../devicetree/bindings/ata/marvell.txt | 16 - .../devicetree/bindings/gpio/mrvl-gpio.txt | 23 - .../devicetree/bindings/watchdog/marvel.txt | 14 - trunk/Documentation/filesystems/Locking | 2 + trunk/Documentation/filesystems/porting | 5 +- trunk/Documentation/filesystems/vfs.txt | 4 + trunk/Documentation/laptops/laptop-mode.txt | 12 +- trunk/Documentation/networking/netconsole.txt | 19 +- trunk/Documentation/security/Yama.txt | 14 +- trunk/Documentation/sysctl/vm.txt | 14 +- trunk/MAINTAINERS | 22 +- trunk/Makefile | 4 +- trunk/arch/arm/Kconfig | 1 - trunk/arch/arm/boot/dts/armada-xp.dtsi | 2 +- trunk/arch/arm/boot/dts/imx23.dtsi | 52 +- trunk/arch/arm/boot/dts/imx27-3ds.dts | 2 +- trunk/arch/arm/boot/dts/imx27.dtsi | 6 - trunk/arch/arm/boot/dts/imx28.dtsi | 74 +- trunk/arch/arm/boot/dts/imx51-babbage.dts | 2 +- trunk/arch/arm/boot/dts/imx51.dtsi | 4 - trunk/arch/arm/boot/dts/imx53-ard.dts | 22 +- trunk/arch/arm/boot/dts/imx53.dtsi | 7 - trunk/arch/arm/boot/dts/imx6q-sabrelite.dts | 1 - trunk/arch/arm/boot/dts/imx6q.dtsi | 7 - trunk/arch/arm/boot/dts/kirkwood-dns320.dts | 62 +- trunk/arch/arm/boot/dts/kirkwood-dns325.dts | 68 +- trunk/arch/arm/boot/dts/kirkwood-dnskw.dtsi | 69 - .../arch/arm/boot/dts/kirkwood-dreamplug.dts | 50 - .../arch/arm/boot/dts/kirkwood-goflexnet.dts | 99 - trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts | 38 - trunk/arch/arm/boot/dts/kirkwood-iconnect.dts | 42 - trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts | 20 - trunk/arch/arm/boot/dts/kirkwood-lsxhl.dts | 20 - trunk/arch/arm/boot/dts/kirkwood-lsxl.dtsi | 95 - .../arch/arm/boot/dts/kirkwood-ts219-6281.dts | 21 - .../arch/arm/boot/dts/kirkwood-ts219-6282.dts | 21 - trunk/arch/arm/boot/dts/kirkwood-ts219.dtsi | 78 - trunk/arch/arm/boot/dts/kirkwood.dtsi | 60 - trunk/arch/arm/configs/imx_v6_v7_defconfig | 1 - trunk/arch/arm/configs/mxs_defconfig | 1 + trunk/arch/arm/configs/tct_hammer_defconfig | 2 +- .../arch/arm/mach-davinci/board-neuros-osd2.c | 39 + trunk/arch/arm/mach-dove/irq.c | 58 +- trunk/arch/arm/mach-exynos/pm_domains.c | 2 +- trunk/arch/arm/mach-imx/clk-imx27.c | 8 +- trunk/arch/arm/mach-imx/clk-imx31.c | 2 +- trunk/arch/arm/mach-imx/clk-imx51-imx53.c | 1 - trunk/arch/arm/mach-integrator/core.c | 1 - .../arch/arm/mach-integrator/integrator_ap.c | 2 +- trunk/arch/arm/mach-kirkwood/Kconfig | 29 - trunk/arch/arm/mach-kirkwood/Makefile | 3 - trunk/arch/arm/mach-kirkwood/Makefile.boot | 4 - trunk/arch/arm/mach-kirkwood/board-dnskw.c | 143 ++ .../arch/arm/mach-kirkwood/board-dreamplug.c | 80 + trunk/arch/arm/mach-kirkwood/board-dt.c | 29 +- .../arch/arm/mach-kirkwood/board-goflexnet.c | 71 - trunk/arch/arm/mach-kirkwood/board-ib62x0.c | 72 + trunk/arch/arm/mach-kirkwood/board-iconnect.c | 56 + trunk/arch/arm/mach-kirkwood/board-lsxl.c | 135 -- trunk/arch/arm/mach-kirkwood/board-ts219.c | 82 - trunk/arch/arm/mach-kirkwood/common.c | 2 - trunk/arch/arm/mach-kirkwood/common.h | 17 - trunk/arch/arm/mach-kirkwood/irq.c | 38 +- trunk/arch/arm/mach-mmp/gplugd.c | 1 - trunk/arch/arm/mach-mv78xx0/irq.c | 22 +- trunk/arch/arm/mach-mxs/Kconfig | 6 + trunk/arch/arm/mach-mxs/Makefile | 3 +- trunk/arch/arm/mach-omap2/Kconfig | 1 - trunk/arch/arm/mach-omap2/cpuidle44xx.c | 145 +- trunk/arch/arm/mach-omap2/timer.c | 4 +- trunk/arch/arm/mach-orion5x/irq.c | 22 +- trunk/arch/arm/mach-prima2/timer.c | 6 +- trunk/arch/arm/mach-pxa/raumfeld.c | 2 +- trunk/arch/arm/mach-s3c24xx/Kconfig | 4 +- trunk/arch/arm/mach-sa1100/leds-hackkit.c | 1 - .../arch/arm/mach-tegra/board-harmony-power.c | 32 +- trunk/arch/arm/mm/dma-mapping.c | 12 +- trunk/arch/arm/plat-mxc/tzic.c | 1 - trunk/arch/arm/plat-orion/common.c | 1 - trunk/arch/arm/plat-orion/gpio.c | 166 +- trunk/arch/arm/plat-orion/include/plat/gpio.h | 16 +- trunk/arch/arm/plat-orion/include/plat/irq.h | 3 +- trunk/arch/arm/plat-orion/irq.c | 40 - trunk/arch/arm/plat-samsung/Kconfig | 3 +- trunk/arch/blackfin/kernel/setup.c | 1 + trunk/arch/ia64/kernel/acpi.c | 5 +- trunk/arch/m68k/Kconfig | 12 + trunk/arch/m68k/Kconfig.cpu | 14 - trunk/arch/m68k/apollo/config.c | 16 +- trunk/arch/m68k/include/asm/Kbuild | 25 - trunk/arch/m68k/include/asm/MC68332.h | 152 ++ trunk/arch/m68k/include/asm/apollodma.h | 248 +++ trunk/arch/m68k/include/asm/apollohw.h | 2 +- trunk/arch/m68k/include/asm/bitsperlong.h | 1 + trunk/arch/m68k/include/asm/cputime.h | 6 + trunk/arch/m68k/include/asm/delay.h | 2 +- trunk/arch/m68k/include/asm/device.h | 7 + .../arch/m68k/include/asm/emergency-restart.h | 6 + trunk/arch/m68k/include/asm/errno.h | 6 + trunk/arch/m68k/include/asm/futex.h | 6 + trunk/arch/m68k/include/asm/ioctl.h | 1 + trunk/arch/m68k/include/asm/ipcbuf.h | 1 + trunk/arch/m68k/include/asm/irq_regs.h | 1 + trunk/arch/m68k/include/asm/kdebug.h | 1 + trunk/arch/m68k/include/asm/kmap_types.h | 6 + trunk/arch/m68k/include/asm/kvm_para.h | 1 + trunk/arch/m68k/include/asm/local.h | 6 + trunk/arch/m68k/include/asm/local64.h | 1 + trunk/arch/m68k/include/asm/mac_mouse.h | 23 + trunk/arch/m68k/include/asm/mcfmbus.h | 77 + trunk/arch/m68k/include/asm/mman.h | 1 + trunk/arch/m68k/include/asm/mutex.h | 9 + trunk/arch/m68k/include/asm/percpu.h | 6 + trunk/arch/m68k/include/asm/resource.h | 6 + trunk/arch/m68k/include/asm/sbus.h | 45 + trunk/arch/m68k/include/asm/scatterlist.h | 6 + trunk/arch/m68k/include/asm/sections.h | 8 + trunk/arch/m68k/include/asm/shm.h | 31 + trunk/arch/m68k/include/asm/siginfo.h | 6 + trunk/arch/m68k/include/asm/statfs.h | 6 + trunk/arch/m68k/include/asm/topology.h | 6 + trunk/arch/m68k/include/asm/types.h | 22 + trunk/arch/m68k/include/asm/unaligned.h | 4 +- trunk/arch/m68k/include/asm/xor.h | 1 + trunk/arch/m68k/kernel/setup_no.c | 11 +- trunk/arch/m68k/kernel/sys_m68k.c | 8 +- trunk/arch/m68k/kernel/vmlinux-nommu.lds | 2 + trunk/arch/m68k/kernel/vmlinux-std.lds | 2 + trunk/arch/m68k/kernel/vmlinux-sun3.lds | 2 + trunk/arch/m68k/lib/muldi3.c | 2 +- trunk/arch/m68k/mm/init_mm.c | 2 +- trunk/arch/m68k/mm/init_no.c | 2 +- trunk/arch/m68k/platform/68328/head-de2.S | 8 +- trunk/arch/m68k/platform/68328/head-pilot.S | 10 +- trunk/arch/m68k/platform/68328/head-ram.S | 4 +- trunk/arch/m68k/platform/68328/head-rom.S | 6 +- trunk/arch/m68k/platform/68360/head-ram.S | 6 +- trunk/arch/m68k/platform/68360/head-rom.S | 8 +- trunk/arch/m68k/platform/coldfire/head.S | 10 +- trunk/arch/m68k/sun3/prom/init.c | 48 +- trunk/arch/microblaze/include/asm/sections.h | 4 + .../arch/microblaze/kernel/microblaze_ksyms.c | 3 + trunk/arch/microblaze/kernel/setup.c | 4 +- trunk/arch/microblaze/kernel/vmlinux.lds.S | 1 + trunk/arch/s390/Kconfig | 1 - trunk/arch/s390/include/asm/sparsemem.h | 2 + trunk/arch/s390/include/asm/syscall.h | 10 - trunk/arch/s390/kernel/compat_linux.c | 2 + trunk/arch/s390/kernel/compat_wrapper.S | 4 +- trunk/arch/s390/kernel/ptrace.c | 7 +- trunk/arch/s390/kernel/sys_s390.c | 9 +- trunk/arch/sh/boards/Kconfig | 13 - trunk/arch/sh/boards/board-apsh4a3a.c | 10 - trunk/arch/sh/boards/board-apsh4ad0a.c | 10 - trunk/arch/sh/boards/board-magicpanelr2.c | 10 - trunk/arch/sh/boards/board-polaris.c | 10 - trunk/arch/sh/boards/board-sh2007.c | 12 - trunk/arch/sh/boards/board-sh7757lcr.c | 14 - trunk/arch/sh/boards/mach-ap325rxa/setup.c | 21 - trunk/arch/sh/boards/mach-ecovec24/setup.c | 125 +- trunk/arch/sh/boards/mach-kfr2r09/setup.c | 12 - trunk/arch/sh/boards/mach-migor/setup.c | 13 - trunk/arch/sh/boards/mach-rsk/setup.c | 10 - trunk/arch/sh/boards/mach-sdk7786/setup.c | 10 - trunk/arch/sh/boards/mach-se/7724/setup.c | 15 - trunk/arch/sh/include/asm/sections.h | 1 + trunk/arch/sh/include/cpu-sh4/cpu/sh7757.h | 2 - trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 4 +- trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 1 - trunk/arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 14 - trunk/arch/sh/kernel/setup.c | 2 +- trunk/arch/sh/kernel/sh_ksyms_32.c | 1 + trunk/arch/sh/kernel/vmlinux.lds.S | 1 + trunk/arch/sh/lib/mcount.S | 8 +- trunk/arch/sh/mm/fault.c | 8 +- trunk/arch/x86/Kconfig | 2 +- trunk/arch/x86/include/asm/mce.h | 8 - trunk/arch/x86/include/asm/olpc.h | 19 + trunk/arch/x86/include/asm/perf_event.h | 11 +- trunk/arch/x86/kernel/acpi/sleep.c | 4 + trunk/arch/x86/kernel/acpi/sleep.h | 2 + trunk/arch/x86/kernel/acpi/wakeup_32.S | 4 +- trunk/arch/x86/kernel/acpi/wakeup_64.S | 4 +- trunk/arch/x86/kernel/alternative.c | 2 +- trunk/arch/x86/kernel/apic/io_apic.c | 4 +- .../arch/x86/kernel/cpu/mcheck/mce-severity.c | 7 + trunk/arch/x86/kernel/cpu/mcheck/mce.c | 43 +- trunk/arch/x86/kernel/cpu/perf_event.c | 89 +- trunk/arch/x86/kernel/cpu/perf_event.h | 20 - .../arch/x86/kernel/cpu/perf_event_amd_ibs.c | 4 +- .../arch/x86/kernel/cpu/perf_event_intel_ds.c | 7 +- .../x86/kernel/cpu/perf_event_intel_uncore.h | 2 +- trunk/arch/x86/kernel/irq.c | 1 - trunk/arch/x86/kernel/kdebugfs.c | 6 +- trunk/arch/x86/kvm/i8259.c | 17 - trunk/arch/x86/kvm/vmx.c | 20 +- trunk/arch/x86/kvm/x86.c | 4 - trunk/arch/x86/mm/srat.c | 15 +- trunk/arch/x86/platform/olpc/olpc-xo1-pm.c | 16 +- trunk/arch/x86/platform/olpc/olpc-xo1-sci.c | 1 - trunk/arch/x86/platform/olpc/olpc-xo15-sci.c | 1 - trunk/arch/x86/platform/olpc/olpc.c | 190 +- trunk/arch/x86/syscalls/syscall_64.tbl | 2 +- trunk/drivers/acpi/ac.c | 4 - trunk/drivers/acpi/acpica/achware.h | 12 +- trunk/drivers/acpi/acpica/hwesleep.c | 19 +- trunk/drivers/acpi/acpica/hwsleep.c | 20 +- trunk/drivers/acpi/acpica/hwxfsleep.c | 22 +- trunk/drivers/acpi/battery.c | 2 - trunk/drivers/acpi/button.c | 4 - trunk/drivers/acpi/fan.c | 4 - trunk/drivers/acpi/numa.c | 12 +- trunk/drivers/acpi/pci_root.c | 11 +- trunk/drivers/acpi/power.c | 4 - trunk/drivers/acpi/processor_driver.c | 2 +- trunk/drivers/acpi/sbs.c | 2 - trunk/drivers/acpi/sleep.c | 75 +- trunk/drivers/acpi/sysfs.c | 4 +- trunk/drivers/acpi/thermal.c | 4 - trunk/drivers/ata/sata_mv.c | 42 +- trunk/drivers/atm/iphase.c | 2 +- trunk/drivers/base/power/clock_ops.c | 3 +- trunk/drivers/base/power/common.c | 4 +- trunk/drivers/block/drbd/drbd_main.c | 4 +- trunk/drivers/bluetooth/btusb.c | 1 + trunk/drivers/char/agp/intel-agp.h | 39 +- trunk/drivers/char/agp/intel-gtt.c | 60 +- trunk/drivers/char/hw_random/omap-rng.c | 2 +- trunk/drivers/char/tpm/tpm_tis.c | 2 - trunk/drivers/cpufreq/pcc-cpufreq.c | 1 - trunk/drivers/dma/sh/shdma-base.c | 9 - trunk/drivers/dma/sh/shdma.c | 12 - trunk/drivers/gpio/gpio-em.c | 2 +- trunk/drivers/gpio/gpio-langwell.c | 7 +- trunk/drivers/gpio/gpio-msic.c | 2 +- trunk/drivers/gpio/gpio-mxc.c | 5 +- trunk/drivers/gpio/gpio-pxa.c | 30 +- trunk/drivers/gpio/gpio-samsung.c | 14 +- trunk/drivers/gpio/gpio-sch.c | 3 +- trunk/drivers/gpu/drm/drm_edid_load.c | 8 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 31 +- trunk/drivers/gpu/drm/i915/i915_gem_context.c | 1 + .../gpu/drm/i915/i915_gem_execbuffer.c | 20 +- trunk/drivers/gpu/drm/i915/i915_gem_gtt.c | 3 +- trunk/drivers/gpu/drm/i915/i915_sysfs.c | 12 - trunk/drivers/gpu/drm/i915/intel_display.c | 1 - trunk/drivers/gpu/drm/i915/intel_drv.h | 20 +- trunk/drivers/gpu/drm/i915/intel_i2c.c | 3 + trunk/drivers/gpu/drm/i915/intel_panel.c | 2 +- trunk/drivers/gpu/drm/i915/intel_pm.c | 6 +- trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 7 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 5 +- trunk/drivers/gpu/drm/mgag200/mgag200_mode.c | 12 +- trunk/drivers/gpu/drm/radeon/atombios_crtc.c | 22 +- trunk/drivers/gpu/drm/radeon/evergreen.c | 71 +- trunk/drivers/gpu/drm/radeon/evergreen_cs.c | 13 +- trunk/drivers/gpu/drm/radeon/evergreend.h | 2 - trunk/drivers/gpu/drm/radeon/ni.c | 14 +- trunk/drivers/gpu/drm/radeon/r600.c | 20 - trunk/drivers/gpu/drm/radeon/r600_cs.c | 65 +- trunk/drivers/gpu/drm/radeon/r600d.h | 3 - trunk/drivers/gpu/drm/radeon/radeon.h | 12 +- trunk/drivers/gpu/drm/radeon/radeon_asic.h | 10 +- .../drivers/gpu/drm/radeon/radeon_atombios.c | 49 +- trunk/drivers/gpu/drm/radeon/radeon_combios.c | 57 +- trunk/drivers/gpu/drm/radeon/radeon_cs.c | 32 +- trunk/drivers/gpu/drm/radeon/radeon_cursor.c | 6 +- trunk/drivers/gpu/drm/radeon/radeon_device.c | 1 - trunk/drivers/gpu/drm/radeon/radeon_drv.c | 5 +- trunk/drivers/gpu/drm/radeon/radeon_gart.c | 26 +- trunk/drivers/gpu/drm/radeon/radeon_gem.c | 13 +- trunk/drivers/gpu/drm/radeon/radeon_kms.c | 35 +- .../gpu/drm/radeon/radeon_legacy_crtc.c | 4 - trunk/drivers/gpu/drm/radeon/radeon_mode.h | 1 - trunk/drivers/gpu/drm/radeon/radeon_object.c | 6 +- trunk/drivers/gpu/drm/radeon/rv515.c | 13 + trunk/drivers/gpu/drm/radeon/si.c | 35 +- trunk/drivers/gpu/drm/radeon/sid.h | 3 - trunk/drivers/gpu/drm/udl/udl_gem.c | 2 +- trunk/drivers/input/touchscreen/eeti_ts.c | 21 +- trunk/drivers/iommu/amd_iommu.c | 25 +- trunk/drivers/iommu/amd_iommu_init.c | 6 +- trunk/drivers/iommu/exynos-iommu.c | 6 +- trunk/drivers/iommu/intel-iommu.c | 26 +- trunk/drivers/iommu/tegra-smmu.c | 17 +- trunk/drivers/isdn/isdnloop/isdnloop.c | 12 + trunk/drivers/isdn/mISDN/layer2.c | 2 +- trunk/drivers/leds/led-triggers.c | 2 +- trunk/drivers/leds/leds-lp8788.c | 2 +- trunk/drivers/leds/leds-renesas-tpu.c | 2 +- trunk/drivers/md/Kconfig | 5 +- trunk/drivers/md/bitmap.c | 2 +- trunk/drivers/md/raid1.c | 57 +- trunk/drivers/md/raid5.c | 107 +- trunk/drivers/md/raid5.h | 1 - trunk/drivers/mfd/asic3.c | 1 - trunk/drivers/mfd/ezx-pcap.c | 2 +- trunk/drivers/mtd/maps/uclinux.c | 5 +- trunk/drivers/mtd/nand/Kconfig | 2 +- trunk/drivers/mtd/nand/omap2.c | 7 +- trunk/drivers/net/appletalk/cops.c | 4 +- trunk/drivers/net/appletalk/ltpc.c | 4 +- trunk/drivers/net/bonding/bond_main.c | 12 +- trunk/drivers/net/cris/eth_v10.c | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x.h | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 72 +- .../net/ethernet/emulex/benet/be_main.c | 2 +- .../ethernet/freescale/fs_enet/mii-bitbang.c | 4 +- .../net/ethernet/freescale/fs_enet/mii-fec.c | 8 +- .../drivers/net/ethernet/intel/e1000e/82571.c | 10 +- .../net/ethernet/intel/e1000e/netdev.c | 36 +- .../net/ethernet/intel/igb/e1000_82575.c | 16 +- .../net/ethernet/intel/igb/e1000_regs.h | 8 +- .../net/ethernet/intel/igb/igb_ethtool.c | 28 +- .../drivers/net/ethernet/intel/igb/igb_main.c | 19 +- .../net/ethernet/intel/ixgbe/ixgbe_82599.c | 3 +- .../net/ethernet/mellanox/mlx4/en_rx.c | 4 +- .../net/ethernet/mellanox/mlx4/en_tx.c | 17 +- .../drivers/net/ethernet/mellanox/mlx4/main.c | 3 + .../drivers/net/ethernet/mellanox/mlx4/mcg.c | 4 +- .../net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + .../net/ethernet/mellanox/mlx4/sense.c | 14 + trunk/drivers/net/ethernet/nxp/lpc_eth.c | 13 + .../ethernet/stmicro/stmmac/stmmac_platform.c | 2 +- trunk/drivers/net/ethernet/ti/davinci_cpdma.c | 3 +- .../drivers/net/ethernet/xscale/ixp4xx_eth.c | 1 - trunk/drivers/net/hyperv/netvsc.c | 7 + trunk/drivers/net/hyperv/rndis_filter.c | 11 - trunk/drivers/net/irda/bfin_sir.c | 8 +- trunk/drivers/net/macvtap.c | 3 +- trunk/drivers/net/netconsole.c | 5 + trunk/drivers/net/phy/mdio-mux-gpio.c | 1 + trunk/drivers/net/ppp/pptp.c | 4 +- trunk/drivers/net/team/team.c | 16 +- trunk/drivers/net/tun.c | 1 + trunk/drivers/net/usb/cdc-phonet.c | 1 - trunk/drivers/net/usb/cdc_ncm.c | 20 - trunk/drivers/net/usb/qmi_wwan.c | 248 ++- trunk/drivers/net/usb/sierra_net.c | 52 +- trunk/drivers/net/wireless/iwlwifi/dvm/rs.c | 13 +- trunk/drivers/net/wireless/libertas/if_usb.c | 1 - trunk/drivers/net/wireless/rt2x00/rt61pci.c | 3 +- trunk/drivers/pinctrl/pinctrl-imx23.c | 2 +- trunk/drivers/pinctrl/pinctrl-imx28.c | 2 +- .../drivers/pinctrl/pinctrl-nomadik-db8500.c | 2 +- trunk/drivers/pinctrl/pinctrl-nomadik.c | 1 + trunk/drivers/pinctrl/pinctrl-sirf.c | 1 + trunk/drivers/pinctrl/pinctrl-u300.c | 8 +- trunk/drivers/platform/Makefile | 1 - trunk/drivers/platform/olpc/Makefile | 4 - trunk/drivers/platform/olpc/olpc-ec.c | 336 ---- trunk/drivers/platform/x86/classmate-laptop.c | 4 - trunk/drivers/platform/x86/fujitsu-tablet.c | 2 - trunk/drivers/platform/x86/hdaps.c | 2 - trunk/drivers/platform/x86/hp_accel.c | 2 +- trunk/drivers/platform/x86/msi-laptop.c | 4 - trunk/drivers/platform/x86/panasonic-laptop.c | 4 - trunk/drivers/platform/x86/sony-laptop.c | 12 +- trunk/drivers/platform/x86/thinkpad_acpi.c | 2 - trunk/drivers/platform/x86/toshiba_acpi.c | 2 - .../drivers/platform/x86/toshiba_bluetooth.c | 4 - trunk/drivers/platform/x86/xo1-rfkill.c | 3 +- trunk/drivers/platform/x86/xo15-ebook.c | 2 - trunk/drivers/power/olpc_battery.c | 1 - trunk/drivers/rtc/interface.c | 2 - trunk/drivers/rtc/rtc-cmos.c | 1 + trunk/drivers/s390/char/sclp_sdias.c | 2 - trunk/drivers/sh/intc/Kconfig | 4 - trunk/drivers/sh/intc/Makefile | 2 +- trunk/drivers/sh/intc/core.c | 11 +- trunk/drivers/sh/intc/internals.h | 5 - trunk/drivers/sh/intc/irqdomain.c | 68 - trunk/drivers/sh/pfc/pinctrl.c | 34 +- trunk/drivers/spi/spi-s3c64xx.c | 2 +- trunk/drivers/staging/olpc_dcon/olpc_dcon.c | 1 - trunk/drivers/tty/serial/sh-sci.c | 5 +- trunk/drivers/usb/early/ehci-dbgp.c | 2 +- trunk/drivers/usb/host/ohci-omap.c | 2 + trunk/drivers/vhost/Kconfig | 3 - trunk/drivers/vhost/Kconfig.tcm | 6 - trunk/drivers/vhost/Makefile | 2 - trunk/drivers/vhost/tcm_vhost.c | 1628 ----------------- trunk/drivers/vhost/tcm_vhost.h | 101 - trunk/drivers/watchdog/orion_wdt.c | 8 - trunk/drivers/zorro/zorro.c | 2 + trunk/fs/bio.c | 2 +- trunk/fs/btrfs/inode.c | 3 +- trunk/fs/btrfs/ioctl.c | 5 + trunk/fs/btrfs/ordered-data.c | 2 +- trunk/fs/btrfs/super.c | 4 + trunk/fs/btrfs/volumes.c | 4 + trunk/fs/ceph/dir.c | 38 + trunk/fs/ceph/file.c | 62 +- trunk/fs/ceph/super.h | 6 +- trunk/fs/cifs/cifsglob.h | 10 - trunk/fs/cifs/cifsproto.h | 11 +- trunk/fs/cifs/cifssmb.c | 31 +- trunk/fs/cifs/inode.c | 302 ++- trunk/fs/cifs/smb1ops.c | 24 - trunk/fs/cifs/smb2inode.c | 39 - trunk/fs/cifs/smb2ops.c | 3 - trunk/fs/cifs/smb2proto.h | 8 - trunk/fs/ecryptfs/ecryptfs_kernel.h | 24 +- trunk/fs/ecryptfs/file.c | 90 +- trunk/fs/ecryptfs/inode.c | 65 +- trunk/fs/ecryptfs/main.c | 22 - trunk/fs/ecryptfs/messaging.c | 136 +- trunk/fs/ecryptfs/miscdev.c | 98 +- trunk/fs/ecryptfs/mmap.c | 39 +- trunk/fs/exofs/inode.c | 27 +- trunk/fs/exofs/ore.c | 14 +- trunk/fs/exofs/super.c | 11 + trunk/fs/ext3/inode.c | 8 + trunk/fs/ext3/super.c | 11 + trunk/fs/ext4/inode.c | 10 +- trunk/fs/ext4/super.c | 11 + trunk/fs/gfs2/meta_io.c | 2 +- trunk/fs/hfs/mdb.c | 4 +- trunk/fs/jbd/journal.c | 4 +- trunk/fs/jbd2/journal.c | 4 +- trunk/fs/nilfs2/super.c | 4 + trunk/fs/nilfs2/the_nilfs.h | 2 + trunk/fs/open.c | 2 +- trunk/fs/super.c | 40 + trunk/fs/ubifs/file.c | 10 +- trunk/fs/ubifs/super.c | 2 +- trunk/include/acpi/acpixf.h | 4 +- trunk/include/acpi/actypes.h | 2 +- trunk/include/drm/drm_pciids.h | 3 - trunk/include/drm/radeon_drm.h | 2 - trunk/include/linux/acpi.h | 2 +- trunk/include/linux/backing-dev.h | 1 + trunk/include/linux/can.h | 25 +- trunk/include/linux/fs.h | 3 + trunk/include/linux/ftrace_event.h | 5 +- trunk/include/linux/hardirq.h | 2 +- trunk/include/linux/if_team.h | 30 +- trunk/include/linux/input/eeti_ts.h | 1 - trunk/include/linux/iommu.h | 2 - trunk/include/linux/ipv6.h | 1 - trunk/include/linux/irq.h | 1 - trunk/include/linux/jiffies.h | 29 +- trunk/include/linux/kdb.h | 2 + trunk/include/linux/mfd/ezx-pcap.h | 1 - trunk/include/linux/netdevice.h | 3 +- trunk/include/linux/netpoll.h | 42 +- trunk/include/linux/olpc-ec.h | 41 - trunk/include/linux/perf_event.h | 3 +- trunk/include/linux/sched.h | 8 + trunk/include/linux/security.h | 2 + trunk/include/linux/shdma-base.h | 2 - trunk/include/linux/timex.h | 2 +- trunk/include/linux/topology.h | 1 - trunk/include/linux/writeback.h | 1 + trunk/include/net/codel.h | 8 +- trunk/include/net/dst.h | 2 +- trunk/include/net/inet_connection_sock.h | 1 - trunk/include/net/inet_sock.h | 9 + trunk/include/net/ip.h | 2 +- trunk/include/net/llc.h | 2 +- trunk/include/net/tcp.h | 1 - trunk/include/trace/events/sched.h | 4 - trunk/include/trace/ftrace.h | 6 +- trunk/kernel/debug/kdb/kdb_debugger.c | 4 - trunk/kernel/debug/kdb/kdb_io.c | 11 + trunk/kernel/debug/kdb/kdb_main.c | 15 +- trunk/kernel/events/callchain.c | 9 +- trunk/kernel/events/core.c | 30 +- trunk/kernel/events/internal.h | 3 +- trunk/kernel/futex.c | 17 +- trunk/kernel/irq/manage.c | 15 +- trunk/kernel/power/suspend.c | 3 + trunk/kernel/printk.c | 2 - trunk/kernel/sched/core.c | 4 +- trunk/kernel/sched/cpupri.c | 10 +- trunk/kernel/sched/fair.c | 29 +- trunk/kernel/time/jiffies.c | 2 +- trunk/kernel/time/ntp.c | 2 +- trunk/kernel/time/timekeeping.c | 407 ++--- trunk/kernel/trace/trace_event_perf.c | 2 +- trunk/kernel/trace/trace_kprobe.c | 6 +- trunk/kernel/trace/trace_syscalls.c | 4 +- trunk/kernel/trace/trace_uprobe.c | 2 +- trunk/kernel/watchdog.c | 21 +- trunk/mm/backing-dev.c | 52 + trunk/mm/page-writeback.c | 1 + trunk/mm/page_alloc.c | 2 +- trunk/net/8021q/vlan_dev.c | 52 +- trunk/net/batman-adv/gateway_client.c | 6 +- trunk/net/batman-adv/translation-table.c | 1 - trunk/net/bridge/br_device.c | 27 +- trunk/net/bridge/br_forward.c | 2 +- trunk/net/bridge/br_if.c | 6 +- trunk/net/bridge/br_private.h | 4 +- trunk/net/ceph/crypto.c | 1 - trunk/net/ceph/crypto.h | 3 +- trunk/net/core/dev.c | 7 +- trunk/net/core/dst.c | 10 +- trunk/net/core/netpoll.c | 109 +- trunk/net/ipv4/fib_trie.c | 2 +- trunk/net/ipv4/ip_output.c | 8 +- trunk/net/ipv4/route.c | 1 + trunk/net/ipv4/tcp_input.c | 4 +- trunk/net/ipv4/tcp_ipv4.c | 14 +- trunk/net/ipv4/tcp_metrics.c | 12 - trunk/net/ipv4/tcp_minisocks.c | 2 +- trunk/net/ipv4/tcp_output.c | 2 +- trunk/net/ipv4/udp.c | 2 +- trunk/net/ipv6/addrconf.c | 4 +- trunk/net/ipv6/proc.c | 4 +- trunk/net/ipv6/tcp_ipv6.c | 28 +- trunk/net/llc/af_llc.c | 5 +- trunk/net/llc/llc_input.c | 21 +- trunk/net/llc/llc_station.c | 29 +- trunk/net/packet/af_packet.c | 3 +- trunk/net/sched/act_gact.c | 14 +- trunk/net/sched/act_ipt.c | 7 +- trunk/net/sched/act_pedit.c | 5 +- trunk/net/sched/act_simple.c | 5 +- trunk/net/sched/sch_qfq.c | 95 +- trunk/net/wireless/core.c | 5 - trunk/net/wireless/core.h | 1 - trunk/net/wireless/util.c | 2 +- trunk/security/yama/yama_lsm.c | 41 - trunk/sound/core/sgbuf.c | 2 +- trunk/sound/pci/emu10k1/memory.c | 5 +- trunk/sound/pci/hda/hda_auto_parser.c | 5 +- trunk/sound/pci/hda/patch_conexant.c | 6 + trunk/sound/pci/hda/patch_hdmi.c | 12 +- trunk/sound/pci/hda/patch_realtek.c | 8 +- trunk/sound/soc/codecs/ab8500-codec.c | 4 - trunk/sound/soc/codecs/ad1980.c | 1 - trunk/sound/soc/codecs/mc13783.c | 2 - trunk/sound/soc/codecs/sgtl5000.c | 3 +- trunk/sound/soc/codecs/stac9766.c | 1 - trunk/sound/soc/codecs/wm8962.c | 3 - trunk/sound/soc/codecs/wm8994.c | 15 +- trunk/sound/soc/codecs/wm9712.c | 1 - trunk/sound/soc/codecs/wm9713.c | 1 - trunk/sound/soc/mxs/mxs-saif.c | 24 - trunk/sound/soc/omap/omap-mcbsp.c | 1 - trunk/sound/soc/omap/omap-pcm.c | 1 - trunk/sound/soc/soc-core.c | 2 +- trunk/sound/soc/tegra/tegra_alc5632.c | 2 +- trunk/sound/soc/tegra/tegra_wm8903.c | 10 +- trunk/sound/soc/ux500/ux500_msp_dai.c | 2 +- trunk/sound/soc/ux500/ux500_msp_i2s.c | 2 +- trunk/sound/soc/ux500/ux500_msp_i2s.h | 2 +- trunk/tools/perf/Makefile | 7 +- trunk/tools/perf/builtin-record.c | 4 +- trunk/tools/perf/builtin-report.c | 5 +- trunk/tools/perf/builtin-test.c | 19 +- trunk/tools/perf/builtin-top.c | 23 +- trunk/tools/perf/util/event.h | 3 + trunk/tools/perf/util/evlist.c | 7 - trunk/tools/perf/util/evlist.h | 3 - trunk/tools/perf/util/evsel.c | 15 +- trunk/tools/perf/util/evsel.h | 10 +- trunk/tools/perf/util/header.c | 9 - trunk/tools/perf/util/intlist.c | 101 - trunk/tools/perf/util/intlist.h | 75 - trunk/tools/perf/util/parse-events-test.c | 12 +- trunk/tools/perf/util/parse-options.c | 3 - trunk/tools/perf/util/python.c | 6 +- trunk/tools/perf/util/rblist.c | 107 -- trunk/tools/perf/util/rblist.h | 47 - trunk/tools/perf/util/session.c | 48 +- trunk/tools/perf/util/session.h | 24 +- trunk/tools/perf/util/strlist.c | 130 +- trunk/tools/perf/util/strlist.h | 11 +- trunk/tools/perf/util/symbol.c | 14 +- trunk/tools/perf/util/target.c | 2 +- 575 files changed, 4340 insertions(+), 7752 deletions(-) delete mode 100644 trunk/Documentation/devicetree/bindings/ata/marvell.txt delete mode 100644 trunk/Documentation/devicetree/bindings/watchdog/marvel.txt delete mode 100644 trunk/arch/arm/boot/dts/kirkwood-dnskw.dtsi delete mode 100644 trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts delete mode 100644 trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts delete mode 100644 trunk/arch/arm/boot/dts/kirkwood-lsxhl.dts delete mode 100644 trunk/arch/arm/boot/dts/kirkwood-lsxl.dtsi delete mode 100644 trunk/arch/arm/boot/dts/kirkwood-ts219-6281.dts delete mode 100644 trunk/arch/arm/boot/dts/kirkwood-ts219-6282.dts delete mode 100644 trunk/arch/arm/boot/dts/kirkwood-ts219.dtsi delete mode 100644 trunk/arch/arm/mach-kirkwood/board-goflexnet.c delete mode 100644 trunk/arch/arm/mach-kirkwood/board-lsxl.c delete mode 100644 trunk/arch/arm/mach-kirkwood/board-ts219.c create mode 100644 trunk/arch/m68k/include/asm/MC68332.h create mode 100644 trunk/arch/m68k/include/asm/apollodma.h create mode 100644 trunk/arch/m68k/include/asm/bitsperlong.h create mode 100644 trunk/arch/m68k/include/asm/cputime.h create mode 100644 trunk/arch/m68k/include/asm/device.h create mode 100644 trunk/arch/m68k/include/asm/emergency-restart.h create mode 100644 trunk/arch/m68k/include/asm/errno.h create mode 100644 trunk/arch/m68k/include/asm/futex.h create mode 100644 trunk/arch/m68k/include/asm/ioctl.h create mode 100644 trunk/arch/m68k/include/asm/ipcbuf.h create mode 100644 trunk/arch/m68k/include/asm/irq_regs.h create mode 100644 trunk/arch/m68k/include/asm/kdebug.h create mode 100644 trunk/arch/m68k/include/asm/kmap_types.h create mode 100644 trunk/arch/m68k/include/asm/kvm_para.h create mode 100644 trunk/arch/m68k/include/asm/local.h create mode 100644 trunk/arch/m68k/include/asm/local64.h create mode 100644 trunk/arch/m68k/include/asm/mac_mouse.h create mode 100644 trunk/arch/m68k/include/asm/mcfmbus.h create mode 100644 trunk/arch/m68k/include/asm/mman.h create mode 100644 trunk/arch/m68k/include/asm/mutex.h create mode 100644 trunk/arch/m68k/include/asm/percpu.h create mode 100644 trunk/arch/m68k/include/asm/resource.h create mode 100644 trunk/arch/m68k/include/asm/sbus.h create mode 100644 trunk/arch/m68k/include/asm/scatterlist.h create mode 100644 trunk/arch/m68k/include/asm/sections.h create mode 100644 trunk/arch/m68k/include/asm/shm.h create mode 100644 trunk/arch/m68k/include/asm/siginfo.h create mode 100644 trunk/arch/m68k/include/asm/statfs.h create mode 100644 trunk/arch/m68k/include/asm/topology.h create mode 100644 trunk/arch/m68k/include/asm/types.h create mode 100644 trunk/arch/m68k/include/asm/xor.h delete mode 100644 trunk/drivers/platform/olpc/Makefile delete mode 100644 trunk/drivers/platform/olpc/olpc-ec.c delete mode 100644 trunk/drivers/sh/intc/irqdomain.c delete mode 100644 trunk/drivers/vhost/Kconfig.tcm delete mode 100644 trunk/drivers/vhost/tcm_vhost.c delete mode 100644 trunk/drivers/vhost/tcm_vhost.h delete mode 100644 trunk/include/linux/olpc-ec.h delete mode 100644 trunk/tools/perf/util/intlist.c delete mode 100644 trunk/tools/perf/util/intlist.h delete mode 100644 trunk/tools/perf/util/rblist.c delete mode 100644 trunk/tools/perf/util/rblist.h diff --git a/[refs] b/[refs] index 4aef43577451..53db838b2604 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4acd4945cd1e1f92b20d14e349c6c6a52acbd42d +refs/heads/master: 61c964ba1748e984cb232b431582815899bf10fe diff --git a/trunk/Documentation/DocBook/filesystems.tmpl b/trunk/Documentation/DocBook/filesystems.tmpl index 25b58efd955d..3fca32c41927 100644 --- a/trunk/Documentation/DocBook/filesystems.tmpl +++ b/trunk/Documentation/DocBook/filesystems.tmpl @@ -224,8 +224,8 @@ all your transactions. -Then at umount time , in your put_super() you can then call journal_destroy() -to clean up your in-core journal object. +Then at umount time , in your put_super() (2.4) or write_super() (2.5) +you can then call journal_destroy() to clean up your in-core journal object. diff --git a/trunk/Documentation/devicetree/bindings/arm/mrvl/intc.txt b/trunk/Documentation/devicetree/bindings/arm/mrvl/intc.txt index 8b53273cb22f..80b9a94d9a23 100644 --- a/trunk/Documentation/devicetree/bindings/arm/mrvl/intc.txt +++ b/trunk/Documentation/devicetree/bindings/arm/mrvl/intc.txt @@ -38,23 +38,3 @@ Example: reg-names = "mux status", "mux mask"; mrvl,intc-nr-irqs = <2>; }; - -* Marvell Orion Interrupt controller - -Required properties -- compatible : Should be "marvell,orion-intc". -- #interrupt-cells: Specifies the number of cells needed to encode an - interrupt source. Supported value is <1>. -- interrupt-controller : Declare this node to be an interrupt controller. -- reg : Interrupt mask address. A list of 4 byte ranges, one per controller. - One entry in the list represents 32 interrupts. - -Example: - - intc: interrupt-controller { - compatible = "marvell,orion-intc", "marvell,intc"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0xfed20204 0x04>, - <0xfed20214 0x04>; - }; diff --git a/trunk/Documentation/devicetree/bindings/ata/marvell.txt b/trunk/Documentation/devicetree/bindings/ata/marvell.txt deleted file mode 100644 index b5cdd20cde9c..000000000000 --- a/trunk/Documentation/devicetree/bindings/ata/marvell.txt +++ /dev/null @@ -1,16 +0,0 @@ -* Marvell Orion SATA - -Required Properties: -- compatibility : "marvell,orion-sata" -- reg : Address range of controller -- interrupts : Interrupt controller is using -- nr-ports : Number of SATA ports in use. - -Example: - - sata@80000 { - compatible = "marvell,orion-sata"; - reg = <0x80000 0x5000>; - interrupts = <21>; - nr-ports = <2>; - } diff --git a/trunk/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/trunk/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt index e13787498bcf..05428f39d9ac 100644 --- a/trunk/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +++ b/trunk/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt @@ -27,26 +27,3 @@ Example: interrupt-controller; #interrupt-cells = <1>; }; - -* Marvell Orion GPIO Controller - -Required properties: -- compatible : Should be "marvell,orion-gpio" -- reg : Address and length of the register set for controller. -- gpio-controller : So we know this is a gpio controller. -- ngpio : How many gpios this controller has. -- interrupts : Up to 4 Interrupts for the controller. - -Optional properties: -- mask-offset : For SMP Orions, offset for Nth CPU - -Example: - - gpio0: gpio@10100 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0x10100 0x40>; - ngpio = <32>; - interrupts = <35>, <36>, <37>, <38>; - }; diff --git a/trunk/Documentation/devicetree/bindings/watchdog/marvel.txt b/trunk/Documentation/devicetree/bindings/watchdog/marvel.txt deleted file mode 100644 index 0b2503ab0a05..000000000000 --- a/trunk/Documentation/devicetree/bindings/watchdog/marvel.txt +++ /dev/null @@ -1,14 +0,0 @@ -* Marvell Orion Watchdog Time - -Required Properties: - -- Compatibility : "marvell,orion-wdt" -- reg : Address of the timer registers - -Example: - - wdt@20300 { - compatible = "marvell,orion-wdt"; - reg = <0x20300 0x28>; - status = "okay"; - }; diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index e540a24e5d06..0f103e39b4f6 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -114,6 +114,7 @@ prototypes: int (*drop_inode) (struct inode *); void (*evict_inode) (struct inode *); void (*put_super) (struct super_block *); + void (*write_super) (struct super_block *); int (*sync_fs)(struct super_block *sb, int wait); int (*freeze_fs) (struct super_block *); int (*unfreeze_fs) (struct super_block *); @@ -135,6 +136,7 @@ write_inode: drop_inode: !!!inode->i_lock!!! evict_inode: put_super: write +write_super: read sync_fs: read freeze_fs: write unfreeze_fs: write diff --git a/trunk/Documentation/filesystems/porting b/trunk/Documentation/filesystems/porting index 0742feebc6e2..2bef2b3843d1 100644 --- a/trunk/Documentation/filesystems/porting +++ b/trunk/Documentation/filesystems/porting @@ -94,8 +94,9 @@ protected. --- [mandatory] -BKL is also moved from around sb operations. BKL should have been shifted into -individual fs sb_op functions. If you don't need it, remove it. +BKL is also moved from around sb operations. ->write_super() Is now called +without BKL held. BKL should have been shifted into individual fs sb_op +functions. If you don't need it, remove it. --- [informational] diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index 2ee133e030c3..065aa2dc0835 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -216,6 +216,7 @@ struct super_operations { void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); + void (*write_super) (struct super_block *); int (*sync_fs)(struct super_block *sb, int wait); int (*freeze_fs) (struct super_block *); int (*unfreeze_fs) (struct super_block *); @@ -272,6 +273,9 @@ or bottom half). put_super: called when the VFS wishes to free the superblock (i.e. unmount). This is called with the superblock lock held + write_super: called when the VFS superblock needs to be written to + disc. This method is optional + sync_fs: called when VFS is writing out all dirty data associated with a superblock. The second parameter indicates whether the method should wait until the write out has been completed. Optional. diff --git a/trunk/Documentation/laptops/laptop-mode.txt b/trunk/Documentation/laptops/laptop-mode.txt index 4ebbfc3f1c6e..0bf25eebce94 100644 --- a/trunk/Documentation/laptops/laptop-mode.txt +++ b/trunk/Documentation/laptops/laptop-mode.txt @@ -262,9 +262,9 @@ MINIMUM_BATTERY_MINUTES=10 # # Allowed dirty background ratio, in percent. Once DIRTY_RATIO has been -# exceeded, the kernel will wake flusher threads which will then reduce the -# amount of dirty memory to dirty_background_ratio. Set this nice and low, -# so once some writeout has commenced, we do a lot of it. +# exceeded, the kernel will wake pdflush which will then reduce the amount +# of dirty memory to dirty_background_ratio. Set this nice and low, so once +# some writeout has commenced, we do a lot of it. # #DIRTY_BACKGROUND_RATIO=5 @@ -384,9 +384,9 @@ CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'} # # Allowed dirty background ratio, in percent. Once DIRTY_RATIO has been -# exceeded, the kernel will wake flusher threads which will then reduce the -# amount of dirty memory to dirty_background_ratio. Set this nice and low, -# so once some writeout has commenced, we do a lot of it. +# exceeded, the kernel will wake pdflush which will then reduce the amount +# of dirty memory to dirty_background_ratio. Set this nice and low, so once +# some writeout has commenced, we do a lot of it. # DIRTY_BACKGROUND_RATIO=${DIRTY_BACKGROUND_RATIO:-'5'} diff --git a/trunk/Documentation/networking/netconsole.txt b/trunk/Documentation/networking/netconsole.txt index 2e9e0ae2cd45..8d022073e3ef 100644 --- a/trunk/Documentation/networking/netconsole.txt +++ b/trunk/Documentation/networking/netconsole.txt @@ -51,23 +51,8 @@ Built-in netconsole starts immediately after the TCP stack is initialized and attempts to bring up the supplied dev at the supplied address. -The remote host has several options to receive the kernel messages, -for example: - -1) syslogd - -2) netcat - - On distributions using a BSD-based netcat version (e.g. Fedora, - openSUSE and Ubuntu) the listening port must be specified without - the -p switch: - - 'nc -u -l -p ' / 'nc -u -l ' or - 'netcat -u -l -p ' / 'netcat -u -l ' - -3) socat - - 'socat udp-recv: -' +The remote host can run either 'netcat -u -l -p ', +'nc -l -u ' or syslogd. Dynamic reconfiguration: ======================== diff --git a/trunk/Documentation/security/Yama.txt b/trunk/Documentation/security/Yama.txt index dd908cf64ecf..e369de2d48cd 100644 --- a/trunk/Documentation/security/Yama.txt +++ b/trunk/Documentation/security/Yama.txt @@ -46,13 +46,14 @@ restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...) so that any otherwise allowed process (even those in external pid namespaces) may attach. -The sysctl settings (writable only with CAP_SYS_PTRACE) are: +These restrictions do not change how ptrace via PTRACE_TRACEME operates. + +The sysctl settings are: 0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other process running under the same uid, as long as it is dumpable (i.e. did not transition uids, start privileged, or have called - prctl(PR_SET_DUMPABLE...) already). Similarly, PTRACE_TRACEME is - unchanged. + prctl(PR_SET_DUMPABLE...) already). 1 - restricted ptrace: a process must have a predefined relationship with the inferior it wants to call PTRACE_ATTACH on. By default, @@ -60,13 +61,12 @@ The sysctl settings (writable only with CAP_SYS_PTRACE) are: classic criteria is also met. To change the relationship, an inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare an allowed debugger PID to call PTRACE_ATTACH on the inferior. - Using PTRACE_TRACEME is unchanged. 2 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace - with PTRACE_ATTACH, or through children calling PTRACE_TRACEME. + with PTRACE_ATTACH. -3 - no attach: no processes may use ptrace with PTRACE_ATTACH nor via - PTRACE_TRACEME. Once set, this sysctl value cannot be changed. +3 - no attach: no processes may use ptrace with PTRACE_ATTACH. Once set, + this sysctl cannot be changed to a lower value. The original children-only logic was based on the restrictions in grsecurity. diff --git a/trunk/Documentation/sysctl/vm.txt b/trunk/Documentation/sysctl/vm.txt index 078701fdbd4d..dcc2a94ae34e 100644 --- a/trunk/Documentation/sysctl/vm.txt +++ b/trunk/Documentation/sysctl/vm.txt @@ -76,8 +76,8 @@ huge pages although processes will also directly compact memory as required. dirty_background_bytes -Contains the amount of dirty memory at which the background kernel -flusher threads will start writeback. +Contains the amount of dirty memory at which the pdflush background writeback +daemon will start writeback. Note: dirty_background_bytes is the counterpart of dirty_background_ratio. Only one of them may be specified at a time. When one sysctl is written it is @@ -89,7 +89,7 @@ other appears as 0 when read. dirty_background_ratio Contains, as a percentage of total system memory, the number of pages at which -the background kernel flusher threads will start writing out dirty data. +the pdflush background writeback daemon will start writing out dirty data. ============================================================== @@ -112,9 +112,9 @@ retained. dirty_expire_centisecs This tunable is used to define when dirty data is old enough to be eligible -for writeout by the kernel flusher threads. It is expressed in 100'ths -of a second. Data which has been dirty in-memory for longer than this -interval will be written out next time a flusher thread wakes up. +for writeout by the pdflush daemons. It is expressed in 100'ths of a second. +Data which has been dirty in-memory for longer than this interval will be +written out next time a pdflush daemon wakes up. ============================================================== @@ -128,7 +128,7 @@ data. dirty_writeback_centisecs -The kernel flusher threads will periodically wake up and write `old' data +The pdflush writeback daemons will periodically wake up and write `old' data out to disk. This tunable expresses the interval between those wakeups, in 100'ths of a second. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index f87589075552..94b823f71e94 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -925,14 +925,14 @@ S: Maintained ARM/NOMADIK ARCHITECTURE M: Alessandro Rubini -M: Linus Walleij +M: Linus Walleij M: STEricsson L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-nomadik/ F: arch/arm/plat-nomadik/ F: drivers/i2c/busses/i2c-nomadik.c -T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT M: Nelson Castillo @@ -1146,7 +1146,7 @@ F: drivers/usb/host/ehci-w90x900.c F: drivers/video/nuc900fb.c ARM/U300 MACHINE SUPPORT -M: Linus Walleij +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: arch/arm/mach-u300/ @@ -1161,20 +1161,15 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git ARM/Ux500 ARM ARCHITECTURE M: Srinidhi Kasagar -M: Linus Walleij +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-ux500/ -F: drivers/clocksource/clksrc-dbx500-prcmu.c F: drivers/dma/ste_dma40* -F: drivers/hwspinlock/u8500_hsem.c F: drivers/mfd/abx500* F: drivers/mfd/ab8500* -F: drivers/mfd/dbx500* -F: drivers/mfd/db8500* -F: drivers/pinctrl/pinctrl-nomadik* +F: drivers/mfd/stmpe* F: drivers/rtc/rtc-ab8500.c -F: drivers/rtc/rtc-pl031.c T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git ARM/VFP SUPPORT @@ -3099,7 +3094,7 @@ F: include/linux/gigaset_dev.h GPIO SUBSYSTEM M: Grant Likely -M: Linus Walleij +M: Linus Walleij S: Maintained T: git git://git.secretlab.ca/git/linux-2.6.git F: Documentation/gpio.txt @@ -5334,15 +5329,14 @@ PIN CONTROL SUBSYSTEM M: Linus Walleij S: Maintained F: drivers/pinctrl/ -F: include/linux/pinctrl/ PIN CONTROLLER - ST SPEAR -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained -F: drivers/pinctrl/spear/ +F: driver/pinctrl/spear/ PKTCDVD DRIVER M: Peter Osterlund diff --git a/trunk/Makefile b/trunk/Makefile index ddf5be952e45..8e4c0a7d402b 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 -PATCHLEVEL = 6 +PATCHLEVEL = 5 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index e91c7cdc6fe5..7980873525b2 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -1151,7 +1151,6 @@ config PLAT_ORION bool select CLKSRC_MMIO select GENERIC_IRQ_CHIP - select IRQ_DOMAIN select COMMON_CLK config PLAT_PXA diff --git a/trunk/arch/arm/boot/dts/armada-xp.dtsi b/trunk/arch/arm/boot/dts/armada-xp.dtsi index 71d6b5d0daf1..e1fa7e6edfe8 100644 --- a/trunk/arch/arm/boot/dts/armada-xp.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp.dtsi @@ -12,7 +12,7 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. * - * Contains definitions specific to the Armada XP SoC that are not + * Contains definitions specific to the Armada 370 SoC that are not * common to all Armada SoCs. */ diff --git a/trunk/arch/arm/boot/dts/imx23.dtsi b/trunk/arch/arm/boot/dts/imx23.dtsi index e6138310e5ce..a874dbfb5ae6 100644 --- a/trunk/arch/arm/boot/dts/imx23.dtsi +++ b/trunk/arch/arm/boot/dts/imx23.dtsi @@ -51,11 +51,11 @@ dma-apbh@80004000 { compatible = "fsl,imx23-dma-apbh"; - reg = <0x80004000 0x2000>; + reg = <0x80004000 2000>; }; ecc@80008000 { - reg = <0x80008000 0x2000>; + reg = <0x80008000 2000>; status = "disabled"; }; @@ -63,7 +63,7 @@ compatible = "fsl,imx23-gpmi-nand"; #address-cells = <1>; #size-cells = <1>; - reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>; + reg = <0x8000c000 2000>, <0x8000a000 2000>; reg-names = "gpmi-nand", "bch"; interrupts = <13>, <56>; interrupt-names = "gpmi-dma", "bch"; @@ -72,14 +72,14 @@ }; ssp0: ssp@80010000 { - reg = <0x80010000 0x2000>; + reg = <0x80010000 2000>; interrupts = <15 14>; fsl,ssp-dma-channel = <1>; status = "disabled"; }; etm@80014000 { - reg = <0x80014000 0x2000>; + reg = <0x80014000 2000>; status = "disabled"; }; @@ -87,7 +87,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx23-pinctrl", "simple-bus"; - reg = <0x80018000 0x2000>; + reg = <0x80018000 2000>; gpio0: gpio@0 { compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; @@ -273,32 +273,32 @@ }; emi@80020000 { - reg = <0x80020000 0x2000>; + reg = <0x80020000 2000>; status = "disabled"; }; dma-apbx@80024000 { compatible = "fsl,imx23-dma-apbx"; - reg = <0x80024000 0x2000>; + reg = <0x80024000 2000>; }; dcp@80028000 { - reg = <0x80028000 0x2000>; + reg = <0x80028000 2000>; status = "disabled"; }; pxp@8002a000 { - reg = <0x8002a000 0x2000>; + reg = <0x8002a000 2000>; status = "disabled"; }; ocotp@8002c000 { - reg = <0x8002c000 0x2000>; + reg = <0x8002c000 2000>; status = "disabled"; }; axi-ahb@8002e000 { - reg = <0x8002e000 0x2000>; + reg = <0x8002e000 2000>; status = "disabled"; }; @@ -310,14 +310,14 @@ }; ssp1: ssp@80034000 { - reg = <0x80034000 0x2000>; + reg = <0x80034000 2000>; interrupts = <2 20>; fsl,ssp-dma-channel = <2>; status = "disabled"; }; tvenc@80038000 { - reg = <0x80038000 0x2000>; + reg = <0x80038000 2000>; status = "disabled"; }; }; @@ -330,37 +330,37 @@ ranges; clkctl@80040000 { - reg = <0x80040000 0x2000>; + reg = <0x80040000 2000>; status = "disabled"; }; saif0: saif@80042000 { - reg = <0x80042000 0x2000>; + reg = <0x80042000 2000>; status = "disabled"; }; power@80044000 { - reg = <0x80044000 0x2000>; + reg = <0x80044000 2000>; status = "disabled"; }; saif1: saif@80046000 { - reg = <0x80046000 0x2000>; + reg = <0x80046000 2000>; status = "disabled"; }; audio-out@80048000 { - reg = <0x80048000 0x2000>; + reg = <0x80048000 2000>; status = "disabled"; }; audio-in@8004c000 { - reg = <0x8004c000 0x2000>; + reg = <0x8004c000 2000>; status = "disabled"; }; lradc@80050000 { - reg = <0x80050000 0x2000>; + reg = <0x80050000 2000>; status = "disabled"; }; @@ -370,26 +370,26 @@ }; i2c@80058000 { - reg = <0x80058000 0x2000>; + reg = <0x80058000 2000>; status = "disabled"; }; rtc@8005c000 { compatible = "fsl,imx23-rtc", "fsl,stmp3xxx-rtc"; - reg = <0x8005c000 0x2000>; + reg = <0x8005c000 2000>; interrupts = <22>; }; pwm: pwm@80064000 { compatible = "fsl,imx23-pwm"; - reg = <0x80064000 0x2000>; + reg = <0x80064000 2000>; #pwm-cells = <2>; fsl,pwm-number = <5>; status = "disabled"; }; timrot@80068000 { - reg = <0x80068000 0x2000>; + reg = <0x80068000 2000>; status = "disabled"; }; @@ -429,7 +429,7 @@ ranges; usbctrl@80080000 { - reg = <0x80080000 0x40000>; + reg = <0x80080000 0x10000>; status = "disabled"; }; }; diff --git a/trunk/arch/arm/boot/dts/imx27-3ds.dts b/trunk/arch/arm/boot/dts/imx27-3ds.dts index 0a8978a40ece..d3f8296e19e0 100644 --- a/trunk/arch/arm/boot/dts/imx27-3ds.dts +++ b/trunk/arch/arm/boot/dts/imx27-3ds.dts @@ -27,7 +27,7 @@ status = "okay"; }; - uart1: serial@1000a000 { + uart@1000a000 { fsl,uart-has-rtscts; status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/imx27.dtsi b/trunk/arch/arm/boot/dts/imx27.dtsi index 5303ab680a34..00bae3aad5ab 100644 --- a/trunk/arch/arm/boot/dts/imx27.dtsi +++ b/trunk/arch/arm/boot/dts/imx27.dtsi @@ -19,12 +19,6 @@ serial3 = &uart4; serial4 = &uart5; serial5 = &uart6; - gpio0 = &gpio1; - gpio1 = &gpio2; - gpio2 = &gpio3; - gpio3 = &gpio4; - gpio4 = &gpio5; - gpio5 = &gpio6; }; avic: avic-interrupt-controller@e0000000 { diff --git a/trunk/arch/arm/boot/dts/imx28.dtsi b/trunk/arch/arm/boot/dts/imx28.dtsi index 3fa6d190fab4..787efac68da8 100644 --- a/trunk/arch/arm/boot/dts/imx28.dtsi +++ b/trunk/arch/arm/boot/dts/imx28.dtsi @@ -57,18 +57,18 @@ }; hsadc@80002000 { - reg = <0x80002000 0x2000>; + reg = <0x80002000 2000>; interrupts = <13 87>; status = "disabled"; }; dma-apbh@80004000 { compatible = "fsl,imx28-dma-apbh"; - reg = <0x80004000 0x2000>; + reg = <0x80004000 2000>; }; perfmon@80006000 { - reg = <0x80006000 0x800>; + reg = <0x80006000 800>; interrupts = <27>; status = "disabled"; }; @@ -77,7 +77,7 @@ compatible = "fsl,imx28-gpmi-nand"; #address-cells = <1>; #size-cells = <1>; - reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>; + reg = <0x8000c000 2000>, <0x8000a000 2000>; reg-names = "gpmi-nand", "bch"; interrupts = <88>, <41>; interrupt-names = "gpmi-dma", "bch"; @@ -86,28 +86,28 @@ }; ssp0: ssp@80010000 { - reg = <0x80010000 0x2000>; + reg = <0x80010000 2000>; interrupts = <96 82>; fsl,ssp-dma-channel = <0>; status = "disabled"; }; ssp1: ssp@80012000 { - reg = <0x80012000 0x2000>; + reg = <0x80012000 2000>; interrupts = <97 83>; fsl,ssp-dma-channel = <1>; status = "disabled"; }; ssp2: ssp@80014000 { - reg = <0x80014000 0x2000>; + reg = <0x80014000 2000>; interrupts = <98 84>; fsl,ssp-dma-channel = <2>; status = "disabled"; }; ssp3: ssp@80016000 { - reg = <0x80016000 0x2000>; + reg = <0x80016000 2000>; interrupts = <99 85>; fsl,ssp-dma-channel = <3>; status = "disabled"; @@ -117,7 +117,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx28-pinctrl", "simple-bus"; - reg = <0x80018000 0x2000>; + reg = <0x80018000 2000>; gpio0: gpio@0 { compatible = "fsl,imx28-gpio", "fsl,mxs-gpio"; @@ -510,96 +510,96 @@ }; digctl@8001c000 { - reg = <0x8001c000 0x2000>; + reg = <0x8001c000 2000>; interrupts = <89>; status = "disabled"; }; etm@80022000 { - reg = <0x80022000 0x2000>; + reg = <0x80022000 2000>; status = "disabled"; }; dma-apbx@80024000 { compatible = "fsl,imx28-dma-apbx"; - reg = <0x80024000 0x2000>; + reg = <0x80024000 2000>; }; dcp@80028000 { - reg = <0x80028000 0x2000>; + reg = <0x80028000 2000>; interrupts = <52 53 54>; status = "disabled"; }; pxp@8002a000 { - reg = <0x8002a000 0x2000>; + reg = <0x8002a000 2000>; interrupts = <39>; status = "disabled"; }; ocotp@8002c000 { - reg = <0x8002c000 0x2000>; + reg = <0x8002c000 2000>; status = "disabled"; }; axi-ahb@8002e000 { - reg = <0x8002e000 0x2000>; + reg = <0x8002e000 2000>; status = "disabled"; }; lcdif@80030000 { compatible = "fsl,imx28-lcdif"; - reg = <0x80030000 0x2000>; + reg = <0x80030000 2000>; interrupts = <38 86>; status = "disabled"; }; can0: can@80032000 { compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan"; - reg = <0x80032000 0x2000>; + reg = <0x80032000 2000>; interrupts = <8>; status = "disabled"; }; can1: can@80034000 { compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan"; - reg = <0x80034000 0x2000>; + reg = <0x80034000 2000>; interrupts = <9>; status = "disabled"; }; simdbg@8003c000 { - reg = <0x8003c000 0x200>; + reg = <0x8003c000 200>; status = "disabled"; }; simgpmisel@8003c200 { - reg = <0x8003c200 0x100>; + reg = <0x8003c200 100>; status = "disabled"; }; simsspsel@8003c300 { - reg = <0x8003c300 0x100>; + reg = <0x8003c300 100>; status = "disabled"; }; simmemsel@8003c400 { - reg = <0x8003c400 0x100>; + reg = <0x8003c400 100>; status = "disabled"; }; gpiomon@8003c500 { - reg = <0x8003c500 0x100>; + reg = <0x8003c500 100>; status = "disabled"; }; simenet@8003c700 { - reg = <0x8003c700 0x100>; + reg = <0x8003c700 100>; status = "disabled"; }; armjtag@8003c800 { - reg = <0x8003c800 0x100>; + reg = <0x8003c800 100>; status = "disabled"; }; }; @@ -612,45 +612,45 @@ ranges; clkctl@80040000 { - reg = <0x80040000 0x2000>; + reg = <0x80040000 2000>; status = "disabled"; }; saif0: saif@80042000 { compatible = "fsl,imx28-saif"; - reg = <0x80042000 0x2000>; + reg = <0x80042000 2000>; interrupts = <59 80>; fsl,saif-dma-channel = <4>; status = "disabled"; }; power@80044000 { - reg = <0x80044000 0x2000>; + reg = <0x80044000 2000>; status = "disabled"; }; saif1: saif@80046000 { compatible = "fsl,imx28-saif"; - reg = <0x80046000 0x2000>; + reg = <0x80046000 2000>; interrupts = <58 81>; fsl,saif-dma-channel = <5>; status = "disabled"; }; lradc@80050000 { - reg = <0x80050000 0x2000>; + reg = <0x80050000 2000>; status = "disabled"; }; spdif@80054000 { - reg = <0x80054000 0x2000>; + reg = <0x80054000 2000>; interrupts = <45 66>; status = "disabled"; }; rtc@80056000 { compatible = "fsl,imx28-rtc", "fsl,stmp3xxx-rtc"; - reg = <0x80056000 0x2000>; + reg = <0x80056000 2000>; interrupts = <29>; }; @@ -658,7 +658,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx28-i2c"; - reg = <0x80058000 0x2000>; + reg = <0x80058000 2000>; interrupts = <111 68>; clock-frequency = <100000>; status = "disabled"; @@ -668,7 +668,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx28-i2c"; - reg = <0x8005a000 0x2000>; + reg = <0x8005a000 2000>; interrupts = <110 69>; clock-frequency = <100000>; status = "disabled"; @@ -676,14 +676,14 @@ pwm: pwm@80064000 { compatible = "fsl,imx28-pwm", "fsl,imx23-pwm"; - reg = <0x80064000 0x2000>; + reg = <0x80064000 2000>; #pwm-cells = <2>; fsl,pwm-number = <8>; status = "disabled"; }; timrot@80068000 { - reg = <0x80068000 0x2000>; + reg = <0x80068000 2000>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/imx51-babbage.dts b/trunk/arch/arm/boot/dts/imx51-babbage.dts index cd86177a3ea2..de065b5976e6 100644 --- a/trunk/arch/arm/boot/dts/imx51-babbage.dts +++ b/trunk/arch/arm/boot/dts/imx51-babbage.dts @@ -53,7 +53,7 @@ spi-max-frequency = <6000000>; reg = <0>; interrupt-parent = <&gpio1>; - interrupts = <8 0x4>; + interrupts = <8>; regulators { sw1_reg: sw1 { diff --git a/trunk/arch/arm/boot/dts/imx51.dtsi b/trunk/arch/arm/boot/dts/imx51.dtsi index aba28dc87fc8..53cbaa3d4f90 100644 --- a/trunk/arch/arm/boot/dts/imx51.dtsi +++ b/trunk/arch/arm/boot/dts/imx51.dtsi @@ -17,10 +17,6 @@ serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; - gpio0 = &gpio1; - gpio1 = &gpio2; - gpio2 = &gpio3; - gpio3 = &gpio4; }; tzic: tz-interrupt-controller@e0000000 { diff --git a/trunk/arch/arm/boot/dts/imx53-ard.dts b/trunk/arch/arm/boot/dts/imx53-ard.dts index da895e93a999..5b8eafcdbeec 100644 --- a/trunk/arch/arm/boot/dts/imx53-ard.dts +++ b/trunk/arch/arm/boot/dts/imx53-ard.dts @@ -64,32 +64,12 @@ reg = <0xf4000000 0x2000000>; phy-mode = "mii"; interrupt-parent = <&gpio2>; - interrupts = <31 0x8>; + interrupts = <31>; reg-io-width = <4>; - /* - * VDD33A and VDDVARIO of LAN9220 are supplied by - * SW4_3V3 of LTC3589. Before the regulator driver - * for this PMIC is available, we use a fixed dummy - * 3V3 regulator to get LAN9220 driver probing work. - */ - vdd33a-supply = <®_3p3v>; - vddvario-supply = <®_3p3v>; smsc,irq-push-pull; }; }; - regulators { - compatible = "simple-bus"; - - reg_3p3v: 3p3v { - compatible = "regulator-fixed"; - regulator-name = "3P3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - }; - gpio-keys { compatible = "gpio-keys"; diff --git a/trunk/arch/arm/boot/dts/imx53.dtsi b/trunk/arch/arm/boot/dts/imx53.dtsi index cd37165edce5..fc79cdc4b4e6 100644 --- a/trunk/arch/arm/boot/dts/imx53.dtsi +++ b/trunk/arch/arm/boot/dts/imx53.dtsi @@ -19,13 +19,6 @@ serial2 = &uart3; serial3 = &uart4; serial4 = &uart5; - gpio0 = &gpio1; - gpio1 = &gpio2; - gpio2 = &gpio3; - gpio3 = &gpio4; - gpio4 = &gpio5; - gpio5 = &gpio6; - gpio6 = &gpio7; }; tzic: tz-interrupt-controller@0fffc000 { diff --git a/trunk/arch/arm/boot/dts/imx6q-sabrelite.dts b/trunk/arch/arm/boot/dts/imx6q-sabrelite.dts index 72f30f3e6171..d42e851ceb97 100644 --- a/trunk/arch/arm/boot/dts/imx6q-sabrelite.dts +++ b/trunk/arch/arm/boot/dts/imx6q-sabrelite.dts @@ -53,7 +53,6 @@ fsl,pins = < 144 0x80000000 /* MX6Q_PAD_EIM_D22__GPIO_3_22 */ 121 0x80000000 /* MX6Q_PAD_EIM_D19__GPIO_3_19 */ - 953 0x80000000 /* MX6Q_PAD_GPIO_0__CCM_CLKO */ >; }; }; diff --git a/trunk/arch/arm/boot/dts/imx6q.dtsi b/trunk/arch/arm/boot/dts/imx6q.dtsi index fd57079f71a9..3d3c64b014e6 100644 --- a/trunk/arch/arm/boot/dts/imx6q.dtsi +++ b/trunk/arch/arm/boot/dts/imx6q.dtsi @@ -19,13 +19,6 @@ serial2 = &uart3; serial3 = &uart4; serial4 = &uart5; - gpio0 = &gpio1; - gpio1 = &gpio2; - gpio2 = &gpio3; - gpio3 = &gpio4; - gpio4 = &gpio5; - gpio5 = &gpio6; - gpio6 = &gpio7; }; cpus { diff --git a/trunk/arch/arm/boot/dts/kirkwood-dns320.dts b/trunk/arch/arm/boot/dts/kirkwood-dns320.dts index 5bb0bf39d3b8..9a33077130e8 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-dns320.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-dns320.dts @@ -1,6 +1,6 @@ /dts-v1/; -/include/ "kirkwood-dnskw.dtsi" +/include/ "kirkwood.dtsi" / { model = "D-Link DNS-320 NAS (Rev A1)"; @@ -15,31 +15,6 @@ bootargs = "console=ttyS0,115200n8 earlyprintk"; }; - gpio-leds { - compatible = "gpio-leds"; - blue-power { - label = "dns320:blue:power"; - gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */ - linux,default-trigger = "default-on"; - }; - blue-usb { - label = "dns320:blue:usb"; - gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */ - }; - orange-l_hdd { - label = "dns320:orange:l_hdd"; - gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */ - }; - orange-r_hdd { - label = "dns320:orange:r_hdd"; - gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */ - }; - orange-usb { - label = "dns320:orange:usb"; - gpios = <&gpio1 3 1>; /* GPIO 35 Active Low */ - }; - }; - ocp@f1000000 { serial@12000 { clock-frequency = <166666667>; @@ -50,5 +25,40 @@ clock-frequency = <166666667>; status = "okay"; }; + + nand@3000000 { + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x100000>; + read-only; + }; + + partition@100000 { + label = "uImage"; + reg = <0x0100000 0x500000>; + }; + + partition@600000 { + label = "ramdisk"; + reg = <0x0600000 0x500000>; + }; + + partition@b00000 { + label = "image"; + reg = <0x0b00000 0x6600000>; + }; + + partition@7100000 { + label = "mini firmware"; + reg = <0x7100000 0xa00000>; + }; + + partition@7b00000 { + label = "config"; + reg = <0x7b00000 0x500000>; + }; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-dns325.dts b/trunk/arch/arm/boot/dts/kirkwood-dns325.dts index d430713ea9b9..16734c1b5dfe 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-dns325.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-dns325.dts @@ -1,6 +1,6 @@ /dts-v1/; -/include/ "kirkwood-dnskw.dtsi" +/include/ "kirkwood.dtsi" / { model = "D-Link DNS-325 NAS (Rev A1)"; @@ -15,43 +15,45 @@ bootargs = "console=ttyS0,115200n8 earlyprintk"; }; - gpio-leds { - compatible = "gpio-leds"; - white-power { - label = "dns325:white:power"; - gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */ - linux,default-trigger = "default-on"; - }; - white-usb { - label = "dns325:white:usb"; - gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */ - }; - red-l_hdd { - label = "dns325:red:l_hdd"; - gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */ - }; - red-r_hdd { - label = "dns325:red:r_hdd"; - gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */ - }; - red-usb { - label = "dns325:red:usb"; - gpios = <&gpio0 29 1>; /* GPIO 29 Active Low */ + ocp@f1000000 { + serial@12000 { + clock-frequency = <200000000>; + status = "okay"; }; - }; - ocp@f1000000 { - i2c@11000 { + nand@3000000 { status = "okay"; - lm75: lm75@48 { - compatible = "national,lm75"; - reg = <0x48>; + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x100000>; + read-only; + }; + + partition@100000 { + label = "uImage"; + reg = <0x0100000 0x500000>; + }; + + partition@600000 { + label = "ramdisk"; + reg = <0x0600000 0x500000>; + }; + + partition@b00000 { + label = "image"; + reg = <0x0b00000 0x6600000>; + }; + + partition@7100000 { + label = "mini firmware"; + reg = <0x7100000 0xa00000>; + }; + + partition@7b00000 { + label = "config"; + reg = <0x7b00000 0x500000>; }; - }; - serial@12000 { - clock-frequency = <200000000>; - status = "okay"; }; }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/trunk/arch/arm/boot/dts/kirkwood-dnskw.dtsi deleted file mode 100644 index 7408655f91b5..000000000000 --- a/trunk/arch/arm/boot/dts/kirkwood-dnskw.dtsi +++ /dev/null @@ -1,69 +0,0 @@ -/include/ "kirkwood.dtsi" - -/ { - model = "D-Link DNS NASes (kirkwood-based)"; - compatible = "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - button@1 { - label = "Power button"; - linux,code = <116>; - gpios = <&gpio1 2 1>; - }; - button@2 { - label = "USB unmount button"; - linux,code = <161>; - gpios = <&gpio1 15 1>; - }; - button@3 { - label = "Reset button"; - linux,code = <0x198>; - gpios = <&gpio1 16 1>; - }; - }; - - ocp@f1000000 { - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - nand@3000000 { - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - read-only; - }; - - partition@100000 { - label = "uImage"; - reg = <0x0100000 0x500000>; - }; - - partition@600000 { - label = "ramdisk"; - reg = <0x0600000 0x500000>; - }; - - partition@b00000 { - label = "image"; - reg = <0x0b00000 0x6600000>; - }; - - partition@7100000 { - label = "mini firmware"; - reg = <0x7100000 0xa00000>; - }; - - partition@7b00000 { - label = "config"; - reg = <0x7b00000 0x500000>; - }; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/kirkwood-dreamplug.dts b/trunk/arch/arm/boot/dts/kirkwood-dreamplug.dts index 26e281fbf6bc..78b0f06a09a2 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -20,55 +20,5 @@ clock-frequency = <200000000>; status = "ok"; }; - - spi@10600 { - status = "okay"; - - m25p40@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "mx25l1606e"; - reg = <0>; - spi-max-frequency = <50000000>; - mode = <0>; - - partition@0 { - reg = <0x0 0x80000>; - label = "u-boot"; - }; - - partition@100000 { - reg = <0x100000 0x10000>; - label = "u-boot env"; - }; - - partition@180000 { - reg = <0x180000 0x10000>; - label = "dtb"; - }; - }; - }; - - sata@80000 { - status = "okay"; - nr-ports = <1>; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - - bluetooth { - label = "dreamplug:blue:bluetooth"; - gpios = <&gpio1 15 1>; - }; - wifi { - label = "dreamplug:green:wifi"; - gpios = <&gpio1 16 1>; - }; - wifi-ap { - label = "dreamplug:green:wifi_ap"; - gpios = <&gpio1 17 1>; - }; }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts b/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts deleted file mode 100644 index 7c8238fbb6f9..000000000000 --- a/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts +++ /dev/null @@ -1,99 +0,0 @@ -/dts-v1/; - -/include/ "kirkwood.dtsi" - -/ { - model = "Seagate GoFlex Net"; - compatible = "seagate,goflexnet", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - memory { - device_type = "memory"; - reg = <0x00000000 0x8000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10"; - }; - - ocp@f1000000 { - serial@12000 { - clock-frequency = <200000000>; - status = "ok"; - }; - - nand@3000000 { - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - read-only; - }; - - partition@100000 { - label = "uImage"; - reg = <0x0100000 0x400000>; - }; - - partition@500000 { - label = "pogoplug"; - reg = <0x0500000 0x2000000>; - }; - - partition@2500000 { - label = "root"; - reg = <0x02500000 0xd800000>; - }; - }; - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - }; - gpio-leds { - compatible = "gpio-leds"; - - health { - label = "status:green:health"; - gpios = <&gpio1 14 1>; - linux,default-trigger = "default-on"; - }; - fault { - label = "status:orange:fault"; - gpios = <&gpio1 15 1>; - }; - left0 { - label = "status:white:left0"; - gpios = <&gpio1 10 0>; - }; - left1 { - label = "status:white:left1"; - gpios = <&gpio1 11 0>; - }; - left2 { - label = "status:white:left2"; - gpios = <&gpio1 12 0>; - }; - left3 { - label = "status:white:left3"; - gpios = <&gpio1 13 0>; - }; - right0 { - label = "status:white:right0"; - gpios = <&gpio1 6 0>; - }; - right1 { - label = "status:white:right1"; - gpios = <&gpio1 7 0>; - }; - right2 { - label = "status:white:right2"; - gpios = <&gpio1 8 0>; - }; - right3 { - label = "status:white:right3"; - gpios = <&gpio1 9 0>; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts b/trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts index 66794ed75ff1..f59dcf6dc45f 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts @@ -21,11 +21,6 @@ status = "okay"; }; - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - nand@3000000 { status = "okay"; @@ -46,37 +41,4 @@ }; }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - button@1 { - label = "USB Copy"; - linux,code = <133>; - gpios = <&gpio0 29 1>; - }; - button@2 { - label = "Reset"; - linux,code = <0x198>; - gpios = <&gpio0 28 1>; - }; - }; - gpio-leds { - compatible = "gpio-leds"; - - green-os { - label = "ib62x0:green:os"; - gpios = <&gpio0 25 0>; - linux,default-trigger = "default-on"; - }; - red-os { - label = "ib62x0:red:os"; - gpios = <&gpio0 22 0>; - }; - usb-copy { - label = "ib62x0:red:usb_copy"; - gpios = <&gpio0 27 0>; - }; - }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-iconnect.dts b/trunk/arch/arm/boot/dts/kirkwood-iconnect.dts index 52d947045106..026a1f82d813 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -18,51 +18,9 @@ }; ocp@f1000000 { - i2c@11000 { - status = "okay"; - - lm63: lm63@4c { - compatible = "national,lm63"; - reg = <0x4c>; - }; - }; serial@12000 { clock-frequency = <200000000>; status = "ok"; }; }; - gpio-leds { - compatible = "gpio-leds"; - - led-level { - label = "led_level"; - gpios = <&gpio1 9 0>; - linux,default-trigger = "default-on"; - }; - power-blue { - label = "power:blue"; - gpios = <&gpio1 11 0>; - linux,default-trigger = "timer"; - }; - usb1 { - label = "usb1:blue"; - gpios = <&gpio1 12 0>; - }; - usb2 { - label = "usb2:blue"; - gpios = <&gpio1 13 0>; - }; - usb3 { - label = "usb3:blue"; - gpios = <&gpio1 14 0>; - }; - usb4 { - label = "usb4:blue"; - gpios = <&gpio1 15 0>; - }; - otb { - label = "otb:blue"; - gpios = <&gpio1 16 0>; - }; - }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts b/trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts deleted file mode 100644 index 9510c9ea666c..000000000000 --- a/trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts +++ /dev/null @@ -1,20 +0,0 @@ -/dts-v1/; - -/include/ "kirkwood-lsxl.dtsi" - -/ { - model = "Buffalo Linkstation LS-CHLv2"; - compatible = "buffalo,lschlv2", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - memory { - device_type = "memory"; - reg = <0x00000000 0x4000000>; - }; - - ocp@f1000000 { - serial@12000 { - clock-frequency = <166666667>; - status = "okay"; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/kirkwood-lsxhl.dts b/trunk/arch/arm/boot/dts/kirkwood-lsxhl.dts deleted file mode 100644 index 739019c4cba9..000000000000 --- a/trunk/arch/arm/boot/dts/kirkwood-lsxhl.dts +++ /dev/null @@ -1,20 +0,0 @@ -/dts-v1/; - -/include/ "kirkwood-lsxl.dtsi" - -/ { - model = "Buffalo Linkstation LS-XHL"; - compatible = "buffalo,lsxhl", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - memory { - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - ocp@f1000000 { - serial@12000 { - clock-frequency = <200000000>; - status = "okay"; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/trunk/arch/arm/boot/dts/kirkwood-lsxl.dtsi deleted file mode 100644 index 8ac51c08269d..000000000000 --- a/trunk/arch/arm/boot/dts/kirkwood-lsxl.dtsi +++ /dev/null @@ -1,95 +0,0 @@ -/include/ "kirkwood.dtsi" - -/ { - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - }; - - ocp@f1000000 { - sata@80000 { - status = "okay"; - nr-ports = <1>; - }; - - spi@10600 { - status = "okay"; - - m25p40@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "m25p40"; - reg = <0>; - spi-max-frequency = <25000000>; - mode = <0>; - - partition@0 { - reg = <0x0 0x60000>; - label = "uboot"; - read-only; - }; - - partition@60000 { - reg = <0x60000 0x10000>; - label = "dtb"; - read-only; - }; - - partition@70000 { - reg = <0x70000 0x10000>; - label = "uboot_env"; - }; - }; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - button@1 { - label = "Function Button"; - linux,code = <132>; - gpios = <&gpio1 9 1>; - }; - button@2 { - label = "Power-on Switch"; - linux,code = <116>; - gpios = <&gpio1 10 1>; - }; - button@3 { - label = "Power-auto Switch"; - linux,code = <142>; - gpios = <&gpio1 11 1>; - }; - }; - - gpio_leds { - compatible = "gpio-leds"; - - led@1 { - label = "lschlv2:blue:func"; - gpios = <&gpio1 4 1>; - }; - - led@2 { - label = "lschlv2:red:alarm"; - gpios = <&gpio1 5 1>; - }; - - led@3 { - label = "lschlv2:amber:info"; - gpios = <&gpio1 6 1>; - }; - - led@4 { - label = "lschlv2:blue:power"; - gpios = <&gpio1 7 1>; - linux,default-trigger = "default-on"; - }; - - led@5 { - label = "lschlv2:red:func"; - gpios = <&gpio1 16 1>; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/trunk/arch/arm/boot/dts/kirkwood-ts219-6281.dts deleted file mode 100644 index ccbf32757800..000000000000 --- a/trunk/arch/arm/boot/dts/kirkwood-ts219-6281.dts +++ /dev/null @@ -1,21 +0,0 @@ -/dts-v1/; - -/include/ "kirkwood-ts219.dtsi" - -/ { - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - button@1 { - label = "USB Copy"; - linux,code = <133>; - gpios = <&gpio0 15 1>; - }; - button@2 { - label = "Reset"; - linux,code = <0x198>; - gpios = <&gpio0 16 1>; - }; - }; -}; \ No newline at end of file diff --git a/trunk/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/trunk/arch/arm/boot/dts/kirkwood-ts219-6282.dts deleted file mode 100644 index fbe9932161a1..000000000000 --- a/trunk/arch/arm/boot/dts/kirkwood-ts219-6282.dts +++ /dev/null @@ -1,21 +0,0 @@ -/dts-v1/; - -/include/ "kirkwood-ts219.dtsi" - -/ { - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - button@1 { - label = "USB Copy"; - linux,code = <133>; - gpios = <&gpio1 11 1>; - }; - button@2 { - label = "Reset"; - linux,code = <0x198>; - gpios = <&gpio1 5 1>; - }; - }; -}; \ No newline at end of file diff --git a/trunk/arch/arm/boot/dts/kirkwood-ts219.dtsi b/trunk/arch/arm/boot/dts/kirkwood-ts219.dtsi deleted file mode 100644 index 64ea27cb3298..000000000000 --- a/trunk/arch/arm/boot/dts/kirkwood-ts219.dtsi +++ /dev/null @@ -1,78 +0,0 @@ -/include/ "kirkwood.dtsi" - -/ { - model = "QNAP TS219 family"; - compatible = "qnap,ts219", "marvell,kirkwood"; - - memory { - device_type = "memory"; - reg = <0x00000000 0x20000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8"; - }; - - ocp@f1000000 { - i2c@11000 { - status = "okay"; - clock-frequency = <400000>; - - s35390a: s35390a@30 { - compatible = "s35390a"; - reg = <0x30>; - }; - }; - serial@12000 { - clock-frequency = <200000000>; - status = "okay"; - }; - serial@12100 { - clock-frequency = <200000000>; - status = "okay"; - }; - spi@10600 { - status = "okay"; - - m25p128@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "m25p128"; - reg = <0>; - spi-max-frequency = <20000000>; - mode = <0>; - - partition@0000000 { - reg = <0x00000000 0x00080000>; - label = "U-Boot"; - }; - - partition@00200000 { - reg = <0x00200000 0x00200000>; - label = "Kernel"; - }; - - partition@00400000 { - reg = <0x00400000 0x00900000>; - label = "RootFS1"; - }; - partition@00d00000 { - reg = <0x00d00000 0x00300000>; - label = "RootFS2"; - }; - partition@00040000 { - reg = <0x00080000 0x00040000>; - label = "U-Boot Config"; - }; - partition@000c0000 { - reg = <0x000c0000 0x00140000>; - label = "NAS Config"; - }; - }; - }; - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/kirkwood.dtsi b/trunk/arch/arm/boot/dts/kirkwood.dtsi index cef9616f330a..f95dbc190ab6 100644 --- a/trunk/arch/arm/boot/dts/kirkwood.dtsi +++ b/trunk/arch/arm/boot/dts/kirkwood.dtsi @@ -2,15 +2,6 @@ / { compatible = "marvell,kirkwood"; - interrupt-parent = <&intc>; - - intc: interrupt-controller { - compatible = "marvell,orion-intc", "marvell,intc"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0xf1020204 0x04>, - <0xf1020214 0x04>; - }; ocp@f1000000 { compatible = "simple-bus"; @@ -18,24 +9,6 @@ #address-cells = <1>; #size-cells = <1>; - gpio0: gpio@10100 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0x10100 0x40>; - ngpio = <32>; - interrupts = <35>, <36>, <37>, <38>; - }; - - gpio1: gpio@10140 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0x10140 0x40>; - ngpio = <18>; - interrupts = <39>, <40>, <41>; - }; - serial@12000 { compatible = "ns16550a"; reg = <0x12000 0x100>; @@ -60,29 +33,6 @@ interrupts = <53>; }; - spi@10600 { - compatible = "marvell,orion-spi"; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - interrupts = <23>; - reg = <0x10600 0x28>; - status = "disabled"; - }; - - wdt@20300 { - compatible = "marvell,orion-wdt"; - reg = <0x20300 0x28>; - status = "okay"; - }; - - sata@80000 { - compatible = "marvell,orion-sata"; - reg = <0x80000 0x5000>; - interrupts = <21>; - status = "disabled"; - }; - nand@3000000 { #address-cells = <1>; #size-cells = <1>; @@ -95,15 +45,5 @@ /* set partition map and/or chip-delay in board dts */ status = "disabled"; }; - - i2c@11000 { - compatible = "marvell,mv64xxx-i2c"; - reg = <0x11000 0x20>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <29>; - clock-frequency = <100000>; - status = "disabled"; - }; }; }; diff --git a/trunk/arch/arm/configs/imx_v6_v7_defconfig b/trunk/arch/arm/configs/imx_v6_v7_defconfig index 3c9f32f9b6b4..f725b9637b33 100644 --- a/trunk/arch/arm/configs/imx_v6_v7_defconfig +++ b/trunk/arch/arm/configs/imx_v6_v7_defconfig @@ -192,7 +192,6 @@ CONFIG_RTC_DRV_MC13XXX=y CONFIG_RTC_DRV_MXC=y CONFIG_DMADEVICES=y CONFIG_IMX_SDMA=y -CONFIG_MXS_DMA=y CONFIG_COMMON_CLK_DEBUG=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT2_FS=y diff --git a/trunk/arch/arm/configs/mxs_defconfig b/trunk/arch/arm/configs/mxs_defconfig index 4edcfb4e4dee..ccdb6357fb74 100644 --- a/trunk/arch/arm/configs/mxs_defconfig +++ b/trunk/arch/arm/configs/mxs_defconfig @@ -34,6 +34,7 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_AEABI=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 CONFIG_AUTO_ZRELADDR=y CONFIG_FPE_NWFPE=y CONFIG_NET=y diff --git a/trunk/arch/arm/configs/tct_hammer_defconfig b/trunk/arch/arm/configs/tct_hammer_defconfig index 71277a1591ba..1d24f8458bef 100644 --- a/trunk/arch/arm/configs/tct_hammer_defconfig +++ b/trunk/arch/arm/configs/tct_hammer_defconfig @@ -7,7 +7,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y # CONFIG_KALLSYMS is not set -# CONFIG_BUGVERBOSE is not set +# CONFIG_BUG is not set # CONFIG_ELF_CORE is not set # CONFIG_SHMEM is not set CONFIG_SLOB=y diff --git a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c index f6b9fc70161b..5de69f2fcca9 100644 --- a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c @@ -162,6 +162,38 @@ static void __init davinci_ntosd2_map_io(void) dm644x_init(); } +/* + I2C initialization +*/ +static struct davinci_i2c_platform_data ntosd2_i2c_pdata = { + .bus_freq = 20 /* kHz */, + .bus_delay = 100 /* usec */, +}; + +static struct i2c_board_info __initdata ntosd2_i2c_info[] = { +}; + +static int ntosd2_init_i2c(void) +{ + int status; + + davinci_init_i2c(&ntosd2_i2c_pdata); + status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type); + if (status == 0) { + status = gpio_direction_input(NTOSD2_MSP430_IRQ); + if (status == 0) { + status = gpio_to_irq(NTOSD2_MSP430_IRQ); + if (status > 0) { + ntosd2_i2c_info[0].irq = status; + i2c_register_board_info(1, + ntosd2_i2c_info, + ARRAY_SIZE(ntosd2_i2c_info)); + } + } + } + return status; +} + static struct davinci_mmc_config davinci_ntosd2_mmc_config = { .wires = 4, .version = MMC_CTLR_VERSION_1 @@ -186,6 +218,7 @@ static __init void davinci_ntosd2_init(void) { struct clk *aemif_clk; struct davinci_soc_info *soc_info = &davinci_soc_info; + int status; aemif_clk = clk_get(NULL, "aemif"); clk_enable(aemif_clk); @@ -209,6 +242,12 @@ static __init void davinci_ntosd2_init(void) platform_add_devices(davinci_ntosd2_devices, ARRAY_SIZE(davinci_ntosd2_devices)); + /* Initialize I2C interface specific for this board */ + status = ntosd2_init_i2c(); + if (status < 0) + pr_warning("davinci_ntosd2_init: msp430 irq setup failed:" + " %d\n", status); + davinci_serial_init(&uart_config); dm644x_init_asp(&dm644x_ntosd2_snd_data); diff --git a/trunk/arch/arm/mach-dove/irq.c b/trunk/arch/arm/mach-dove/irq.c index 9bc97a5baaa8..f07fd16e0c9b 100644 --- a/trunk/arch/arm/mach-dove/irq.c +++ b/trunk/arch/arm/mach-dove/irq.c @@ -20,6 +20,22 @@ #include #include "common.h" +static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + int irqoff; + BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO); + + irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 : + 3 + irq - IRQ_DOVE_GPIO_24_31; + + orion_gpio_irq_handler(irqoff << 3); + if (irq == IRQ_DOVE_HIGH_GPIO) { + orion_gpio_irq_handler(40); + orion_gpio_irq_handler(48); + orion_gpio_irq_handler(56); + } +} + static void pmu_irq_mask(struct irq_data *d) { int pin = irq_to_pmu(d->irq); @@ -74,27 +90,6 @@ static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc) } } -static int __initdata gpio0_irqs[4] = { - IRQ_DOVE_GPIO_0_7, - IRQ_DOVE_GPIO_8_15, - IRQ_DOVE_GPIO_16_23, - IRQ_DOVE_GPIO_24_31, -}; - -static int __initdata gpio1_irqs[4] = { - IRQ_DOVE_HIGH_GPIO, - 0, - 0, - 0, -}; - -static int __initdata gpio2_irqs[4] = { - 0, - 0, - 0, - 0, -}; - void __init dove_init_irq(void) { int i; @@ -105,14 +100,19 @@ void __init dove_init_irq(void) /* * Initialize gpiolib for GPIOs 0-71. */ - orion_gpio_init(NULL, 0, 32, (void __iomem *)DOVE_GPIO_LO_VIRT_BASE, 0, - IRQ_DOVE_GPIO_START, gpio0_irqs); - - orion_gpio_init(NULL, 32, 32, (void __iomem *)DOVE_GPIO_HI_VIRT_BASE, 0, - IRQ_DOVE_GPIO_START + 32, gpio1_irqs); - - orion_gpio_init(NULL, 64, 8, (void __iomem *)DOVE_GPIO2_VIRT_BASE, 0, - IRQ_DOVE_GPIO_START + 64, gpio2_irqs); + orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0, + IRQ_DOVE_GPIO_START); + irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler); + irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler); + irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler); + irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler); + + orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0, + IRQ_DOVE_GPIO_START + 32); + irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler); + + orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0, + IRQ_DOVE_GPIO_START + 64); /* * Mask and clear PMU interrupts diff --git a/trunk/arch/arm/mach-exynos/pm_domains.c b/trunk/arch/arm/mach-exynos/pm_domains.c index c0bc83a7663e..373c3c00d24c 100644 --- a/trunk/arch/arm/mach-exynos/pm_domains.c +++ b/trunk/arch/arm/mach-exynos/pm_domains.c @@ -115,7 +115,7 @@ static __init int exynos_pm_dt_parse_domains(void) } #endif /* CONFIG_OF */ -static __init __maybe_unused void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, +static __init void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd) { if (pdev->dev.bus) { diff --git a/trunk/arch/arm/mach-imx/clk-imx27.c b/trunk/arch/arm/mach-imx/clk-imx27.c index f69ca4680049..7aa6313fb167 100644 --- a/trunk/arch/arm/mach-imx/clk-imx27.c +++ b/trunk/arch/arm/mach-imx/clk-imx27.c @@ -223,7 +223,7 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0"); clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0"); clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0"); - clk_register_clkdev(clk[csi_ahb_gate], "ahb", "mx2-camera.0"); + clk_register_clkdev(clk[csi_ahb_gate], NULL, "mx2-camera.0"); clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc"); @@ -250,10 +250,8 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1"); clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0"); clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad"); - clk_register_clkdev(clk[emma_ahb_gate], "emma-ahb", "mx2-camera.0"); - clk_register_clkdev(clk[emma_ipg_gate], "emma-ipg", "mx2-camera.0"); - clk_register_clkdev(clk[emma_ahb_gate], "ahb", "m2m-emmaprp.0"); - clk_register_clkdev(clk[emma_ipg_gate], "ipg", "m2m-emmaprp.0"); + clk_register_clkdev(clk[emma_ahb_gate], "ahb", "imx-emma"); + clk_register_clkdev(clk[emma_ipg_gate], "ipg", "imx-emma"); clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL); clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL); clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL); diff --git a/trunk/arch/arm/mach-imx/clk-imx31.c b/trunk/arch/arm/mach-imx/clk-imx31.c index 1253af2d9971..8e19e70f90f9 100644 --- a/trunk/arch/arm/mach-imx/clk-imx31.c +++ b/trunk/arch/arm/mach-imx/clk-imx31.c @@ -130,7 +130,7 @@ int __init mx31_clocks_init(unsigned long fref) clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0"); clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); - clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad"); + clk_register_clkdev(clk[kpp_gate], "kpp", NULL); clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0"); clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0"); clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); diff --git a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c index 4bdcaa97bd98..f6086693ebd2 100644 --- a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c @@ -303,7 +303,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk_prepare_enable(clk[aips_tz2]); /* fec */ clk_prepare_enable(clk[spba]); clk_prepare_enable(clk[emi_fast_gate]); /* fec */ - clk_prepare_enable(clk[emi_slow_gate]); /* eim */ clk_prepare_enable(clk[tmax1]); clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */ clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */ diff --git a/trunk/arch/arm/mach-integrator/core.c b/trunk/arch/arm/mach-integrator/core.c index 3fa6c51390da..ebf680bebdf2 100644 --- a/trunk/arch/arm/mach-integrator/core.c +++ b/trunk/arch/arm/mach-integrator/core.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-integrator/integrator_ap.c b/trunk/arch/arm/mach-integrator/integrator_ap.c index 3b2267529f5e..7b1055c8e0b9 100644 --- a/trunk/arch/arm/mach-integrator/integrator_ap.c +++ b/trunk/arch/arm/mach-integrator/integrator_ap.c @@ -456,7 +456,7 @@ static void __init ap_init_timer(void) clk = clk_get_sys("ap_timer", NULL); BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); + clk_enable(clk); rate = clk_get_rate(clk); writel(0, TIMER0_VA_BASE + TIMER_CTRL); diff --git a/trunk/arch/arm/mach-kirkwood/Kconfig b/trunk/arch/arm/mach-kirkwood/Kconfig index ca5c15a4e626..199764fe0fb0 100644 --- a/trunk/arch/arm/mach-kirkwood/Kconfig +++ b/trunk/arch/arm/mach-kirkwood/Kconfig @@ -80,35 +80,6 @@ config MACH_IB62X0_DT RaidSonic IB-NAS6210 & IB-NAS6220 devices, using Flattened Device Tree. -config MACH_TS219_DT - bool "Device Tree for QNAP TS-11X, TS-21X NAS" - select ARCH_KIRKWOOD_DT - select ARM_APPENDED_DTB - select ARM_ATAG_DTB_COMPAT - help - Say 'Y' here if you want your kernel to support the QNAP - TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and - TS-219P+ Turbo NAS devices using Fattened Device Tree. - There are two different Device Tree descriptions, depending - on if the device is based on an if the board uses the MV6281 - or MV6282. If you have the wrong one, the buttons will not - work. - -config MACH_GOFLEXNET_DT - bool "Seagate GoFlex Net (Flattened Device Tree)" - select ARCH_KIRKWOOD_DT - help - Say 'Y' here if you want your kernel to support the - Seagate GoFlex Net (Flattened Device Tree). - -config MACH_LSXL_DT - bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)" - select ARCH_KIRKWOOD_DT - help - Say 'Y' here if you want your kernel to support the - Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using - Flattened Device Tree. - config MACH_TS219 bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" help diff --git a/trunk/arch/arm/mach-kirkwood/Makefile b/trunk/arch/arm/mach-kirkwood/Makefile index 055c85a1cc46..d2b05907b10e 100644 --- a/trunk/arch/arm/mach-kirkwood/Makefile +++ b/trunk/arch/arm/mach-kirkwood/Makefile @@ -25,6 +25,3 @@ obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o -obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o -obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o -obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o diff --git a/trunk/arch/arm/mach-kirkwood/Makefile.boot b/trunk/arch/arm/mach-kirkwood/Makefile.boot index a5717558ee89..02edbdf5b065 100644 --- a/trunk/arch/arm/mach-kirkwood/Makefile.boot +++ b/trunk/arch/arm/mach-kirkwood/Makefile.boot @@ -7,7 +7,3 @@ dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns320.dtb dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb -dtb-$(CONFIG_MACH_TS219_DT) += kirkwood-qnap-ts219.dtb -dtb-$(CONFIG_MACH_GOFLEXNET_DT) += kirkwood-goflexnet.dtb -dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb -dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb diff --git a/trunk/arch/arm/mach-kirkwood/board-dnskw.c b/trunk/arch/arm/mach-kirkwood/board-dnskw.c index 4ab35065a144..58c2d68f9443 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dnskw.c +++ b/trunk/arch/arm/mach-kirkwood/board-dnskw.c @@ -14,11 +14,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -33,6 +35,10 @@ static struct mv643xx_eth_platform_data dnskw_ge00_data = { .phy_addr = MV643XX_ETH_PHY_ADDR(8), }; +static struct mv_sata_platform_data dnskw_sata_data = { + .n_ports = 2, +}; + static unsigned int dnskw_mpp_config[] __initdata = { MPP13_UART1_TXD, /* Custom ... */ MPP14_UART1_RXD, /* ... Controller (DNS-320 only) */ @@ -67,6 +73,132 @@ static unsigned int dnskw_mpp_config[] __initdata = { 0 }; +static struct gpio_led dns325_led_pins[] = { + { + .name = "dns325:white:power", + .gpio = 26, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "dns325:white:usb", + .gpio = 43, + .active_low = 1, + }, + { + .name = "dns325:red:l_hdd", + .gpio = 28, + .active_low = 1, + }, + { + .name = "dns325:red:r_hdd", + .gpio = 27, + .active_low = 1, + }, + { + .name = "dns325:red:usb", + .gpio = 29, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data dns325_led_data = { + .num_leds = ARRAY_SIZE(dns325_led_pins), + .leds = dns325_led_pins, +}; + +static struct platform_device dns325_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &dns325_led_data, + }, +}; + +static struct gpio_led dns320_led_pins[] = { + { + .name = "dns320:blue:power", + .gpio = 26, + .active_low = 1, + .default_trigger = "default-on", + }, + { + .name = "dns320:blue:usb", + .gpio = 43, + .active_low = 1, + }, + { + .name = "dns320:orange:l_hdd", + .gpio = 28, + .active_low = 1, + }, + { + .name = "dns320:orange:r_hdd", + .gpio = 27, + .active_low = 1, + }, + { + .name = "dns320:orange:usb", + .gpio = 35, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data dns320_led_data = { + .num_leds = ARRAY_SIZE(dns320_led_pins), + .leds = dns320_led_pins, +}; + +static struct platform_device dns320_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &dns320_led_data, + }, +}; + +static struct i2c_board_info dns325_i2c_board_info[] __initdata = { + { + I2C_BOARD_INFO("lm75", 0x48), + }, + /* Something at 0x0c also */ +}; + +static struct gpio_keys_button dnskw_button_pins[] = { + { + .code = KEY_POWER, + .gpio = 34, + .desc = "Power button", + .active_low = 1, + }, + { + .code = KEY_EJECTCD, + .gpio = 47, + .desc = "USB unmount button", + .active_low = 1, + }, + { + .code = KEY_RESTART, + .gpio = 48, + .desc = "Reset button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data dnskw_button_data = { + .buttons = dnskw_button_pins, + .nbuttons = ARRAY_SIZE(dnskw_button_pins), +}; + +static struct platform_device dnskw_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &dnskw_button_data, + } +}; + /* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */ static struct gpio_fan_speed dnskw_fan_speed[] = { { 0, 0 }, @@ -113,9 +245,20 @@ void __init dnskw_init(void) kirkwood_ehci_init(); kirkwood_ge00_init(&dnskw_ge00_data); + kirkwood_sata_init(&dnskw_sata_data); + kirkwood_i2c_init(); + platform_device_register(&dnskw_button_device); platform_device_register(&dnskw_fan_device); + if (of_machine_is_compatible("dlink,dns-325")) { + i2c_register_board_info(0, dns325_i2c_board_info, + ARRAY_SIZE(dns325_i2c_board_info)); + platform_device_register(&dns325_led_device); + + } else if (of_machine_is_compatible("dlink,dns-320")) + platform_device_register(&dns320_led_device); + /* Register power-off GPIO. */ if (gpio_request(36, "dnskw:power:off") == 0 && gpio_direction_output(36, 0) == 0) diff --git a/trunk/arch/arm/mach-kirkwood/board-dreamplug.c b/trunk/arch/arm/mach-kirkwood/board-dreamplug.c index aeb234d0d0e3..55e357ab2923 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dreamplug.c +++ b/trunk/arch/arm/mach-kirkwood/board-dreamplug.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +36,42 @@ #include "common.h" #include "mpp.h" +struct mtd_partition dreamplug_partitions[] = { + { + .name = "u-boot", + .size = SZ_512K, + .offset = 0, + }, + { + .name = "u-boot env", + .size = SZ_64K, + .offset = SZ_512K + SZ_512K, + }, + { + .name = "dtb", + .size = SZ_64K, + .offset = SZ_512K + SZ_512K + SZ_512K, + }, +}; + +static const struct flash_platform_data dreamplug_spi_slave_data = { + .type = "mx25l1606e", + .name = "spi_flash", + .parts = dreamplug_partitions, + .nr_parts = ARRAY_SIZE(dreamplug_partitions), +}; + +static struct spi_board_info __initdata dreamplug_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &dreamplug_spi_slave_data, + .irq = -1, + .max_speed_hz = 50000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + static struct mv643xx_eth_platform_data dreamplug_ge00_data = { .phy_addr = MV643XX_ETH_PHY_ADDR(0), }; @@ -42,10 +80,45 @@ static struct mv643xx_eth_platform_data dreamplug_ge01_data = { .phy_addr = MV643XX_ETH_PHY_ADDR(1), }; +static struct mv_sata_platform_data dreamplug_sata_data = { + .n_ports = 1, +}; + static struct mvsdio_platform_data dreamplug_mvsdio_data = { /* unfortunately the CD signal has not been connected */ }; +static struct gpio_led dreamplug_led_pins[] = { + { + .name = "dreamplug:blue:bluetooth", + .gpio = 47, + .active_low = 1, + }, + { + .name = "dreamplug:green:wifi", + .gpio = 48, + .active_low = 1, + }, + { + .name = "dreamplug:green:wifi_ap", + .gpio = 49, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data dreamplug_led_data = { + .leds = dreamplug_led_pins, + .num_leds = ARRAY_SIZE(dreamplug_led_pins), +}; + +static struct platform_device dreamplug_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &dreamplug_led_data, + } +}; + static unsigned int dreamplug_mpp_config[] __initdata = { MPP0_SPI_SCn, MPP1_SPI_MOSI, @@ -64,8 +137,15 @@ void __init dreamplug_init(void) */ kirkwood_mpp_conf(dreamplug_mpp_config); + spi_register_board_info(dreamplug_spi_slave_info, + ARRAY_SIZE(dreamplug_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_ehci_init(); kirkwood_ge00_init(&dreamplug_ge00_data); kirkwood_ge01_init(&dreamplug_ge01_data); + kirkwood_sata_init(&dreamplug_sata_data); kirkwood_sdio_init(&dreamplug_mvsdio_data); + + platform_device_register(&dreamplug_leds); } diff --git a/trunk/arch/arm/mach-kirkwood/board-dt.c b/trunk/arch/arm/mach-kirkwood/board-dt.c index e4eb450de301..edc3f8a9d45e 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dt.c +++ b/trunk/arch/arm/mach-kirkwood/board-dt.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "common.h" static struct of_device_id kirkwood_dt_match_table[] __initdata = { @@ -26,16 +25,6 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = { { } }; -struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = { - OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL), - OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0", - NULL), - OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL), - OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL), - OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL), - {}, -}; - static void __init kirkwood_dt_init(void) { pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); @@ -58,6 +47,7 @@ static void __init kirkwood_dt_init(void) kirkwood_clk_init(); /* internal devices that every board has */ + kirkwood_wdt_init(); kirkwood_xor0_init(); kirkwood_xor1_init(); kirkwood_crypto_init(); @@ -78,17 +68,7 @@ static void __init kirkwood_dt_init(void) if (of_machine_is_compatible("raidsonic,ib-nas62x0")) ib62x0_init(); - if (of_machine_is_compatible("qnap,ts219")) - qnap_dt_ts219_init(); - - if (of_machine_is_compatible("seagate,goflexnet")) - goflexnet_init(); - - if (of_machine_is_compatible("buffalo,lsxl")) - lsxl_init(); - - of_platform_populate(NULL, kirkwood_dt_match_table, - kirkwood_auxdata_lookup, NULL); + of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL); } static const char *kirkwood_dt_board_compat[] = { @@ -97,9 +77,6 @@ static const char *kirkwood_dt_board_compat[] = { "dlink,dns-325", "iom,iconnect", "raidsonic,ib-nas62x0", - "qnap,ts219", - "seagate,goflexnet", - "buffalo,lsxl", NULL }; @@ -107,7 +84,7 @@ DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)") /* Maintainer: Jason Cooper */ .map_io = kirkwood_map_io, .init_early = kirkwood_init_early, - .init_irq = orion_dt_init_irq, + .init_irq = kirkwood_init_irq, .timer = &kirkwood_timer, .init_machine = kirkwood_dt_init, .restart = kirkwood_restart, diff --git a/trunk/arch/arm/mach-kirkwood/board-goflexnet.c b/trunk/arch/arm/mach-kirkwood/board-goflexnet.c deleted file mode 100644 index 413e2c8ef5fe..000000000000 --- a/trunk/arch/arm/mach-kirkwood/board-goflexnet.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2012 (C), Jason Cooper - * - * arch/arm/mach-kirkwood/board-goflexnet.c - * - * Seagate GoFlext Net Board Init for drivers not converted to - * flattened device tree yet. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - * - * Copied and modified for Seagate GoFlex Net support by - * Joshua Coombs based on ArchLinux ARM's - * GoFlex kernel patches. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "mpp.h" - -static struct mv643xx_eth_platform_data goflexnet_ge00_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(0), -}; - -static unsigned int goflexnet_mpp_config[] __initdata = { - MPP29_GPIO, /* USB Power Enable */ - MPP47_GPIO, /* LED Orange */ - MPP46_GPIO, /* LED Green */ - MPP45_GPIO, /* LED Left Capacity 3 */ - MPP44_GPIO, /* LED Left Capacity 2 */ - MPP43_GPIO, /* LED Left Capacity 1 */ - MPP42_GPIO, /* LED Left Capacity 0 */ - MPP41_GPIO, /* LED Right Capacity 3 */ - MPP40_GPIO, /* LED Right Capacity 2 */ - MPP39_GPIO, /* LED Right Capacity 1 */ - MPP38_GPIO, /* LED Right Capacity 0 */ - 0 -}; - -void __init goflexnet_init(void) -{ - /* - * Basic setup. Needs to be called early. - */ - kirkwood_mpp_conf(goflexnet_mpp_config); - - if (gpio_request(29, "USB Power Enable") != 0 || - gpio_direction_output(29, 1) != 0) - pr_err("can't setup GPIO 29 (USB Power Enable)\n"); - kirkwood_ehci_init(); - - kirkwood_ge00_init(&goflexnet_ge00_data); -} diff --git a/trunk/arch/arm/mach-kirkwood/board-ib62x0.c b/trunk/arch/arm/mach-kirkwood/board-ib62x0.c index cfc47f80e734..eddf1df8891f 100644 --- a/trunk/arch/arm/mach-kirkwood/board-ib62x0.c +++ b/trunk/arch/arm/mach-kirkwood/board-ib62x0.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -31,6 +33,10 @@ static struct mv643xx_eth_platform_data ib62x0_ge00_data = { .phy_addr = MV643XX_ETH_PHY_ADDR(8), }; +static struct mv_sata_platform_data ib62x0_sata_data = { + .n_ports = 2, +}; + static unsigned int ib62x0_mpp_config[] __initdata = { MPP0_NF_IO2, MPP1_NF_IO3, @@ -49,6 +55,69 @@ static unsigned int ib62x0_mpp_config[] __initdata = { 0 }; +static struct gpio_led ib62x0_led_pins[] = { + { + .name = "ib62x0:green:os", + .default_trigger = "default-on", + .gpio = 25, + .active_low = 0, + }, + { + .name = "ib62x0:red:os", + .default_trigger = "none", + .gpio = 22, + .active_low = 0, + }, + { + .name = "ib62x0:red:usb_copy", + .default_trigger = "none", + .gpio = 27, + .active_low = 0, + }, +}; + +static struct gpio_led_platform_data ib62x0_led_data = { + .leds = ib62x0_led_pins, + .num_leds = ARRAY_SIZE(ib62x0_led_pins), +}; + +static struct platform_device ib62x0_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &ib62x0_led_data, + } +}; + +static struct gpio_keys_button ib62x0_button_pins[] = { + { + .code = KEY_COPY, + .gpio = 29, + .desc = "USB Copy", + .active_low = 1, + }, + { + .code = KEY_RESTART, + .gpio = 28, + .desc = "Reset", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data ib62x0_button_data = { + .buttons = ib62x0_button_pins, + .nbuttons = ARRAY_SIZE(ib62x0_button_pins), +}; + +static struct platform_device ib62x0_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ib62x0_button_data, + } +}; + static void ib62x0_power_off(void) { gpio_set_value(IB62X0_GPIO_POWER_OFF, 1); @@ -63,6 +132,9 @@ void __init ib62x0_init(void) kirkwood_ehci_init(); kirkwood_ge00_init(&ib62x0_ge00_data); + kirkwood_sata_init(&ib62x0_sata_data); + platform_device_register(&ib62x0_led_device); + platform_device_register(&ib62x0_button_device); if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 && gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0) pm_power_off = ib62x0_power_off; diff --git a/trunk/arch/arm/mach-kirkwood/board-iconnect.c b/trunk/arch/arm/mach-kirkwood/board-iconnect.c index d7a9198ed300..b0d3cc49269d 100644 --- a/trunk/arch/arm/mach-kirkwood/board-iconnect.c +++ b/trunk/arch/arm/mach-kirkwood/board-iconnect.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include #include @@ -30,6 +32,50 @@ static struct mv643xx_eth_platform_data iconnect_ge00_data = { .phy_addr = MV643XX_ETH_PHY_ADDR(11), }; +static struct gpio_led iconnect_led_pins[] = { + { + .name = "led_level", + .gpio = 41, + .default_trigger = "default-on", + }, { + .name = "power:blue", + .gpio = 42, + .default_trigger = "timer", + }, { + .name = "power:red", + .gpio = 43, + }, { + .name = "usb1:blue", + .gpio = 44, + }, { + .name = "usb2:blue", + .gpio = 45, + }, { + .name = "usb3:blue", + .gpio = 46, + }, { + .name = "usb4:blue", + .gpio = 47, + }, { + .name = "otb:blue", + .gpio = 48, + }, +}; + +static struct gpio_led_platform_data iconnect_led_data = { + .leds = iconnect_led_pins, + .num_leds = ARRAY_SIZE(iconnect_led_pins), + .gpio_blink_set = orion_gpio_led_blink_set, +}; + +static struct platform_device iconnect_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &iconnect_led_data, + } +}; + static unsigned int iconnect_mpp_config[] __initdata = { MPP12_GPIO, MPP35_GPIO, @@ -44,6 +90,12 @@ static unsigned int iconnect_mpp_config[] __initdata = { 0 }; +static struct i2c_board_info __initdata iconnect_board_info[] = { + { + I2C_BOARD_INFO("lm63", 0x4c), + }, +}; + static struct mtd_partition iconnect_nand_parts[] = { { .name = "flash", @@ -90,11 +142,15 @@ void __init iconnect_init(void) { kirkwood_mpp_conf(iconnect_mpp_config); kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 25); + kirkwood_i2c_init(); + i2c_register_board_info(0, iconnect_board_info, + ARRAY_SIZE(iconnect_board_info)); kirkwood_ehci_init(); kirkwood_ge00_init(&iconnect_ge00_data); platform_device_register(&iconnect_button_device); + platform_device_register(&iconnect_leds); } static int __init iconnect_pci_init(void) diff --git a/trunk/arch/arm/mach-kirkwood/board-lsxl.c b/trunk/arch/arm/mach-kirkwood/board-lsxl.c deleted file mode 100644 index 83d8975592f8..000000000000 --- a/trunk/arch/arm/mach-kirkwood/board-lsxl.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2012 (C), Michael Walle - * - * arch/arm/mach-kirkwood/board-lsxl.c - * - * Buffalo Linkstation LS-XHL and LS-CHLv2 init for drivers not - * converted to flattened device tree yet. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "mpp.h" - -static struct mv643xx_eth_platform_data lsxl_ge00_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(0), -}; - -static struct mv643xx_eth_platform_data lsxl_ge01_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(8), -}; - -static unsigned int lsxl_mpp_config[] __initdata = { - MPP10_GPO, /* HDD Power Enable */ - MPP11_GPIO, /* USB Vbus Enable */ - MPP18_GPO, /* FAN High Enable# */ - MPP19_GPO, /* FAN Low Enable# */ - MPP36_GPIO, /* Function Blue LED */ - MPP37_GPIO, /* Alarm LED */ - MPP38_GPIO, /* Info LED */ - MPP39_GPIO, /* Power LED */ - MPP40_GPIO, /* Fan Lock */ - MPP41_GPIO, /* Function Button */ - MPP42_GPIO, /* Power Switch */ - MPP43_GPIO, /* Power Auto Switch */ - MPP48_GPIO, /* Function Red LED */ - 0 -}; - -#define LSXL_GPIO_FAN_HIGH 18 -#define LSXL_GPIO_FAN_LOW 19 -#define LSXL_GPIO_FAN_LOCK 40 - -static struct gpio_fan_alarm lsxl_alarm = { - .gpio = LSXL_GPIO_FAN_LOCK, -}; - -static struct gpio_fan_speed lsxl_speeds[] = { - { - .rpm = 0, - .ctrl_val = 3, - }, { - .rpm = 1500, - .ctrl_val = 1, - }, { - .rpm = 3250, - .ctrl_val = 2, - }, { - .rpm = 5000, - .ctrl_val = 0, - } -}; - -static int lsxl_gpio_list[] = { - LSXL_GPIO_FAN_HIGH, LSXL_GPIO_FAN_LOW, -}; - -static struct gpio_fan_platform_data lsxl_fan_data = { - .num_ctrl = ARRAY_SIZE(lsxl_gpio_list), - .ctrl = lsxl_gpio_list, - .alarm = &lsxl_alarm, - .num_speed = ARRAY_SIZE(lsxl_speeds), - .speed = lsxl_speeds, -}; - -static struct platform_device lsxl_fan_device = { - .name = "gpio-fan", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &lsxl_fan_data, - }, -}; - -/* - * On the LS-XHL/LS-CHLv2, the shutdown process is following: - * - Userland monitors key events until the power switch goes to off position - * - The board reboots - * - U-boot starts and goes into an idle mode waiting for the user - * to move the switch to ON position - * - */ -static void lsxl_power_off(void) -{ - kirkwood_restart('h', NULL); -} - -#define LSXL_GPIO_HDD_POWER 10 -#define LSXL_GPIO_USB_POWER 11 - -void __init lsxl_init(void) -{ - /* - * Basic setup. Needs to be called early. - */ - kirkwood_mpp_conf(lsxl_mpp_config); - - /* usb and sata power on */ - gpio_set_value(LSXL_GPIO_USB_POWER, 1); - gpio_set_value(LSXL_GPIO_HDD_POWER, 1); - - kirkwood_ehci_init(); - kirkwood_ge00_init(&lsxl_ge00_data); - kirkwood_ge01_init(&lsxl_ge01_data); - platform_device_register(&lsxl_fan_device); - - /* register power-off method */ - pm_power_off = lsxl_power_off; -} diff --git a/trunk/arch/arm/mach-kirkwood/board-ts219.c b/trunk/arch/arm/mach-kirkwood/board-ts219.c deleted file mode 100644 index 1750e68506c1..000000000000 --- a/trunk/arch/arm/mach-kirkwood/board-ts219.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * QNAP TS-11x/TS-21x Turbo NAS Board Setup via DT - * - * Copyright (C) 2012 Andrew Lunn - * - * Based on the board file ts219-setup.c: - * - * Copyright (C) 2009 Martin Michlmayr - * Copyright (C) 2008 Byron Bradley - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "mpp.h" -#include "tsx1x-common.h" - -static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(8), -}; - -static unsigned int qnap_ts219_mpp_config[] __initdata = { - MPP0_SPI_SCn, - MPP1_SPI_MOSI, - MPP2_SPI_SCK, - MPP3_SPI_MISO, - MPP4_SATA1_ACTn, - MPP5_SATA0_ACTn, - MPP8_TW0_SDA, - MPP9_TW0_SCK, - MPP10_UART0_TXD, - MPP11_UART0_RXD, - MPP13_UART1_TXD, /* PIC controller */ - MPP14_UART1_RXD, /* PIC controller */ - MPP15_GPIO, /* USB Copy button (on devices with 88F6281) */ - MPP16_GPIO, /* Reset button (on devices with 88F6281) */ - MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */ - MPP37_GPIO, /* Reset button (on devices with 88F6282) */ - MPP43_GPIO, /* USB Copy button (on devices with 88F6282) */ - MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */ - 0 -}; - -void __init qnap_dt_ts219_init(void) -{ - u32 dev, rev; - - kirkwood_mpp_conf(qnap_ts219_mpp_config); - - kirkwood_pcie_id(&dev, &rev); - if (dev == MV88F6282_DEV_ID) - qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); - - kirkwood_ge00_init(&qnap_ts219_ge00_data); - kirkwood_ehci_init(); - - pm_power_off = qnap_tsx1x_power_off; -} - -/* FIXME: Will not work with DT. Maybe use MPP40_GPIO? */ -static int __init ts219_pci_init(void) -{ - if (machine_is_ts219()) - kirkwood_pcie_init(KW_PCIE0); - - return 0; -} -subsys_initcall(ts219_pci_init); diff --git a/trunk/arch/arm/mach-kirkwood/common.c b/trunk/arch/arm/mach-kirkwood/common.c index c4b64adcbfce..c9201539ffbd 100644 --- a/trunk/arch/arm/mach-kirkwood/common.c +++ b/trunk/arch/arm/mach-kirkwood/common.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -277,7 +276,6 @@ void __init kirkwood_clk_init(void) orion_clkdev_add("0", "pcie", pex0); orion_clkdev_add("1", "pcie", pex1); orion_clkdev_add(NULL, "kirkwood-i2s", audio); - orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit); /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., * so should never be gated. diff --git a/trunk/arch/arm/mach-kirkwood/common.h b/trunk/arch/arm/mach-kirkwood/common.h index 304dd1abfdca..9248fa2c165b 100644 --- a/trunk/arch/arm/mach-kirkwood/common.h +++ b/trunk/arch/arm/mach-kirkwood/common.h @@ -58,11 +58,6 @@ void dreamplug_init(void); #else static inline void dreamplug_init(void) {}; #endif -#ifdef CONFIG_MACH_TS219_DT -void qnap_dt_ts219_init(void); -#else -static inline void qnap_dt_ts219_init(void) {}; -#endif #ifdef CONFIG_MACH_DLINK_KIRKWOOD_DT void dnskw_init(void); @@ -82,18 +77,6 @@ void ib62x0_init(void); static inline void ib62x0_init(void) {}; #endif -#ifdef CONFIG_MACH_GOFLEXNET_DT -void goflexnet_init(void); -#else -static inline void goflexnet_init(void) {}; -#endif - -#ifdef CONFIG_MACH_LSXL_DT -void lsxl_init(void); -#else -static inline void lsxl_init(void) {}; -#endif - /* early init functions not converted to fdt yet */ char *kirkwood_id(void); void kirkwood_l2_init(void); diff --git a/trunk/arch/arm/mach-kirkwood/irq.c b/trunk/arch/arm/mach-kirkwood/irq.c index 720063ffa19d..c4c68e5b94f1 100644 --- a/trunk/arch/arm/mach-kirkwood/irq.c +++ b/trunk/arch/arm/mach-kirkwood/irq.c @@ -9,23 +9,20 @@ */ #include #include +#include #include +#include #include #include +#include "common.h" -static int __initdata gpio0_irqs[4] = { - IRQ_KIRKWOOD_GPIO_LOW_0_7, - IRQ_KIRKWOOD_GPIO_LOW_8_15, - IRQ_KIRKWOOD_GPIO_LOW_16_23, - IRQ_KIRKWOOD_GPIO_LOW_24_31, -}; +static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + BUG_ON(irq < IRQ_KIRKWOOD_GPIO_LOW_0_7); + BUG_ON(irq > IRQ_KIRKWOOD_GPIO_HIGH_16_23); -static int __initdata gpio1_irqs[4] = { - IRQ_KIRKWOOD_GPIO_HIGH_0_7, - IRQ_KIRKWOOD_GPIO_HIGH_8_15, - IRQ_KIRKWOOD_GPIO_HIGH_16_23, - 0, -}; + orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3); +} void __init kirkwood_init_irq(void) { @@ -35,8 +32,17 @@ void __init kirkwood_init_irq(void) /* * Initialize gpiolib for GPIOs 0-49. */ - orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_LOW_VIRT_BASE, 0, - IRQ_KIRKWOOD_GPIO_START, gpio0_irqs); - orion_gpio_init(NULL, 32, 18, (void __iomem *)GPIO_HIGH_VIRT_BASE, 0, - IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs); + orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0, + IRQ_KIRKWOOD_GPIO_START); + irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler); + irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler); + irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler); + irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler); + + orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0, + IRQ_KIRKWOOD_GPIO_START + 32); + irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler); + irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler); + irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, + gpio_irq_handler); } diff --git a/trunk/arch/arm/mach-mmp/gplugd.c b/trunk/arch/arm/mach-mmp/gplugd.c index 5c3d61ee729a..f516e74ce0d5 100644 --- a/trunk/arch/arm/mach-mmp/gplugd.c +++ b/trunk/arch/arm/mach-mmp/gplugd.c @@ -14,7 +14,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-mv78xx0/irq.c b/trunk/arch/arm/mach-mv78xx0/irq.c index eff9a750bbe2..e421b701663b 100644 --- a/trunk/arch/arm/mach-mv78xx0/irq.c +++ b/trunk/arch/arm/mach-mv78xx0/irq.c @@ -9,17 +9,19 @@ */ #include #include +#include +#include #include #include #include #include "common.h" -static int __initdata gpio0_irqs[4] = { - IRQ_MV78XX0_GPIO_0_7, - IRQ_MV78XX0_GPIO_8_15, - IRQ_MV78XX0_GPIO_16_23, - IRQ_MV78XX0_GPIO_24_31, -}; +static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + BUG_ON(irq < IRQ_MV78XX0_GPIO_0_7 || irq > IRQ_MV78XX0_GPIO_24_31); + + orion_gpio_irq_handler((irq - IRQ_MV78XX0_GPIO_0_7) << 3); +} void __init mv78xx0_init_irq(void) { @@ -32,7 +34,11 @@ void __init mv78xx0_init_irq(void) * registers for core #1 are at an offset of 0x18 from those of * core #0.) */ - orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, + orion_gpio_init(0, 32, GPIO_VIRT_BASE, mv78xx0_core_index() ? 0x18 : 0, - IRQ_MV78XX0_GPIO_START, gpio0_irqs); + IRQ_MV78XX0_GPIO_START); + irq_set_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler); + irq_set_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler); + irq_set_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler); + irq_set_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler); } diff --git a/trunk/arch/arm/mach-mxs/Kconfig b/trunk/arch/arm/mach-mxs/Kconfig index 9a8bbda195b2..ccdf83b17cf1 100644 --- a/trunk/arch/arm/mach-mxs/Kconfig +++ b/trunk/arch/arm/mach-mxs/Kconfig @@ -2,6 +2,9 @@ if ARCH_MXS source "arch/arm/mach-mxs/devices/Kconfig" +config MXS_OCOTP + bool + config SOC_IMX23 bool select ARM_AMBA @@ -63,6 +66,7 @@ config MACH_MX28EVK select MXS_HAVE_PLATFORM_MXS_SAIF select MXS_HAVE_PLATFORM_MXS_I2C select MXS_HAVE_PLATFORM_RTC_STMP3XXX + select MXS_OCOTP help Include support for MX28EVK platform. This includes specific configurations for the board and its peripherals. @@ -90,6 +94,7 @@ config MODULE_M28 select MXS_HAVE_PLATFORM_MXS_I2C select MXS_HAVE_PLATFORM_MXS_MMC select MXS_HAVE_PLATFORM_MXSFB + select MXS_OCOTP config MODULE_APX4 bool @@ -101,6 +106,7 @@ config MODULE_APX4 select MXS_HAVE_PLATFORM_MXS_I2C select MXS_HAVE_PLATFORM_MXS_MMC select MXS_HAVE_PLATFORM_MXS_SAIF + select MXS_OCOTP config MACH_TX28 bool "Ka-Ro TX28 module" diff --git a/trunk/arch/arm/mach-mxs/Makefile b/trunk/arch/arm/mach-mxs/Makefile index fed3695a1339..e41590ccb437 100644 --- a/trunk/arch/arm/mach-mxs/Makefile +++ b/trunk/arch/arm/mach-mxs/Makefile @@ -1,6 +1,7 @@ # Common support -obj-y := devices.o icoll.o iomux.o ocotp.o system.o timer.o mm.o +obj-y := devices.o icoll.o iomux.o system.o timer.o mm.o +obj-$(CONFIG_MXS_OCOTP) += ocotp.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig index dd2db025f778..dd0fbf76ac79 100644 --- a/trunk/arch/arm/mach-omap2/Kconfig +++ b/trunk/arch/arm/mach-omap2/Kconfig @@ -62,7 +62,6 @@ config ARCH_OMAP4 select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PM - select ARCH_NEEDS_CPU_IDLE_COUPLED config SOC_OMAP5 bool "TI OMAP5" diff --git a/trunk/arch/arm/mach-omap2/cpuidle44xx.c b/trunk/arch/arm/mach-omap2/cpuidle44xx.c index ee05e193fc61..02d15bbd4e35 100644 --- a/trunk/arch/arm/mach-omap2/cpuidle44xx.c +++ b/trunk/arch/arm/mach-omap2/cpuidle44xx.c @@ -21,7 +21,6 @@ #include "common.h" #include "pm.h" #include "prm.h" -#include "clockdomain.h" /* Machine specific information */ struct omap4_idle_statedata { @@ -48,14 +47,10 @@ static struct omap4_idle_statedata omap4_idle_data[] = { }, }; -static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS]; -static struct clockdomain *cpu_clkdm[NR_CPUS]; - -static atomic_t abort_barrier; -static bool cpu_done[NR_CPUS]; +static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; /** - * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions + * omap4_enter_idle - Programs OMAP4 to enter the specified state * @dev: cpuidle device * @drv: cpuidle driver * @index: the index of state to be entered @@ -64,84 +59,60 @@ static bool cpu_done[NR_CPUS]; * specified low power state selected by the governor. * Returns the amount of time spent in the low power state. */ -static int omap4_enter_idle_simple(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - local_fiq_disable(); - omap_do_wfi(); - local_fiq_enable(); - - return index; -} - -static int omap4_enter_idle_coupled(struct cpuidle_device *dev, +static int omap4_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct omap4_idle_statedata *cx = &omap4_idle_data[index]; + u32 cpu1_state; int cpu_id = smp_processor_id(); local_fiq_disable(); /* - * CPU0 has to wait and stay ON until CPU1 is OFF state. + * CPU0 has to stay ON (i.e in C1) until CPU1 is OFF state. * This is necessary to honour hardware recommondation * of triggeing all the possible low power modes once CPU1 is * out of coherency and in OFF mode. + * Update dev->last_state so that governor stats reflects right + * data. */ - if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { - while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) { - cpu_relax(); - - /* - * CPU1 could have already entered & exited idle - * without hitting off because of a wakeup - * or a failed attempt to hit off mode. Check for - * that here, otherwise we could spin forever - * waiting for CPU1 off. - */ - if (cpu_done[1]) - goto fail; - - } + cpu1_state = pwrdm_read_pwrst(cpu1_pd); + if (cpu1_state != PWRDM_POWER_OFF) { + index = drv->safe_state_index; + cx = &omap4_idle_data[index]; } - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); + if (index > 0) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); /* * Call idle CPU PM enter notifier chain so that * VFP and per CPU interrupt context is saved. */ - cpu_pm_enter(); - - if (dev->cpu == 0) { - pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); - omap_set_pwrdm_state(mpu_pd, cx->mpu_state); - - /* - * Call idle CPU cluster PM enter notifier chain - * to save GIC and wakeupgen context. - */ - if ((cx->mpu_state == PWRDM_POWER_RET) && - (cx->mpu_logic_state == PWRDM_POWER_OFF)) - cpu_cluster_pm_enter(); - } + if (cx->cpu_state == PWRDM_POWER_OFF) + cpu_pm_enter(); - omap4_enter_lowpower(dev->cpu, cx->cpu_state); - cpu_done[dev->cpu] = true; + pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); + omap_set_pwrdm_state(mpu_pd, cx->mpu_state); - /* Wakeup CPU1 only if it is not offlined */ - if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { - clkdm_wakeup(cpu_clkdm[1]); - clkdm_allow_idle(cpu_clkdm[1]); - } + /* + * Call idle CPU cluster PM enter notifier chain + * to save GIC and wakeupgen context. + */ + if ((cx->mpu_state == PWRDM_POWER_RET) && + (cx->mpu_logic_state == PWRDM_POWER_OFF)) + cpu_cluster_pm_enter(); + + omap4_enter_lowpower(dev->cpu, cx->cpu_state); /* * Call idle CPU PM exit notifier chain to restore - * VFP and per CPU IRQ context. + * VFP and per CPU IRQ context. Only CPU0 state is + * considered since CPU1 is managed by CPU hotplug. */ - cpu_pm_exit(); + if (pwrdm_read_prev_pwrst(cpu0_pd) == PWRDM_POWER_OFF) + cpu_pm_exit(); /* * Call idle CPU cluster PM exit notifier chain @@ -150,11 +121,8 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev, if (omap4_mpuss_read_prev_context_state()) cpu_cluster_pm_exit(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); - -fail: - cpuidle_coupled_parallel_barrier(dev, &abort_barrier); - cpu_done[dev->cpu] = false; + if (index > 0) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); local_fiq_enable(); @@ -173,7 +141,7 @@ struct cpuidle_driver omap4_idle_driver = { .exit_latency = 2 + 2, .target_residency = 5, .flags = CPUIDLE_FLAG_TIME_VALID, - .enter = omap4_enter_idle_simple, + .enter = omap4_enter_idle, .name = "C1", .desc = "MPUSS ON" }, @@ -181,8 +149,8 @@ struct cpuidle_driver omap4_idle_driver = { /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ .exit_latency = 328 + 440, .target_residency = 960, - .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, - .enter = omap4_enter_idle_coupled, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = omap4_enter_idle, .name = "C2", .desc = "MPUSS CSWR", }, @@ -190,8 +158,8 @@ struct cpuidle_driver omap4_idle_driver = { /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ .exit_latency = 460 + 518, .target_residency = 1100, - .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, - .enter = omap4_enter_idle_coupled, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = omap4_enter_idle, .name = "C3", .desc = "MPUSS OSWR", }, @@ -200,16 +168,6 @@ struct cpuidle_driver omap4_idle_driver = { .safe_state_index = 0, }; -/* - * For each cpu, setup the broadcast timer because local timers - * stops for the states above C1. - */ -static void omap_setup_broadcast_timer(void *arg) -{ - int cpu = smp_processor_id(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); -} - /** * omap4_idle_init - Init routine for OMAP4 idle * @@ -222,30 +180,19 @@ int __init omap4_idle_init(void) unsigned int cpu_id = 0; mpu_pd = pwrdm_lookup("mpu_pwrdm"); - cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm"); - cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm"); - if ((!mpu_pd) || (!cpu_pd[0]) || (!cpu_pd[1])) + cpu0_pd = pwrdm_lookup("cpu0_pwrdm"); + cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); + if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) return -ENODEV; - cpu_clkdm[0] = clkdm_lookup("mpu0_clkdm"); - cpu_clkdm[1] = clkdm_lookup("mpu1_clkdm"); - if (!cpu_clkdm[0] || !cpu_clkdm[1]) - return -ENODEV; - - /* Configure the broadcast timer on each cpu */ - on_each_cpu(omap_setup_broadcast_timer, NULL, 1); - - for_each_cpu(cpu_id, cpu_online_mask) { - dev = &per_cpu(omap4_idle_dev, cpu_id); - dev->cpu = cpu_id; - dev->coupled_cpus = *cpu_online_mask; + dev = &per_cpu(omap4_idle_dev, cpu_id); + dev->cpu = cpu_id; - cpuidle_register_driver(&omap4_idle_driver); + cpuidle_register_driver(&omap4_idle_driver); - if (cpuidle_register_device(dev)) { - pr_err("%s: CPUidle register failed\n", __func__); - return -EIO; - } + if (cpuidle_register_device(dev)) { + pr_err("%s: CPUidle register device failed\n", __func__); + return -EIO; } return 0; diff --git a/trunk/arch/arm/mach-omap2/timer.c b/trunk/arch/arm/mach-omap2/timer.c index 2ff6d41ec6c6..13d20c8a283d 100644 --- a/trunk/arch/arm/mach-omap2/timer.c +++ b/trunk/arch/arm/mach-omap2/timer.c @@ -130,7 +130,6 @@ static struct clock_event_device clockevent_gpt = { .name = "gp_timer", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .shift = 32, - .rating = 300, .set_next_event = omap2_gp_timer_set_next_event, .set_mode = omap2_gp_timer_set_mode, }; @@ -224,8 +223,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, clockevent_delta2ns(3, &clockevent_gpt); /* Timer internal resynch latency. */ - clockevent_gpt.cpumask = cpu_possible_mask; - clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); + clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", diff --git a/trunk/arch/arm/mach-orion5x/irq.c b/trunk/arch/arm/mach-orion5x/irq.c index 17da7091d310..b1b45fff776e 100644 --- a/trunk/arch/arm/mach-orion5x/irq.c +++ b/trunk/arch/arm/mach-orion5x/irq.c @@ -11,16 +11,19 @@ */ #include #include +#include #include +#include #include #include +#include "common.h" -static int __initdata gpio0_irqs[4] = { - IRQ_ORION5X_GPIO_0_7, - IRQ_ORION5X_GPIO_8_15, - IRQ_ORION5X_GPIO_16_23, - IRQ_ORION5X_GPIO_24_31, -}; +static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31); + + orion_gpio_irq_handler((irq - IRQ_ORION5X_GPIO_0_7) << 3); +} void __init orion5x_init_irq(void) { @@ -29,6 +32,9 @@ void __init orion5x_init_irq(void) /* * Initialize gpiolib for GPIOs 0-31. */ - orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, 0, - IRQ_ORION5X_GPIO_START, gpio0_irqs); + orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0, IRQ_ORION5X_GPIO_START); + irq_set_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler); + irq_set_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler); + irq_set_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler); + irq_set_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler); } diff --git a/trunk/arch/arm/mach-prima2/timer.c b/trunk/arch/arm/mach-prima2/timer.c index f224107de7bc..0d024b1e916d 100644 --- a/trunk/arch/arm/mach-prima2/timer.c +++ b/trunk/arch/arm/mach-prima2/timer.c @@ -132,11 +132,11 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs) { int i; - for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) + for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); - writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); - writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); + writel_relaxed(sirfsoc_timer_reg_val[i - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); + writel_relaxed(sirfsoc_timer_reg_val[i - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); } static struct clock_event_device sirfsoc_clockevent = { diff --git a/trunk/arch/arm/mach-pxa/raumfeld.c b/trunk/arch/arm/mach-pxa/raumfeld.c index d89d87ae144c..5905ed130e94 100644 --- a/trunk/arch/arm/mach-pxa/raumfeld.c +++ b/trunk/arch/arm/mach-pxa/raumfeld.c @@ -953,12 +953,12 @@ static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = { static struct eeti_ts_platform_data eeti_ts_pdata = { .irq_active_high = 1, - .irq_gpio = GPIO_TOUCH_IRQ, }; static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = { .type = "eeti_ts", .addr = 0x0a, + .irq = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ), .platform_data = &eeti_ts_pdata, }; diff --git a/trunk/arch/arm/mach-s3c24xx/Kconfig b/trunk/arch/arm/mach-s3c24xx/Kconfig index d56b0f7f2b20..e24961109b70 100644 --- a/trunk/arch/arm/mach-s3c24xx/Kconfig +++ b/trunk/arch/arm/mach-s3c24xx/Kconfig @@ -483,7 +483,7 @@ config MACH_NEO1973_GTA02 select I2C select POWER_SUPPLY select MACH_NEO1973 - select S3C24XX_PWM + select S3C2410_PWM select S3C_DEV_USB_HOST help Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone @@ -493,7 +493,7 @@ config MACH_RX1950 select S3C24XX_DCLK select PM_H1940 if PM select I2C - select S3C24XX_PWM + select S3C2410_PWM select S3C_DEV_NAND select S3C2410_IOTIMING if S3C2440_CPUFREQ select S3C2440_XTAL_16934400 diff --git a/trunk/arch/arm/mach-sa1100/leds-hackkit.c b/trunk/arch/arm/mach-sa1100/leds-hackkit.c index f8e47235babe..6a2352436e62 100644 --- a/trunk/arch/arm/mach-sa1100/leds-hackkit.c +++ b/trunk/arch/arm/mach-sa1100/leds-hackkit.c @@ -10,7 +10,6 @@ * as cpu led, the green one is used as timer led. */ #include -#include #include #include diff --git a/trunk/arch/arm/mach-tegra/board-harmony-power.c b/trunk/arch/arm/mach-tegra/board-harmony-power.c index b7344beec102..8fd387bf31f0 100644 --- a/trunk/arch/arm/mach-tegra/board-harmony-power.c +++ b/trunk/arch/arm/mach-tegra/board-harmony-power.c @@ -51,7 +51,7 @@ static struct regulator_init_data ldo0_data = { .consumer_supplies = tps658621_ldo0_supply, }; -#define HARMONY_REGULATOR_INIT(_id, _name, _supply, _minmv, _maxmv, _on)\ +#define HARMONY_REGULATOR_INIT(_id, _name, _supply, _minmv, _maxmv) \ static struct regulator_init_data _id##_data = { \ .supply_regulator = _supply, \ .constraints = { \ @@ -63,22 +63,21 @@ static struct regulator_init_data ldo0_data = { .valid_ops_mask = (REGULATOR_CHANGE_MODE | \ REGULATOR_CHANGE_STATUS | \ REGULATOR_CHANGE_VOLTAGE), \ - .always_on = _on, \ }, \ } -HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500, 1); -HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500, 1); -HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550, 1); -HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500, 1); -HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500, 0); -HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300, 1); -HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475, 1); -HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL, 1250, 3300, 1); -HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300, 0); -HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300, 0); -HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300, 0); -HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300, 1); +HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500); +HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500); +HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550); +HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500); +HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500); +HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300); +HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475); +HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL, 1250, 3300); +HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300); +HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300); +HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300); +HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300); #define TPS_REG(_id, _data) \ { \ @@ -120,10 +119,9 @@ static struct i2c_board_info __initdata harmony_regulators[] = { int __init harmony_regulator_init(void) { - regulator_register_always_on(0, "vdd_sys", - NULL, 0, 5000000); - if (machine_is_harmony()) { + regulator_register_always_on(0, "vdd_sys", + NULL, 0, 5000000); i2c_register_board_info(3, harmony_regulators, 1); } else { /* Harmony, booted using device tree */ struct device_node *np; diff --git a/trunk/arch/arm/mm/dma-mapping.c b/trunk/arch/arm/mm/dma-mapping.c index 4e7d1182e8a3..c2cdf6500f75 100644 --- a/trunk/arch/arm/mm/dma-mapping.c +++ b/trunk/arch/arm/mm/dma-mapping.c @@ -358,7 +358,7 @@ void __init dma_contiguous_remap(void) if (end > arm_lowmem_limit) end = arm_lowmem_limit; if (start >= end) - continue; + return; map.pfn = __phys_to_pfn(start); map.virtual = __phys_to_virt(start); @@ -423,7 +423,7 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) unsigned int pageno; unsigned long flags; void *ptr = NULL; - unsigned long align_mask; + size_t align; if (!pool->vaddr) { WARN(1, "coherent pool not initialised!\n"); @@ -435,11 +435,11 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) * small, so align them to their order in pages, minimum is a page * size. This helps reduce fragmentation of the DMA space. */ - align_mask = (1 << get_order(size)) - 1; + align = PAGE_SIZE << get_order(size); spin_lock_irqsave(&pool->lock, flags); pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages, - 0, count, align_mask); + 0, count, (1 << align) - 1); if (pageno < pool->nr_pages) { bitmap_set(pool->bitmap, pageno, count); ptr = pool->vaddr + PAGE_SIZE * pageno; @@ -648,12 +648,12 @@ void arm_dma_free(struct device *dev, size_t size, void *cpu_addr, if (arch_is_coherent() || nommu()) { __dma_free_buffer(page, size); - } else if (__free_from_pool(cpu_addr, size)) { - return; } else if (!IS_ENABLED(CONFIG_CMA)) { __dma_free_remap(cpu_addr, size); __dma_free_buffer(page, size); } else { + if (__free_from_pool(cpu_addr, size)) + return; /* * Non-atomic allocations cannot be freed with IRQs disabled */ diff --git a/trunk/arch/arm/plat-mxc/tzic.c b/trunk/arch/arm/plat-mxc/tzic.c index 3ed1adbc09f8..c2193178210b 100644 --- a/trunk/arch/arm/plat-mxc/tzic.c +++ b/trunk/arch/arm/plat-mxc/tzic.c @@ -23,7 +23,6 @@ #include #include -#include #include "irq-common.h" diff --git a/trunk/arch/arm/plat-orion/common.c b/trunk/arch/arm/plat-orion/common.c index d245a87dc014..c1793786aea9 100644 --- a/trunk/arch/arm/plat-orion/common.c +++ b/trunk/arch/arm/plat-orion/common.c @@ -47,7 +47,6 @@ void __init orion_clkdev_init(struct clk *tclk) orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk); orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk); orion_clkdev_add(NULL, "orion_wdt", tclk); - orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", tclk); } /* Fill in the resources structure and link it into the platform diff --git a/trunk/arch/arm/plat-orion/gpio.c b/trunk/arch/arm/plat-orion/gpio.c index dfda74fae6f2..af95af257301 100644 --- a/trunk/arch/arm/plat-orion/gpio.c +++ b/trunk/arch/arm/plat-orion/gpio.c @@ -8,22 +8,15 @@ * warranty of any kind, whether express or implied. */ -#define DEBUG - #include #include #include -#include #include #include #include #include #include #include -#include -#include -#include -#include /* * GPIO unit register offsets. @@ -45,7 +38,6 @@ struct orion_gpio_chip { unsigned long valid_output; int mask_offset; int secondary_irq_base; - struct irq_domain *domain; }; static void __iomem *GPIO_OUT(struct orion_gpio_chip *ochip) @@ -230,10 +222,10 @@ static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin) struct orion_gpio_chip *ochip = container_of(chip, struct orion_gpio_chip, chip); - return irq_create_mapping(ochip->domain, - ochip->secondary_irq_base + pin); + return ochip->secondary_irq_base + pin; } + /* * Orion-specific GPIO API extensions. */ @@ -361,10 +353,12 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) int pin; u32 u; - pin = d->hwirq - ochip->secondary_irq_base; + pin = d->irq - gc->irq_base; u = readl(GPIO_IO_CONF(ochip)) & (1 << pin); if (!u) { + printk(KERN_ERR "orion gpio_irq_set_type failed " + "(irq %d, pin %d).\n", d->irq, pin); return -EINVAL; } @@ -403,53 +397,17 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) u &= ~(1 << pin); /* rising */ writel(u, GPIO_IN_POL(ochip)); } - return 0; -} - -static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) -{ - struct orion_gpio_chip *ochip = irq_get_handler_data(irq); - u32 cause, type; - int i; - - if (ochip == NULL) - return; - - cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip)); - cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip)); - - for (i = 0; i < ochip->chip.ngpio; i++) { - int irq; - - irq = ochip->secondary_irq_base + i; - if (!(cause & (1 << i))) - continue; - - type = irqd_get_trigger_type(irq_get_irq_data(irq)); - if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { - /* Swap polarity (race with GPIO line) */ - u32 polarity; - - polarity = readl(GPIO_IN_POL(ochip)); - polarity ^= 1 << i; - writel(polarity, GPIO_IN_POL(ochip)); - } - generic_handle_irq(irq); - } + return 0; } -void __init orion_gpio_init(struct device_node *np, - int gpio_base, int ngpio, - void __iomem *base, int mask_offset, - int secondary_irq_base, - int irqs[4]) +void __init orion_gpio_init(int gpio_base, int ngpio, + u32 base, int mask_offset, int secondary_irq_base) { struct orion_gpio_chip *ochip; struct irq_chip_generic *gc; struct irq_chip_type *ct; char gc_label[16]; - int i; if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips)) return; @@ -468,10 +426,6 @@ void __init orion_gpio_init(struct device_node *np, ochip->chip.base = gpio_base; ochip->chip.ngpio = ngpio; ochip->chip.can_sleep = 0; -#ifdef CONFIG_OF - ochip->chip.of_node = np; -#endif - spin_lock_init(&ochip->lock); ochip->base = (void __iomem *)base; ochip->valid_input = 0; @@ -481,6 +435,8 @@ void __init orion_gpio_init(struct device_node *np, gpiochip_add(&ochip->chip); + orion_gpio_chip_count++; + /* * Mask and clear GPIO interrupts. */ @@ -488,28 +444,16 @@ void __init orion_gpio_init(struct device_node *np, writel(0, GPIO_EDGE_MASK(ochip)); writel(0, GPIO_LEVEL_MASK(ochip)); - /* Setup the interrupt handlers. Each chip can have up to 4 - * interrupt handlers, with each handler dealing with 8 GPIO - * pins. */ - - for (i = 0; i < 4; i++) { - if (irqs[i]) { - irq_set_handler_data(irqs[i], ochip); - irq_set_chained_handler(irqs[i], gpio_irq_handler); - } - } - - gc = irq_alloc_generic_chip("orion_gpio_irq", 2, - secondary_irq_base, + gc = irq_alloc_generic_chip("orion_gpio_irq", 2, secondary_irq_base, ochip->base, handle_level_irq); gc->private = ochip; + ct = gc->chip_types; ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF; ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; ct->chip.irq_mask = irq_gc_mask_clr_bit; ct->chip.irq_unmask = irq_gc_mask_set_bit; ct->chip.irq_set_type = gpio_irq_set_type; - ct->chip.name = ochip->chip.label; ct++; ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF; @@ -520,69 +464,41 @@ void __init orion_gpio_init(struct device_node *np, ct->chip.irq_unmask = irq_gc_mask_set_bit; ct->chip.irq_set_type = gpio_irq_set_type; ct->handler = handle_edge_irq; - ct->chip.name = ochip->chip.label; irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); - - /* Setup irq domain on top of the generic chip. */ - ochip->domain = irq_domain_add_legacy(np, - ochip->chip.ngpio, - ochip->secondary_irq_base, - ochip->secondary_irq_base, - &irq_domain_simple_ops, - ochip); - if (!ochip->domain) - panic("%s: couldn't allocate irq domain (DT).\n", - ochip->chip.label); - - orion_gpio_chip_count++; } -#ifdef CONFIG_OF -static void __init orion_gpio_of_init_one(struct device_node *np, - int irq_gpio_base) +void orion_gpio_irq_handler(int pinoff) { - int ngpio, gpio_base, mask_offset; - void __iomem *base; - int ret, i; - int irqs[4]; - int secondary_irq_base; - - ret = of_property_read_u32(np, "ngpio", &ngpio); - if (ret) - goto out; - ret = of_property_read_u32(np, "mask-offset", &mask_offset); - if (ret == -EINVAL) - mask_offset = 0; - else - goto out; - base = of_iomap(np, 0); - if (!base) - goto out; - - secondary_irq_base = irq_gpio_base + (32 * orion_gpio_chip_count); - gpio_base = 32 * orion_gpio_chip_count; - - /* Get the interrupt numbers. Each chip can have up to 4 - * interrupt handlers, with each handler dealing with 8 GPIO - * pins. */ - - for (i = 0; i < 4; i++) - irqs[i] = irq_of_parse_and_map(np, i); - - orion_gpio_init(np, gpio_base, ngpio, base, mask_offset, - secondary_irq_base, irqs); - return; -out: - pr_err("%s: %s: missing mandatory property\n", __func__, np->name); -} + struct orion_gpio_chip *ochip; + u32 cause, type; + int i; -void __init orion_gpio_of_init(int irq_gpio_base) -{ - struct device_node *np; + ochip = orion_gpio_chip_find(pinoff); + if (ochip == NULL) + return; + + cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip)); + cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip)); - for_each_compatible_node(np, NULL, "marvell,orion-gpio") - orion_gpio_of_init_one(np, irq_gpio_base); + for (i = 0; i < ochip->chip.ngpio; i++) { + int irq; + + irq = ochip->secondary_irq_base + i; + + if (!(cause & (1 << i))) + continue; + + type = irqd_get_trigger_type(irq_get_irq_data(irq)); + if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { + /* Swap polarity (race with GPIO line) */ + u32 polarity; + + polarity = readl(GPIO_IN_POL(ochip)); + polarity ^= 1 << i; + writel(polarity, GPIO_IN_POL(ochip)); + } + generic_handle_irq(irq); + } } -#endif diff --git a/trunk/arch/arm/plat-orion/include/plat/gpio.h b/trunk/arch/arm/plat-orion/include/plat/gpio.h index 81c6fc8a7b28..bec0c98ce41f 100644 --- a/trunk/arch/arm/plat-orion/include/plat/gpio.h +++ b/trunk/arch/arm/plat-orion/include/plat/gpio.h @@ -13,7 +13,7 @@ #include #include -#include + /* * Orion-specific GPIO API extensions. */ @@ -27,11 +27,13 @@ int orion_gpio_led_blink_set(unsigned gpio, int state, void orion_gpio_set_valid(unsigned pin, int mode); /* Initialize gpiolib. */ -void __init orion_gpio_init(struct device_node *np, - int gpio_base, int ngpio, - void __iomem *base, int mask_offset, - int secondary_irq_base, - int irq[4]); +void __init orion_gpio_init(int gpio_base, int ngpio, + u32 base, int mask_offset, int secondary_irq_base); + +/* + * GPIO interrupt handling. + */ +void orion_gpio_irq_handler(int irqoff); + -void __init orion_gpio_of_init(int irq_gpio_base); #endif diff --git a/trunk/arch/arm/plat-orion/include/plat/irq.h b/trunk/arch/arm/plat-orion/include/plat/irq.h index 50547e417936..f05eeab94968 100644 --- a/trunk/arch/arm/plat-orion/include/plat/irq.h +++ b/trunk/arch/arm/plat-orion/include/plat/irq.h @@ -12,5 +12,6 @@ #define __PLAT_IRQ_H void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr); -void __init orion_dt_init_irq(void); + + #endif diff --git a/trunk/arch/arm/plat-orion/irq.c b/trunk/arch/arm/plat-orion/irq.c index d751964def4c..2d5b9c1ef389 100644 --- a/trunk/arch/arm/plat-orion/irq.c +++ b/trunk/arch/arm/plat-orion/irq.c @@ -11,12 +11,8 @@ #include #include #include -#include #include -#include -#include #include -#include void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) { @@ -36,39 +32,3 @@ void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); } - -#ifdef CONFIG_OF -static int __init orion_add_irq_domain(struct device_node *np, - struct device_node *interrupt_parent) -{ - int i = 0, irq_gpio; - void __iomem *base; - - do { - base = of_iomap(np, i); - if (base) { - orion_irq_init(i * 32, base); - i++; - } - } while (base); - - irq_domain_add_legacy(np, i * 32, 0, 0, - &irq_domain_simple_ops, NULL); - - irq_gpio = i * 32; - orion_gpio_of_init(irq_gpio); - - return 0; -} - -static const struct of_device_id orion_irq_match[] = { - { .compatible = "marvell,orion-intc", - .data = orion_add_irq_domain, }, - {}, -}; - -void __init orion_dt_init_irq(void) -{ - of_irq_init(orion_irq_match); -} -#endif diff --git a/trunk/arch/arm/plat-samsung/Kconfig b/trunk/arch/arm/plat-samsung/Kconfig index 9c3b90c3538e..7aca31c1df1f 100644 --- a/trunk/arch/arm/plat-samsung/Kconfig +++ b/trunk/arch/arm/plat-samsung/Kconfig @@ -403,8 +403,7 @@ config S5P_DEV_USB_EHCI config S3C24XX_PWM bool "PWM device support" - select PWM - select PWM_SAMSUNG + select HAVE_PWM help Support for exporting the PWM timer blocks via the pwm device system diff --git a/trunk/arch/blackfin/kernel/setup.c b/trunk/arch/blackfin/kernel/setup.c index fb96e607adcf..ada8f0fc71e4 100644 --- a/trunk/arch/blackfin/kernel/setup.c +++ b/trunk/arch/blackfin/kernel/setup.c @@ -52,6 +52,7 @@ EXPORT_SYMBOL(reserved_mem_dcache_on); #ifdef CONFIG_MTD_UCLINUX extern struct map_info uclinux_ram_map; unsigned long memory_mtd_end, memory_mtd_start, mtd_size; +unsigned long _ebss; EXPORT_SYMBOL(memory_mtd_end); EXPORT_SYMBOL(memory_mtd_start); EXPORT_SYMBOL(mtd_size); diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 440578850ae5..6f38b6120d96 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -497,7 +497,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) srat_num_cpus++; } -int __init +void __init acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) { unsigned long paddr, size; @@ -512,7 +512,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) /* Ignore disabled entries */ if (!(ma->flags & ACPI_SRAT_MEM_ENABLED)) - return -1; + return; /* record this node in proximity bitmap */ pxm_bit_set(pxm); @@ -531,7 +531,6 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) p->size = size; p->nid = pxm; num_node_memblks++; - return 0; } void __init acpi_numa_arch_fixup(void) diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 4a469907f04a..0b0f8b8c4a26 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -54,6 +54,18 @@ config ZONE_DMA bool default y +config CPU_HAS_NO_BITFIELDS + bool + +config CPU_HAS_NO_MULDIV64 + bool + +config CPU_HAS_ADDRESS_SPACES + bool + +config FPU + bool + config HZ int default 1000 if CLEOPATRA diff --git a/trunk/arch/m68k/Kconfig.cpu b/trunk/arch/m68k/Kconfig.cpu index 82068349a2bb..43a9f8f1b8eb 100644 --- a/trunk/arch/m68k/Kconfig.cpu +++ b/trunk/arch/m68k/Kconfig.cpu @@ -37,7 +37,6 @@ config M68000 bool select CPU_HAS_NO_BITFIELDS select CPU_HAS_NO_MULDIV64 - select CPU_HAS_NO_UNALIGNED select GENERIC_CSUM help The Freescale (was Motorola) 68000 CPU is the first generation of @@ -49,7 +48,6 @@ config M68000 config MCPU32 bool select CPU_HAS_NO_BITFIELDS - select CPU_HAS_NO_UNALIGNED help The Freescale (was then Motorola) CPU32 is a CPU core that is based on the 68020 processor. For the most part it is used in @@ -378,18 +376,6 @@ config NODES_SHIFT default "3" depends on !SINGLE_MEMORY_CHUNK -config CPU_HAS_NO_BITFIELDS - bool - -config CPU_HAS_NO_MULDIV64 - bool - -config CPU_HAS_NO_UNALIGNED - bool - -config CPU_HAS_ADDRESS_SPACES - bool - config FPU bool diff --git a/trunk/arch/m68k/apollo/config.c b/trunk/arch/m68k/apollo/config.c index f5565d6eeb8e..0a30406b9442 100644 --- a/trunk/arch/m68k/apollo/config.c +++ b/trunk/arch/m68k/apollo/config.c @@ -177,8 +177,8 @@ irqreturn_t dn_timer_int(int irq, void *dev_id) timer_handler(irq, dev_id); - x = *(volatile unsigned char *)(apollo_timer + 3); - x = *(volatile unsigned char *)(apollo_timer + 5); + x=*(volatile unsigned char *)(timer+3); + x=*(volatile unsigned char *)(timer+5); return IRQ_HANDLED; } @@ -186,17 +186,17 @@ irqreturn_t dn_timer_int(int irq, void *dev_id) void dn_sched_init(irq_handler_t timer_routine) { /* program timer 1 */ - *(volatile unsigned char *)(apollo_timer + 3) = 0x01; - *(volatile unsigned char *)(apollo_timer + 1) = 0x40; - *(volatile unsigned char *)(apollo_timer + 5) = 0x09; - *(volatile unsigned char *)(apollo_timer + 7) = 0xc4; + *(volatile unsigned char *)(timer+3)=0x01; + *(volatile unsigned char *)(timer+1)=0x40; + *(volatile unsigned char *)(timer+5)=0x09; + *(volatile unsigned char *)(timer+7)=0xc4; /* enable IRQ of PIC B */ *(volatile unsigned char *)(pica+1)&=(~8); #if 0 - printk("*(0x10803) %02x\n",*(volatile unsigned char *)(apollo_timer + 0x3)); - printk("*(0x10803) %02x\n",*(volatile unsigned char *)(apollo_timer + 0x3)); + printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); + printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); #endif if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine)) diff --git a/trunk/arch/m68k/include/asm/Kbuild b/trunk/arch/m68k/include/asm/Kbuild index a74e5d95c384..eafa2539a8ee 100644 --- a/trunk/arch/m68k/include/asm/Kbuild +++ b/trunk/arch/m68k/include/asm/Kbuild @@ -1,29 +1,4 @@ include include/asm-generic/Kbuild.asm header-y += cachectl.h -generic-y += bitsperlong.h -generic-y += cputime.h -generic-y += device.h -generic-y += emergency-restart.h -generic-y += errno.h -generic-y += futex.h -generic-y += ioctl.h -generic-y += ipcbuf.h -generic-y += irq_regs.h -generic-y += kdebug.h -generic-y += kmap_types.h -generic-y += kvm_para.h -generic-y += local64.h -generic-y += local.h -generic-y += mman.h -generic-y += mutex.h -generic-y += percpu.h -generic-y += resource.h -generic-y += scatterlist.h -generic-y += sections.h -generic-y += siginfo.h -generic-y += statfs.h -generic-y += topology.h -generic-y += types.h generic-y += word-at-a-time.h -generic-y += xor.h diff --git a/trunk/arch/m68k/include/asm/MC68332.h b/trunk/arch/m68k/include/asm/MC68332.h new file mode 100644 index 000000000000..6bb8f02685a2 --- /dev/null +++ b/trunk/arch/m68k/include/asm/MC68332.h @@ -0,0 +1,152 @@ + +/* include/asm-m68knommu/MC68332.h: '332 control registers + * + * Copyright (C) 1998 Kenneth Albanowski , + * + */ + +#ifndef _MC68332_H_ +#define _MC68332_H_ + +#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) +#define WORD_REF(addr) (*((volatile unsigned short*)addr)) + +#define PORTE_ADDR 0xfffa11 +#define PORTE BYTE_REF(PORTE_ADDR) +#define DDRE_ADDR 0xfffa15 +#define DDRE BYTE_REF(DDRE_ADDR) +#define PEPAR_ADDR 0xfffa17 +#define PEPAR BYTE_REF(PEPAR_ADDR) + +#define PORTF_ADDR 0xfffa19 +#define PORTF BYTE_REF(PORTF_ADDR) +#define DDRF_ADDR 0xfffa1d +#define DDRF BYTE_REF(DDRF_ADDR) +#define PFPAR_ADDR 0xfffa1f +#define PFPAR BYTE_REF(PFPAR_ADDR) + +#define PORTQS_ADDR 0xfffc15 +#define PORTQS BYTE_REF(PORTQS_ADDR) +#define DDRQS_ADDR 0xfffc17 +#define DDRQS BYTE_REF(DDRQS_ADDR) +#define PQSPAR_ADDR 0xfffc16 +#define PQSPAR BYTE_REF(PQSPAR_ADDR) + +#define CSPAR0_ADDR 0xFFFA44 +#define CSPAR0 WORD_REF(CSPAR0_ADDR) +#define CSPAR1_ADDR 0xFFFA46 +#define CSPAR1 WORD_REF(CSPAR1_ADDR) +#define CSARBT_ADDR 0xFFFA48 +#define CSARBT WORD_REF(CSARBT_ADDR) +#define CSOPBT_ADDR 0xFFFA4A +#define CSOPBT WORD_REF(CSOPBT_ADDR) +#define CSBAR0_ADDR 0xFFFA4C +#define CSBAR0 WORD_REF(CSBAR0_ADDR) +#define CSOR0_ADDR 0xFFFA4E +#define CSOR0 WORD_REF(CSOR0_ADDR) +#define CSBAR1_ADDR 0xFFFA50 +#define CSBAR1 WORD_REF(CSBAR1_ADDR) +#define CSOR1_ADDR 0xFFFA52 +#define CSOR1 WORD_REF(CSOR1_ADDR) +#define CSBAR2_ADDR 0xFFFA54 +#define CSBAR2 WORD_REF(CSBAR2_ADDR) +#define CSOR2_ADDR 0xFFFA56 +#define CSOR2 WORD_REF(CSOR2_ADDR) +#define CSBAR3_ADDR 0xFFFA58 +#define CSBAR3 WORD_REF(CSBAR3_ADDR) +#define CSOR3_ADDR 0xFFFA5A +#define CSOR3 WORD_REF(CSOR3_ADDR) +#define CSBAR4_ADDR 0xFFFA5C +#define CSBAR4 WORD_REF(CSBAR4_ADDR) +#define CSOR4_ADDR 0xFFFA5E +#define CSOR4 WORD_REF(CSOR4_ADDR) +#define CSBAR5_ADDR 0xFFFA60 +#define CSBAR5 WORD_REF(CSBAR5_ADDR) +#define CSOR5_ADDR 0xFFFA62 +#define CSOR5 WORD_REF(CSOR5_ADDR) +#define CSBAR6_ADDR 0xFFFA64 +#define CSBAR6 WORD_REF(CSBAR6_ADDR) +#define CSOR6_ADDR 0xFFFA66 +#define CSOR6 WORD_REF(CSOR6_ADDR) +#define CSBAR7_ADDR 0xFFFA68 +#define CSBAR7 WORD_REF(CSBAR7_ADDR) +#define CSOR7_ADDR 0xFFFA6A +#define CSOR7 WORD_REF(CSOR7_ADDR) +#define CSBAR8_ADDR 0xFFFA6C +#define CSBAR8 WORD_REF(CSBAR8_ADDR) +#define CSOR8_ADDR 0xFFFA6E +#define CSOR8 WORD_REF(CSOR8_ADDR) +#define CSBAR9_ADDR 0xFFFA70 +#define CSBAR9 WORD_REF(CSBAR9_ADDR) +#define CSOR9_ADDR 0xFFFA72 +#define CSOR9 WORD_REF(CSOR9_ADDR) +#define CSBAR10_ADDR 0xFFFA74 +#define CSBAR10 WORD_REF(CSBAR10_ADDR) +#define CSOR10_ADDR 0xFFFA76 +#define CSOR10 WORD_REF(CSOR10_ADDR) + +#define CSOR_MODE_ASYNC 0x0000 +#define CSOR_MODE_SYNC 0x8000 +#define CSOR_MODE_MASK 0x8000 +#define CSOR_BYTE_DISABLE 0x0000 +#define CSOR_BYTE_UPPER 0x4000 +#define CSOR_BYTE_LOWER 0x2000 +#define CSOR_BYTE_BOTH 0x6000 +#define CSOR_BYTE_MASK 0x6000 +#define CSOR_RW_RSVD 0x0000 +#define CSOR_RW_READ 0x0800 +#define CSOR_RW_WRITE 0x1000 +#define CSOR_RW_BOTH 0x1800 +#define CSOR_RW_MASK 0x1800 +#define CSOR_STROBE_DS 0x0400 +#define CSOR_STROBE_AS 0x0000 +#define CSOR_STROBE_MASK 0x0400 +#define CSOR_DSACK_WAIT(x) (wait << 6) +#define CSOR_DSACK_FTERM (14 << 6) +#define CSOR_DSACK_EXTERNAL (15 << 6) +#define CSOR_DSACK_MASK 0x03c0 +#define CSOR_SPACE_CPU 0x0000 +#define CSOR_SPACE_USER 0x0010 +#define CSOR_SPACE_SU 0x0020 +#define CSOR_SPACE_BOTH 0x0030 +#define CSOR_SPACE_MASK 0x0030 +#define CSOR_IPL_ALL 0x0000 +#define CSOR_IPL_PRIORITY(x) (x << 1) +#define CSOR_IPL_MASK 0x000e +#define CSOR_AVEC_ON 0x0001 +#define CSOR_AVEC_OFF 0x0000 +#define CSOR_AVEC_MASK 0x0001 + +#define CSBAR_ADDR(x) ((addr >> 11) << 3) +#define CSBAR_ADDR_MASK 0xfff8 +#define CSBAR_BLKSIZE_2K 0x0000 +#define CSBAR_BLKSIZE_8K 0x0001 +#define CSBAR_BLKSIZE_16K 0x0002 +#define CSBAR_BLKSIZE_64K 0x0003 +#define CSBAR_BLKSIZE_128K 0x0004 +#define CSBAR_BLKSIZE_256K 0x0005 +#define CSBAR_BLKSIZE_512K 0x0006 +#define CSBAR_BLKSIZE_1M 0x0007 +#define CSBAR_BLKSIZE_MASK 0x0007 + +#define CSPAR_DISC 0 +#define CSPAR_ALT 1 +#define CSPAR_CS8 2 +#define CSPAR_CS16 3 +#define CSPAR_MASK 3 + +#define CSPAR0_CSBOOT(x) (x << 0) +#define CSPAR0_CS0(x) (x << 2) +#define CSPAR0_CS1(x) (x << 4) +#define CSPAR0_CS2(x) (x << 6) +#define CSPAR0_CS3(x) (x << 8) +#define CSPAR0_CS4(x) (x << 10) +#define CSPAR0_CS5(x) (x << 12) + +#define CSPAR1_CS6(x) (x << 0) +#define CSPAR1_CS7(x) (x << 2) +#define CSPAR1_CS8(x) (x << 4) +#define CSPAR1_CS9(x) (x << 6) +#define CSPAR1_CS10(x) (x << 8) + +#endif diff --git a/trunk/arch/m68k/include/asm/apollodma.h b/trunk/arch/m68k/include/asm/apollodma.h new file mode 100644 index 000000000000..954adc851adb --- /dev/null +++ b/trunk/arch/m68k/include/asm/apollodma.h @@ -0,0 +1,248 @@ +/* + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +#ifndef _ASM_APOLLO_DMA_H +#define _ASM_APOLLO_DMA_H + +#include /* need byte IO */ +#include /* And spinlocks */ +#include + + +#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val)) +#define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE))) + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + +/* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x10C00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG (IO_DMA1_BASE+0x08) /* command register (w) */ +#define DMA1_STAT_REG (IO_DMA1_BASE+0x08) /* status register (r) */ +#define DMA1_REQ_REG (IO_DMA1_BASE+0x09) /* request register (w) */ +#define DMA1_MASK_REG (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */ +#define DMA1_MODE_REG (IO_DMA1_BASE+0x0B) /* mode register (w) */ +#define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */ +#define DMA1_RESET_REG (IO_DMA1_BASE+0x0D) /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E) /* Clear Mask */ +#define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */ + +#define DMA2_CMD_REG (IO_DMA2_BASE+0x10) /* command register (w) */ +#define DMA2_STAT_REG (IO_DMA2_BASE+0x10) /* status register (r) */ +#define DMA2_REQ_REG (IO_DMA2_BASE+0x12) /* request register (w) */ +#define DMA2_MASK_REG (IO_DMA2_BASE+0x14) /* single-channel mask (w) */ +#define DMA2_MODE_REG (IO_DMA2_BASE+0x16) /* mode register (w) */ +#define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */ +#define DMA2_RESET_REG (IO_DMA2_BASE+0x1A) /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C) /* Clear Mask */ +#define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */ + +#define DMA_ADDR_0 (IO_DMA1_BASE+0x00) /* DMA address registers */ +#define DMA_ADDR_1 (IO_DMA1_BASE+0x02) +#define DMA_ADDR_2 (IO_DMA1_BASE+0x04) +#define DMA_ADDR_3 (IO_DMA1_BASE+0x06) +#define DMA_ADDR_4 (IO_DMA2_BASE+0x00) +#define DMA_ADDR_5 (IO_DMA2_BASE+0x04) +#define DMA_ADDR_6 (IO_DMA2_BASE+0x08) +#define DMA_ADDR_7 (IO_DMA2_BASE+0x0C) + +#define DMA_CNT_0 (IO_DMA1_BASE+0x01) /* DMA count registers */ +#define DMA_CNT_1 (IO_DMA1_BASE+0x03) +#define DMA_CNT_2 (IO_DMA1_BASE+0x05) +#define DMA_CNT_3 (IO_DMA1_BASE+0x07) +#define DMA_CNT_4 (IO_DMA2_BASE+0x02) +#define DMA_CNT_5 (IO_DMA2_BASE+0x06) +#define DMA_CNT_6 (IO_DMA2_BASE+0x0A) +#define DMA_CNT_7 (IO_DMA2_BASE+0x0E) + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +#define DMA_AUTOINIT 0x10 + +#define DMA_8BIT 0 +#define DMA_16BIT 1 +#define DMA_BUSMASTER 2 + +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr, DMA1_MASK_REG); + else + dma_outb(dmanr & 3, DMA2_MASK_REG); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while holding the DMA lock ! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + if (dmanr <= 3) { + dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr<=3)? count : (count<<1); +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +/* These are in arch/m68k/apollo/dma.c: */ +extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type); +extern void dma_unmap_page(unsigned short dma_addr); + +#endif /* _ASM_APOLLO_DMA_H */ diff --git a/trunk/arch/m68k/include/asm/apollohw.h b/trunk/arch/m68k/include/asm/apollohw.h index 635ef4f89010..a1373b9aa281 100644 --- a/trunk/arch/m68k/include/asm/apollohw.h +++ b/trunk/arch/m68k/include/asm/apollohw.h @@ -98,7 +98,7 @@ extern u_long timer_physaddr; #define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr)) #define pica (IO_BASE + pica_physaddr) #define picb (IO_BASE + picb_physaddr) -#define apollo_timer (IO_BASE + timer_physaddr) +#define timer (IO_BASE + timer_physaddr) #define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000)) #define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE) diff --git a/trunk/arch/m68k/include/asm/bitsperlong.h b/trunk/arch/m68k/include/asm/bitsperlong.h new file mode 100644 index 000000000000..6dc0bb0c13b2 --- /dev/null +++ b/trunk/arch/m68k/include/asm/bitsperlong.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/include/asm/cputime.h b/trunk/arch/m68k/include/asm/cputime.h new file mode 100644 index 000000000000..c79c5e892305 --- /dev/null +++ b/trunk/arch/m68k/include/asm/cputime.h @@ -0,0 +1,6 @@ +#ifndef __M68K_CPUTIME_H +#define __M68K_CPUTIME_H + +#include + +#endif /* __M68K_CPUTIME_H */ diff --git a/trunk/arch/m68k/include/asm/delay.h b/trunk/arch/m68k/include/asm/delay.h index 12d8fe4f1d30..9c09becfd4c9 100644 --- a/trunk/arch/m68k/include/asm/delay.h +++ b/trunk/arch/m68k/include/asm/delay.h @@ -43,7 +43,7 @@ static inline void __delay(unsigned long loops) extern void __bad_udelay(void); -#ifdef CONFIG_CPU_HAS_NO_MULDIV64 +#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) /* * The simpler m68k and ColdFire processors do not have a 32*32->64 * multiply instruction. So we need to handle them a little differently. diff --git a/trunk/arch/m68k/include/asm/device.h b/trunk/arch/m68k/include/asm/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/trunk/arch/m68k/include/asm/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/trunk/arch/m68k/include/asm/emergency-restart.h b/trunk/arch/m68k/include/asm/emergency-restart.h new file mode 100644 index 000000000000..108d8c48e42e --- /dev/null +++ b/trunk/arch/m68k/include/asm/emergency-restart.h @@ -0,0 +1,6 @@ +#ifndef _ASM_EMERGENCY_RESTART_H +#define _ASM_EMERGENCY_RESTART_H + +#include + +#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/trunk/arch/m68k/include/asm/errno.h b/trunk/arch/m68k/include/asm/errno.h new file mode 100644 index 000000000000..0d4e188d6ef6 --- /dev/null +++ b/trunk/arch/m68k/include/asm/errno.h @@ -0,0 +1,6 @@ +#ifndef _M68K_ERRNO_H +#define _M68K_ERRNO_H + +#include + +#endif /* _M68K_ERRNO_H */ diff --git a/trunk/arch/m68k/include/asm/futex.h b/trunk/arch/m68k/include/asm/futex.h new file mode 100644 index 000000000000..6a332a9f099c --- /dev/null +++ b/trunk/arch/m68k/include/asm/futex.h @@ -0,0 +1,6 @@ +#ifndef _ASM_FUTEX_H +#define _ASM_FUTEX_H + +#include + +#endif diff --git a/trunk/arch/m68k/include/asm/ioctl.h b/trunk/arch/m68k/include/asm/ioctl.h new file mode 100644 index 000000000000..b279fe06dfe5 --- /dev/null +++ b/trunk/arch/m68k/include/asm/ioctl.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/include/asm/ipcbuf.h b/trunk/arch/m68k/include/asm/ipcbuf.h new file mode 100644 index 000000000000..84c7e51cb6d0 --- /dev/null +++ b/trunk/arch/m68k/include/asm/ipcbuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/include/asm/irq_regs.h b/trunk/arch/m68k/include/asm/irq_regs.h new file mode 100644 index 000000000000..3dd9c0b70270 --- /dev/null +++ b/trunk/arch/m68k/include/asm/irq_regs.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/include/asm/kdebug.h b/trunk/arch/m68k/include/asm/kdebug.h new file mode 100644 index 000000000000..6ece1b037665 --- /dev/null +++ b/trunk/arch/m68k/include/asm/kdebug.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/include/asm/kmap_types.h b/trunk/arch/m68k/include/asm/kmap_types.h new file mode 100644 index 000000000000..3413cc1390ec --- /dev/null +++ b/trunk/arch/m68k/include/asm/kmap_types.h @@ -0,0 +1,6 @@ +#ifndef __ASM_M68K_KMAP_TYPES_H +#define __ASM_M68K_KMAP_TYPES_H + +#include + +#endif /* __ASM_M68K_KMAP_TYPES_H */ diff --git a/trunk/arch/m68k/include/asm/kvm_para.h b/trunk/arch/m68k/include/asm/kvm_para.h new file mode 100644 index 000000000000..14fab8f0b957 --- /dev/null +++ b/trunk/arch/m68k/include/asm/kvm_para.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/include/asm/local.h b/trunk/arch/m68k/include/asm/local.h new file mode 100644 index 000000000000..6c259263e1f0 --- /dev/null +++ b/trunk/arch/m68k/include/asm/local.h @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_LOCAL_H +#define _ASM_M68K_LOCAL_H + +#include + +#endif /* _ASM_M68K_LOCAL_H */ diff --git a/trunk/arch/m68k/include/asm/local64.h b/trunk/arch/m68k/include/asm/local64.h new file mode 100644 index 000000000000..36c93b5cc239 --- /dev/null +++ b/trunk/arch/m68k/include/asm/local64.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/include/asm/mac_mouse.h b/trunk/arch/m68k/include/asm/mac_mouse.h new file mode 100644 index 000000000000..39a5c292eaee --- /dev/null +++ b/trunk/arch/m68k/include/asm/mac_mouse.h @@ -0,0 +1,23 @@ +#ifndef _ASM_MAC_MOUSE_H +#define _ASM_MAC_MOUSE_H + +/* + * linux/include/asm-m68k/mac_mouse.h + * header file for Macintosh ADB mouse driver + * 27-10-97 Michael Schmitz + * copied from: + * header file for Atari Mouse driver + * by Robert de Vries (robert@and.nl) on 19Jul93 + */ + +struct mouse_status { + char buttons; + short dx; + short dy; + int ready; + int active; + wait_queue_head_t wait; + struct fasync_struct *fasyncptr; +}; + +#endif diff --git a/trunk/arch/m68k/include/asm/mcfmbus.h b/trunk/arch/m68k/include/asm/mcfmbus.h new file mode 100644 index 000000000000..319899c47a2c --- /dev/null +++ b/trunk/arch/m68k/include/asm/mcfmbus.h @@ -0,0 +1,77 @@ +/****************************************************************************/ + +/* + * mcfmbus.h -- Coldfire MBUS support defines. + * + * (C) Copyright 1999, Martin Floeer (mfloeer@axcent.de) + */ + +/****************************************************************************/ + + +#ifndef mcfmbus_h +#define mcfmbus_h + + +#define MCFMBUS_BASE 0x280 +#define MCFMBUS_IRQ_VECTOR 0x19 +#define MCFMBUS_IRQ 0x1 +#define MCFMBUS_CLK 0x3f +#define MCFMBUS_IRQ_LEVEL 0x07 /*IRQ Level 1*/ +#define MCFMBUS_ADDRESS 0x01 + + +/* +* Define the 5307 MBUS register set addresses +*/ + +#define MCFMBUS_MADR 0x00 +#define MCFMBUS_MFDR 0x04 +#define MCFMBUS_MBCR 0x08 +#define MCFMBUS_MBSR 0x0C +#define MCFMBUS_MBDR 0x10 + + +#define MCFMBUS_MADR_ADDR(a) (((a)&0x7F)<<0x01) /*Slave Address*/ + +#define MCFMBUS_MFDR_MBC(a) ((a)&0x3F) /*M-Bus Clock*/ + +/* +* Define bit flags in Control Register +*/ + +#define MCFMBUS_MBCR_MEN (0x80) /* M-Bus Enable */ +#define MCFMBUS_MBCR_MIEN (0x40) /* M-Bus Interrupt Enable */ +#define MCFMBUS_MBCR_MSTA (0x20) /* Master/Slave Mode Select Bit */ +#define MCFMBUS_MBCR_MTX (0x10) /* Transmit/Rcv Mode Select Bit */ +#define MCFMBUS_MBCR_TXAK (0x08) /* Transmit Acknowledge Enable */ +#define MCFMBUS_MBCR_RSTA (0x04) /* Repeat Start */ + +/* +* Define bit flags in Status Register +*/ + +#define MCFMBUS_MBSR_MCF (0x80) /* Data Transfer Complete */ +#define MCFMBUS_MBSR_MAAS (0x40) /* Addressed as a Slave */ +#define MCFMBUS_MBSR_MBB (0x20) /* Bus Busy */ +#define MCFMBUS_MBSR_MAL (0x10) /* Arbitration Lost */ +#define MCFMBUS_MBSR_SRW (0x04) /* Slave Transmit */ +#define MCFMBUS_MBSR_MIF (0x02) /* M-Bus Interrupt */ +#define MCFMBUS_MBSR_RXAK (0x01) /* No Acknowledge Received */ + +/* +* Define bit flags in DATA I/O Register +*/ + +#define MCFMBUS_MBDR_READ (0x01) /* 1=read 0=write MBUS */ + +#define MBUSIOCSCLOCK 1 +#define MBUSIOCGCLOCK 2 +#define MBUSIOCSADDR 3 +#define MBUSIOCGADDR 4 +#define MBUSIOCSSLADDR 5 +#define MBUSIOCGSLADDR 6 +#define MBUSIOCSSUBADDR 7 +#define MBUSIOCGSUBADDR 8 + +#endif diff --git a/trunk/arch/m68k/include/asm/mman.h b/trunk/arch/m68k/include/asm/mman.h new file mode 100644 index 000000000000..8eebf89f5ab1 --- /dev/null +++ b/trunk/arch/m68k/include/asm/mman.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/include/asm/mutex.h b/trunk/arch/m68k/include/asm/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/trunk/arch/m68k/include/asm/mutex.h @@ -0,0 +1,9 @@ +/* + * Pull in the generic implementation for the mutex fastpath. + * + * TODO: implement optimized primitives instead, or leave the generic + * implementation in place, or pick the atomic_xchg() based generic + * implementation. (see asm-generic/mutex-xchg.h for details) + */ + +#include diff --git a/trunk/arch/m68k/include/asm/percpu.h b/trunk/arch/m68k/include/asm/percpu.h new file mode 100644 index 000000000000..0859d048faf5 --- /dev/null +++ b/trunk/arch/m68k/include/asm/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ASM_M68K_PERCPU_H +#define __ASM_M68K_PERCPU_H + +#include + +#endif /* __ASM_M68K_PERCPU_H */ diff --git a/trunk/arch/m68k/include/asm/resource.h b/trunk/arch/m68k/include/asm/resource.h new file mode 100644 index 000000000000..e7d35019f337 --- /dev/null +++ b/trunk/arch/m68k/include/asm/resource.h @@ -0,0 +1,6 @@ +#ifndef _M68K_RESOURCE_H +#define _M68K_RESOURCE_H + +#include + +#endif /* _M68K_RESOURCE_H */ diff --git a/trunk/arch/m68k/include/asm/sbus.h b/trunk/arch/m68k/include/asm/sbus.h new file mode 100644 index 000000000000..bfe3ba147f2e --- /dev/null +++ b/trunk/arch/m68k/include/asm/sbus.h @@ -0,0 +1,45 @@ +/* + * some sbus structures and macros to make usage of sbus drivers possible + */ + +#ifndef __M68K_SBUS_H +#define __M68K_SBUS_H + +struct sbus_dev { + struct { + unsigned int which_io; + unsigned int phys_addr; + } reg_addrs[1]; +}; + +/* sbus IO functions stolen from include/asm-sparc/io.h for the serial driver */ +/* No SBUS on the Sun3, kludge -- sam */ + +static inline void _sbus_writeb(unsigned char val, unsigned long addr) +{ + *(volatile unsigned char *)addr = val; +} + +static inline unsigned char _sbus_readb(unsigned long addr) +{ + return *(volatile unsigned char *)addr; +} + +static inline void _sbus_writel(unsigned long val, unsigned long addr) +{ + *(volatile unsigned long *)addr = val; + +} + +extern inline unsigned long _sbus_readl(unsigned long addr) +{ + return *(volatile unsigned long *)addr; +} + + +#define sbus_readb(a) _sbus_readb((unsigned long)a) +#define sbus_writeb(v, a) _sbus_writeb(v, (unsigned long)a) +#define sbus_readl(a) _sbus_readl((unsigned long)a) +#define sbus_writel(v, a) _sbus_writel(v, (unsigned long)a) + +#endif diff --git a/trunk/arch/m68k/include/asm/scatterlist.h b/trunk/arch/m68k/include/asm/scatterlist.h new file mode 100644 index 000000000000..312505452a1e --- /dev/null +++ b/trunk/arch/m68k/include/asm/scatterlist.h @@ -0,0 +1,6 @@ +#ifndef _M68K_SCATTERLIST_H +#define _M68K_SCATTERLIST_H + +#include + +#endif /* !(_M68K_SCATTERLIST_H) */ diff --git a/trunk/arch/m68k/include/asm/sections.h b/trunk/arch/m68k/include/asm/sections.h new file mode 100644 index 000000000000..5277e52715ec --- /dev/null +++ b/trunk/arch/m68k/include/asm/sections.h @@ -0,0 +1,8 @@ +#ifndef _ASM_M68K_SECTIONS_H +#define _ASM_M68K_SECTIONS_H + +#include + +extern char _sbss[], _ebss[]; + +#endif /* _ASM_M68K_SECTIONS_H */ diff --git a/trunk/arch/m68k/include/asm/shm.h b/trunk/arch/m68k/include/asm/shm.h new file mode 100644 index 000000000000..fa56ec84a126 --- /dev/null +++ b/trunk/arch/m68k/include/asm/shm.h @@ -0,0 +1,31 @@ +#ifndef _M68K_SHM_H +#define _M68K_SHM_H + + +/* format of page table entries that correspond to shared memory pages + currently out in swap space (see also mm/swap.c): + bits 0-1 (PAGE_PRESENT) is = 0 + bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE + bits 31..9 are used like this: + bits 15..9 (SHM_ID) the id of the shared memory segment + bits 30..16 (SHM_IDX) the index of the page within the shared memory segment + (actually only bits 25..16 get used since SHMMAX is so low) + bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach +*/ +/* on the m68k both bits 0 and 1 must be zero */ +/* format on the sun3 is similar, but bits 30, 31 are set to zero and all + others are reduced by 2. --m */ + +#ifndef CONFIG_SUN3 +#define SHM_ID_SHIFT 9 +#else +#define SHM_ID_SHIFT 7 +#endif +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +#endif /* _M68K_SHM_H */ diff --git a/trunk/arch/m68k/include/asm/siginfo.h b/trunk/arch/m68k/include/asm/siginfo.h new file mode 100644 index 000000000000..851d3d784b53 --- /dev/null +++ b/trunk/arch/m68k/include/asm/siginfo.h @@ -0,0 +1,6 @@ +#ifndef _M68K_SIGINFO_H +#define _M68K_SIGINFO_H + +#include + +#endif diff --git a/trunk/arch/m68k/include/asm/statfs.h b/trunk/arch/m68k/include/asm/statfs.h new file mode 100644 index 000000000000..08d93f14e061 --- /dev/null +++ b/trunk/arch/m68k/include/asm/statfs.h @@ -0,0 +1,6 @@ +#ifndef _M68K_STATFS_H +#define _M68K_STATFS_H + +#include + +#endif /* _M68K_STATFS_H */ diff --git a/trunk/arch/m68k/include/asm/topology.h b/trunk/arch/m68k/include/asm/topology.h new file mode 100644 index 000000000000..ca173e9f26ff --- /dev/null +++ b/trunk/arch/m68k/include/asm/topology.h @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_TOPOLOGY_H +#define _ASM_M68K_TOPOLOGY_H + +#include + +#endif /* _ASM_M68K_TOPOLOGY_H */ diff --git a/trunk/arch/m68k/include/asm/types.h b/trunk/arch/m68k/include/asm/types.h new file mode 100644 index 000000000000..89705adcbd52 --- /dev/null +++ b/trunk/arch/m68k/include/asm/types.h @@ -0,0 +1,22 @@ +#ifndef _M68K_TYPES_H +#define _M68K_TYPES_H + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ +#include + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#define BITS_PER_LONG 32 + +#endif /* __KERNEL__ */ + +#endif /* _M68K_TYPES_H */ diff --git a/trunk/arch/m68k/include/asm/unaligned.h b/trunk/arch/m68k/include/asm/unaligned.h index 2b3ca0bf7a0d..f4043ae63db1 100644 --- a/trunk/arch/m68k/include/asm/unaligned.h +++ b/trunk/arch/m68k/include/asm/unaligned.h @@ -2,7 +2,7 @@ #define _ASM_M68K_UNALIGNED_H -#ifdef CONFIG_CPU_HAS_NO_UNALIGNED +#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68000) #include #include #include @@ -12,7 +12,7 @@ #else /* - * The m68k can do unaligned accesses itself. + * The m68k can do unaligned accesses itself. */ #include #include diff --git a/trunk/arch/m68k/include/asm/xor.h b/trunk/arch/m68k/include/asm/xor.h new file mode 100644 index 000000000000..c82eb12a5b18 --- /dev/null +++ b/trunk/arch/m68k/include/asm/xor.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68k/kernel/setup_no.c b/trunk/arch/m68k/kernel/setup_no.c index 71fb29938dba..7dc186b7a85f 100644 --- a/trunk/arch/m68k/kernel/setup_no.c +++ b/trunk/arch/m68k/kernel/setup_no.c @@ -218,10 +218,13 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n"); #endif - pr_debug("KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p BSS=0x%p-0x%p\n", - _stext, _etext, _sdata, _edata, __bss_start, __bss_stop); - pr_debug("MEMORY -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx\n ", - __bss_stop, memory_start, memory_start, memory_end); + pr_debug("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x " + "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext, + (int) &_sdata, (int) &_edata, + (int) &_sbss, (int) &_ebss); + pr_debug("MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ", + (int) &_ebss, (int) memory_start, + (int) memory_start, (int) memory_end); /* Keep a copy of command line */ *cmdline_p = &command_line[0]; diff --git a/trunk/arch/m68k/kernel/sys_m68k.c b/trunk/arch/m68k/kernel/sys_m68k.c index 9a5932ec3689..8623f8dc16f8 100644 --- a/trunk/arch/m68k/kernel/sys_m68k.c +++ b/trunk/arch/m68k/kernel/sys_m68k.c @@ -479,13 +479,9 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, goto bad_access; } - /* - * No need to check for EFAULT; we know that the page is - * present and writable. - */ - __get_user(mem_value, mem); + mem_value = *mem; if (mem_value == oldval) - __put_user(newval, mem); + *mem = newval; pte_unmap_unlock(pte, ptl); up_read(&mm->mmap_sem); diff --git a/trunk/arch/m68k/kernel/vmlinux-nommu.lds b/trunk/arch/m68k/kernel/vmlinux-nommu.lds index 06a763f49fd3..40e02d9c38b4 100644 --- a/trunk/arch/m68k/kernel/vmlinux-nommu.lds +++ b/trunk/arch/m68k/kernel/vmlinux-nommu.lds @@ -78,7 +78,9 @@ SECTIONS { __init_end = .; } + _sbss = .; BSS_SECTION(0, 0, 0) + _ebss = .; _end = .; diff --git a/trunk/arch/m68k/kernel/vmlinux-std.lds b/trunk/arch/m68k/kernel/vmlinux-std.lds index d0993594f558..63407c836826 100644 --- a/trunk/arch/m68k/kernel/vmlinux-std.lds +++ b/trunk/arch/m68k/kernel/vmlinux-std.lds @@ -31,7 +31,9 @@ SECTIONS RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) + _sbss = .; BSS_SECTION(0, 0, 0) + _ebss = .; _edata = .; /* End of data section */ diff --git a/trunk/arch/m68k/kernel/vmlinux-sun3.lds b/trunk/arch/m68k/kernel/vmlinux-sun3.lds index 8080469ee6c1..ad0f46d64c0b 100644 --- a/trunk/arch/m68k/kernel/vmlinux-sun3.lds +++ b/trunk/arch/m68k/kernel/vmlinux-sun3.lds @@ -44,7 +44,9 @@ __init_begin = .; . = ALIGN(PAGE_SIZE); __init_end = .; + _sbss = .; BSS_SECTION(0, 0, 0) + _ebss = .; _end = . ; diff --git a/trunk/arch/m68k/lib/muldi3.c b/trunk/arch/m68k/lib/muldi3.c index ee5f0b1b5c5d..79e928a525d0 100644 --- a/trunk/arch/m68k/lib/muldi3.c +++ b/trunk/arch/m68k/lib/muldi3.c @@ -19,7 +19,7 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef CONFIG_CPU_HAS_NO_MULDIV64 +#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) #define SI_TYPE_SIZE 32 #define __BITS4 (SI_TYPE_SIZE / 4) diff --git a/trunk/arch/m68k/mm/init_mm.c b/trunk/arch/m68k/mm/init_mm.c index 282f9de68966..f77f258dce3a 100644 --- a/trunk/arch/m68k/mm/init_mm.c +++ b/trunk/arch/m68k/mm/init_mm.c @@ -104,7 +104,7 @@ void __init print_memmap(void) MLK_ROUNDUP(__init_begin, __init_end), MLK_ROUNDUP(_stext, _etext), MLK_ROUNDUP(_sdata, _edata), - MLK_ROUNDUP(__bss_start, __bss_stop)); + MLK_ROUNDUP(_sbss, _ebss)); } void __init mem_init(void) diff --git a/trunk/arch/m68k/mm/init_no.c b/trunk/arch/m68k/mm/init_no.c index 688e3664aea0..345ec0d83e3d 100644 --- a/trunk/arch/m68k/mm/init_no.c +++ b/trunk/arch/m68k/mm/init_no.c @@ -91,7 +91,7 @@ void __init mem_init(void) totalram_pages = free_all_bootmem(); codek = (_etext - _stext) >> 10; - datak = (__bss_stop - _sdata) >> 10; + datak = (_ebss - _sdata) >> 10; initk = (__init_begin - __init_end) >> 10; tmp = nr_free_pages() << PAGE_SHIFT; diff --git a/trunk/arch/m68k/platform/68328/head-de2.S b/trunk/arch/m68k/platform/68328/head-de2.S index 537d3245b539..f632fdcb93e9 100644 --- a/trunk/arch/m68k/platform/68328/head-de2.S +++ b/trunk/arch/m68k/platform/68328/head-de2.S @@ -60,8 +60,8 @@ _start: * Move ROM filesystem above bss :-) */ - moveal #__bss_start, %a0 /* romfs at the start of bss */ - moveal #__bss_stop, %a1 /* Set up destination */ + moveal #_sbss, %a0 /* romfs at the start of bss */ + moveal #_ebss, %a1 /* Set up destination */ movel %a0, %a2 /* Copy of bss start */ movel 8(%a0), %d1 /* Get size of ROMFS */ @@ -84,8 +84,8 @@ _start: * Initialize BSS segment to 0 */ - lea __bss_start, %a0 - lea __bss_stop, %a1 + lea _sbss, %a0 + lea _ebss, %a1 /* Copy 0 to %a0 until %a0 == %a1 */ 2: cmpal %a0, %a1 diff --git a/trunk/arch/m68k/platform/68328/head-pilot.S b/trunk/arch/m68k/platform/68328/head-pilot.S index 45a9dad29e3d..2ebfd6420818 100644 --- a/trunk/arch/m68k/platform/68328/head-pilot.S +++ b/trunk/arch/m68k/platform/68328/head-pilot.S @@ -110,7 +110,7 @@ L0: movel #CONFIG_VECTORBASE, %d7 addl #16, %d7 moveal %d7, %a0 - moveal #__bss_stop, %a1 + moveal #_ebss, %a1 lea %a1@(512), %a2 DBG_PUTC('C') @@ -138,8 +138,8 @@ LD1: DBG_PUTC('E') - moveal #__bss_start, %a0 - moveal #__bss_stop, %a1 + moveal #_sbss, %a0 + moveal #_ebss, %a1 /* Copy 0 to %a0 until %a0 == %a1 */ L1: @@ -150,7 +150,7 @@ L1: DBG_PUTC('F') /* Copy command line from end of bss to command line */ - moveal #__bss_stop, %a0 + moveal #_ebss, %a0 moveal #command_line, %a1 lea %a1@(512), %a2 @@ -165,7 +165,7 @@ L3: movel #_sdata, %d0 movel %d0, _rambase - movel #__bss_stop, %d0 + movel #_ebss, %d0 movel %d0, _ramstart movel %a4, %d0 diff --git a/trunk/arch/m68k/platform/68328/head-ram.S b/trunk/arch/m68k/platform/68328/head-ram.S index 5189ef926098..7f1aeeacb219 100644 --- a/trunk/arch/m68k/platform/68328/head-ram.S +++ b/trunk/arch/m68k/platform/68328/head-ram.S @@ -76,8 +76,8 @@ pclp3: beq pclp3 #endif /* DEBUG */ moveal #0x007ffff0, %ssp - moveal #__bss_start, %a0 - moveal #__bss_stop, %a1 + moveal #_sbss, %a0 + moveal #_ebss, %a1 /* Copy 0 to %a0 until %a0 >= %a1 */ L1: diff --git a/trunk/arch/m68k/platform/68328/head-rom.S b/trunk/arch/m68k/platform/68328/head-rom.S index 3dff98ba2e97..a5ff96d0295f 100644 --- a/trunk/arch/m68k/platform/68328/head-rom.S +++ b/trunk/arch/m68k/platform/68328/head-rom.S @@ -59,8 +59,8 @@ _stext: movew #0x2700,%sr cmpal %a1, %a2 bhi 1b - moveal #__bss_start, %a0 - moveal #__bss_stop, %a1 + moveal #_sbss, %a0 + moveal #_ebss, %a1 /* Copy 0 to %a0 until %a0 == %a1 */ 1: @@ -70,7 +70,7 @@ _stext: movew #0x2700,%sr movel #_sdata, %d0 movel %d0, _rambase - movel #__bss_stop, %d0 + movel #_ebss, %d0 movel %d0, _ramstart movel #RAMEND-CONFIG_MEMORY_RESERVE*0x100000, %d0 movel %d0, _ramend diff --git a/trunk/arch/m68k/platform/68360/head-ram.S b/trunk/arch/m68k/platform/68360/head-ram.S index acd213170d80..8eb94fb6b971 100644 --- a/trunk/arch/m68k/platform/68360/head-ram.S +++ b/trunk/arch/m68k/platform/68360/head-ram.S @@ -219,8 +219,8 @@ LD1: cmp.l #_edata, %a1 blt LD1 - moveal #__bss_start, %a0 - moveal #__bss_stop, %a1 + moveal #_sbss, %a0 + moveal #_ebss, %a1 /* Copy 0 to %a0 until %a0 == %a1 */ L1: @@ -234,7 +234,7 @@ load_quicc: store_ram_size: /* Set ram size information */ move.l #_sdata, _rambase - move.l #__bss_stop, _ramstart + move.l #_ebss, _ramstart move.l #RAMEND, %d0 sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ move.l %d0, _ramend /* Different from RAMEND.*/ diff --git a/trunk/arch/m68k/platform/68360/head-rom.S b/trunk/arch/m68k/platform/68360/head-rom.S index dfc756d99886..97510e55b802 100644 --- a/trunk/arch/m68k/platform/68360/head-rom.S +++ b/trunk/arch/m68k/platform/68360/head-rom.S @@ -13,7 +13,7 @@ */ .global _stext -.global __bss_start +.global _sbss .global _start .global _rambase @@ -229,8 +229,8 @@ LD1: cmp.l #_edata, %a1 blt LD1 - moveal #__bss_start, %a0 - moveal #__bss_stop, %a1 + moveal #_sbss, %a0 + moveal #_ebss, %a1 /* Copy 0 to %a0 until %a0 == %a1 */ L1: @@ -244,7 +244,7 @@ load_quicc: store_ram_size: /* Set ram size information */ move.l #_sdata, _rambase - move.l #__bss_stop, _ramstart + move.l #_ebss, _ramstart move.l #RAMEND, %d0 sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ move.l %d0, _ramend /* Different from RAMEND.*/ diff --git a/trunk/arch/m68k/platform/coldfire/head.S b/trunk/arch/m68k/platform/coldfire/head.S index b88f5716f357..4e0c9eb3bd1f 100644 --- a/trunk/arch/m68k/platform/coldfire/head.S +++ b/trunk/arch/m68k/platform/coldfire/head.S @@ -230,8 +230,8 @@ _vstart: /* * Move ROM filesystem above bss :-) */ - lea __bss_start,%a0 /* get start of bss */ - lea __bss_stop,%a1 /* set up destination */ + lea _sbss,%a0 /* get start of bss */ + lea _ebss,%a1 /* set up destination */ movel %a0,%a2 /* copy of bss start */ movel 8(%a0),%d0 /* get size of ROMFS */ @@ -249,7 +249,7 @@ _copy_romfs: bne _copy_romfs #else /* CONFIG_ROMFS_FS */ - lea __bss_stop,%a1 + lea _ebss,%a1 movel %a1,_ramstart #endif /* CONFIG_ROMFS_FS */ @@ -257,8 +257,8 @@ _copy_romfs: /* * Zero out the bss region. */ - lea __bss_start,%a0 /* get start of bss */ - lea __bss_stop,%a1 /* get end of bss */ + lea _sbss,%a0 /* get start of bss */ + lea _ebss,%a1 /* get end of bss */ clrl %d0 /* set value */ _clear_bss: movel %d0,(%a0)+ /* clear each word */ diff --git a/trunk/arch/m68k/sun3/prom/init.c b/trunk/arch/m68k/sun3/prom/init.c index eeba067d565f..d8e6349336b4 100644 --- a/trunk/arch/m68k/sun3/prom/init.c +++ b/trunk/arch/m68k/sun3/prom/init.c @@ -22,13 +22,57 @@ int prom_root_node; struct linux_nodeops *prom_nodeops; /* You must call prom_init() before you attempt to use any of the - * routines in the prom library. - * It gets passed the pointer to the PROM vector. + * routines in the prom library. It returns 0 on success, 1 on + * failure. It gets passed the pointer to the PROM vector. */ +extern void prom_meminit(void); +extern void prom_ranges_init(void); + void __init prom_init(struct linux_romvec *rp) { romvec = rp; +#ifndef CONFIG_SUN3 + switch(romvec->pv_romvers) { + case 0: + prom_vers = PROM_V0; + break; + case 2: + prom_vers = PROM_V2; + break; + case 3: + prom_vers = PROM_V3; + break; + case 4: + prom_vers = PROM_P1275; + prom_printf("PROMLIB: Sun IEEE Prom not supported yet\n"); + prom_halt(); + break; + default: + prom_printf("PROMLIB: Bad PROM version %d\n", + romvec->pv_romvers); + prom_halt(); + break; + }; + + prom_rev = romvec->pv_plugin_revision; + prom_prev = romvec->pv_printrev; + prom_nodeops = romvec->pv_nodeops; + + prom_root_node = prom_getsibling(0); + if((prom_root_node == 0) || (prom_root_node == -1)) + prom_halt(); + + if((((unsigned long) prom_nodeops) == 0) || + (((unsigned long) prom_nodeops) == -1)) + prom_halt(); + + prom_meminit(); + + prom_ranges_init(); +#endif +// printk("PROMLIB: Sun Boot Prom Version %d Revision %d\n", +// romvec->pv_romvers, prom_rev); /* Initialization successful. */ return; diff --git a/trunk/arch/microblaze/include/asm/sections.h b/trunk/arch/microblaze/include/asm/sections.h index c07ed5d2a820..4487e150b455 100644 --- a/trunk/arch/microblaze/include/asm/sections.h +++ b/trunk/arch/microblaze/include/asm/sections.h @@ -18,6 +18,10 @@ extern char _ssbss[], _esbss[]; extern unsigned long __ivt_start[], __ivt_end[]; extern char _etext[], _stext[]; +# ifdef CONFIG_MTD_UCLINUX +extern char *_ebss; +# endif + extern u32 _fdt_start[], _fdt_end[]; # endif /* !__ASSEMBLY__ */ diff --git a/trunk/arch/microblaze/kernel/microblaze_ksyms.c b/trunk/arch/microblaze/kernel/microblaze_ksyms.c index 2b25bcf05c00..bb4907c828dc 100644 --- a/trunk/arch/microblaze/kernel/microblaze_ksyms.c +++ b/trunk/arch/microblaze/kernel/microblaze_ksyms.c @@ -21,6 +21,9 @@ #include #include +extern char *_ebss; +EXPORT_SYMBOL_GPL(_ebss); + #ifdef CONFIG_FUNCTION_TRACER extern void _mcount(void); EXPORT_SYMBOL(_mcount); diff --git a/trunk/arch/microblaze/kernel/setup.c b/trunk/arch/microblaze/kernel/setup.c index 4da971d4392f..16d8dfd9094b 100644 --- a/trunk/arch/microblaze/kernel/setup.c +++ b/trunk/arch/microblaze/kernel/setup.c @@ -121,7 +121,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, /* Move ROMFS out of BSS before clearing it */ if (romfs_size > 0) { - memmove(&__bss_stop, (int *)romfs_base, romfs_size); + memmove(&_ebss, (int *)romfs_base, romfs_size); klimit += romfs_size; } #endif @@ -165,7 +165,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, BUG_ON(romfs_size < 0); /* What else can we do? */ printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n", - romfs_size, romfs_base, (unsigned)&__bss_stop); + romfs_size, romfs_base, (unsigned)&_ebss); printk("New klimit: 0x%08x\n", (unsigned)klimit); #endif diff --git a/trunk/arch/microblaze/kernel/vmlinux.lds.S b/trunk/arch/microblaze/kernel/vmlinux.lds.S index 936d01a689d7..109e9d86ade4 100644 --- a/trunk/arch/microblaze/kernel/vmlinux.lds.S +++ b/trunk/arch/microblaze/kernel/vmlinux.lds.S @@ -131,6 +131,7 @@ SECTIONS { *(COMMON) . = ALIGN (4) ; __bss_stop = . ; + _ebss = . ; } . = ALIGN(PAGE_SIZE); _end = .; diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 107610e01a29..76de6b68487c 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -124,7 +124,6 @@ config S390 select GENERIC_TIME_VSYSCALL select GENERIC_CLOCKEVENTS select KTIME_SCALAR if 32BIT - select HAVE_ARCH_SECCOMP_FILTER config SCHED_OMIT_FRAME_POINTER def_bool y diff --git a/trunk/arch/s390/include/asm/sparsemem.h b/trunk/arch/s390/include/asm/sparsemem.h index a60d085ddb4d..0fb34027d3f6 100644 --- a/trunk/arch/s390/include/asm/sparsemem.h +++ b/trunk/arch/s390/include/asm/sparsemem.h @@ -4,11 +4,13 @@ #ifdef CONFIG_64BIT #define SECTION_SIZE_BITS 28 +#define MAX_PHYSADDR_BITS 46 #define MAX_PHYSMEM_BITS 46 #else #define SECTION_SIZE_BITS 25 +#define MAX_PHYSADDR_BITS 31 #define MAX_PHYSMEM_BITS 31 #endif /* CONFIG_64BIT */ diff --git a/trunk/arch/s390/include/asm/syscall.h b/trunk/arch/s390/include/asm/syscall.h index fe7b99759e12..fb214dd9b7e0 100644 --- a/trunk/arch/s390/include/asm/syscall.h +++ b/trunk/arch/s390/include/asm/syscall.h @@ -12,7 +12,6 @@ #ifndef _ASM_SYSCALL_H #define _ASM_SYSCALL_H 1 -#include #include #include #include @@ -88,13 +87,4 @@ static inline void syscall_set_arguments(struct task_struct *task, regs->orig_gpr2 = args[0]; } -static inline int syscall_get_arch(struct task_struct *task, - struct pt_regs *regs) -{ -#ifdef CONFIG_COMPAT - if (test_tsk_thread_flag(task, TIF_31BIT)) - return AUDIT_ARCH_S390; -#endif - return sizeof(long) == 8 ? AUDIT_ARCH_S390X : AUDIT_ARCH_S390; -} #endif /* _ASM_SYSCALL_H */ diff --git a/trunk/arch/s390/kernel/compat_linux.c b/trunk/arch/s390/kernel/compat_linux.c index f606d935f495..d1225089a4bb 100644 --- a/trunk/arch/s390/kernel/compat_linux.c +++ b/trunk/arch/s390/kernel/compat_linux.c @@ -620,6 +620,7 @@ asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg) return -EFAULT; if (a.offset & ~PAGE_MASK) return -EINVAL; + a.addr = (unsigned long) compat_ptr(a.addr); return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); } @@ -630,6 +631,7 @@ asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) if (copy_from_user(&a, arg, sizeof(a))) return -EFAULT; + a.addr = (unsigned long) compat_ptr(a.addr); return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); } diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 2d82cfcbce5b..e835d6d5b7fd 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -1635,7 +1635,7 @@ ENTRY(compat_sys_process_vm_readv_wrapper) llgfr %r6,%r6 # unsigned long llgf %r0,164(%r15) # unsigned long stg %r0,160(%r15) - jg compat_sys_process_vm_readv + jg sys_process_vm_readv ENTRY(compat_sys_process_vm_writev_wrapper) lgfr %r2,%r2 # compat_pid_t @@ -1645,4 +1645,4 @@ ENTRY(compat_sys_process_vm_writev_wrapper) llgfr %r6,%r6 # unsigned long llgf %r0,164(%r15) # unsigned long stg %r0,160(%r15) - jg compat_sys_process_vm_writev + jg sys_process_vm_writev diff --git a/trunk/arch/s390/kernel/ptrace.c b/trunk/arch/s390/kernel/ptrace.c index e4be113fbac6..f4eb37680b91 100644 --- a/trunk/arch/s390/kernel/ptrace.c +++ b/trunk/arch/s390/kernel/ptrace.c @@ -719,11 +719,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) long ret = 0; /* Do the secure computing check first. */ - if (secure_computing(regs->gprs[2])) { - /* seccomp failures shouldn't expose any additional code. */ - ret = -1; - goto out; - } + secure_computing_strict(regs->gprs[2]); /* * The sysc_tracesys code in entry.S stored the system @@ -749,7 +745,6 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) regs->gprs[2], regs->orig_gpr2, regs->gprs[3], regs->gprs[4], regs->gprs[5]); -out: return ret ?: regs->gprs[2]; } diff --git a/trunk/arch/s390/kernel/sys_s390.c b/trunk/arch/s390/kernel/sys_s390.c index d0964d22adb5..b4a29eee41b8 100644 --- a/trunk/arch/s390/kernel/sys_s390.c +++ b/trunk/arch/s390/kernel/sys_s390.c @@ -81,12 +81,11 @@ SYSCALL_DEFINE1(s390_personality, unsigned int, personality) { unsigned int ret; - if (personality(current->personality) == PER_LINUX32 && - personality(personality) == PER_LINUX) - personality |= PER_LINUX32; + if (current->personality == PER_LINUX32 && personality == PER_LINUX) + personality = PER_LINUX32; ret = sys_personality(personality); - if (personality(ret) == PER_LINUX32) - ret &= ~PER_LINUX32; + if (ret == PER_LINUX32) + ret = PER_LINUX; return ret; } diff --git a/trunk/arch/sh/boards/Kconfig b/trunk/arch/sh/boards/Kconfig index fb5805745ace..7048c03490d9 100644 --- a/trunk/arch/sh/boards/Kconfig +++ b/trunk/arch/sh/boards/Kconfig @@ -57,7 +57,6 @@ config SH_7724_SOLUTION_ENGINE depends on CPU_SUBTYPE_SH7724 select ARCH_REQUIRE_GPIOLIB select SND_SOC_AK4642 if SND_SIMPLE_CARD - select REGULATOR_FIXED_VOLTAGE if REGULATOR help Select 7724 SolutionEngine if configuring for a Hitachi SH7724 evaluation board. @@ -141,7 +140,6 @@ config SH_RSK bool "Renesas Starter Kit" depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203 || \ CPU_SUBTYPE_SH7264 || CPU_SUBTYPE_SH7269 - select REGULATOR_FIXED_VOLTAGE if REGULATOR help Select this option if configuring for any of the RSK+ MCU evaluation platforms. @@ -161,7 +159,6 @@ config SH_SDK7786 select NO_IOPORT if !PCI select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_SRAM_POOL - select REGULATOR_FIXED_VOLTAGE if REGULATOR help Select SDK7786 if configuring for a Renesas Technology Europe SH7786-65nm board. @@ -176,7 +173,6 @@ config SH_SH7757LCR bool "SH7757LCR" depends on CPU_SUBTYPE_SH7757 select ARCH_REQUIRE_GPIOLIB - select REGULATOR_FIXED_VOLTAGE if REGULATOR config SH_SH7785LCR bool "SH7785LCR" @@ -210,7 +206,6 @@ config SH_MIGOR bool "Migo-R" depends on CPU_SUBTYPE_SH7722 select ARCH_REQUIRE_GPIOLIB - select REGULATOR_FIXED_VOLTAGE if REGULATOR help Select Migo-R if configuring for the SH7722 Migo-R platform by Renesas System Solutions Asia Pte. Ltd. @@ -219,7 +214,6 @@ config SH_AP325RXA bool "AP-325RXA" depends on CPU_SUBTYPE_SH7723 select ARCH_REQUIRE_GPIOLIB - select REGULATOR_FIXED_VOLTAGE if REGULATOR help Renesas "AP-325RXA" support. Compatible with ALGO SYSTEM CO.,LTD. "AP-320A" @@ -228,7 +222,6 @@ config SH_KFR2R09 bool "KFR2R09" depends on CPU_SUBTYPE_SH7724 select ARCH_REQUIRE_GPIOLIB - select REGULATOR_FIXED_VOLTAGE if REGULATOR help "Kit For R2R for 2009" support. @@ -237,7 +230,6 @@ config SH_ECOVEC depends on CPU_SUBTYPE_SH7724 select ARCH_REQUIRE_GPIOLIB select SND_SOC_DA7210 if SND_SIMPLE_CARD - select REGULATOR_FIXED_VOLTAGE if REGULATOR help Renesas "R0P7724LC0011/21RL (EcoVec)" support. @@ -313,7 +305,6 @@ config SH_MAGIC_PANEL_R2 bool "Magic Panel R2" depends on CPU_SUBTYPE_SH7720 select ARCH_REQUIRE_GPIOLIB - select REGULATOR_FIXED_VOLTAGE if REGULATOR help Select Magic Panel R2 if configuring for Magic Panel R2. @@ -325,7 +316,6 @@ config SH_CAYMAN config SH_POLARIS bool "SMSC Polaris" select CPU_HAS_IPR_IRQ - select REGULATOR_FIXED_VOLTAGE if REGULATOR depends on CPU_SUBTYPE_SH7709 help Select if configuring for an SMSC Polaris development board @@ -333,7 +323,6 @@ config SH_POLARIS config SH_SH2007 bool "SH-2007 board" select NO_IOPORT - select REGULATOR_FIXED_VOLTAGE if REGULATOR depends on CPU_SUBTYPE_SH7780 help SH-2007 is a single-board computer based around SH7780 chip @@ -345,7 +334,6 @@ config SH_SH2007 config SH_APSH4A3A bool "AP-SH4A-3A" select SH_ALPHA_BOARD - select REGULATOR_FIXED_VOLTAGE if REGULATOR depends on CPU_SUBTYPE_SH7785 help Select AP-SH4A-3A if configuring for an ALPHAPROJECT AP-SH4A-3A. @@ -354,7 +342,6 @@ config SH_APSH4AD0A bool "AP-SH4AD-0A" select SH_ALPHA_BOARD select SYS_SUPPORTS_PCI - select REGULATOR_FIXED_VOLTAGE if REGULATOR depends on CPU_SUBTYPE_SH7786 help Select AP-SH4AD-0A if configuring for an ALPHAPROJECT AP-SH4AD-0A. diff --git a/trunk/arch/sh/boards/board-apsh4a3a.c b/trunk/arch/sh/boards/board-apsh4a3a.c index 0a39c241628a..2823619c6006 100644 --- a/trunk/arch/sh/boards/board-apsh4a3a.c +++ b/trunk/arch/sh/boards/board-apsh4a3a.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include #include @@ -68,12 +66,6 @@ static struct platform_device nor_flash_device = { .resource = nor_flash_resources, }; -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - static struct resource smsc911x_resources[] = { [0] = { .name = "smsc911x-memory", @@ -113,8 +105,6 @@ static struct platform_device *apsh4a3a_devices[] __initdata = { static int __init apsh4a3a_devices_setup(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - return platform_add_devices(apsh4a3a_devices, ARRAY_SIZE(apsh4a3a_devices)); } diff --git a/trunk/arch/sh/boards/board-apsh4ad0a.c b/trunk/arch/sh/boards/board-apsh4ad0a.c index 92eac3a99187..b4d6292a9247 100644 --- a/trunk/arch/sh/boards/board-apsh4ad0a.c +++ b/trunk/arch/sh/boards/board-apsh4ad0a.c @@ -12,20 +12,12 @@ #include #include #include -#include -#include #include #include #include #include #include -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - static struct resource smsc911x_resources[] = { [0] = { .name = "smsc911x-memory", @@ -64,8 +56,6 @@ static struct platform_device *apsh4ad0a_devices[] __initdata = { static int __init apsh4ad0a_devices_setup(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - return platform_add_devices(apsh4ad0a_devices, ARRAY_SIZE(apsh4ad0a_devices)); } diff --git a/trunk/arch/sh/boards/board-magicpanelr2.c b/trunk/arch/sh/boards/board-magicpanelr2.c index 20500858b56c..90568f9de3a4 100644 --- a/trunk/arch/sh/boards/board-magicpanelr2.c +++ b/trunk/arch/sh/boards/board-magicpanelr2.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -26,12 +24,6 @@ #include #include -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - #define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL) /* Wait until reset finished. Timeout is 100ms. */ @@ -356,8 +348,6 @@ static struct platform_device *mpr2_devices[] __initdata = { static int __init mpr2_devices_setup(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); } device_initcall(mpr2_devices_setup); diff --git a/trunk/arch/sh/boards/board-polaris.c b/trunk/arch/sh/boards/board-polaris.c index 37a08d094727..0978ae2e4847 100644 --- a/trunk/arch/sh/boards/board-polaris.c +++ b/trunk/arch/sh/boards/board-polaris.c @@ -9,8 +9,6 @@ #include #include #include -#include -#include #include #include #include @@ -24,12 +22,6 @@ #define AREA5_WAIT_CTRL (0x1C00) #define WAIT_STATES_10 (0x7) -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - static struct resource smsc911x_resources[] = { [0] = { .name = "smsc911x-memory", @@ -96,8 +88,6 @@ static int __init polaris_initialise(void) printk(KERN_INFO "Configuring Polaris external bus\n"); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - /* Configure area 5 with 2 wait states */ wcr = __raw_readw(WCR2); wcr &= (~AREA5_WAIT_CTRL); diff --git a/trunk/arch/sh/boards/board-sh2007.c b/trunk/arch/sh/boards/board-sh2007.c index 1980bb7e5780..b90b78f6a829 100644 --- a/trunk/arch/sh/boards/board-sh2007.c +++ b/trunk/arch/sh/boards/board-sh2007.c @@ -6,8 +6,6 @@ */ #include #include -#include -#include #include #include #include @@ -15,14 +13,6 @@ #include #include -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), - REGULATOR_SUPPLY("vddvario", "smsc911x.1"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), -}; - struct smsc911x_platform_config smc911x_info = { .flags = SMSC911X_USE_32BIT, .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, @@ -108,8 +98,6 @@ static struct platform_device *sh2007_devices[] __initdata = { static int __init sh2007_io_init(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices)); return 0; } diff --git a/trunk/arch/sh/boards/board-sh7757lcr.c b/trunk/arch/sh/boards/board-sh7757lcr.c index 41f86702eb9f..5087f8bb4cff 100644 --- a/trunk/arch/sh/boards/board-sh7757lcr.c +++ b/trunk/arch/sh/boards/board-sh7757lcr.c @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include #include @@ -201,15 +199,6 @@ static struct platform_device sh7757_eth_giga1_device = { }, }; -/* Fixed 3.3V regulator to be used by SDHI0, MMCIF */ -static struct regulator_consumer_supply fixed3v3_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), -}; - /* SH_MMCIF */ static struct resource sh_mmcif_resources[] = { [0] = { @@ -340,9 +329,6 @@ static struct spi_board_info spi_board_info[] = { static int __init sh7757lcr_devices_setup(void) { - regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, - ARRAY_SIZE(fixed3v3_power_consumers), 3300000); - /* RGMII (PTA) */ gpio_request(GPIO_FN_ET0_MDC, NULL); gpio_request(GPIO_FN_ET0_MDIO, NULL); diff --git a/trunk/arch/sh/boards/mach-ap325rxa/setup.c b/trunk/arch/sh/boards/mach-ap325rxa/setup.c index 9e963c1d1447..f33ebf447073 100644 --- a/trunk/arch/sh/boards/mach-ap325rxa/setup.c +++ b/trunk/arch/sh/boards/mach-ap325rxa/setup.c @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include #include @@ -36,12 +34,6 @@ #include #include -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - static struct smsc911x_platform_config smsc911x_config = { .phy_interface = PHY_INTERFACE_MODE_MII, .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, @@ -431,15 +423,6 @@ static struct platform_device ceu_device = { }, }; -/* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */ -static struct regulator_consumer_supply fixed3v3_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), -}; - static struct resource sdhi0_cn3_resources[] = { [0] = { .name = "SDHI0", @@ -561,10 +544,6 @@ static int __init ap325rxa_devices_setup(void) &ap325rxa_sdram_leave_start, &ap325rxa_sdram_leave_end); - regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, - ARRAY_SIZE(fixed3v3_power_consumers), 3300000); - regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - /* LD3 and LD4 LEDs */ gpio_request(GPIO_PTX5, NULL); /* RUN */ gpio_direction_output(GPIO_PTX5, 1); diff --git a/trunk/arch/sh/boards/mach-ecovec24/setup.c b/trunk/arch/sh/boards/mach-ecovec24/setup.c index 64559e8af14b..4158d70c0dea 100644 --- a/trunk/arch/sh/boards/mach-ecovec24/setup.c +++ b/trunk/arch/sh/boards/mach-ecovec24/setup.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include #include @@ -244,17 +242,9 @@ static int usbhs_get_id(struct platform_device *pdev) return gpio_get_value(GPIO_PTB3); } -static void usbhs_phy_reset(struct platform_device *pdev) -{ - /* enable vbus if HOST */ - if (!gpio_get_value(GPIO_PTB3)) - gpio_set_value(GPIO_PTB5, 1); -} - static struct renesas_usbhs_platform_info usbhs_info = { .platform_callback = { .get_id = usbhs_get_id, - .phy_reset = usbhs_phy_reset, }, .driver_param = { .buswait_bwait = 4, @@ -528,86 +518,10 @@ static struct i2c_board_info ts_i2c_clients = { .irq = IRQ0, }; -static struct regulator_consumer_supply cn12_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), -}; - -static struct regulator_init_data cn12_power_init_data = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(cn12_power_consumers), - .consumer_supplies = cn12_power_consumers, -}; - -static struct fixed_voltage_config cn12_power_info = { - .supply_name = "CN12 SD/MMC Vdd", - .microvolts = 3300000, - .gpio = GPIO_PTB7, - .enable_high = 1, - .init_data = &cn12_power_init_data, -}; - -static struct platform_device cn12_power = { - .name = "reg-fixed-voltage", - .id = 0, - .dev = { - .platform_data = &cn12_power_info, - }, -}; - #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) /* SDHI0 */ -static struct regulator_consumer_supply sdhi0_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), -}; - -static struct regulator_init_data sdhi0_power_init_data = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(sdhi0_power_consumers), - .consumer_supplies = sdhi0_power_consumers, -}; - -static struct fixed_voltage_config sdhi0_power_info = { - .supply_name = "CN11 SD/MMC Vdd", - .microvolts = 3300000, - .gpio = GPIO_PTB6, - .enable_high = 1, - .init_data = &sdhi0_power_init_data, -}; - -static struct platform_device sdhi0_power = { - .name = "reg-fixed-voltage", - .id = 1, - .dev = { - .platform_data = &sdhi0_power_info, - }, -}; - static void sdhi0_set_pwr(struct platform_device *pdev, int state) { - static int power_gpio = -EINVAL; - - if (power_gpio < 0) { - int ret = gpio_request(GPIO_PTB6, NULL); - if (!ret) { - power_gpio = GPIO_PTB6; - gpio_direction_output(power_gpio, 0); - } - } - - /* - * Toggle the GPIO regardless, whether we managed to grab it above or - * the fixed regulator driver did. - */ gpio_set_value(GPIO_PTB6, state); } @@ -648,27 +562,13 @@ static struct platform_device sdhi0_device = { }, }; -static void cn12_set_pwr(struct platform_device *pdev, int state) +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) +/* SDHI1 */ +static void sdhi1_set_pwr(struct platform_device *pdev, int state) { - static int power_gpio = -EINVAL; - - if (power_gpio < 0) { - int ret = gpio_request(GPIO_PTB7, NULL); - if (!ret) { - power_gpio = GPIO_PTB7; - gpio_direction_output(power_gpio, 0); - } - } - - /* - * Toggle the GPIO regardless, whether we managed to grab it above or - * the fixed regulator driver did. - */ gpio_set_value(GPIO_PTB7, state); } -#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) -/* SDHI1 */ static int sdhi1_get_cd(struct platform_device *pdev) { return !gpio_get_value(GPIO_PTW7); @@ -679,7 +579,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | MMC_CAP_NEEDS_POLL, - .set_pwr = cn12_set_pwr, + .set_pwr = sdhi1_set_pwr, .get_cd = sdhi1_get_cd, }; @@ -999,9 +899,14 @@ static struct platform_device vou_device = { #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) /* SH_MMCIF */ +static void mmcif_set_pwr(struct platform_device *pdev, int state) +{ + gpio_set_value(GPIO_PTB7, state); +} + static void mmcif_down_pwr(struct platform_device *pdev) { - cn12_set_pwr(pdev, 0); + gpio_set_value(GPIO_PTB7, 0); } static struct resource sh_mmcif_resources[] = { @@ -1024,7 +929,7 @@ static struct resource sh_mmcif_resources[] = { }; static struct sh_mmcif_plat_data sh_mmcif_plat = { - .set_pwr = cn12_set_pwr, + .set_pwr = mmcif_set_pwr, .down_pwr = mmcif_down_pwr, .sup_pclk = 0, /* SH7724: Max Pclk/2 */ .caps = MMC_CAP_4_BIT_DATA | @@ -1055,9 +960,7 @@ static struct platform_device *ecovec_devices[] __initdata = { &ceu0_device, &ceu1_device, &keysc_device, - &cn12_power, #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) - &sdhi0_power, &sdhi0_device, #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) &sdhi1_device, @@ -1355,6 +1258,8 @@ static int __init arch_setup(void) gpio_request(GPIO_FN_SDHI0D2, NULL); gpio_request(GPIO_FN_SDHI0D1, NULL); gpio_request(GPIO_FN_SDHI0D0, NULL); + gpio_request(GPIO_PTB6, NULL); + gpio_direction_output(GPIO_PTB6, 0); #else /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ gpio_request(GPIO_FN_MSIOF0_TXD, NULL); @@ -1383,6 +1288,8 @@ static int __init arch_setup(void) gpio_request(GPIO_FN_MMC_D0, NULL); gpio_request(GPIO_FN_MMC_CLK, NULL); gpio_request(GPIO_FN_MMC_CMD, NULL); + gpio_request(GPIO_PTB7, NULL); + gpio_direction_output(GPIO_PTB7, 0); cn12_enabled = true; #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) @@ -1394,6 +1301,8 @@ static int __init arch_setup(void) gpio_request(GPIO_FN_SDHI1D2, NULL); gpio_request(GPIO_FN_SDHI1D1, NULL); gpio_request(GPIO_FN_SDHI1D0, NULL); + gpio_request(GPIO_PTB7, NULL); + gpio_direction_output(GPIO_PTB7, 0); /* Card-detect, used on CN12 with SDHI1 */ gpio_request(GPIO_PTW7, NULL); diff --git a/trunk/arch/sh/boards/mach-kfr2r09/setup.c b/trunk/arch/sh/boards/mach-kfr2r09/setup.c index f2a4304fbe23..43a179ce9afc 100644 --- a/trunk/arch/sh/boards/mach-kfr2r09/setup.c +++ b/trunk/arch/sh/boards/mach-kfr2r09/setup.c @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include #include #include @@ -343,13 +341,6 @@ static struct platform_device kfr2r09_camera = { }, }; -/* Fixed 3.3V regulator to be used by SDHI0 */ -static struct regulator_consumer_supply fixed3v3_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), -}; - static struct resource kfr2r09_sh_sdhi0_resources[] = { [0] = { .name = "SDHI0", @@ -532,9 +523,6 @@ static int __init kfr2r09_devices_setup(void) &kfr2r09_sdram_leave_start, &kfr2r09_sdram_leave_end); - regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, - ARRAY_SIZE(fixed3v3_power_consumers), 3300000); - /* enable SCIF1 serial port for YC401 console support */ gpio_request(GPIO_FN_SCIF1_RXD, NULL); gpio_request(GPIO_FN_SCIF1_TXD, NULL); diff --git a/trunk/arch/sh/boards/mach-migor/setup.c b/trunk/arch/sh/boards/mach-migor/setup.c index 8b73194ed2ce..a8a1ca741c85 100644 --- a/trunk/arch/sh/boards/mach-migor/setup.c +++ b/trunk/arch/sh/boards/mach-migor/setup.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include #include @@ -388,13 +386,6 @@ static struct platform_device migor_ceu_device = { }, }; -/* Fixed 3.3V regulator to be used by SDHI0 */ -static struct regulator_consumer_supply fixed3v3_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), -}; - static struct resource sdhi_cn9_resources[] = { [0] = { .name = "SDHI", @@ -507,10 +498,6 @@ static int __init migor_devices_setup(void) &migor_sdram_enter_end, &migor_sdram_leave_start, &migor_sdram_leave_end); - - regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, - ARRAY_SIZE(fixed3v3_power_consumers), 3300000); - /* Let D11 LED show STATUS0 */ gpio_request(GPIO_FN_STATUS0, NULL); diff --git a/trunk/arch/sh/boards/mach-rsk/setup.c b/trunk/arch/sh/boards/mach-rsk/setup.c index 2685ea03b064..895f030070d3 100644 --- a/trunk/arch/sh/boards/mach-rsk/setup.c +++ b/trunk/arch/sh/boards/mach-rsk/setup.c @@ -16,17 +16,9 @@ #include #include #include -#include -#include #include #include -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - static const char *part_probes[] = { "cmdlinepart", NULL }; static struct mtd_partition rsk_partitions[] = { @@ -75,8 +67,6 @@ static struct platform_device *rsk_devices[] __initdata = { static int __init rsk_devices_setup(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - return platform_add_devices(rsk_devices, ARRAY_SIZE(rsk_devices)); } diff --git a/trunk/arch/sh/boards/mach-sdk7786/setup.c b/trunk/arch/sh/boards/mach-sdk7786/setup.c index c29268bfd34a..27a2314f50ac 100644 --- a/trunk/arch/sh/boards/mach-sdk7786/setup.c +++ b/trunk/arch/sh/boards/mach-sdk7786/setup.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include #include @@ -40,12 +38,6 @@ static struct platform_device heartbeat_device = { .resource = &heartbeat_resource, }; -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - static struct resource smsc911x_resources[] = { [0] = { .name = "smsc911x-memory", @@ -244,8 +236,6 @@ static void __init sdk7786_setup(char **cmdline_p) { pr_info("Renesas Technology Europe SDK7786 support:\n"); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - sdk7786_fpga_init(); sdk7786_nmi_init(); diff --git a/trunk/arch/sh/boards/mach-se/7724/setup.c b/trunk/arch/sh/boards/mach-se/7724/setup.c index 35f6efa3ac0e..ffbf5bc7366b 100644 --- a/trunk/arch/sh/boards/mach-se/7724/setup.c +++ b/trunk/arch/sh/boards/mach-se/7724/setup.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include @@ -456,15 +454,6 @@ static struct platform_device sh7724_usb1_gadget_device = { .resource = sh7724_usb1_gadget_resources, }; -/* Fixed 3.3V regulator to be used by SDHI0, SDHI1 */ -static struct regulator_consumer_supply fixed3v3_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), -}; - static struct resource sdhi0_cn7_resources[] = { [0] = { .name = "SDHI0", @@ -695,10 +684,6 @@ static int __init devices_setup(void) &ms7724se_sdram_enter_end, &ms7724se_sdram_leave_start, &ms7724se_sdram_leave_end); - - regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, - ARRAY_SIZE(fixed3v3_power_consumers), 3300000); - /* Reset Release */ fpga_out = __raw_readw(FPGA_OUT); /* bit4: NTSC_PDN, bit5: NTSC_RESET */ diff --git a/trunk/arch/sh/include/asm/sections.h b/trunk/arch/sh/include/asm/sections.h index 1b6199740e98..4a5350037c8f 100644 --- a/trunk/arch/sh/include/asm/sections.h +++ b/trunk/arch/sh/include/asm/sections.h @@ -6,6 +6,7 @@ extern long __nosave_begin, __nosave_end; extern long __machvec_start, __machvec_end; extern char __uncached_start, __uncached_end; +extern char _ebss[]; extern char __start_eh_frame[], __stop_eh_frame[]; #endif /* __ASM_SH_SECTIONS_H */ diff --git a/trunk/arch/sh/include/cpu-sh4/cpu/sh7757.h b/trunk/arch/sh/include/cpu-sh4/cpu/sh7757.h index 5340f3bc1863..41f9f8b9db73 100644 --- a/trunk/arch/sh/include/cpu-sh4/cpu/sh7757.h +++ b/trunk/arch/sh/include/cpu-sh4/cpu/sh7757.h @@ -283,7 +283,5 @@ enum { SHDMA_SLAVE_RIIC8_RX, SHDMA_SLAVE_RIIC9_TX, SHDMA_SLAVE_RIIC9_RX, - SHDMA_SLAVE_RSPI_TX, - SHDMA_SLAVE_RSPI_RX, }; #endif /* __ASM_SH7757_H__ */ diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 5f30f805d2f2..c87e78f73234 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -334,8 +334,8 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]), CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]), CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]), - CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[HWBLK_USB1]), - CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[HWBLK_USB0]), + CLKDEV_CON_ID("usb1", &mstp_clks[HWBLK_USB1]), + CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB0]), CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]), CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]), diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 6a868b091c2d..65786c7f5ded 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 4a2f357f4df8..a7708425afa9 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -216,20 +216,6 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x42, }, - { - .slave_id = SHDMA_SLAVE_RSPI_TX, - .addr = 0xfe480004, - .chcr = SM_INC | 0x800 | 0x40000000 | - TS_INDEX2VAL(XMIT_SZ_16BIT), - .mid_rid = 0xc1, - }, - { - .slave_id = SHDMA_SLAVE_RSPI_RX, - .addr = 0xfe480004, - .chcr = DM_INC | 0x800 | 0x40000000 | - TS_INDEX2VAL(XMIT_SZ_16BIT), - .mid_rid = 0xc2, - }, }; static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index ebe7a7d97215..7b57bf1dc855 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -273,7 +273,7 @@ void __init setup_arch(char **cmdline_p) data_resource.start = virt_to_phys(_etext); data_resource.end = virt_to_phys(_edata)-1; bss_resource.start = virt_to_phys(__bss_start); - bss_resource.end = virt_to_phys(__bss_stop)-1; + bss_resource.end = virt_to_phys(_ebss)-1; #ifdef CONFIG_CMDLINE_OVERWRITE strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); diff --git a/trunk/arch/sh/kernel/sh_ksyms_32.c b/trunk/arch/sh/kernel/sh_ksyms_32.c index 2a0a596ebf67..3896f26efa4a 100644 --- a/trunk/arch/sh/kernel/sh_ksyms_32.c +++ b/trunk/arch/sh/kernel/sh_ksyms_32.c @@ -19,6 +19,7 @@ EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_generic); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__clear_user); +EXPORT_SYMBOL(_ebss); EXPORT_SYMBOL(empty_zero_page); #define DECLARE_EXPORT(name) \ diff --git a/trunk/arch/sh/kernel/vmlinux.lds.S b/trunk/arch/sh/kernel/vmlinux.lds.S index db88cbf9eafd..c98905f71e28 100644 --- a/trunk/arch/sh/kernel/vmlinux.lds.S +++ b/trunk/arch/sh/kernel/vmlinux.lds.S @@ -78,6 +78,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); __init_end = .; BSS_SECTION(0, PAGE_SIZE, 4) + _ebss = .; /* uClinux MTD sucks */ _end = . ; STABS_DEBUG diff --git a/trunk/arch/sh/lib/mcount.S b/trunk/arch/sh/lib/mcount.S index 60164e65d665..84a57761f17e 100644 --- a/trunk/arch/sh/lib/mcount.S +++ b/trunk/arch/sh/lib/mcount.S @@ -39,7 +39,7 @@ * * Make sure the stack pointer contains a valid address. Valid * addresses for kernel stacks are anywhere after the bss - * (after __bss_stop) and anywhere in init_thread_union (init_stack). + * (after _ebss) and anywhere in init_thread_union (init_stack). */ #define STACK_CHECK() \ mov #(THREAD_SIZE >> 10), r0; \ @@ -60,7 +60,7 @@ cmp/hi r2, r1; \ bf stack_panic; \ \ - /* If sp > __bss_stop then we're OK. */ \ + /* If sp > _ebss then we're OK. */ \ mov.l .L_ebss, r1; \ cmp/hi r1, r15; \ bt 1f; \ @@ -70,7 +70,7 @@ cmp/hs r1, r15; \ bf stack_panic; \ \ - /* If sp > init_stack && sp < __bss_stop, not OK. */ \ + /* If sp > init_stack && sp < _ebss, not OK. */ \ add r0, r1; \ cmp/hs r1, r15; \ bt stack_panic; \ @@ -292,6 +292,8 @@ stack_panic: nop .align 2 +.L_ebss: + .long _ebss .L_init_thread_union: .long init_thread_union .Lpanic: diff --git a/trunk/arch/sh/mm/fault.c b/trunk/arch/sh/mm/fault.c index 3bdc1ad9a341..1fc25d85e515 100644 --- a/trunk/arch/sh/mm/fault.c +++ b/trunk/arch/sh/mm/fault.c @@ -58,15 +58,11 @@ static void show_pte(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; - if (mm) { + if (mm) pgd = mm->pgd; - } else { + else pgd = get_TTB(); - if (unlikely(!pgd)) - pgd = swapper_pg_dir; - } - printk(KERN_ALERT "pgd = %p\n", pgd); pgd += pgd_index(addr); printk(KERN_ALERT "[%08lx] *pgd=%0*Lx", addr, diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 8ec3a1aa4abd..ba2657c49217 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1527,7 +1527,7 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection" + bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" ---help--- This option turns on the -fstack-protector GCC feature. This feature puts, at the beginning of functions, a canary value on diff --git a/trunk/arch/x86/include/asm/mce.h b/trunk/arch/x86/include/asm/mce.h index a3ac52b29cbf..441520e4174f 100644 --- a/trunk/arch/x86/include/asm/mce.h +++ b/trunk/arch/x86/include/asm/mce.h @@ -33,14 +33,6 @@ #define MCI_STATUS_PCC (1ULL<<57) /* processor context corrupt */ #define MCI_STATUS_S (1ULL<<56) /* Signaled machine check */ #define MCI_STATUS_AR (1ULL<<55) /* Action required */ -#define MCACOD 0xffff /* MCA Error Code */ - -/* Architecturally defined codes from SDM Vol. 3B Chapter 15 */ -#define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */ -#define MCACOD_SCRUBMSK 0xfff0 -#define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */ -#define MCACOD_DATA 0x0134 /* Data Load */ -#define MCACOD_INSTR 0x0150 /* Instruction Fetch */ /* MCi_MISC register defines */ #define MCI_MISC_ADDR_LSB(m) ((m) & 0x3f) diff --git a/trunk/arch/x86/include/asm/olpc.h b/trunk/arch/x86/include/asm/olpc.h index 72f9adf6eca4..87bdbca72f94 100644 --- a/trunk/arch/x86/include/asm/olpc.h +++ b/trunk/arch/x86/include/asm/olpc.h @@ -100,6 +100,25 @@ extern void olpc_xo1_pm_wakeup_clear(u16 value); extern int pci_olpc_init(void); +/* EC related functions */ + +extern int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, + unsigned char *outbuf, size_t outlen); + +/* EC commands */ + +#define EC_FIRMWARE_REV 0x08 +#define EC_WRITE_SCI_MASK 0x1b +#define EC_WAKE_UP_WLAN 0x24 +#define EC_WLAN_LEAVE_RESET 0x25 +#define EC_READ_EB_MODE 0x2a +#define EC_SET_SCI_INHIBIT 0x32 +#define EC_SET_SCI_INHIBIT_RELEASE 0x34 +#define EC_WLAN_ENTER_RESET 0x35 +#define EC_WRITE_EXT_SCI_MASK 0x38 +#define EC_SCI_QUERY 0x84 +#define EC_EXT_SCI_QUERY 0x85 + /* SCI source values */ #define EC_SCI_SRC_EMPTY 0x00 diff --git a/trunk/arch/x86/include/asm/perf_event.h b/trunk/arch/x86/include/asm/perf_event.h index cb4e43bce98a..dab39350e51e 100644 --- a/trunk/arch/x86/include/asm/perf_event.h +++ b/trunk/arch/x86/include/asm/perf_event.h @@ -196,16 +196,11 @@ static inline u32 get_ibs_caps(void) { return 0; } extern void perf_events_lapic_init(void); /* - * Abuse bits {3,5} of the cpu eflags register. These flags are otherwise - * unused and ABI specified to be 0, so nobody should care what we do with - * them. - * - * EXACT - the IP points to the exact instruction that triggered the - * event (HW bugs exempt). - * VM - original X86_VM_MASK; see set_linear_ip(). + * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups. + * This flag is otherwise unused and ABI specified to be 0, so nobody should + * care what we do with it. */ #define PERF_EFLAGS_EXACT (1UL << 3) -#define PERF_EFLAGS_VM (1UL << 5) struct pt_regs; extern unsigned long perf_instruction_pointer(struct pt_regs *regs); diff --git a/trunk/arch/x86/kernel/acpi/sleep.c b/trunk/arch/x86/kernel/acpi/sleep.c index 1b8e5a03d942..95bf99de9058 100644 --- a/trunk/arch/x86/kernel/acpi/sleep.c +++ b/trunk/arch/x86/kernel/acpi/sleep.c @@ -25,6 +25,10 @@ unsigned long acpi_realmode_flags; static char temp_stack[4096]; #endif +asmlinkage void acpi_enter_s3(void) +{ + acpi_enter_sleep_state(3, wake_sleep_flags); +} /** * acpi_suspend_lowlevel - save kernel state * diff --git a/trunk/arch/x86/kernel/acpi/sleep.h b/trunk/arch/x86/kernel/acpi/sleep.h index 67f59f8c6956..5653a5791ec9 100644 --- a/trunk/arch/x86/kernel/acpi/sleep.h +++ b/trunk/arch/x86/kernel/acpi/sleep.h @@ -2,6 +2,7 @@ * Variables and functions used by the code in sleep.c */ +#include #include extern unsigned long saved_video_mode; @@ -10,6 +11,7 @@ extern long saved_magic; extern int wakeup_pmode_return; extern u8 wake_sleep_flags; +extern asmlinkage void acpi_enter_s3(void); extern unsigned long acpi_copy_wakeup_routine(unsigned long); extern void wakeup_long64(void); diff --git a/trunk/arch/x86/kernel/acpi/wakeup_32.S b/trunk/arch/x86/kernel/acpi/wakeup_32.S index 13ab720573e3..72610839f03b 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_32.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_32.S @@ -74,9 +74,7 @@ restore_registers: ENTRY(do_suspend_lowlevel) call save_processor_state call save_registers - pushl $3 - call acpi_enter_sleep_state - addl $4, %esp + call acpi_enter_s3 # In case of S3 failure, we'll emerge here. Jump # to ret_point to recover diff --git a/trunk/arch/x86/kernel/acpi/wakeup_64.S b/trunk/arch/x86/kernel/acpi/wakeup_64.S index 8ea5164cbd04..014d1d28c397 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_64.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_64.S @@ -71,9 +71,7 @@ ENTRY(do_suspend_lowlevel) movq %rsi, saved_rsi addq $8, %rsp - movl $3, %edi - xorl %eax, %eax - call acpi_enter_sleep_state + call acpi_enter_s3 /* in case something went wrong, restore the machine status and go on */ jmp resume_point diff --git a/trunk/arch/x86/kernel/alternative.c b/trunk/arch/x86/kernel/alternative.c index afb7ff79a29f..931280ff8299 100644 --- a/trunk/arch/x86/kernel/alternative.c +++ b/trunk/arch/x86/kernel/alternative.c @@ -224,7 +224,7 @@ void __init arch_init_ideal_nops(void) ideal_nops = intel_nops; #endif } - break; + default: #ifdef CONFIG_X86_64 ideal_nops = k8_nops; diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c index a6c64aaddf9a..406eee784684 100644 --- a/trunk/arch/x86/kernel/apic/io_apic.c +++ b/trunk/arch/x86/kernel/apic/io_apic.c @@ -1204,7 +1204,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) BUG_ON(!cfg->vector); vector = cfg->vector; - for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) + for_each_cpu(cpu, cfg->domain) per_cpu(vector_irq, cpu)[vector] = -1; cfg->vector = 0; @@ -1212,7 +1212,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) if (likely(!cfg->move_in_progress)) return; - for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { + for_each_cpu(cpu, cfg->old_domain) { for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { if (per_cpu(vector_irq, cpu)[vector] != irq) diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce-severity.c b/trunk/arch/x86/kernel/cpu/mcheck/mce-severity.c index 13017626f9a8..413c2ced887c 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce-severity.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce-severity.c @@ -55,6 +55,13 @@ static struct severity { #define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S) #define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR) #define MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV) +#define MCACOD 0xffff +/* Architecturally defined codes from SDM Vol. 3B Chapter 15 */ +#define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */ +#define MCACOD_SCRUBMSK 0xfff0 +#define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */ +#define MCACOD_DATA 0x0134 /* Data Load */ +#define MCACOD_INSTR 0x0150 /* Instruction Fetch */ MCESEV( NO, "Invalid", diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce.c b/trunk/arch/x86/kernel/cpu/mcheck/mce.c index 292d0258311c..5e095f873e3e 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce.c @@ -103,8 +103,6 @@ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { static DEFINE_PER_CPU(struct work_struct, mce_work); -static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs); - /* * CPU/chipset specific EDAC code can register a notifier call here to print * MCE errors in a human-readable form. @@ -652,18 +650,14 @@ EXPORT_SYMBOL_GPL(machine_check_poll); * Do a quick check if any of the events requires a panic. * This decides if we keep the events around or clear them. */ -static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp, - struct pt_regs *regs) +static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp) { int i, ret = 0; for (i = 0; i < banks; i++) { m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); - if (m->status & MCI_STATUS_VAL) { + if (m->status & MCI_STATUS_VAL) __set_bit(i, validp); - if (quirk_no_way_out) - quirk_no_way_out(i, m, regs); - } if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY) ret = 1; } @@ -1046,7 +1040,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) *final = m; memset(valid_banks, 0, sizeof(valid_banks)); - no_way_out = mce_no_way_out(&m, &msg, valid_banks, regs); + no_way_out = mce_no_way_out(&m, &msg, valid_banks); barrier(); @@ -1424,34 +1418,6 @@ static void __mcheck_cpu_init_generic(void) } } -/* - * During IFU recovery Sandy Bridge -EP4S processors set the RIPV and - * EIPV bits in MCG_STATUS to zero on the affected logical processor (SDM - * Vol 3B Table 15-20). But this confuses both the code that determines - * whether the machine check occurred in kernel or user mode, and also - * the severity assessment code. Pretend that EIPV was set, and take the - * ip/cs values from the pt_regs that mce_gather_info() ignored earlier. - */ -static void quirk_sandybridge_ifu(int bank, struct mce *m, struct pt_regs *regs) -{ - if (bank != 0) - return; - if ((m->mcgstatus & (MCG_STATUS_EIPV|MCG_STATUS_RIPV)) != 0) - return; - if ((m->status & (MCI_STATUS_OVER|MCI_STATUS_UC| - MCI_STATUS_EN|MCI_STATUS_MISCV|MCI_STATUS_ADDRV| - MCI_STATUS_PCC|MCI_STATUS_S|MCI_STATUS_AR| - MCACOD)) != - (MCI_STATUS_UC|MCI_STATUS_EN| - MCI_STATUS_MISCV|MCI_STATUS_ADDRV|MCI_STATUS_S| - MCI_STATUS_AR|MCACOD_INSTR)) - return; - - m->mcgstatus |= MCG_STATUS_EIPV; - m->ip = regs->ip; - m->cs = regs->cs; -} - /* Add per CPU specific workarounds here */ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) { @@ -1549,9 +1515,6 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) */ if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0) mce_bootlog = 0; - - if (c->x86 == 6 && c->x86_model == 45) - quirk_no_way_out = quirk_sandybridge_ifu; } if (monarch_timeout < 0) monarch_timeout = 0; diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c index 915b876edd1e..29557aa06dda 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.c +++ b/trunk/arch/x86/kernel/cpu/perf_event.c @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include "perf_event.h" @@ -1740,29 +1738,6 @@ valid_user_frame(const void __user *fp, unsigned long size) return (__range_not_ok(fp, size, TASK_SIZE) == 0); } -static unsigned long get_segment_base(unsigned int segment) -{ - struct desc_struct *desc; - int idx = segment >> 3; - - if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) { - if (idx > LDT_ENTRIES) - return 0; - - if (idx > current->active_mm->context.size) - return 0; - - desc = current->active_mm->context.ldt; - } else { - if (idx > GDT_ENTRIES) - return 0; - - desc = __this_cpu_ptr(&gdt_page.gdt[0]); - } - - return get_desc_base(desc + idx); -} - #ifdef CONFIG_COMPAT #include @@ -1771,17 +1746,13 @@ static inline int perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) { /* 32-bit process in 64-bit kernel. */ - unsigned long ss_base, cs_base; struct stack_frame_ia32 frame; const void __user *fp; if (!test_thread_flag(TIF_IA32)) return 0; - cs_base = get_segment_base(regs->cs); - ss_base = get_segment_base(regs->ss); - - fp = compat_ptr(ss_base + regs->bp); + fp = compat_ptr(regs->bp); while (entry->nr < PERF_MAX_STACK_DEPTH) { unsigned long bytes; frame.next_frame = 0; @@ -1794,8 +1765,8 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) if (!valid_user_frame(fp, sizeof(frame))) break; - perf_callchain_store(entry, cs_base + frame.return_address); - fp = compat_ptr(ss_base + frame.next_frame); + perf_callchain_store(entry, frame.return_address); + fp = compat_ptr(frame.next_frame); } return 1; } @@ -1818,12 +1789,6 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) return; } - /* - * We don't know what to do with VM86 stacks.. ignore them for now. - */ - if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM)) - return; - fp = (void __user *)regs->bp; perf_callchain_store(entry, regs->ip); @@ -1851,50 +1816,16 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) } } -/* - * Deal with code segment offsets for the various execution modes: - * - * VM86 - the good olde 16 bit days, where the linear address is - * 20 bits and we use regs->ip + 0x10 * regs->cs. - * - * IA32 - Where we need to look at GDT/LDT segment descriptor tables - * to figure out what the 32bit base address is. - * - * X32 - has TIF_X32 set, but is running in x86_64 - * - * X86_64 - CS,DS,SS,ES are all zero based. - */ -static unsigned long code_segment_base(struct pt_regs *regs) -{ - /* - * If we are in VM86 mode, add the segment offset to convert to a - * linear address. - */ - if (regs->flags & X86_VM_MASK) - return 0x10 * regs->cs; - - /* - * For IA32 we look at the GDT/LDT segment base to convert the - * effective IP to a linear address. - */ -#ifdef CONFIG_X86_32 - if (user_mode(regs) && regs->cs != __USER_CS) - return get_segment_base(regs->cs); -#else - if (test_thread_flag(TIF_IA32)) { - if (user_mode(regs) && regs->cs != __USER32_CS) - return get_segment_base(regs->cs); - } -#endif - return 0; -} - unsigned long perf_instruction_pointer(struct pt_regs *regs) { + unsigned long ip; + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) - return perf_guest_cbs->get_guest_ip(); + ip = perf_guest_cbs->get_guest_ip(); + else + ip = instruction_pointer(regs); - return regs->ip + code_segment_base(regs); + return ip; } unsigned long perf_misc_flags(struct pt_regs *regs) @@ -1907,7 +1838,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs) else misc |= PERF_RECORD_MISC_GUEST_KERNEL; } else { - if (user_mode(regs)) + if (!kernel_ip(regs->ip)) misc |= PERF_RECORD_MISC_USER; else misc |= PERF_RECORD_MISC_KERNEL; diff --git a/trunk/arch/x86/kernel/cpu/perf_event.h b/trunk/arch/x86/kernel/cpu/perf_event.h index 6605a81ba339..821d53b696d1 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.h +++ b/trunk/arch/x86/kernel/cpu/perf_event.h @@ -516,26 +516,6 @@ static inline bool kernel_ip(unsigned long ip) #endif } -/* - * Not all PMUs provide the right context information to place the reported IP - * into full context. Specifically segment registers are typically not - * supplied. - * - * Assuming the address is a linear address (it is for IBS), we fake the CS and - * vm86 mode using the known zero-based code segment and 'fix up' the registers - * to reflect this. - * - * Intel PEBS/LBR appear to typically provide the effective address, nothing - * much we can do about that but pray and treat it like a linear address. - */ -static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip) -{ - regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS; - if (regs->flags & X86_VM_MASK) - regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK); - regs->ip = ip; -} - #ifdef CONFIG_CPU_SUP_AMD int amd_pmu_init(void); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c index 7bfb5bec8630..da9bcdcd9856 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c @@ -13,8 +13,6 @@ #include -#include "perf_event.h" - static u32 ibs_caps; #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) @@ -538,7 +536,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) { regs.flags &= ~PERF_EFLAGS_EXACT; } else { - set_linear_ip(®s, ibs_data.regs[1]); + instruction_pointer_set(®s, ibs_data.regs[1]); regs.flags |= PERF_EFLAGS_EXACT; } diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c index e38d97bf4259..629ae0b7ad90 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -499,7 +499,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) * We sampled a branch insn, rewind using the LBR stack */ if (ip == to) { - set_linear_ip(regs, from); + regs->ip = from; return 1; } @@ -529,7 +529,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) } while (to < ip); if (to == ip) { - set_linear_ip(regs, old_to); + regs->ip = old_to; return 1; } @@ -569,8 +569,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event, * A possible PERF_SAMPLE_REGS will have to transfer all regs. */ regs = *iregs; - regs.flags = pebs->flags; - set_linear_ip(®s, pebs->ip); + regs.ip = pebs->ip; regs.bp = pebs->bp; regs.sp = pebs->sp; diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h index c9e5dc56630a..f3851892e077 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -5,7 +5,7 @@ #include "perf_event.h" #define UNCORE_PMU_NAME_LEN 32 -#define UNCORE_PMU_HRTIMER_INTERVAL (60LL * NSEC_PER_SEC) +#define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) #define UNCORE_FIXED_EVENT 0xff #define UNCORE_PMC_IDX_MAX_GENERIC 8 diff --git a/trunk/arch/x86/kernel/irq.c b/trunk/arch/x86/kernel/irq.c index 7ad683d78645..1f5f1d5d2a02 100644 --- a/trunk/arch/x86/kernel/irq.c +++ b/trunk/arch/x86/kernel/irq.c @@ -328,7 +328,6 @@ void fixup_irqs(void) chip->irq_retrigger(data); raw_spin_unlock(&desc->lock); } - __this_cpu_write(vector_irq[vector], -1); } } #endif diff --git a/trunk/arch/x86/kernel/kdebugfs.c b/trunk/arch/x86/kernel/kdebugfs.c index dc1404bf8e4b..1d5d31ea686b 100644 --- a/trunk/arch/x86/kernel/kdebugfs.c +++ b/trunk/arch/x86/kernel/kdebugfs.c @@ -107,7 +107,7 @@ static int __init create_setup_data_nodes(struct dentry *parent) { struct setup_data_node *node; struct setup_data *data; - int error; + int error = -ENOMEM; struct dentry *d; struct page *pg; u64 pa_data; @@ -121,10 +121,8 @@ static int __init create_setup_data_nodes(struct dentry *parent) while (pa_data) { node = kmalloc(sizeof(*node), GFP_KERNEL); - if (!node) { - error = -ENOMEM; + if (!node) goto err_dir; - } pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT); if (PageHighMem(pg)) { diff --git a/trunk/arch/x86/kvm/i8259.c b/trunk/arch/x86/kvm/i8259.c index e498b18f010c..1df8fb9e1d5d 100644 --- a/trunk/arch/x86/kvm/i8259.c +++ b/trunk/arch/x86/kvm/i8259.c @@ -316,11 +316,6 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val) addr &= 1; if (addr == 0) { if (val & 0x10) { - u8 edge_irr = s->irr & ~s->elcr; - int i; - bool found; - struct kvm_vcpu *vcpu; - s->init4 = val & 1; s->last_irr = 0; s->irr &= s->elcr; @@ -338,18 +333,6 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val) if (val & 0x08) pr_pic_unimpl( "level sensitive irq not supported"); - - kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm) - if (kvm_apic_accept_pic_intr(vcpu)) { - found = true; - break; - } - - - if (found) - for (irq = 0; irq < PIC_NUM_PINS/2; irq++) - if (edge_irr & (1 << irq)) - pic_clear_isr(s, irq); } else if (val & 0x08) { if (val & 0x04) s->poll = 1; diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index c00f03de1b79..c39b60707e02 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -1488,6 +1488,13 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx) loadsegment(ds, vmx->host_state.ds_sel); loadsegment(es, vmx->host_state.es_sel); } +#else + /* + * The sysexit path does not restore ds/es, so we must set them to + * a reasonable value ourselves. + */ + loadsegment(ds, __USER_DS); + loadsegment(es, __USER_DS); #endif reload_tss(); #ifdef CONFIG_X86_64 @@ -6363,19 +6370,6 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) #endif ); -#ifndef CONFIG_X86_64 - /* - * The sysexit path does not restore ds/es, so we must set them to - * a reasonable value ourselves. - * - * We can't defer this to vmx_load_host_state() since that function - * may be executed in interrupt context, which saves and restore segments - * around it, nullifying its effect. - */ - loadsegment(ds, __USER_DS); - loadsegment(es, __USER_DS); -#endif - vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) | (1 << VCPU_EXREG_RFLAGS) | (1 << VCPU_EXREG_CPL) diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 42bce48f6928..59b59508ff07 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -925,10 +925,6 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) */ getboottime(&boot); - if (kvm->arch.kvmclock_offset) { - struct timespec ts = ns_to_timespec(kvm->arch.kvmclock_offset); - boot = timespec_sub(boot, ts); - } wc.sec = boot.tv_sec; wc.nsec = boot.tv_nsec; wc.version = version; diff --git a/trunk/arch/x86/mm/srat.c b/trunk/arch/x86/mm/srat.c index 4ddf497ca65b..4599c3e8bcb6 100644 --- a/trunk/arch/x86/mm/srat.c +++ b/trunk/arch/x86/mm/srat.c @@ -142,23 +142,23 @@ static inline int save_add_info(void) {return 0;} #endif /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ -int __init +void __init acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) { u64 start, end; int node, pxm; if (srat_disabled()) - return -1; + return; if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) { bad_srat(); - return -1; + return; } if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) - return -1; + return; if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info()) - return -1; + return; start = ma->base_address; end = start + ma->length; pxm = ma->proximity_domain; @@ -168,12 +168,12 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains.\n"); bad_srat(); - return -1; + return; } if (numa_add_memblk(node, start, end) < 0) { bad_srat(); - return -1; + return; } node_set(node, numa_nodes_parsed); @@ -181,7 +181,6 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n", node, pxm, (unsigned long long) start, (unsigned long long) end - 1); - return 0; } void __init acpi_numa_arch_fixup(void) {} diff --git a/trunk/arch/x86/platform/olpc/olpc-xo1-pm.c b/trunk/arch/x86/platform/olpc/olpc-xo1-pm.c index d75582d1aa55..0ce8616c88ae 100644 --- a/trunk/arch/x86/platform/olpc/olpc-xo1-pm.c +++ b/trunk/arch/x86/platform/olpc/olpc-xo1-pm.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -52,11 +51,16 @@ EXPORT_SYMBOL_GPL(olpc_xo1_pm_wakeup_clear); static int xo1_power_state_enter(suspend_state_t pm_state) { unsigned long saved_sci_mask; + int r; /* Only STR is supported */ if (pm_state != PM_SUSPEND_MEM) return -EINVAL; + r = olpc_ec_cmd(EC_SET_SCI_INHIBIT, NULL, 0, NULL, 0); + if (r) + return r; + /* * Save SCI mask (this gets lost since PM1_EN is used as a mask for * wakeup events, which is not necessarily the same event set) @@ -72,6 +76,16 @@ static int xo1_power_state_enter(suspend_state_t pm_state) /* Restore SCI mask (using dword access to CS5536_PM1_EN) */ outl(saved_sci_mask, acpi_base + CS5536_PM1_STS); + /* Tell the EC to stop inhibiting SCIs */ + olpc_ec_cmd(EC_SET_SCI_INHIBIT_RELEASE, NULL, 0, NULL, 0); + + /* + * Tell the wireless module to restart USB communication. + * Must be done twice. + */ + olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); + olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); + return 0; } diff --git a/trunk/arch/x86/platform/olpc/olpc-xo1-sci.c b/trunk/arch/x86/platform/olpc/olpc-xo1-sci.c index 63d4aa40956e..04b8c73659c5 100644 --- a/trunk/arch/x86/platform/olpc/olpc-xo1-sci.c +++ b/trunk/arch/x86/platform/olpc/olpc-xo1-sci.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/x86/platform/olpc/olpc-xo15-sci.c b/trunk/arch/x86/platform/olpc/olpc-xo15-sci.c index 2fdca25905ae..599be499fdf7 100644 --- a/trunk/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/trunk/arch/x86/platform/olpc/olpc-xo15-sci.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/x86/platform/olpc/olpc.c b/trunk/arch/x86/platform/olpc/olpc.c index 27376081ddec..a4bee53c2e54 100644 --- a/trunk/arch/x86/platform/olpc/olpc.c +++ b/trunk/arch/x86/platform/olpc/olpc.c @@ -14,13 +14,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include -#include #include #include @@ -30,6 +31,17 @@ struct olpc_platform_t olpc_platform_info; EXPORT_SYMBOL_GPL(olpc_platform_info); +static DEFINE_SPINLOCK(ec_lock); + +/* debugfs interface to EC commands */ +#define EC_MAX_CMD_ARGS (5 + 1) /* cmd byte + 5 args */ +#define EC_MAX_CMD_REPLY (8) + +static struct dentry *ec_debugfs_dir; +static DEFINE_MUTEX(ec_debugfs_cmd_lock); +static unsigned char ec_debugfs_resp[EC_MAX_CMD_REPLY]; +static unsigned int ec_debugfs_resp_bytes; + /* EC event mask to be applied during suspend (defining wakeup sources). */ static u16 ec_wakeup_mask; @@ -113,13 +125,16 @@ static int __wait_on_obf(unsigned int line, unsigned int port, int desired) * . Unfortunately, while * OpenFirmware's source is available, the EC's is not. */ -static int olpc_xo1_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, - size_t outlen, void *arg) +int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, + unsigned char *outbuf, size_t outlen) { + unsigned long flags; int ret = -EIO; int i; int restarts = 0; + spin_lock_irqsave(&ec_lock, flags); + /* Clear OBF */ for (i = 0; i < 10 && (obf_status(0x6c) == 1); i++) inb(0x68); @@ -183,8 +198,10 @@ static int olpc_xo1_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, ret = 0; err: + spin_unlock_irqrestore(&ec_lock, flags); return ret; } +EXPORT_SYMBOL_GPL(olpc_ec_cmd); void olpc_ec_wakeup_set(u16 value) { @@ -263,6 +280,96 @@ int olpc_ec_sci_query(u16 *sci_value) } EXPORT_SYMBOL_GPL(olpc_ec_sci_query); +static ssize_t ec_debugfs_cmd_write(struct file *file, const char __user *buf, + size_t size, loff_t *ppos) +{ + int i, m; + unsigned char ec_cmd[EC_MAX_CMD_ARGS]; + unsigned int ec_cmd_int[EC_MAX_CMD_ARGS]; + char cmdbuf[64]; + int ec_cmd_bytes; + + mutex_lock(&ec_debugfs_cmd_lock); + + size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size); + + m = sscanf(cmdbuf, "%x:%u %x %x %x %x %x", &ec_cmd_int[0], + &ec_debugfs_resp_bytes, + &ec_cmd_int[1], &ec_cmd_int[2], &ec_cmd_int[3], + &ec_cmd_int[4], &ec_cmd_int[5]); + if (m < 2 || ec_debugfs_resp_bytes > EC_MAX_CMD_REPLY) { + /* reset to prevent overflow on read */ + ec_debugfs_resp_bytes = 0; + + printk(KERN_DEBUG "olpc-ec: bad ec cmd: " + "cmd:response-count [arg1 [arg2 ...]]\n"); + size = -EINVAL; + goto out; + } + + /* convert scanf'd ints to char */ + ec_cmd_bytes = m - 2; + for (i = 0; i <= ec_cmd_bytes; i++) + ec_cmd[i] = ec_cmd_int[i]; + + printk(KERN_DEBUG "olpc-ec: debugfs cmd 0x%02x with %d args " + "%02x %02x %02x %02x %02x, want %d returns\n", + ec_cmd[0], ec_cmd_bytes, ec_cmd[1], ec_cmd[2], ec_cmd[3], + ec_cmd[4], ec_cmd[5], ec_debugfs_resp_bytes); + + olpc_ec_cmd(ec_cmd[0], (ec_cmd_bytes == 0) ? NULL : &ec_cmd[1], + ec_cmd_bytes, ec_debugfs_resp, ec_debugfs_resp_bytes); + + printk(KERN_DEBUG "olpc-ec: response " + "%02x %02x %02x %02x %02x %02x %02x %02x (%d bytes expected)\n", + ec_debugfs_resp[0], ec_debugfs_resp[1], ec_debugfs_resp[2], + ec_debugfs_resp[3], ec_debugfs_resp[4], ec_debugfs_resp[5], + ec_debugfs_resp[6], ec_debugfs_resp[7], ec_debugfs_resp_bytes); + +out: + mutex_unlock(&ec_debugfs_cmd_lock); + return size; +} + +static ssize_t ec_debugfs_cmd_read(struct file *file, char __user *buf, + size_t size, loff_t *ppos) +{ + unsigned int i, r; + char *rp; + char respbuf[64]; + + mutex_lock(&ec_debugfs_cmd_lock); + rp = respbuf; + rp += sprintf(rp, "%02x", ec_debugfs_resp[0]); + for (i = 1; i < ec_debugfs_resp_bytes; i++) + rp += sprintf(rp, ", %02x", ec_debugfs_resp[i]); + mutex_unlock(&ec_debugfs_cmd_lock); + rp += sprintf(rp, "\n"); + + r = rp - respbuf; + return simple_read_from_buffer(buf, size, ppos, respbuf, r); +} + +static const struct file_operations ec_debugfs_genops = { + .write = ec_debugfs_cmd_write, + .read = ec_debugfs_cmd_read, +}; + +static void setup_debugfs(void) +{ + ec_debugfs_dir = debugfs_create_dir("olpc-ec", 0); + if (ec_debugfs_dir == ERR_PTR(-ENODEV)) + return; + + debugfs_create_file("cmd", 0600, ec_debugfs_dir, NULL, + &ec_debugfs_genops); +} + +static int olpc_ec_suspend(void) +{ + return olpc_ec_mask_write(ec_wakeup_mask); +} + static bool __init check_ofw_architecture(struct device_node *root) { const char *olpc_arch; @@ -317,59 +424,8 @@ static int __init add_xo1_platform_devices(void) return 0; } -static int olpc_xo1_ec_probe(struct platform_device *pdev) -{ - /* get the EC revision */ - olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, - (unsigned char *) &olpc_platform_info.ecver, 1); - - /* EC version 0x5f adds support for wide SCI mask */ - if (olpc_platform_info.ecver >= 0x5f) - olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI; - - pr_info("OLPC board revision %s%X (EC=%x)\n", - ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "", - olpc_platform_info.boardrev >> 4, - olpc_platform_info.ecver); - - return 0; -} -static int olpc_xo1_ec_suspend(struct platform_device *pdev) -{ - olpc_ec_mask_write(ec_wakeup_mask); - - /* - * Squelch SCIs while suspended. This is a fix for - * . - */ - return olpc_ec_cmd(EC_SET_SCI_INHIBIT, NULL, 0, NULL, 0); -} - -static int olpc_xo1_ec_resume(struct platform_device *pdev) -{ - /* Tell the EC to stop inhibiting SCIs */ - olpc_ec_cmd(EC_SET_SCI_INHIBIT_RELEASE, NULL, 0, NULL, 0); - - /* - * Tell the wireless module to restart USB communication. - * Must be done twice. - */ - olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); - olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); - - return 0; -} - -static struct olpc_ec_driver ec_xo1_driver = { - .probe = olpc_xo1_ec_probe, - .suspend = olpc_xo1_ec_suspend, - .resume = olpc_xo1_ec_resume, - .ec_cmd = olpc_xo1_ec_cmd, -}; - -static struct olpc_ec_driver ec_xo1_5_driver = { - .probe = olpc_xo1_ec_probe, - .ec_cmd = olpc_xo1_ec_cmd, +static struct syscore_ops olpc_syscore_ops = { + .suspend = olpc_ec_suspend, }; static int __init olpc_init(void) @@ -379,17 +435,16 @@ static int __init olpc_init(void) if (!olpc_ofw_present() || !platform_detect()) return 0; - /* register the XO-1 and 1.5-specific EC handler */ - if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) /* XO-1 */ - olpc_ec_driver_register(&ec_xo1_driver, NULL); - else - olpc_ec_driver_register(&ec_xo1_5_driver, NULL); - platform_device_register_simple("olpc-ec", -1, NULL, 0); + spin_lock_init(&ec_lock); /* assume B1 and above models always have a DCON */ if (olpc_board_at_least(olpc_board(0xb1))) olpc_platform_info.flags |= OLPC_F_DCON; + /* get the EC revision */ + olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, + (unsigned char *) &olpc_platform_info.ecver, 1); + #ifdef CONFIG_PCI_OLPC /* If the VSA exists let it emulate PCI, if not emulate in kernel. * XO-1 only. */ @@ -397,6 +452,14 @@ static int __init olpc_init(void) !cs5535_has_vsa2()) x86_init.pci.arch_init = pci_olpc_init; #endif + /* EC version 0x5f adds support for wide SCI mask */ + if (olpc_platform_info.ecver >= 0x5f) + olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI; + + printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n", + ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "", + olpc_platform_info.boardrev >> 4, + olpc_platform_info.ecver); if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) { /* XO-1 */ r = add_xo1_platform_devices(); @@ -404,6 +467,9 @@ static int __init olpc_init(void) return r; } + register_syscore_ops(&olpc_syscore_ops); + setup_debugfs(); + return 0; } diff --git a/trunk/arch/x86/syscalls/syscall_64.tbl b/trunk/arch/x86/syscalls/syscall_64.tbl index 29aed7ac2c02..51171aeff0dc 100644 --- a/trunk/arch/x86/syscalls/syscall_64.tbl +++ b/trunk/arch/x86/syscalls/syscall_64.tbl @@ -318,7 +318,7 @@ 309 common getcpu sys_getcpu 310 64 process_vm_readv sys_process_vm_readv 311 64 process_vm_writev sys_process_vm_writev -312 common kcmp sys_kcmp +312 64 kcmp sys_kcmp # # x32-specific system call numbers start at 512 to avoid cache impact diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index d5fdd36190cc..ac7034129f3f 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -69,9 +69,7 @@ static const struct acpi_device_id ac_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ac_device_ids); -#ifdef CONFIG_PM_SLEEP static int acpi_ac_resume(struct device *dev); -#endif static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); static struct acpi_driver acpi_ac_driver = { @@ -315,7 +313,6 @@ static int acpi_ac_add(struct acpi_device *device) return result; } -#ifdef CONFIG_PM_SLEEP static int acpi_ac_resume(struct device *dev) { struct acpi_ac *ac; @@ -335,7 +332,6 @@ static int acpi_ac_resume(struct device *dev) kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); return 0; } -#endif static int acpi_ac_remove(struct acpi_device *device, int type) { diff --git a/trunk/drivers/acpi/acpica/achware.h b/trunk/drivers/acpi/acpica/achware.h index 5de4ec72766d..5ccb99ae3a6f 100644 --- a/trunk/drivers/acpi/acpica/achware.h +++ b/trunk/drivers/acpi/acpica/achware.h @@ -83,22 +83,22 @@ acpi_status acpi_hw_clear_acpi_status(void); /* * hwsleep - sleep/wake support (Legacy sleep registers) */ -acpi_status acpi_hw_legacy_sleep(u8 sleep_state); +acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags); -acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state); +acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags); -acpi_status acpi_hw_legacy_wake(u8 sleep_state); +acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags); /* * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers) */ void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument); -acpi_status acpi_hw_extended_sleep(u8 sleep_state); +acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags); -acpi_status acpi_hw_extended_wake_prep(u8 sleep_state); +acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags); -acpi_status acpi_hw_extended_wake(u8 sleep_state); +acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags); /* * hwvalid - Port I/O with validation diff --git a/trunk/drivers/acpi/acpica/hwesleep.c b/trunk/drivers/acpi/acpica/hwesleep.c index 94996f9ae3ad..48518dac5342 100644 --- a/trunk/drivers/acpi/acpica/hwesleep.c +++ b/trunk/drivers/acpi/acpica/hwesleep.c @@ -90,6 +90,7 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument) * FUNCTION: acpi_hw_extended_sleep * * PARAMETERS: sleep_state - Which sleep state to enter + * flags - ACPI_EXECUTE_GTS to run optional method * * RETURN: Status * @@ -99,7 +100,7 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument) * ******************************************************************************/ -acpi_status acpi_hw_extended_sleep(u8 sleep_state) +acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) { acpi_status status; u8 sleep_type_value; @@ -124,6 +125,12 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state) acpi_gbl_system_awake_and_running = FALSE; + /* Optionally execute _GTS (Going To Sleep) */ + + if (flags & ACPI_EXECUTE_GTS) { + acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); + } + /* Flush caches, as per ACPI specification */ ACPI_FLUSH_CPU_CACHE(); @@ -165,6 +172,7 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state) * FUNCTION: acpi_hw_extended_wake_prep * * PARAMETERS: sleep_state - Which sleep state we just exited + * flags - ACPI_EXECUTE_BFS to run optional method * * RETURN: Status * @@ -173,7 +181,7 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state) * ******************************************************************************/ -acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) +acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) { acpi_status status; u8 sleep_type_value; @@ -192,6 +200,11 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) &acpi_gbl_FADT.sleep_control); } + /* Optionally execute _BFS (Back From Sleep) */ + + if (flags & ACPI_EXECUTE_BFS) { + acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); + } return_ACPI_STATUS(AE_OK); } @@ -209,7 +222,7 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) * ******************************************************************************/ -acpi_status acpi_hw_extended_wake(u8 sleep_state) +acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags) { ACPI_FUNCTION_TRACE(hw_extended_wake); diff --git a/trunk/drivers/acpi/acpica/hwsleep.c b/trunk/drivers/acpi/acpica/hwsleep.c index 3fddde056a5e..9960fe9ef533 100644 --- a/trunk/drivers/acpi/acpica/hwsleep.c +++ b/trunk/drivers/acpi/acpica/hwsleep.c @@ -56,6 +56,7 @@ ACPI_MODULE_NAME("hwsleep") * FUNCTION: acpi_hw_legacy_sleep * * PARAMETERS: sleep_state - Which sleep state to enter + * flags - ACPI_EXECUTE_GTS to run optional method * * RETURN: Status * @@ -63,7 +64,7 @@ ACPI_MODULE_NAME("hwsleep") * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * ******************************************************************************/ -acpi_status acpi_hw_legacy_sleep(u8 sleep_state) +acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) { struct acpi_bit_register_info *sleep_type_reg_info; struct acpi_bit_register_info *sleep_enable_reg_info; @@ -109,6 +110,12 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state) return_ACPI_STATUS(status); } + /* Optionally execute _GTS (Going To Sleep) */ + + if (flags & ACPI_EXECUTE_GTS) { + acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); + } + /* Get current value of PM1A control */ status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, @@ -207,6 +214,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state) * FUNCTION: acpi_hw_legacy_wake_prep * * PARAMETERS: sleep_state - Which sleep state we just exited + * flags - ACPI_EXECUTE_BFS to run optional method * * RETURN: Status * @@ -216,7 +224,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state) * ******************************************************************************/ -acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) +acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) { acpi_status status; struct acpi_bit_register_info *sleep_type_reg_info; @@ -267,6 +275,11 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) } } + /* Optionally execute _BFS (Back From Sleep) */ + + if (flags & ACPI_EXECUTE_BFS) { + acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); + } return_ACPI_STATUS(status); } @@ -275,6 +288,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) * FUNCTION: acpi_hw_legacy_wake * * PARAMETERS: sleep_state - Which sleep state we just exited + * flags - Reserved, set to zero * * RETURN: Status * @@ -283,7 +297,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) * ******************************************************************************/ -acpi_status acpi_hw_legacy_wake(u8 sleep_state) +acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) { acpi_status status; diff --git a/trunk/drivers/acpi/acpica/hwxfsleep.c b/trunk/drivers/acpi/acpica/hwxfsleep.c index 1f165a750ae2..f8684bfe7907 100644 --- a/trunk/drivers/acpi/acpica/hwxfsleep.c +++ b/trunk/drivers/acpi/acpica/hwxfsleep.c @@ -50,7 +50,7 @@ ACPI_MODULE_NAME("hwxfsleep") /* Local prototypes */ static acpi_status -acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id); +acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id); /* * Dispatch table used to efficiently branch to the various sleep @@ -235,7 +235,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) * ******************************************************************************/ static acpi_status -acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id) +acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) { acpi_status status; struct acpi_sleep_functions *sleep_functions = @@ -248,11 +248,11 @@ acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id) * use the extended sleep registers */ if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) { - status = sleep_functions->extended_function(sleep_state); + status = sleep_functions->extended_function(sleep_state, flags); } else { /* Legacy sleep */ - status = sleep_functions->legacy_function(sleep_state); + status = sleep_functions->legacy_function(sleep_state, flags); } return (status); @@ -262,7 +262,7 @@ acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id) * For the case where reduced-hardware-only code is being generated, * we know that only the extended sleep registers are available */ - status = sleep_functions->extended_function(sleep_state); + status = sleep_functions->extended_function(sleep_state, flags); return (status); #endif /* !ACPI_REDUCED_HARDWARE */ @@ -349,6 +349,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) * FUNCTION: acpi_enter_sleep_state * * PARAMETERS: sleep_state - Which sleep state to enter + * flags - ACPI_EXECUTE_GTS to run optional method * * RETURN: Status * @@ -356,7 +357,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * ******************************************************************************/ -acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) +acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags) { acpi_status status; @@ -370,7 +371,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) } status = - acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID); + acpi_hw_sleep_dispatch(sleep_state, flags, ACPI_SLEEP_FUNCTION_ID); return_ACPI_STATUS(status); } @@ -390,14 +391,14 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) * Called with interrupts DISABLED. * ******************************************************************************/ -acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) +acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags) { acpi_status status; ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); status = - acpi_hw_sleep_dispatch(sleep_state, + acpi_hw_sleep_dispatch(sleep_state, flags, ACPI_WAKE_PREP_FUNCTION_ID); return_ACPI_STATUS(status); } @@ -422,7 +423,8 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); - status = acpi_hw_sleep_dispatch(sleep_state, ACPI_WAKE_FUNCTION_ID); + + status = acpi_hw_sleep_dispatch(sleep_state, 0, ACPI_WAKE_FUNCTION_ID); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 45e3e1759fb8..ff2c876ec412 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -1052,7 +1052,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type) return 0; } -#ifdef CONFIG_PM_SLEEP /* this is needed to learn about changes made in suspended state */ static int acpi_battery_resume(struct device *dev) { @@ -1069,7 +1068,6 @@ static int acpi_battery_resume(struct device *dev) acpi_battery_update(battery); return 0; } -#endif static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); diff --git a/trunk/drivers/acpi/button.c b/trunk/drivers/acpi/button.c index 314a3b84bbc7..79d4c22f7a6d 100644 --- a/trunk/drivers/acpi/button.c +++ b/trunk/drivers/acpi/button.c @@ -78,9 +78,7 @@ static int acpi_button_add(struct acpi_device *device); static int acpi_button_remove(struct acpi_device *device, int type); static void acpi_button_notify(struct acpi_device *device, u32 event); -#ifdef CONFIG_PM_SLEEP static int acpi_button_resume(struct device *dev); -#endif static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); static struct acpi_driver acpi_button_driver = { @@ -312,7 +310,6 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) } } -#ifdef CONFIG_PM_SLEEP static int acpi_button_resume(struct device *dev) { struct acpi_device *device = to_acpi_device(dev); @@ -322,7 +319,6 @@ static int acpi_button_resume(struct device *dev) return acpi_lid_send_state(device); return 0; } -#endif static int acpi_button_add(struct acpi_device *device) { diff --git a/trunk/drivers/acpi/fan.c b/trunk/drivers/acpi/fan.c index bc36a476f1ab..669d9ee80d16 100644 --- a/trunk/drivers/acpi/fan.c +++ b/trunk/drivers/acpi/fan.c @@ -53,10 +53,8 @@ static const struct acpi_device_id fan_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, fan_device_ids); -#ifdef CONFIG_PM_SLEEP static int acpi_fan_suspend(struct device *dev); static int acpi_fan_resume(struct device *dev); -#endif static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); static struct acpi_driver acpi_fan_driver = { @@ -186,7 +184,6 @@ static int acpi_fan_remove(struct acpi_device *device, int type) return 0; } -#ifdef CONFIG_PM_SLEEP static int acpi_fan_suspend(struct device *dev) { if (!dev) @@ -210,7 +207,6 @@ static int acpi_fan_resume(struct device *dev) return result; } -#endif static int __init acpi_fan_init(void) { diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index cb31298ca684..e56f3be7b07d 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -237,8 +237,6 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header, return 0; } -static int __initdata parsed_numa_memblks; - static int __init acpi_parse_memory_affinity(struct acpi_subtable_header * header, const unsigned long end) @@ -252,8 +250,8 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, acpi_table_print_srat_entry(header); /* let architecture-dependent part to do it */ - if (!acpi_numa_memory_affinity_init(memory_affinity)) - parsed_numa_memblks++; + acpi_numa_memory_affinity_init(memory_affinity); + return 0; } @@ -306,10 +304,8 @@ int __init acpi_numa_init(void) acpi_numa_arch_fixup(); - if (cnt < 0) - return cnt; - else if (!parsed_numa_memblks) - return -ENOENT; + if (cnt <= 0) + return cnt ?: -ENOENT; return 0; } diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 72a2c98bc429..ec54014c321c 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -573,15 +573,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) OSC_CLOCK_PWR_CAPABILITY_SUPPORT; if (pci_msi_enabled()) flags |= OSC_MSI_SUPPORT; - if (flags != base_flags) { - status = acpi_pci_osc_support(root, flags); - if (ACPI_FAILURE(status)) { - dev_info(root->bus->bridge, "ACPI _OSC support " - "notification failed, disabling PCIe ASPM\n"); - pcie_no_aspm(); - flags = base_flags; - } - } + if (flags != base_flags) + acpi_pci_osc_support(root, flags); if (!pcie_ports_disabled && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index fc1803414629..215ecd097408 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -67,9 +67,7 @@ static const struct acpi_device_id power_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, power_device_ids); -#ifdef CONFIG_PM_SLEEP static int acpi_power_resume(struct device *dev); -#endif static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume); static struct acpi_driver acpi_power_driver = { @@ -777,7 +775,6 @@ static int acpi_power_remove(struct acpi_device *device, int type) return 0; } -#ifdef CONFIG_PM_SLEEP static int acpi_power_resume(struct device *dev) { int result = 0, state; @@ -806,7 +803,6 @@ static int acpi_power_resume(struct device *dev) return result; } -#endif int __init acpi_power_init(void) { diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index bfc31cb0dd3e..ff8e04f2fab4 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -437,7 +437,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, /* Normal CPU soft online event */ } else { acpi_processor_ppc_has_changed(pr, 0); - acpi_processor_hotplug(pr); + acpi_processor_cst_has_changed(pr); acpi_processor_reevaluate_tstate(pr, action); acpi_processor_tstate_has_changed(pr); } diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index ff0740e0a9c2..c0b9aa5faf4c 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -988,7 +988,6 @@ static void acpi_sbs_rmdirs(void) #endif } -#ifdef CONFIG_PM_SLEEP static int acpi_sbs_resume(struct device *dev) { struct acpi_sbs *sbs; @@ -998,7 +997,6 @@ static int acpi_sbs_resume(struct device *dev) acpi_sbs_callback(sbs); return 0; } -#endif static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index fdcdbb652915..7a7a9c929247 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -28,7 +28,36 @@ #include "internal.h" #include "sleep.h" +u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS; +static unsigned int gts, bfs; +static int set_param_wake_flag(const char *val, struct kernel_param *kp) +{ + int ret = param_set_int(val, kp); + + if (ret) + return ret; + + if (kp->arg == (const char *)>s) { + if (gts) + wake_sleep_flags |= ACPI_EXECUTE_GTS; + else + wake_sleep_flags &= ~ACPI_EXECUTE_GTS; + } + if (kp->arg == (const char *)&bfs) { + if (bfs) + wake_sleep_flags |= ACPI_EXECUTE_BFS; + else + wake_sleep_flags &= ~ACPI_EXECUTE_BFS; + } + return ret; +} +module_param_call(gts, set_param_wake_flag, param_get_int, >s, 0644); +module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644); +MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); +MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); + static u8 sleep_states[ACPI_S_STATE_COUNT]; +static bool pwr_btn_event_pending; static void acpi_sleep_tts_switch(u32 acpi_state) { @@ -81,7 +110,6 @@ static int acpi_sleep_prepare(u32 acpi_state) #ifdef CONFIG_ACPI_SLEEP static u32 acpi_target_sleep_state = ACPI_STATE_S0; -static bool pwr_btn_event_pending; /* * The ACPI specification wants us to save NVS memory regions during hibernation @@ -277,7 +305,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) switch (acpi_state) { case ACPI_STATE_S1: barrier(); - status = acpi_enter_sleep_state(acpi_state); + status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags); break; case ACPI_STATE_S3: @@ -291,8 +319,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) /* This violates the spec but is required for bug compatibility. */ acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); - /* Reprogram control registers */ - acpi_leave_sleep_state_prep(acpi_state); + /* Reprogram control registers and execute _BFS */ + acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags); /* ACPI 3.0 specs (P62) says that it's the responsibility * of the OSPM to clear the status bit [ implying that the @@ -575,9 +603,9 @@ static int acpi_hibernation_enter(void) ACPI_FLUSH_CPU_CACHE(); /* This shouldn't return. If it returns, we have a problem */ - status = acpi_enter_sleep_state(ACPI_STATE_S4); - /* Reprogram control registers */ - acpi_leave_sleep_state_prep(ACPI_STATE_S4); + status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags); + /* Reprogram control registers and execute _BFS */ + acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); return ACPI_SUCCESS(status) ? 0 : -EFAULT; } @@ -589,8 +617,8 @@ static void acpi_hibernation_leave(void) * enable it here. */ acpi_enable(); - /* Reprogram control registers */ - acpi_leave_sleep_state_prep(ACPI_STATE_S4); + /* Reprogram control registers and execute _BFS */ + acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); /* Check the hardware signature */ if (facs && s4_hardware_signature != facs->hardware_signature) { printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " @@ -864,7 +892,33 @@ static void acpi_power_off(void) /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ printk(KERN_DEBUG "%s called\n", __func__); local_irq_disable(); - acpi_enter_sleep_state(ACPI_STATE_S5); + acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags); +} + +/* + * ACPI 2.0 created the optional _GTS and _BFS, + * but industry adoption has been neither rapid nor broad. + * + * Linux gets into trouble when it executes poorly validated + * paths through the BIOS, so disable _GTS and _BFS by default, + * but do speak up and offer the option to enable them. + */ +static void __init acpi_gts_bfs_check(void) +{ + acpi_handle dummy; + + if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__GTS, &dummy))) + { + printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n"); + printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, " + "please notify linux-acpi@vger.kernel.org\n"); + } + if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__BFS, &dummy))) + { + printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n"); + printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, " + "please notify linux-acpi@vger.kernel.org\n"); + } } int __init acpi_sleep_init(void) @@ -925,5 +979,6 @@ int __init acpi_sleep_init(void) * object can also be evaluated when the system enters S5. */ register_reboot_notifier(&tts_notifier); + acpi_gts_bfs_check(); return 0; } diff --git a/trunk/drivers/acpi/sysfs.c b/trunk/drivers/acpi/sysfs.c index 7c3f98ba4afe..240a24400976 100644 --- a/trunk/drivers/acpi/sysfs.c +++ b/trunk/drivers/acpi/sysfs.c @@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) { int result = 0; - if (!strncmp(val, "enable", sizeof("enable") - 1)) { + if (!strncmp(val, "enable", strlen("enable"))) { result = acpi_debug_trace(trace_method_name, trace_debug_level, trace_debug_layer, 0); if (result) @@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) goto exit; } - if (!strncmp(val, "disable", sizeof("disable") - 1)) { + if (!strncmp(val, "disable", strlen("disable"))) { int name = 0; result = acpi_debug_trace((char *)&name, trace_debug_level, trace_debug_layer, 0); diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index edda74a43406..9fe90e9fecb5 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -106,9 +106,7 @@ static const struct acpi_device_id thermal_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, thermal_device_ids); -#ifdef CONFIG_PM_SLEEP static int acpi_thermal_resume(struct device *dev); -#endif static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); static struct acpi_driver acpi_thermal_driver = { @@ -1043,7 +1041,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) return 0; } -#ifdef CONFIG_PM_SLEEP static int acpi_thermal_resume(struct device *dev) { struct acpi_thermal *tz; @@ -1078,7 +1075,6 @@ static int acpi_thermal_resume(struct device *dev) return AE_OK; } -#endif static int thermal_act(const struct dmi_system_id *d) { diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 311be18d3f03..24712adf69df 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -65,8 +65,6 @@ #include #include #include -#include -#include #include #include #include @@ -4028,7 +4026,7 @@ static int mv_platform_probe(struct platform_device *pdev) struct ata_host *host; struct mv_host_priv *hpriv; struct resource *res; - int n_ports = 0, irq = 0; + int n_ports = 0; int rc; #if defined(CONFIG_HAVE_CLK) int port; @@ -4052,14 +4050,8 @@ static int mv_platform_probe(struct platform_device *pdev) return -EINVAL; /* allocate host */ - if (pdev->dev.of_node) { - of_property_read_u32(pdev->dev.of_node, "nr-ports", &n_ports); - irq = irq_of_parse_and_map(pdev->dev.of_node, 0); - } else { - mv_platform_data = pdev->dev.platform_data; - n_ports = mv_platform_data->n_ports; - irq = platform_get_irq(pdev, 0); - } + mv_platform_data = pdev->dev.platform_data; + n_ports = mv_platform_data->n_ports; host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); @@ -4117,7 +4109,8 @@ static int mv_platform_probe(struct platform_device *pdev) dev_info(&pdev->dev, "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH, host->n_ports); - rc = ata_host_activate(host, irq, mv_interrupt, IRQF_SHARED, &mv6_sht); + rc = ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, + IRQF_SHARED, &mv6_sht); if (!rc) return 0; @@ -4212,24 +4205,15 @@ static int mv_platform_resume(struct platform_device *pdev) #define mv_platform_resume NULL #endif -#ifdef CONFIG_OF -static struct of_device_id mv_sata_dt_ids[] __devinitdata = { - { .compatible = "marvell,orion-sata", }, - {}, -}; -MODULE_DEVICE_TABLE(of, mv_sata_dt_ids); -#endif - static struct platform_driver mv_platform_driver = { - .probe = mv_platform_probe, - .remove = __devexit_p(mv_platform_remove), - .suspend = mv_platform_suspend, - .resume = mv_platform_resume, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(mv_sata_dt_ids), - }, + .probe = mv_platform_probe, + .remove = __devexit_p(mv_platform_remove), + .suspend = mv_platform_suspend, + .resume = mv_platform_resume, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, }; diff --git a/trunk/drivers/atm/iphase.c b/trunk/drivers/atm/iphase.c index 96cce6d53195..d4386019af5d 100644 --- a/trunk/drivers/atm/iphase.c +++ b/trunk/drivers/atm/iphase.c @@ -2362,7 +2362,7 @@ static int __devinit ia_init(struct atm_dev *dev) { printk(DEV_LABEL " (itf %d): can't set up page mapping\n", dev->number); - return -ENOMEM; + return error; } IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n", dev->number, iadev->pci->revision, base, iadev->irq);) diff --git a/trunk/drivers/base/power/clock_ops.c b/trunk/drivers/base/power/clock_ops.c index eb78e9640c4a..869d7ff2227f 100644 --- a/trunk/drivers/base/power/clock_ops.c +++ b/trunk/drivers/base/power/clock_ops.c @@ -169,7 +169,8 @@ void pm_clk_init(struct device *dev) */ int pm_clk_create(struct device *dev) { - return dev_pm_get_subsys_data(dev); + int ret = dev_pm_get_subsys_data(dev); + return ret < 0 ? ret : 0; } /** diff --git a/trunk/drivers/base/power/common.c b/trunk/drivers/base/power/common.c index 39c32529b833..a14085cc613f 100644 --- a/trunk/drivers/base/power/common.c +++ b/trunk/drivers/base/power/common.c @@ -24,6 +24,7 @@ int dev_pm_get_subsys_data(struct device *dev) { struct pm_subsys_data *psd; + int ret = 0; psd = kzalloc(sizeof(*psd), GFP_KERNEL); if (!psd) @@ -39,6 +40,7 @@ int dev_pm_get_subsys_data(struct device *dev) dev->power.subsys_data = psd; pm_clk_init(dev); psd = NULL; + ret = 1; } spin_unlock_irq(&dev->power.lock); @@ -46,7 +48,7 @@ int dev_pm_get_subsys_data(struct device *dev) /* kfree() verifies that its argument is nonzero. */ kfree(psd); - return 0; + return ret; } EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data); diff --git a/trunk/drivers/block/drbd/drbd_main.c b/trunk/drivers/block/drbd/drbd_main.c index dbe6135a2abe..2e0e7fc1dbba 100644 --- a/trunk/drivers/block/drbd/drbd_main.c +++ b/trunk/drivers/block/drbd/drbd_main.c @@ -3537,9 +3537,9 @@ static void drbd_cleanup(void) } /** - * drbd_congested() - Callback for the flusher thread + * drbd_congested() - Callback for pdflush * @congested_data: User data - * @bdi_bits: Bits the BDI flusher thread is currently interested in + * @bdi_bits: Bits pdflush is currently interested in * * Returns 1<address_length); if (pcch_virt_addr == NULL) { pr_debug("probe: could not map shared mem region\n"); - ret = -ENOMEM; goto out_free; } pcch_hdr = pcch_virt_addr; diff --git a/trunk/drivers/dma/sh/shdma-base.c b/trunk/drivers/dma/sh/shdma-base.c index f4cd946d259d..27f5c781fd73 100644 --- a/trunk/drivers/dma/sh/shdma-base.c +++ b/trunk/drivers/dma/sh/shdma-base.c @@ -483,7 +483,6 @@ static struct shdma_desc *shdma_add_desc(struct shdma_chan *schan, new->mark = DESC_PREPARED; new->async_tx.flags = flags; new->direction = direction; - new->partial = 0; *len -= copy_size; if (direction == DMA_MEM_TO_MEM || direction == DMA_MEM_TO_DEV) @@ -645,14 +644,6 @@ static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, case DMA_TERMINATE_ALL: spin_lock_irqsave(&schan->chan_lock, flags); ops->halt_channel(schan); - - if (ops->get_partial && !list_empty(&schan->ld_queue)) { - /* Record partial transfer */ - struct shdma_desc *desc = list_first_entry(&schan->ld_queue, - struct shdma_desc, node); - desc->partial = ops->get_partial(schan, desc); - } - spin_unlock_irqrestore(&schan->chan_lock, flags); shdma_chan_ld_cleanup(schan, true); diff --git a/trunk/drivers/dma/sh/shdma.c b/trunk/drivers/dma/sh/shdma.c index f41bcc5267fd..027c9be97654 100644 --- a/trunk/drivers/dma/sh/shdma.c +++ b/trunk/drivers/dma/sh/shdma.c @@ -381,17 +381,6 @@ static bool sh_dmae_chan_irq(struct shdma_chan *schan, int irq) return true; } -static size_t sh_dmae_get_partial(struct shdma_chan *schan, - struct shdma_desc *sdesc) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, - shdma_chan); - struct sh_dmae_desc *sh_desc = container_of(sdesc, - struct sh_dmae_desc, shdma_desc); - return (sh_desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) << - sh_chan->xmit_shift; -} - /* Called from error IRQ or NMI */ static bool sh_dmae_reset(struct sh_dmae_device *shdev) { @@ -643,7 +632,6 @@ static const struct shdma_ops sh_dmae_shdma_ops = { .start_xfer = sh_dmae_start_xfer, .embedded_desc = sh_dmae_embedded_desc, .chan_irq = sh_dmae_chan_irq, - .get_partial = sh_dmae_get_partial, }; static int __devinit sh_dmae_probe(struct platform_device *pdev) diff --git a/trunk/drivers/gpio/gpio-em.c b/trunk/drivers/gpio/gpio-em.c index ae37181798b3..150d9768811d 100644 --- a/trunk/drivers/gpio/gpio-em.c +++ b/trunk/drivers/gpio/gpio-em.c @@ -266,7 +266,7 @@ static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) return 0; } -static void em_gio_irq_domain_cleanup(struct em_gio_priv *p) +static void __devexit em_gio_irq_domain_cleanup(struct em_gio_priv *p) { struct gpio_em_config *pdata = p->pdev->dev.platform_data; diff --git a/trunk/drivers/gpio/gpio-langwell.c b/trunk/drivers/gpio/gpio-langwell.c index 202a99207b7d..a1c8754f52cf 100644 --- a/trunk/drivers/gpio/gpio-langwell.c +++ b/trunk/drivers/gpio/gpio-langwell.c @@ -339,7 +339,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, resource_size_t start, len; struct lnw_gpio *lnw; u32 gpio_base; - int retval; + int retval = 0; int ngpio = id->driver_data; retval = pci_enable_device(pdev); @@ -357,7 +357,6 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, base = ioremap_nocache(start, len); if (!base) { dev_err(&pdev->dev, "error mapping bar1\n"); - retval = -EFAULT; goto err3; } gpio_base = *((u32 *)base + 1); @@ -382,10 +381,8 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, &lnw_gpio_irq_ops, lnw); - if (!lnw->domain) { - retval = -ENOMEM; + if (!lnw->domain) goto err3; - } lnw->reg_base = base; lnw->chip.label = dev_name(&pdev->dev); diff --git a/trunk/drivers/gpio/gpio-msic.c b/trunk/drivers/gpio/gpio-msic.c index b38986285868..71a838f44501 100644 --- a/trunk/drivers/gpio/gpio-msic.c +++ b/trunk/drivers/gpio/gpio-msic.c @@ -99,7 +99,7 @@ static int msic_gpio_to_oreg(unsigned offset) if (offset < 20) return INTEL_MSIC_GPIO0HV0CTLO - offset + 16; - return INTEL_MSIC_GPIO1HV0CTLO - offset + 20; + return INTEL_MSIC_GPIO1HV0CTLO + offset + 20; } static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) diff --git a/trunk/drivers/gpio/gpio-mxc.c b/trunk/drivers/gpio/gpio-mxc.c index 80f44bb64a87..4db460b6ecf7 100644 --- a/trunk/drivers/gpio/gpio-mxc.c +++ b/trunk/drivers/gpio/gpio-mxc.c @@ -465,8 +465,9 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) goto out_iounmap; port->bgc.gc.to_irq = mxc_gpio_to_irq; - port->bgc.gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : - pdev->id * 32; + port->bgc.gc.base = pdev->id * 32; + port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir); + port->bgc.data = port->bgc.read_reg(port->bgc.reg_set); err = gpiochip_add(&port->bgc.gc); if (err) diff --git a/trunk/drivers/gpio/gpio-pxa.c b/trunk/drivers/gpio/gpio-pxa.c index 9cac88a65f78..58a6a63a6ece 100644 --- a/trunk/drivers/gpio/gpio-pxa.c +++ b/trunk/drivers/gpio/gpio-pxa.c @@ -62,7 +62,6 @@ int pxa_last_gpio; #ifdef CONFIG_OF static struct irq_domain *domain; -static struct device_node *pxa_gpio_of_node; #endif struct pxa_gpio_chip { @@ -278,24 +277,6 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) (value ? GPSR_OFFSET : GPCR_OFFSET)); } -#ifdef CONFIG_OF_GPIO -static int pxa_gpio_of_xlate(struct gpio_chip *gc, - const struct of_phandle_args *gpiospec, - u32 *flags) -{ - if (gpiospec->args[0] > pxa_last_gpio) - return -EINVAL; - - if (gc != &pxa_gpio_chips[gpiospec->args[0] / 32].chip) - return -EINVAL; - - if (flags) - *flags = gpiospec->args[1]; - - return gpiospec->args[0] % 32; -} -#endif - static int __devinit pxa_init_gpio_chip(int gpio_end, int (*set_wake)(unsigned int, unsigned int)) { @@ -323,11 +304,6 @@ static int __devinit pxa_init_gpio_chip(int gpio_end, c->get = pxa_gpio_get; c->set = pxa_gpio_set; c->to_irq = pxa_gpio_to_irq; -#ifdef CONFIG_OF_GPIO - c->of_node = pxa_gpio_of_node; - c->of_xlate = pxa_gpio_of_xlate; - c->of_gpio_n_cells = 2; -#endif /* number of GPIOs on last bank may be less than 32 */ c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; @@ -512,7 +488,6 @@ static int pxa_gpio_nums(void) return count; } -#ifdef CONFIG_OF static struct of_device_id pxa_gpio_dt_ids[] = { { .compatible = "mrvl,pxa-gpio" }, { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, @@ -530,9 +505,9 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, const struct irq_domain_ops pxa_irq_domain_ops = { .map = pxa_irq_domain_map, - .xlate = irq_domain_xlate_twocell, }; +#ifdef CONFIG_OF static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) { int ret, nr_banks, nr_gpios, irq_base; @@ -570,7 +545,6 @@ static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) } domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, &pxa_irq_domain_ops, NULL); - pxa_gpio_of_node = np; return 0; err: iounmap(gpio_reg_base); @@ -679,7 +653,7 @@ static struct platform_driver pxa_gpio_driver = { .probe = pxa_gpio_probe, .driver = { .name = "pxa-gpio", - .of_match_table = of_match_ptr(pxa_gpio_dt_ids), + .of_match_table = pxa_gpio_dt_ids, }, }; diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c index ba126cc04073..92f7b2bb79d4 100644 --- a/trunk/drivers/gpio/gpio-samsung.c +++ b/trunk/drivers/gpio/gpio-samsung.c @@ -2452,6 +2452,12 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { .ngpio = EXYNOS5_GPIO_C3_NR, .label = "GPC3", }, + }, { + .chip = { + .base = EXYNOS5_GPC4(0), + .ngpio = EXYNOS5_GPIO_C4_NR, + .label = "GPC4", + }, }, { .chip = { .base = EXYNOS5_GPD0(0), @@ -2506,12 +2512,6 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { .ngpio = EXYNOS5_GPIO_Y6_NR, .label = "GPY6", }, - }, { - .chip = { - .base = EXYNOS5_GPC4(0), - .ngpio = EXYNOS5_GPIO_C4_NR, - .label = "GPC4", - }, }, { .config = &samsung_gpio_cfgs[9], .irq_base = IRQ_EINT(0), @@ -2836,7 +2836,7 @@ static __init void exynos5_gpiolib_init(void) } /* need to set base address for gpc4 */ - exynos5_gpios_1[20].base = gpio_base1 + 0x2E0; + exynos5_gpios_1[11].base = gpio_base1 + 0x2E0; /* need to set base address for gpx */ chip = &exynos5_gpios_1[21]; diff --git a/trunk/drivers/gpio/gpio-sch.c b/trunk/drivers/gpio/gpio-sch.c index 8707d4572a06..424dce8e3f30 100644 --- a/trunk/drivers/gpio/gpio-sch.c +++ b/trunk/drivers/gpio/gpio-sch.c @@ -241,8 +241,7 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev) break; default: - err = -ENODEV; - goto err_sch_gpio_core; + return -ENODEV; } sch_gpio_core.dev = &pdev->dev; diff --git a/trunk/drivers/gpu/drm/drm_edid_load.c b/trunk/drivers/gpu/drm/drm_edid_load.c index 0303935d10e2..66d4a28ad5a2 100644 --- a/trunk/drivers/gpu/drm/drm_edid_load.c +++ b/trunk/drivers/gpu/drm/drm_edid_load.c @@ -119,7 +119,7 @@ static int edid_load(struct drm_connector *connector, char *name, { const struct firmware *fw; struct platform_device *pdev; - u8 *fwdata = NULL, *edid, *new_edid; + u8 *fwdata = NULL, *edid; int fwsize, expected; int builtin = 0, err = 0; int i, valid_extensions = 0; @@ -195,14 +195,12 @@ static int edid_load(struct drm_connector *connector, char *name, "\"%s\" for connector \"%s\"\n", valid_extensions, edid[0x7e], name, connector_name); edid[0x7e] = valid_extensions; - new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, + edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); - if (new_edid == NULL) { + if (edid == NULL) { err = -ENOMEM; - kfree(edid); goto relfw_out; } - edid = new_edid; } connector->display_info.raw_edid = edid; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index a24ffbe97c01..ed22612bc847 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -346,40 +346,11 @@ static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ - INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */ INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ - INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */ INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ - INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */ - INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ - INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ - INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */ - INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ - INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ - INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */ - INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ - INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ - INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */ - INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ - INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ - INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */ - INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ - INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ - INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */ - INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ - INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ - INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ - INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */ - INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ - INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */ - INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */ - INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ - INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ - INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ - INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ - INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */ + INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */ INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_context.c b/trunk/drivers/gpu/drm/i915/i915_gem_context.c index a9d58d72bb4d..da8b01fb1bf8 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_context.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_context.c @@ -451,6 +451,7 @@ int i915_switch_context(struct intel_ring_buffer *ring, struct drm_i915_file_private *file_priv = NULL; struct i915_hw_context *to; struct drm_i915_gem_object *from_obj = ring->last_context_obj; + int ret; if (dev_priv->hw_contexts_disabled) return 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c index ff2819ea0813..5af631e788c8 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -291,16 +291,6 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, target_i915_obj = to_intel_bo(target_obj); target_offset = target_i915_obj->gtt_offset; - /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and - * pipe_control writes because the gpu doesn't properly redirect them - * through the ppgtt for non_secure batchbuffers. */ - if (unlikely(IS_GEN6(dev) && - reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && - !target_i915_obj->has_global_gtt_mapping)) { - i915_gem_gtt_bind_object(target_i915_obj, - target_i915_obj->cache_level); - } - /* The target buffer should have appeared before us in the * exec_object list, so it should have a GTT space bound by now. */ @@ -409,6 +399,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, io_mapping_unmap_atomic(reloc_page); } + /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and + * pipe_control writes because the gpu doesn't properly redirect them + * through the ppgtt for non_secure batchbuffers. */ + if (unlikely(IS_GEN6(dev) && + reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && + !target_i915_obj->has_global_gtt_mapping)) { + i915_gem_gtt_bind_object(target_i915_obj, + target_i915_obj->cache_level); + } + /* and update the user's relocation entry */ reloc->presumed_offset = target_offset; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c index ee9b68f6bc36..9fd25a435536 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -361,8 +361,7 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - /* don't map imported dma buf objects */ - if (dev_priv->mm.gtt->needs_dmar && !obj->sg_table) + if (dev_priv->mm.gtt->needs_dmar) return intel_gtt_map_memory(obj->pages, obj->base.size >> PAGE_SHIFT, &obj->sg_list, diff --git a/trunk/drivers/gpu/drm/i915/i915_sysfs.c b/trunk/drivers/gpu/drm/i915/i915_sysfs.c index 7631807a2788..2f5388af8df9 100644 --- a/trunk/drivers/gpu/drm/i915/i915_sysfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_sysfs.c @@ -32,7 +32,6 @@ #include "intel_drv.h" #include "i915_drv.h" -#ifdef CONFIG_PM static u32 calc_residency(struct drm_device *dev, const u32 reg) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -225,14 +224,3 @@ void i915_teardown_sysfs(struct drm_device *dev) device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); } -#else -void i915_setup_sysfs(struct drm_device *dev) -{ - return; -} - -void i915_teardown_sysfs(struct drm_device *dev) -{ - return; -} -#endif /* CONFIG_PM */ diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 88913a47cd34..f6159765f1eb 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -869,7 +869,6 @@ intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, unsigned long bestppm, ppm, absppm; int dotclk, flag; - flag = 0; dotclk = target * 1000; bestppm = 1000000; ppm = absppm = 0; diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 132ab511b90c..84353559441c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -46,16 +46,15 @@ }) #define wait_for_atomic_us(COND, US) ({ \ - unsigned long timeout__ = jiffies + usecs_to_jiffies(US); \ - int ret__ = 0; \ - while (!(COND)) { \ - if (time_after(jiffies, timeout__)) { \ - ret__ = -ETIMEDOUT; \ - break; \ - } \ - cpu_relax(); \ - } \ - ret__; \ + int i, ret__ = -ETIMEDOUT; \ + for (i = 0; i < (US); i++) { \ + if ((COND)) { \ + ret__ = 0; \ + break; \ + } \ + udelay(1); \ + } \ + ret__; \ }) #define wait_for(COND, MS) _wait_for(COND, MS, 1) @@ -381,6 +380,7 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); extern u32 intel_panel_get_max_backlight(struct drm_device *dev); +extern u32 intel_panel_get_backlight(struct drm_device *dev); extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); extern int intel_panel_setup_backlight(struct drm_device *dev); extern void intel_panel_enable_backlight(struct drm_device *dev, diff --git a/trunk/drivers/gpu/drm/i915/intel_i2c.c b/trunk/drivers/gpu/drm/i915/intel_i2c.c index d79500bc1ce5..1991a4408cf9 100644 --- a/trunk/drivers/gpu/drm/i915/intel_i2c.c +++ b/trunk/drivers/gpu/drm/i915/intel_i2c.c @@ -540,6 +540,9 @@ void intel_teardown_gmbus(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int i; + if (dev_priv->gmbus == NULL) + return; + for (i = 0; i < GMBUS_NUM_PORTS; i++) { struct intel_gmbus *bus = &dev_priv->gmbus[i]; i2c_del_adapter(&bus->adapter); diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index 9474488db948..10c7d39034e1 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -213,7 +213,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) return val; } -static u32 intel_panel_get_backlight(struct drm_device *dev) +u32 intel_panel_get_backlight(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; u32 val; diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index 58c07cdafb7e..94aabcaa3a67 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -3963,7 +3963,6 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) DRM_ERROR("Force wake wait timed out\n"); I915_WRITE_NOTRACE(FORCEWAKE, 1); - POSTING_READ(FORCEWAKE); if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) DRM_ERROR("Force wake wait timed out\n"); @@ -3984,7 +3983,6 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) DRM_ERROR("Force wake wait timed out\n"); I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); - POSTING_READ(FORCEWAKE_MT); if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) DRM_ERROR("Force wake wait timed out\n"); @@ -4020,14 +4018,14 @@ void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE, 0); - POSTING_READ(FORCEWAKE); + /* The below doubles as a POSTING_READ */ gen6_gt_check_fifodbg(dev_priv); } static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); - POSTING_READ(FORCEWAKE_MT); + /* The below doubles as a POSTING_READ */ gen6_gt_check_fifodbg(dev_priv); } diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 414af1e2973b..bf0195a96d53 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -289,6 +289,8 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_WRITE_HEAD(ring, 0); ring->write_tail(ring, 0); + /* Initialize the ring. */ + I915_WRITE_START(ring, obj->gtt_offset); head = I915_READ_HEAD(ring) & HEAD_ADDR; /* G45 ring initialization fails to reset head to zero */ @@ -314,11 +316,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) } } - /* Initialize the ring. This must happen _after_ we've cleared the ring - * registers with the above sequence (the readback of the HEAD registers - * also enforces ordering), otherwise the hw might lose the new ring - * register values. */ - I915_WRITE_START(ring, obj->gtt_offset); I915_WRITE_CTL(ring, ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID); diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index d172e9873131..26a6a4d0d078 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -444,16 +444,13 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, struct i2c_msg *msgs; int i, ret = true; - /* Would be simpler to allocate both in one go ? */ buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); if (!buf) return false; msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); - if (!msgs) { - kfree(buf); + if (!msgs) return false; - } intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); diff --git a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c index b69642d5d850..a4d7c500c97b 100644 --- a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -468,11 +468,10 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) { unsigned int vcomax, vcomin, pllreffreq; unsigned int delta, tmpdelta; - int testr, testn, testm, testo; + unsigned int testr, testn, testm, testo; unsigned int p, m, n; - unsigned int computed, vco; + unsigned int computed; int tmp; - const unsigned int m_div_val[] = { 1, 2, 4, 8 }; m = n = p = 0; vcomax = 1488000; @@ -491,13 +490,12 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) if (delta == 0) break; for (testo = 5; testo < 33; testo++) { - vco = pllreffreq * (testn + 1) / + computed = pllreffreq * (testn + 1) / (testr + 1); - if (vco < vcomin) + if (computed < vcomin) continue; - if (vco > vcomax) + if (computed > vcomax) continue; - computed = vco / (m_div_val[testm] * (testo + 1)); if (computed > clock) tmpdelta = computed - clock; else diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index c6fcb5b86a45..9e6f76fec527 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -259,7 +259,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) /* adjust pm to dpms changes BEFORE enabling crtcs */ radeon_pm_compute_clocks(rdev); /* disable crtc pair power gating before programming */ - if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) + if (ASIC_IS_DCE6(rdev)) atombios_powergate_crtc(crtc, ATOM_DISABLE); atombios_enable_crtc(crtc, ATOM_ENABLE); if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) @@ -279,7 +279,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) atombios_enable_crtc(crtc, ATOM_DISABLE); radeon_crtc->enabled = false; /* power gating is per-pair */ - if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { + if (ASIC_IS_DCE6(rdev)) { struct drm_crtc *other_crtc; struct radeon_crtc *other_radeon_crtc; list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { @@ -1531,12 +1531,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) * crtc virtual pixel clock. */ if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { - if (rdev->clock.dp_extclk) - return ATOM_PPLL_INVALID; + if (ASIC_IS_DCE5(rdev)) + return ATOM_DCPLL; else if (ASIC_IS_DCE6(rdev)) return ATOM_PPLL0; - else if (ASIC_IS_DCE5(rdev)) - return ATOM_DCPLL; + else if (rdev->clock.dp_extclk) + return ATOM_PPLL_INVALID; } } } @@ -1635,28 +1635,18 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, static void atombios_crtc_prepare(struct drm_crtc *crtc) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - radeon_crtc->in_mode_set = true; /* pick pll */ radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); - /* disable crtc pair power gating before programming */ - if (ASIC_IS_DCE6(rdev)) - atombios_powergate_crtc(crtc, ATOM_DISABLE); - atombios_lock_crtc(crtc, ATOM_ENABLE); atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); } static void atombios_crtc_commit(struct drm_crtc *crtc) { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); atombios_lock_crtc(crtc, ATOM_DISABLE); - radeon_crtc->in_mode_set = false; } static void atombios_crtc_disable(struct drm_crtc *crtc) diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index e93b80a6d4e9..e585a3b947eb 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -1229,8 +1229,24 @@ void evergreen_agp_enable(struct radeon_device *rdev) void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) { + save->vga_control[0] = RREG32(D1VGA_CONTROL); + save->vga_control[1] = RREG32(D2VGA_CONTROL); save->vga_render_control = RREG32(VGA_RENDER_CONTROL); save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); + save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); + save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); + if (rdev->num_crtc >= 4) { + save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); + save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); + save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); + save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); + } + if (rdev->num_crtc >= 6) { + save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); + save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); + save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); + save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + } /* Stop all video */ WREG32(VGA_RENDER_CONTROL, 0); @@ -1341,6 +1357,47 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s /* Unlock host access */ WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); mdelay(1); + /* Restore video state */ + WREG32(D1VGA_CONTROL, save->vga_control[0]); + WREG32(D2VGA_CONTROL, save->vga_control[1]); + if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); + WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); + } + if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); + WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); + } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); + if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); + } + if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + } + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); + if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); + } + if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); + } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); + if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + } + if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } WREG32(VGA_RENDER_CONTROL, save->vga_render_control); } @@ -1929,18 +1986,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) if (rdev->flags & RADEON_IS_IGP) rdev->config.evergreen.tile_config |= 1 << 4; else { - switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { - case 0: /* four banks */ - rdev->config.evergreen.tile_config |= 0 << 4; - break; - case 1: /* eight banks */ + if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) rdev->config.evergreen.tile_config |= 1 << 4; - break; - case 2: /* sixteen banks */ - default: - rdev->config.evergreen.tile_config |= 2 << 4; - break; - } + else + rdev->config.evergreen.tile_config |= 0 << 4; } rdev->config.evergreen.tile_config |= 0 << 8; rdev->config.evergreen.tile_config |= diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index e44a62a07fe3..c16554122ccd 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -788,13 +788,6 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, case V_030000_SQ_TEX_DIM_1D_ARRAY: case V_030000_SQ_TEX_DIM_2D_ARRAY: depth = 1; - break; - case V_030000_SQ_TEX_DIM_2D_MSAA: - case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA: - surf.nsamples = 1 << llevel; - llevel = 0; - depth = 1; - break; case V_030000_SQ_TEX_DIM_3D: break; default: @@ -968,15 +961,13 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) if (track->db_dirty) { /* Check stencil buffer */ - if (G_028044_FORMAT(track->db_s_info) != V_028044_STENCIL_INVALID && - G_028800_STENCIL_ENABLE(track->db_depth_control)) { + if (G_028800_STENCIL_ENABLE(track->db_depth_control)) { r = evergreen_cs_track_validate_stencil(p); if (r) return r; } /* Check depth buffer */ - if (G_028040_FORMAT(track->db_z_info) != V_028040_Z_INVALID && - G_028800_Z_ENABLE(track->db_depth_control)) { + if (G_028800_Z_ENABLE(track->db_depth_control)) { r = evergreen_cs_track_validate_depth(p); if (r) return r; diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index 79347855d9bf..d3bd098e4e19 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -1277,8 +1277,6 @@ #define S_028044_FORMAT(x) (((x) & 0x1) << 0) #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) #define C_028044_FORMAT 0xFFFFFFFE -#define V_028044_STENCIL_INVALID 0 -#define V_028044_STENCIL_8 1 #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) #define DB_Z_READ_BASE 0x28048 #define DB_STENCIL_READ_BASE 0x2804c diff --git a/trunk/drivers/gpu/drm/radeon/ni.c b/trunk/drivers/gpu/drm/radeon/ni.c index 853800e8582f..9945d86d9001 100644 --- a/trunk/drivers/gpu/drm/radeon/ni.c +++ b/trunk/drivers/gpu/drm/radeon/ni.c @@ -574,18 +574,10 @@ static void cayman_gpu_init(struct radeon_device *rdev) if (rdev->flags & RADEON_IS_IGP) rdev->config.cayman.tile_config |= 1 << 4; else { - switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { - case 0: /* four banks */ - rdev->config.cayman.tile_config |= 0 << 4; - break; - case 1: /* eight banks */ + if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) rdev->config.cayman.tile_config |= 1 << 4; - break; - case 2: /* sixteen banks */ - default: - rdev->config.cayman.tile_config |= 2 << 4; - break; - } + else + rdev->config.cayman.tile_config |= 0 << 4; } rdev->config.cayman.tile_config |= ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index d79c639ae739..637280f541a3 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -3789,23 +3789,3 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); } } - -/** - * r600_get_gpu_clock - return GPU clock counter snapshot - * - * @rdev: radeon_device pointer - * - * Fetches a GPU clock counter snapshot (R6xx-cayman). - * Returns the 64 bit clock counter snapshot. - */ -uint64_t r600_get_gpu_clock(struct radeon_device *rdev) -{ - uint64_t clock; - - mutex_lock(&rdev->gpu_clock_mutex); - WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); - clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | - ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); - mutex_unlock(&rdev->gpu_clock_mutex); - return clock; -} diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index 3dab49cb1d4a..ca87f7afaf23 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -764,10 +764,8 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) } /* Check depth buffer */ - if (track->db_dirty && - G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && - (G_028800_STENCIL_ENABLE(track->db_depth_control) || - G_028800_Z_ENABLE(track->db_depth_control))) { + if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || + G_028800_Z_ENABLE(track->db_depth_control))) { r = r600_cs_track_validate_db(p); if (r) return r; @@ -1559,14 +1557,13 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, u32 tiling_flags) { struct r600_cs_track *track = p->track; - u32 dim, nfaces, llevel, blevel, w0, h0, d0; - u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; + u32 nfaces, llevel, blevel, w0, h0, d0; + u32 word0, word1, l0_size, mipmap_size, word2, word3; u32 height_align, pitch, pitch_align, depth_align; - u32 barray, larray; + u32 array, barray, larray; u64 base_align; struct array_mode_checker array_check; u32 format; - bool is_array; /* on legacy kernel we don't perform advanced check */ if (p->rdev == NULL) @@ -1584,28 +1581,12 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); } word1 = radeon_get_ib_value(p, idx + 1); - word2 = radeon_get_ib_value(p, idx + 2) << 8; - word3 = radeon_get_ib_value(p, idx + 3) << 8; - word4 = radeon_get_ib_value(p, idx + 4); - word5 = radeon_get_ib_value(p, idx + 5); - dim = G_038000_DIM(word0); w0 = G_038000_TEX_WIDTH(word0) + 1; - pitch = (G_038000_PITCH(word0) + 1) * 8; h0 = G_038004_TEX_HEIGHT(word1) + 1; d0 = G_038004_TEX_DEPTH(word1); - format = G_038004_DATA_FORMAT(word1); - blevel = G_038010_BASE_LEVEL(word4); - llevel = G_038014_LAST_LEVEL(word5); - /* pitch in texels */ - array_check.array_mode = G_038000_TILE_MODE(word0); - array_check.group_size = track->group_size; - array_check.nbanks = track->nbanks; - array_check.npipes = track->npipes; - array_check.nsamples = 1; - array_check.blocksize = r600_fmt_get_blocksize(format); nfaces = 1; - is_array = false; - switch (dim) { + array = 0; + switch (G_038000_DIM(word0)) { case V_038000_SQ_TEX_DIM_1D: case V_038000_SQ_TEX_DIM_2D: case V_038000_SQ_TEX_DIM_3D: @@ -1618,25 +1599,29 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, break; case V_038000_SQ_TEX_DIM_1D_ARRAY: case V_038000_SQ_TEX_DIM_2D_ARRAY: - is_array = true; + array = 1; break; - case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: - is_array = true; - /* fall through */ case V_038000_SQ_TEX_DIM_2D_MSAA: - array_check.nsamples = 1 << llevel; - llevel = 0; - break; + case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: default: dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); return -EINVAL; } + format = G_038004_DATA_FORMAT(word1); if (!r600_fmt_is_valid_texture(format, p->family)) { dev_warn(p->dev, "%s:%d texture invalid format %d\n", __func__, __LINE__, format); return -EINVAL; } + /* pitch in texels */ + pitch = (G_038000_PITCH(word0) + 1) * 8; + array_check.array_mode = G_038000_TILE_MODE(word0); + array_check.group_size = track->group_size; + array_check.nbanks = track->nbanks; + array_check.npipes = track->npipes; + array_check.nsamples = 1; + array_check.blocksize = r600_fmt_get_blocksize(format); if (r600_get_array_mode_alignment(&array_check, &pitch_align, &height_align, &depth_align, &base_align)) { dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", @@ -1662,13 +1647,20 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, return -EINVAL; } + word2 = radeon_get_ib_value(p, idx + 2) << 8; + word3 = radeon_get_ib_value(p, idx + 3) << 8; + + word0 = radeon_get_ib_value(p, idx + 4); + word1 = radeon_get_ib_value(p, idx + 5); + blevel = G_038010_BASE_LEVEL(word0); + llevel = G_038014_LAST_LEVEL(word1); if (blevel > llevel) { dev_warn(p->dev, "texture blevel %d > llevel %d\n", blevel, llevel); } - if (is_array) { - barray = G_038014_BASE_ARRAY(word5); - larray = G_038014_LAST_ARRAY(word5); + if (array == 1) { + barray = G_038014_BASE_ARRAY(word1); + larray = G_038014_LAST_ARRAY(word1); nfaces = larray - barray + 1; } @@ -1685,6 +1677,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, return -EINVAL; } /* using get ib will give us the offset into the mipmap bo */ + word3 = radeon_get_ib_value(p, idx + 3) << 8; if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ diff --git a/trunk/drivers/gpu/drm/radeon/r600d.h b/trunk/drivers/gpu/drm/radeon/r600d.h index fd328f4c3ea8..4b116ae75fc2 100644 --- a/trunk/drivers/gpu/drm/radeon/r600d.h +++ b/trunk/drivers/gpu/drm/radeon/r600d.h @@ -602,9 +602,6 @@ #define RLC_HB_WPTR 0x3f1c #define RLC_HB_WPTR_LSB_ADDR 0x3f14 #define RLC_HB_WPTR_MSB_ADDR 0x3f18 -#define RLC_GPU_CLOCK_COUNT_LSB 0x3f38 -#define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c -#define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40 #define RLC_MC_CNTL 0x3f44 #define RLC_UCODE_CNTL 0x3f48 #define RLC_UCODE_ADDR 0x3f2c diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index 99304194a65c..5431af292408 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -300,7 +300,6 @@ struct radeon_bo_va { uint64_t soffset; uint64_t eoffset; uint32_t flags; - struct radeon_fence *fence; bool valid; }; @@ -1534,7 +1533,6 @@ struct radeon_device { unsigned debugfs_count; /* virtual memory */ struct radeon_vm_manager vm_manager; - struct mutex gpu_clock_mutex; }; int radeon_device_init(struct radeon_device *rdev, @@ -1735,11 +1733,11 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) -#define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc)) -#define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) -#define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) -#define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) -#define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) +#define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc)) +#define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base)) +#define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc)) +#define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc)) +#define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev)) /* Common functions */ /* AGP */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.h b/trunk/drivers/gpu/drm/radeon/radeon_asic.h index 18c38d14c8cd..f4af24310438 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.h @@ -255,10 +255,13 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev); * rv515 */ struct rv515_mc_save { + u32 d1vga_control; + u32 d2vga_control; u32 vga_render_control; u32 vga_hdp_control; + u32 d1crtc_control; + u32 d2crtc_control; }; - int rv515_init(struct radeon_device *rdev); void rv515_fini(struct radeon_device *rdev); uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); @@ -368,7 +371,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_sa_bo *vb); int r600_mc_wait_for_idle(struct radeon_device *rdev); -uint64_t r600_get_gpu_clock(struct radeon_device *rdev); /* * rv770,rv730,rv710,rv740 @@ -387,10 +389,11 @@ void r700_cp_fini(struct radeon_device *rdev); * evergreen */ struct evergreen_mc_save { + u32 vga_control[6]; u32 vga_render_control; u32 vga_hdp_control; + u32 crtc_control[6]; }; - void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); int evergreen_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); @@ -469,6 +472,5 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); -uint64_t si_get_gpu_clock(struct radeon_device *rdev); #endif diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index f9c21f9d16bc..b1e3820df363 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1263,8 +1263,6 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) union igp_info { struct _ATOM_INTEGRATED_SYSTEM_INFO info; struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; }; bool radeon_atombios_sideport_present(struct radeon_device *rdev) @@ -1392,50 +1390,27 @@ static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, struct radeon_mode_info *mode_info = &rdev->mode_info; int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); u16 data_offset, size; - union igp_info *igp_info; + struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; u8 frev, crev; u16 percentage = 0, rate = 0; /* get any igp specific overrides */ if (atom_parse_data_header(mode_info->atom_context, index, &size, &frev, &crev, &data_offset)) { - igp_info = (union igp_info *) + igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) (mode_info->atom_context->bios + data_offset); - switch (crev) { - case 6: - switch (id) { - case ASIC_INTERNAL_SS_ON_TMDS: - percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage); - rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz); - break; - case ASIC_INTERNAL_SS_ON_HDMI: - percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage); - rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz); - break; - case ASIC_INTERNAL_SS_ON_LVDS: - percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage); - rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz); - break; - } + switch (id) { + case ASIC_INTERNAL_SS_ON_TMDS: + percentage = le16_to_cpu(igp_info->usDVISSPercentage); + rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); break; - case 7: - switch (id) { - case ASIC_INTERNAL_SS_ON_TMDS: - percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage); - rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz); - break; - case ASIC_INTERNAL_SS_ON_HDMI: - percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage); - rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz); - break; - case ASIC_INTERNAL_SS_ON_LVDS: - percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage); - rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz); - break; - } + case ASIC_INTERNAL_SS_ON_HDMI: + percentage = le16_to_cpu(igp_info->usHDMISSPercentage); + rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); break; - default: - DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); + case ASIC_INTERNAL_SS_ON_LVDS: + percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); + rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); break; } if (percentage) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index f75247d42ffd..576f4f6919f2 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -719,34 +719,6 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde return i2c; } -static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct radeon_i2c_bus_rec i2c; - u16 offset; - u8 id, blocks, clk, data; - int i; - - i2c.valid = false; - - offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); - if (offset) { - blocks = RBIOS8(offset + 2); - for (i = 0; i < blocks; i++) { - id = RBIOS8(offset + 3 + (i * 5) + 0); - if (id == 136) { - clk = RBIOS8(offset + 3 + (i * 5) + 3); - data = RBIOS8(offset + 3 + (i * 5) + 4); - /* gpiopad */ - i2c = combios_setup_i2c_bus(rdev, DDC_MONID, - (1 << clk), (1 << data)); - break; - } - } - } - return i2c; -} - void radeon_combios_i2c_init(struct radeon_device *rdev) { struct drm_device *dev = rdev->ddev; @@ -783,14 +755,30 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) } else if (rdev->family == CHIP_RS300 || rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { + u16 offset; + u8 id, blocks, clk, data; + int i; + /* 0x68 */ i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); - /* gpiopad */ - i2c = radeon_combios_get_i2c_info_from_table(rdev); - if (i2c.valid) - rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); + offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); + if (offset) { + blocks = RBIOS8(offset + 2); + for (i = 0; i < blocks; i++) { + id = RBIOS8(offset + 3 + (i * 5) + 0); + if (id == 136) { + clk = RBIOS8(offset + 3 + (i * 5) + 3); + data = RBIOS8(offset + 3 + (i * 5) + 4); + /* gpiopad */ + i2c = combios_setup_i2c_bus(rdev, DDC_MONID, + (1 << clk), (1 << data)); + rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); + break; + } + } + } } else if ((rdev->family == CHIP_R200) || (rdev->family >= CHIP_R300)) { /* 0x68 */ @@ -2333,10 +2321,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) connector = (tmp >> 12) & 0xf; ddc_type = (tmp >> 8) & 0xf; - if (ddc_type == 5) - ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev); - else - ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); + ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); switch (connector) { case CONNECTOR_PROPRIETARY_LEGACY: diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cs.c b/trunk/drivers/gpu/drm/radeon/radeon_cs.c index b4a0db24f4dd..8a4c49ef0cc4 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cs.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cs.c @@ -278,30 +278,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) return 0; } -static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser, - struct radeon_fence *fence) -{ - struct radeon_fpriv *fpriv = parser->filp->driver_priv; - struct radeon_vm *vm = &fpriv->vm; - struct radeon_bo_list *lobj; - - if (parser->chunk_ib_idx == -1) { - return; - } - if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) { - return; - } - - list_for_each_entry(lobj, &parser->validated, tv.head) { - struct radeon_bo_va *bo_va; - struct radeon_bo *rbo = lobj->bo; - - bo_va = radeon_bo_va(rbo, vm); - radeon_fence_unref(&bo_va->fence); - bo_va->fence = radeon_fence_ref(fence); - } -} - /** * cs_parser_fini() - clean parser states * @parser: parser structure holding parsing context. @@ -314,14 +290,11 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) { unsigned i; - if (!error) { - /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */ - radeon_bo_vm_fence_va(parser, parser->ib.fence); + if (!error) ttm_eu_fence_buffer_objects(&parser->validated, parser->ib.fence); - } else { + else ttm_eu_backoff_reservation(&parser->validated); - } if (parser->relocs != NULL) { for (i = 0; i < parser->nrelocs; i++) { @@ -415,6 +388,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, if (parser->chunk_ib_idx == -1) return 0; + if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) return 0; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cursor.c b/trunk/drivers/gpu/drm/radeon/radeon_cursor.c index 8794744cdf1a..711e95ad39bf 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cursor.c @@ -67,8 +67,7 @@ static void radeon_hide_cursor(struct drm_crtc *crtc) if (ASIC_IS_DCE4(rdev)) { WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); - WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | - EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); + WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); } else if (ASIC_IS_AVIVO(rdev)) { WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); @@ -95,8 +94,7 @@ static void radeon_show_cursor(struct drm_crtc *crtc) if (ASIC_IS_DCE4(rdev)) { WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | - EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | - EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); + EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); } else if (ASIC_IS_AVIVO(rdev)) { WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index d2e243867ac6..742af8244e89 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -1009,7 +1009,6 @@ int radeon_device_init(struct radeon_device *rdev, atomic_set(&rdev->ih.lock, 0); mutex_init(&rdev->gem.mutex); mutex_init(&rdev->pm.mutex); - mutex_init(&rdev->gpu_clock_mutex); init_rwsem(&rdev->pm.mclk_lock); init_rwsem(&rdev->exclusive_lock); init_waitqueue_head(&rdev->irq.vblank_queue); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index d7269f48d37c..dcea6f01ae4e 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -59,12 +59,9 @@ * 2.15.0 - add max_pipes query * 2.16.0 - fix evergreen 2D tiled surface calculation * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx - * 2.18.0 - r600-eg: allow "invalid" DB formats - * 2.19.0 - r600-eg: MSAA textures - * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 20 +#define KMS_DRIVER_MINOR 17 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gart.c b/trunk/drivers/gpu/drm/radeon/radeon_gart.c index bb3b7fe05ccd..b3720054614d 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gart.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gart.c @@ -814,7 +814,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, return -EINVAL; } - if (bo_va->valid && mem) + if (bo_va->valid) return 0; ngpu_pages = radeon_bo_ngpu_pages(bo); @@ -859,27 +859,11 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, struct radeon_bo *bo) { struct radeon_bo_va *bo_va; - int r; bo_va = radeon_bo_va(bo, vm); if (bo_va == NULL) return 0; - /* wait for va use to end */ - while (bo_va->fence) { - r = radeon_fence_wait(bo_va->fence, false); - if (r) { - DRM_ERROR("error while waiting for fence: %d\n", r); - } - if (r == -EDEADLK) { - r = radeon_gpu_reset(rdev); - if (!r) - continue; - } - break; - } - radeon_fence_unref(&bo_va->fence); - mutex_lock(&rdev->vm_manager.lock); mutex_lock(&vm->mutex); radeon_vm_bo_update_pte(rdev, vm, bo, NULL); @@ -950,7 +934,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) } /** - * radeon_vm_fini - tear down a vm instance + * radeon_vm_init - tear down a vm instance * * @rdev: radeon_device pointer * @vm: requested vm @@ -968,15 +952,12 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_vm_unbind_locked(rdev, vm); mutex_unlock(&rdev->vm_manager.lock); - /* remove all bo at this point non are busy any more because unbind - * waited for the last vm fence to signal - */ + /* remove all bo */ r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); if (!r) { bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); list_del_init(&bo_va->bo_list); list_del_init(&bo_va->vm_list); - radeon_fence_unref(&bo_va->fence); radeon_bo_unreserve(rdev->ring_tmp_bo.bo); kfree(bo_va); } @@ -988,7 +969,6 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) r = radeon_bo_reserve(bo_va->bo, false); if (!r) { list_del_init(&bo_va->bo_list); - radeon_fence_unref(&bo_va->fence); radeon_bo_unreserve(bo_va->bo); kfree(bo_va); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gem.c b/trunk/drivers/gpu/drm/radeon/radeon_gem.c index 1b57b0058ad6..84d045245739 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gem.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gem.c @@ -134,16 +134,25 @@ void radeon_gem_object_close(struct drm_gem_object *obj, struct radeon_device *rdev = rbo->rdev; struct radeon_fpriv *fpriv = file_priv->driver_priv; struct radeon_vm *vm = &fpriv->vm; + struct radeon_bo_va *bo_va, *tmp; if (rdev->family < CHIP_CAYMAN) { return; } if (radeon_bo_reserve(rbo, false)) { - dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n"); return; } - radeon_vm_bo_rmv(rdev, vm, rbo); + list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { + if (bo_va->vm == vm) { + /* remove from this vm address space */ + mutex_lock(&vm->mutex); + list_del(&bo_va->vm_list); + mutex_unlock(&vm->mutex); + list_del(&bo_va->bo_list); + kfree(bo_va); + } + } radeon_bo_unreserve(rbo); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_kms.c index 414b4acf6947..1d73f16b5d97 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_kms.c @@ -29,7 +29,6 @@ #include "drm_sarea.h" #include "radeon.h" #include "radeon_drm.h" -#include "radeon_asic.h" #include #include @@ -168,39 +167,17 @@ static void radeon_set_filp_rights(struct drm_device *dev, int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct radeon_device *rdev = dev->dev_private; - struct drm_radeon_info *info = data; + struct drm_radeon_info *info; struct radeon_mode_info *minfo = &rdev->mode_info; - uint32_t value, *value_ptr; - uint64_t value64, *value_ptr64; + uint32_t *value_ptr; + uint32_t value; struct drm_crtc *crtc; int i, found; - /* TIMESTAMP is a 64-bit value, needs special handling. */ - if (info->request == RADEON_INFO_TIMESTAMP) { - if (rdev->family >= CHIP_R600) { - value_ptr64 = (uint64_t*)((unsigned long)info->value); - if (rdev->family >= CHIP_TAHITI) { - value64 = si_get_gpu_clock(rdev); - } else { - value64 = r600_get_gpu_clock(rdev); - } - - if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { - DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); - return -EFAULT; - } - return 0; - } else { - DRM_DEBUG_KMS("timestamp is r6xx+ only!\n"); - return -EINVAL; - } - } - + info = data; value_ptr = (uint32_t *)((unsigned long)info->value); - if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { - DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); + if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) return -EFAULT; - } switch (info->request) { case RADEON_INFO_DEVICE_ID: @@ -360,7 +337,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return -EINVAL; } if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { - DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); + DRM_ERROR("copy_to_user\n"); return -EFAULT; } return 0; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 94b4a1c12893..d5fd615897ec 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -1025,11 +1025,9 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, static void radeon_crtc_prepare(struct drm_crtc *crtc) { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct drm_crtc *crtci; - radeon_crtc->in_mode_set = true; /* * The hardware wedges sometimes if you reconfigure one CRTC * whilst another is running (see fdo bug #24611). @@ -1040,7 +1038,6 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc) static void radeon_crtc_commit(struct drm_crtc *crtc) { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct drm_crtc *crtci; @@ -1051,7 +1048,6 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) if (crtci->enabled) radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); } - radeon_crtc->in_mode_set = false; } static const struct drm_crtc_helper_funcs legacy_helper_funcs = { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index d56978949f34..f380d59c5763 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -275,7 +275,6 @@ struct radeon_crtc { u16 lut_r[256], lut_g[256], lut_b[256]; bool enabled; bool can_tile; - bool in_mode_set; uint32_t crtc_offset; struct drm_gem_object *cursor_bo; uint64_t cursor_addr; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.c b/trunk/drivers/gpu/drm/radeon/radeon_object.c index 1cb014b571ab..1f1a4c803c1d 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.c @@ -52,7 +52,11 @@ void radeon_bo_clear_va(struct radeon_bo *bo) list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { /* remove from all vm address space */ - radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo); + mutex_lock(&bo_va->vm->mutex); + list_del(&bo_va->vm_list); + mutex_unlock(&bo_va->vm->mutex); + list_del(&bo_va->bo_list); + kfree(bo_va); } } diff --git a/trunk/drivers/gpu/drm/radeon/rv515.c b/trunk/drivers/gpu/drm/radeon/rv515.c index aa8ef491ef3c..a12fbcc8ccb6 100644 --- a/trunk/drivers/gpu/drm/radeon/rv515.c +++ b/trunk/drivers/gpu/drm/radeon/rv515.c @@ -281,8 +281,12 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) { + save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); + save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); + save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); + save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); /* Stop all video */ WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); @@ -307,6 +311,15 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) /* Unlock host access */ WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); mdelay(1); + /* Restore video state */ + WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); + WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); + WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); + WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); + WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); + WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); + WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); + WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); } diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 0139e227e3c7..c053f8193771 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -1639,19 +1639,11 @@ static void si_gpu_init(struct radeon_device *rdev) /* XXX what about 12? */ rdev->config.si.tile_config |= (3 << 0); break; - } - switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { - case 0: /* four banks */ - rdev->config.si.tile_config |= 0 << 4; - break; - case 1: /* eight banks */ - rdev->config.si.tile_config |= 1 << 4; - break; - case 2: /* sixteen banks */ - default: - rdev->config.si.tile_config |= 2 << 4; - break; } + if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) + rdev->config.si.tile_config |= 1 << 4; + else + rdev->config.si.tile_config |= 0 << 4; rdev->config.si.tile_config |= ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; rdev->config.si.tile_config |= @@ -3968,22 +3960,3 @@ void si_fini(struct radeon_device *rdev) rdev->bios = NULL; } -/** - * si_get_gpu_clock - return GPU clock counter snapshot - * - * @rdev: radeon_device pointer - * - * Fetches a GPU clock counter snapshot (SI). - * Returns the 64 bit clock counter snapshot. - */ -uint64_t si_get_gpu_clock(struct radeon_device *rdev) -{ - uint64_t clock; - - mutex_lock(&rdev->gpu_clock_mutex); - WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); - clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | - ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); - mutex_unlock(&rdev->gpu_clock_mutex); - return clock; -} diff --git a/trunk/drivers/gpu/drm/radeon/sid.h b/trunk/drivers/gpu/drm/radeon/sid.h index ef4815c27b1c..7869089e8761 100644 --- a/trunk/drivers/gpu/drm/radeon/sid.h +++ b/trunk/drivers/gpu/drm/radeon/sid.h @@ -698,9 +698,6 @@ #define RLC_UCODE_ADDR 0xC32C #define RLC_UCODE_DATA 0xC330 -#define RLC_GPU_CLOCK_COUNT_LSB 0xC338 -#define RLC_GPU_CLOCK_COUNT_MSB 0xC33C -#define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 #define RLC_MC_CNTL 0xC344 #define RLC_UCODE_CNTL 0xC348 diff --git a/trunk/drivers/gpu/drm/udl/udl_gem.c b/trunk/drivers/gpu/drm/udl/udl_gem.c index 291ecc145585..7bd65bdd15a8 100644 --- a/trunk/drivers/gpu/drm/udl/udl_gem.c +++ b/trunk/drivers/gpu/drm/udl/udl_gem.c @@ -308,7 +308,7 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, /* need to attach */ attach = dma_buf_attach(dma_buf, dev->dev); if (IS_ERR(attach)) - return ERR_CAST(attach); + return ERR_PTR(PTR_ERR(attach)); sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); if (IS_ERR(sg)) { diff --git a/trunk/drivers/input/touchscreen/eeti_ts.c b/trunk/drivers/input/touchscreen/eeti_ts.c index 908407efc672..503c7096ed36 100644 --- a/trunk/drivers/input/touchscreen/eeti_ts.c +++ b/trunk/drivers/input/touchscreen/eeti_ts.c @@ -48,7 +48,7 @@ struct eeti_ts_priv { struct input_dev *input; struct work_struct work; struct mutex mutex; - int irq_gpio, irq, irq_active_high; + int irq, irq_active_high; }; #define EETI_TS_BITDEPTH (11) @@ -62,7 +62,7 @@ struct eeti_ts_priv { static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv) { - return gpio_get_value(priv->irq_gpio) == priv->irq_active_high; + return gpio_get_value(irq_to_gpio(priv->irq)) == priv->irq_active_high; } static void eeti_ts_read(struct work_struct *work) @@ -157,7 +157,7 @@ static void eeti_ts_close(struct input_dev *dev) static int __devinit eeti_ts_probe(struct i2c_client *client, const struct i2c_device_id *idp) { - struct eeti_ts_platform_data *pdata = client->dev.platform_data; + struct eeti_ts_platform_data *pdata; struct eeti_ts_priv *priv; struct input_dev *input; unsigned int irq_flags; @@ -199,12 +199,9 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, priv->client = client; priv->input = input; - priv->irq_gpio = pdata->irq_gpio; - priv->irq = gpio_to_irq(pdata->irq_gpio); + priv->irq = client->irq; - err = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name); - if (err < 0) - goto err1; + pdata = client->dev.platform_data; if (pdata) priv->irq_active_high = pdata->irq_active_high; @@ -218,13 +215,13 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, err = input_register_device(input); if (err) - goto err2; + goto err1; err = request_irq(priv->irq, eeti_ts_isr, irq_flags, client->name, priv); if (err) { dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); - goto err3; + goto err2; } /* @@ -236,11 +233,9 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, device_init_wakeup(&client->dev, 0); return 0; -err3: +err2: input_unregister_device(input); input = NULL; /* so we dont try to free it below */ -err2: - gpio_free(pdata->irq_gpio); err1: input_free_device(input); kfree(priv); diff --git a/trunk/drivers/iommu/amd_iommu.c b/trunk/drivers/iommu/amd_iommu.c index b64502dfa9f4..6d1cbdfc9b2a 100644 --- a/trunk/drivers/iommu/amd_iommu.c +++ b/trunk/drivers/iommu/amd_iommu.c @@ -296,13 +296,8 @@ static int iommu_init_device(struct device *dev) } else dma_pdev = pci_dev_get(pdev); - /* Account for quirked devices */ swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); - /* - * If it's a multifunction device that does not support our - * required ACS flags, add to the same group as function 0. - */ if (dma_pdev->multifunction && !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) swap_pci_ref(&dma_pdev, @@ -310,28 +305,14 @@ static int iommu_init_device(struct device *dev) PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), 0))); - /* - * Devices on the root bus go through the iommu. If that's not us, - * find the next upstream device and test ACS up to the root bus. - * Finding the next device may require skipping virtual buses. - */ while (!pci_is_root_bus(dma_pdev->bus)) { - struct pci_bus *bus = dma_pdev->bus; - - while (!bus->self) { - if (!pci_is_root_bus(bus)) - bus = bus->parent; - else - goto root_bus; - } - - if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) + if (pci_acs_path_enabled(dma_pdev->bus->self, + NULL, REQ_ACS_FLAGS)) break; - swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); + swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); } -root_bus: group = iommu_group_get(&dma_pdev->dev); pci_dev_put(dma_pdev); if (!group) { diff --git a/trunk/drivers/iommu/amd_iommu_init.c b/trunk/drivers/iommu/amd_iommu_init.c index 0a2ea317120a..500e7f15f5c2 100644 --- a/trunk/drivers/iommu/amd_iommu_init.c +++ b/trunk/drivers/iommu/amd_iommu_init.c @@ -1131,6 +1131,9 @@ static int __init amd_iommu_init_pci(void) break; } + /* Make sure ACS will be enabled */ + pci_request_acs(); + ret = amd_iommu_init_devices(); print_iommu_info(); @@ -1649,9 +1652,6 @@ static bool detect_ivrs(void) early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size); - /* Make sure ACS will be enabled during PCI probe */ - pci_request_acs(); - return true; } diff --git a/trunk/drivers/iommu/exynos-iommu.c b/trunk/drivers/iommu/exynos-iommu.c index 80bad32aa463..45350ff5e93c 100644 --- a/trunk/drivers/iommu/exynos-iommu.c +++ b/trunk/drivers/iommu/exynos-iommu.c @@ -732,9 +732,9 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain) spin_lock_init(&priv->pgtablelock); INIT_LIST_HEAD(&priv->clients); - domain->geometry.aperture_start = 0; - domain->geometry.aperture_end = ~0UL; - domain->geometry.force_aperture = true; + dom->geometry.aperture_start = 0; + dom->geometry.aperture_end = ~0UL; + dom->geometry.force_aperture = true; domain->priv = priv; return 0; diff --git a/trunk/drivers/iommu/intel-iommu.c b/trunk/drivers/iommu/intel-iommu.c index 2297ec193eb4..7469b5346643 100644 --- a/trunk/drivers/iommu/intel-iommu.c +++ b/trunk/drivers/iommu/intel-iommu.c @@ -2008,7 +2008,6 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) if (!drhd) { printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", pci_name(pdev)); - free_domain_mem(domain); return NULL; } iommu = drhd->iommu; @@ -4125,13 +4124,8 @@ static int intel_iommu_add_device(struct device *dev) } else dma_pdev = pci_dev_get(pdev); - /* Account for quirked devices */ swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); - /* - * If it's a multifunction device that does not support our - * required ACS flags, add to the same group as function 0. - */ if (dma_pdev->multifunction && !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) swap_pci_ref(&dma_pdev, @@ -4139,28 +4133,14 @@ static int intel_iommu_add_device(struct device *dev) PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), 0))); - /* - * Devices on the root bus go through the iommu. If that's not us, - * find the next upstream device and test ACS up to the root bus. - * Finding the next device may require skipping virtual buses. - */ while (!pci_is_root_bus(dma_pdev->bus)) { - struct pci_bus *bus = dma_pdev->bus; - - while (!bus->self) { - if (!pci_is_root_bus(bus)) - bus = bus->parent; - else - goto root_bus; - } - - if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) + if (pci_acs_path_enabled(dma_pdev->bus->self, + NULL, REQ_ACS_FLAGS)) break; - swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); + swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); } -root_bus: group = iommu_group_get(&dma_pdev->dev); pci_dev_put(dma_pdev); if (!group) { diff --git a/trunk/drivers/iommu/tegra-smmu.c b/trunk/drivers/iommu/tegra-smmu.c index 2a4bb36bc688..4ba325ab6262 100644 --- a/trunk/drivers/iommu/tegra-smmu.c +++ b/trunk/drivers/iommu/tegra-smmu.c @@ -799,14 +799,14 @@ static void smmu_iommu_detach_dev(struct iommu_domain *domain, goto out; } } - dev_err(smmu->dev, "Couldn't find %s\n", dev_name(dev)); + dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev)); out: spin_unlock(&as->client_lock); } static int smmu_iommu_domain_init(struct iommu_domain *domain) { - int i, err = -EAGAIN; + int i, err = -ENODEV; unsigned long flags; struct smmu_as *as; struct smmu_device *smmu = smmu_handle; @@ -814,14 +814,11 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain) /* Look for a free AS with lock held */ for (i = 0; i < smmu->num_as; i++) { as = &smmu->as[i]; - - if (as->pdir_page) - continue; - - err = alloc_pdir(as); - if (!err) - goto found; - + if (!as->pdir_page) { + err = alloc_pdir(as); + if (!err) + goto found; + } if (err != -EAGAIN) break; } diff --git a/trunk/drivers/isdn/isdnloop/isdnloop.c b/trunk/drivers/isdn/isdnloop/isdnloop.c index baf2686aa8eb..5405ec644db3 100644 --- a/trunk/drivers/isdn/isdnloop/isdnloop.c +++ b/trunk/drivers/isdn/isdnloop/isdnloop.c @@ -16,6 +16,7 @@ #include #include "isdnloop.h" +static char *revision = "$Revision: 1.11.6.7 $"; static char *isdnloop_id = "loop0"; MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); @@ -1493,6 +1494,17 @@ isdnloop_addcard(char *id1) static int __init isdnloop_init(void) { + char *p; + char rev[10]; + + if ((p = strchr(revision, ':'))) { + strcpy(rev, p + 1); + p = strchr(rev, '$'); + *p = 0; + } else + strcpy(rev, " ??? "); + printk(KERN_NOTICE "isdnloop-ISDN-driver Rev%s\n", rev); + if (isdnloop_id) return (isdnloop_addcard(isdnloop_id)); diff --git a/trunk/drivers/isdn/mISDN/layer2.c b/trunk/drivers/isdn/mISDN/layer2.c index 949cabb88f1c..0dc8abca1407 100644 --- a/trunk/drivers/isdn/mISDN/layer2.c +++ b/trunk/drivers/isdn/mISDN/layer2.c @@ -2222,7 +2222,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei, InitWin(l2); l2->l2m.fsm = &l2fsm; if (test_bit(FLG_LAPB, &l2->flag) || - test_bit(FLG_FIXED_TEI, &l2->flag) || + test_bit(FLG_PTP, &l2->flag) || test_bit(FLG_LAPD_NET, &l2->flag)) l2->l2m.state = ST_L2_4; else diff --git a/trunk/drivers/leds/led-triggers.c b/trunk/drivers/leds/led-triggers.c index 363975b3c925..6157cbbf4113 100644 --- a/trunk/drivers/leds/led-triggers.c +++ b/trunk/drivers/leds/led-triggers.c @@ -224,7 +224,7 @@ void led_trigger_event(struct led_trigger *trig, struct led_classdev *led_cdev; led_cdev = list_entry(entry, struct led_classdev, trig_list); - __led_set_brightness(led_cdev, brightness); + led_set_brightness(led_cdev, brightness); } read_unlock(&trig->leddev_list_lock); } diff --git a/trunk/drivers/leds/leds-lp8788.c b/trunk/drivers/leds/leds-lp8788.c index 0ade6ebfc914..53bd136f1ef0 100644 --- a/trunk/drivers/leds/leds-lp8788.c +++ b/trunk/drivers/leds/leds-lp8788.c @@ -63,7 +63,7 @@ static int lp8788_led_init_device(struct lp8788_led *led, /* scale configuration */ addr = LP8788_ISINK_CTRL; mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET); - val = cfg->scale << (cfg->num + LP8788_ISINK_SCALE_OFFSET); + val = cfg->scale << cfg->num; ret = lp8788_update_bits(led->lp, addr, mask, val); if (ret) return ret; diff --git a/trunk/drivers/leds/leds-renesas-tpu.c b/trunk/drivers/leds/leds-renesas-tpu.c index 771ea067e680..9ee12c28059a 100644 --- a/trunk/drivers/leds/leds-renesas-tpu.c +++ b/trunk/drivers/leds/leds-renesas-tpu.c @@ -247,7 +247,7 @@ static int __devinit r_tpu_probe(struct platform_device *pdev) if (!cfg) { dev_err(&pdev->dev, "missing platform data\n"); - return -ENODEV; + goto err0; } p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); diff --git a/trunk/drivers/md/Kconfig b/trunk/drivers/md/Kconfig index d949b781f6f8..1eee45b69b71 100644 --- a/trunk/drivers/md/Kconfig +++ b/trunk/drivers/md/Kconfig @@ -268,14 +268,13 @@ config DM_MIRROR needed for live data migration tools such as 'pvmove'. config DM_RAID - tristate "RAID 1/4/5/6/10 target" + tristate "RAID 1/4/5/6 target" depends on BLK_DEV_DM select MD_RAID1 - select MD_RAID10 select MD_RAID456 select BLK_DEV_MD ---help--- - A dm target that supports RAID1, RAID10, RAID4, RAID5 and RAID6 mappings + A dm target that supports RAID1, RAID4, RAID5 and RAID6 mappings A RAID-5 set of N drives with a capacity of C MB per drive provides the capacity of C * (N - 1) MB, and protects against a failure diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 94e7f6ba2e11..15dbe03117e4 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -1305,7 +1305,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect prepare_to_wait(&bitmap->overflow_wait, &__wait, TASK_UNINTERRUPTIBLE); spin_unlock_irq(&bitmap->counts.lock); - schedule(); + io_schedule(); finish_wait(&bitmap->overflow_wait, &__wait); continue; } diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 611b5f797618..9f7f8bee8442 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -944,44 +944,6 @@ static void alloc_behind_pages(struct bio *bio, struct r1bio *r1_bio) pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); } -struct raid1_plug_cb { - struct blk_plug_cb cb; - struct bio_list pending; - int pending_cnt; -}; - -static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) -{ - struct raid1_plug_cb *plug = container_of(cb, struct raid1_plug_cb, - cb); - struct mddev *mddev = plug->cb.data; - struct r1conf *conf = mddev->private; - struct bio *bio; - - if (from_schedule) { - spin_lock_irq(&conf->device_lock); - bio_list_merge(&conf->pending_bio_list, &plug->pending); - conf->pending_count += plug->pending_cnt; - spin_unlock_irq(&conf->device_lock); - md_wakeup_thread(mddev->thread); - kfree(plug); - return; - } - - /* we aren't scheduling, so we can do the write-out directly. */ - bio = bio_list_get(&plug->pending); - bitmap_unplug(mddev->bitmap); - wake_up(&conf->wait_barrier); - - while (bio) { /* submit pending writes */ - struct bio *next = bio->bi_next; - bio->bi_next = NULL; - generic_make_request(bio); - bio = next; - } - kfree(plug); -} - static void make_request(struct mddev *mddev, struct bio * bio) { struct r1conf *conf = mddev->private; @@ -995,8 +957,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); struct md_rdev *blocked_rdev; - struct blk_plug_cb *cb; - struct raid1_plug_cb *plug = NULL; int first_clone; int sectors_handled; int max_sectors; @@ -1299,22 +1259,11 @@ static void make_request(struct mddev *mddev, struct bio * bio) mbio->bi_private = r1_bio; atomic_inc(&r1_bio->remaining); - - cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug)); - if (cb) - plug = container_of(cb, struct raid1_plug_cb, cb); - else - plug = NULL; spin_lock_irqsave(&conf->device_lock, flags); - if (plug) { - bio_list_add(&plug->pending, mbio); - plug->pending_cnt++; - } else { - bio_list_add(&conf->pending_bio_list, mbio); - conf->pending_count++; - } + bio_list_add(&conf->pending_bio_list, mbio); + conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); - if (!plug) + if (!mddev_check_plugged(mddev)) md_wakeup_thread(mddev->thread); } /* Mustn't call r1_bio_write_done before this next test, diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index adda94df5eb2..87a2d0bdedd1 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -484,8 +484,7 @@ get_active_stripe(struct r5conf *conf, sector_t sector, } else { if (atomic_read(&sh->count)) { BUG_ON(!list_empty(&sh->lru) - && !test_bit(STRIPE_EXPANDING, &sh->state) - && !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)); + && !test_bit(STRIPE_EXPANDING, &sh->state)); } else { if (!test_bit(STRIPE_HANDLE, &sh->state)) atomic_inc(&conf->active_stripes); @@ -4011,62 +4010,6 @@ static struct stripe_head *__get_priority_stripe(struct r5conf *conf) return sh; } -struct raid5_plug_cb { - struct blk_plug_cb cb; - struct list_head list; -}; - -static void raid5_unplug(struct blk_plug_cb *blk_cb, bool from_schedule) -{ - struct raid5_plug_cb *cb = container_of( - blk_cb, struct raid5_plug_cb, cb); - struct stripe_head *sh; - struct mddev *mddev = cb->cb.data; - struct r5conf *conf = mddev->private; - - if (cb->list.next && !list_empty(&cb->list)) { - spin_lock_irq(&conf->device_lock); - while (!list_empty(&cb->list)) { - sh = list_first_entry(&cb->list, struct stripe_head, lru); - list_del_init(&sh->lru); - /* - * avoid race release_stripe_plug() sees - * STRIPE_ON_UNPLUG_LIST clear but the stripe - * is still in our list - */ - smp_mb__before_clear_bit(); - clear_bit(STRIPE_ON_UNPLUG_LIST, &sh->state); - __release_stripe(conf, sh); - } - spin_unlock_irq(&conf->device_lock); - } - kfree(cb); -} - -static void release_stripe_plug(struct mddev *mddev, - struct stripe_head *sh) -{ - struct blk_plug_cb *blk_cb = blk_check_plugged( - raid5_unplug, mddev, - sizeof(struct raid5_plug_cb)); - struct raid5_plug_cb *cb; - - if (!blk_cb) { - release_stripe(sh); - return; - } - - cb = container_of(blk_cb, struct raid5_plug_cb, cb); - - if (cb->list.next == NULL) - INIT_LIST_HEAD(&cb->list); - - if (!test_and_set_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)) - list_add_tail(&sh->lru, &cb->list); - else - release_stripe(sh); -} - static void make_request(struct mddev *mddev, struct bio * bi) { struct r5conf *conf = mddev->private; @@ -4195,7 +4138,8 @@ static void make_request(struct mddev *mddev, struct bio * bi) if ((bi->bi_rw & REQ_NOIDLE) && !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) atomic_inc(&conf->preread_active_stripes); - release_stripe_plug(mddev, sh); + mddev_check_plugged(mddev); + release_stripe(sh); } else { /* cannot get stripe for read-ahead, just give-up */ clear_bit(BIO_UPTODATE, &bi->bi_flags); @@ -4593,30 +4537,6 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio) return handled; } -#define MAX_STRIPE_BATCH 8 -static int handle_active_stripes(struct r5conf *conf) -{ - struct stripe_head *batch[MAX_STRIPE_BATCH], *sh; - int i, batch_size = 0; - - while (batch_size < MAX_STRIPE_BATCH && - (sh = __get_priority_stripe(conf)) != NULL) - batch[batch_size++] = sh; - - if (batch_size == 0) - return batch_size; - spin_unlock_irq(&conf->device_lock); - - for (i = 0; i < batch_size; i++) - handle_stripe(batch[i]); - - cond_resched(); - - spin_lock_irq(&conf->device_lock); - for (i = 0; i < batch_size; i++) - __release_stripe(conf, batch[i]); - return batch_size; -} /* * This is our raid5 kernel thread. @@ -4627,6 +4547,7 @@ static int handle_active_stripes(struct r5conf *conf) */ static void raid5d(struct mddev *mddev) { + struct stripe_head *sh; struct r5conf *conf = mddev->private; int handled; struct blk_plug plug; @@ -4640,7 +4561,6 @@ static void raid5d(struct mddev *mddev) spin_lock_irq(&conf->device_lock); while (1) { struct bio *bio; - int batch_size; if ( !list_empty(&conf->bitmap_list)) { @@ -4664,16 +4584,21 @@ static void raid5d(struct mddev *mddev) handled++; } - batch_size = handle_active_stripes(conf); - if (!batch_size) + sh = __get_priority_stripe(conf); + + if (!sh) break; - handled += batch_size; + spin_unlock_irq(&conf->device_lock); + + handled++; + handle_stripe(sh); + release_stripe(sh); + cond_resched(); - if (mddev->flags & ~(1<device_lock); + if (mddev->flags & ~(1<device_lock); - } + + spin_lock_irq(&conf->device_lock); } pr_debug("%d stripes handled\n", handled); diff --git a/trunk/drivers/md/raid5.h b/trunk/drivers/md/raid5.h index a9fc24901eda..61dbb615c30b 100644 --- a/trunk/drivers/md/raid5.h +++ b/trunk/drivers/md/raid5.h @@ -321,7 +321,6 @@ enum { STRIPE_BIOFILL_RUN, STRIPE_COMPUTE_RUN, STRIPE_OPS_REQ_PENDING, - STRIPE_ON_UNPLUG_LIST, }; /* diff --git a/trunk/drivers/mfd/asic3.c b/trunk/drivers/mfd/asic3.c index 683e18a23329..383421bf5760 100644 --- a/trunk/drivers/mfd/asic3.c +++ b/trunk/drivers/mfd/asic3.c @@ -925,7 +925,6 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, goto out; } - ret = 0; if (pdata->leds) { int i; diff --git a/trunk/drivers/mfd/ezx-pcap.c b/trunk/drivers/mfd/ezx-pcap.c index db662e2dcfa5..43a76c41cfcc 100644 --- a/trunk/drivers/mfd/ezx-pcap.c +++ b/trunk/drivers/mfd/ezx-pcap.c @@ -202,7 +202,7 @@ static void pcap_isr_work(struct work_struct *work) } local_irq_enable(); ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); - } while (gpio_get_value(pdata->gpio)); + } while (gpio_get_value(irq_to_gpio(pcap->spi->irq))); } static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) diff --git a/trunk/drivers/mtd/maps/uclinux.c b/trunk/drivers/mtd/maps/uclinux.c index c3bb304eca07..cfff454f628b 100644 --- a/trunk/drivers/mtd/maps/uclinux.c +++ b/trunk/drivers/mtd/maps/uclinux.c @@ -19,13 +19,14 @@ #include #include #include -#include /****************************************************************************/ +extern char _ebss; + struct map_info uclinux_ram_map = { .name = "RAM", - .phys = (unsigned long)__bss_stop, + .phys = (unsigned long)&_ebss, .size = 0, }; diff --git a/trunk/drivers/mtd/nand/Kconfig b/trunk/drivers/mtd/nand/Kconfig index 8ca417614c57..31bb7e5b504a 100644 --- a/trunk/drivers/mtd/nand/Kconfig +++ b/trunk/drivers/mtd/nand/Kconfig @@ -480,7 +480,7 @@ config MTD_NAND_NANDSIM config MTD_NAND_GPMI_NAND bool "GPMI NAND Flash Controller driver" - depends on MTD_NAND && MXS_DMA + depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q) help Enables NAND Flash support for IMX23 or IMX28. The GPMI controller is very powerful, with the help of BCH diff --git a/trunk/drivers/mtd/nand/omap2.c b/trunk/drivers/mtd/nand/omap2.c index ac4fd756eda3..e9309b3659e7 100644 --- a/trunk/drivers/mtd/nand/omap2.c +++ b/trunk/drivers/mtd/nand/omap2.c @@ -1245,6 +1245,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) goto out_release_mem_region; } else { struct dma_slave_config cfg; + int rc; memset(&cfg, 0, sizeof(cfg)); cfg.src_addr = info->phys_base; @@ -1253,10 +1254,10 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.src_maxburst = 16; cfg.dst_maxburst = 16; - err = dmaengine_slave_config(info->dma, &cfg); - if (err) { + rc = dmaengine_slave_config(info->dma, &cfg); + if (rc) { dev_err(&pdev->dev, "DMA engine slave config failed: %d\n", - err); + rc); goto out_release_mem_region; } info->nand.read_buf = omap_read_buf_dma_pref; diff --git a/trunk/drivers/net/appletalk/cops.c b/trunk/drivers/net/appletalk/cops.c index cff6f023c03a..545c09ed9079 100644 --- a/trunk/drivers/net/appletalk/cops.c +++ b/trunk/drivers/net/appletalk/cops.c @@ -996,7 +996,9 @@ static int __init cops_module_init(void) printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", cardname); cops_dev = cops_probe(-1); - return PTR_RET(cops_dev); + if (IS_ERR(cops_dev)) + return PTR_ERR(cops_dev); + return 0; } static void __exit cops_module_exit(void) diff --git a/trunk/drivers/net/appletalk/ltpc.c b/trunk/drivers/net/appletalk/ltpc.c index b5782cdf0bca..0910dce3996d 100644 --- a/trunk/drivers/net/appletalk/ltpc.c +++ b/trunk/drivers/net/appletalk/ltpc.c @@ -1243,7 +1243,9 @@ static int __init ltpc_module_init(void) "ltpc: Autoprobing is not recommended for modules\n"); dev_ltpc = ltpc_probe(); - return PTR_RET(dev_ltpc); + if (IS_ERR(dev_ltpc)) + return PTR_ERR(dev_ltpc); + return 0; } module_init(ltpc_module_init); #endif diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index d688a8af432c..6fae5f3ec7f6 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -398,7 +398,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping; - if (unlikely(netpoll_tx_running(bond->dev))) + if (unlikely(netpoll_tx_running(slave_dev))) bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); else dev_queue_xmit(skb); @@ -1235,12 +1235,12 @@ static inline int slave_enable_netpoll(struct slave *slave) struct netpoll *np; int err = 0; - np = kzalloc(sizeof(*np), GFP_ATOMIC); + np = kzalloc(sizeof(*np), GFP_KERNEL); err = -ENOMEM; if (!np) goto out; - err = __netpoll_setup(np, slave->dev, GFP_ATOMIC); + err = __netpoll_setup(np, slave->dev); if (err) { kfree(np); goto out; @@ -1257,7 +1257,9 @@ static inline void slave_disable_netpoll(struct slave *slave) return; slave->np = NULL; - __netpoll_free_rcu(np); + synchronize_rcu_bh(); + __netpoll_cleanup(np); + kfree(np); } static inline bool slave_dev_support_netpoll(struct net_device *slave_dev) { @@ -1290,7 +1292,7 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev) read_unlock(&bond->lock); } -static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, gfp_t gfp) +static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) { struct bonding *bond = netdev_priv(dev); struct slave *slave; diff --git a/trunk/drivers/net/cris/eth_v10.c b/trunk/drivers/net/cris/eth_v10.c index 021d69c5d9bc..f0c8bd54ce29 100644 --- a/trunk/drivers/net/cris/eth_v10.c +++ b/trunk/drivers/net/cris/eth_v10.c @@ -1712,7 +1712,7 @@ e100_set_network_leds(int active) static void e100_netpoll(struct net_device* netdev) { - e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev); + e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL); } #endif diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 463b9ec57d80..77bcd4cb4ffb 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1278,7 +1278,7 @@ struct bnx2x { #define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT) #define BNX2X_FW_RX_ALIGN_END \ - max_t(u64, 1UL << BNX2X_RX_ALIGN_SHIFT, \ + max(1UL << BNX2X_RX_ALIGN_SHIFT, \ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 02b5a343b195..dd451c3dd83d 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -4041,6 +4041,20 @@ static bool bnx2x_get_load_status(struct bnx2x *bp, int engine) return val != 0; } +/* + * Reset the load status for the current engine. + */ +static void bnx2x_clear_load_status(struct bnx2x *bp) +{ + u32 val; + u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : + BNX2X_PATH0_LOAD_CNT_MASK); + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); +} + static void _print_next_block(int idx, const char *blk) { pr_cont("%s%s", idx ? ", " : "", blk); @@ -9370,24 +9384,32 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp) return rc; } +static bool __devinit bnx2x_can_flr(struct bnx2x *bp) +{ + int pos; + u32 cap; + struct pci_dev *dev = bp->pdev; + + pos = pci_pcie_cap(dev); + if (!pos) + return false; + + pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap); + if (!(cap & PCI_EXP_DEVCAP_FLR)) + return false; + + return true; +} + static int __devinit bnx2x_do_flr(struct bnx2x *bp) { int i, pos; u16 status; struct pci_dev *dev = bp->pdev; - - if (CHIP_IS_E1x(bp)) { - BNX2X_DEV_INFO("FLR not supported in E1/E1H\n"); - return -EINVAL; - } - - /* only bootcode REQ_BC_VER_4_INITIATE_FLR and onwards support flr */ - if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { - BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", - bp->common.bc_ver); - return -EINVAL; - } + /* probe the capability first */ + if (bnx2x_can_flr(bp)) + return -ENOTTY; pos = pci_pcie_cap(dev); if (!pos) @@ -9407,8 +9429,12 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp) "transaction is not cleared; proceeding with reset anyway\n"); clear: + if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { + BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", + bp->common.bc_ver); + return -EINVAL; + } - BNX2X_DEV_INFO("Initiating FLR\n"); bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0); return 0; @@ -9428,21 +9454,8 @@ static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp) * the one required, then FLR will be sufficient to clean any residue * left by previous driver */ - rc = bnx2x_test_firmware_version(bp, false); - - if (!rc) { - /* fw version is good */ - BNX2X_DEV_INFO("FW version matches our own. Attempting FLR\n"); - rc = bnx2x_do_flr(bp); - } - - if (!rc) { - /* FLR was performed */ - BNX2X_DEV_INFO("FLR successful\n"); - return 0; - } - - BNX2X_DEV_INFO("Could not FLR\n"); + if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp)) + return bnx2x_do_flr(bp); /* Close the MCP request, return failure*/ rc = bnx2x_prev_mcp_done(bp); @@ -11414,6 +11427,9 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, if (!chip_is_e1x) REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); + /* Reset the load counter */ + bnx2x_clear_load_status(bp); + dev->watchdog_timeo = TX_TIMEOUT; dev->netdev_ops = &bnx2x_netdev_ops; diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index 90a903d83d87..c60de89b6669 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -1948,7 +1948,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter) if (adapter->num_rx_qs != MAX_RX_QS) dev_info(&adapter->pdev->dev, - "Created only %d receive queues\n", adapter->num_rx_qs); + "Created only %d receive queues", adapter->num_rx_qs); return 0; } diff --git a/trunk/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/trunk/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c index 151453309401..0f2d1a710909 100644 --- a/trunk/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +++ b/trunk/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c @@ -174,10 +174,8 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) new_bus->phy_mask = ~0; new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (!new_bus->irq) { - ret = -ENOMEM; + if (!new_bus->irq) goto out_unmap_regs; - } new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); diff --git a/trunk/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/trunk/drivers/net/ethernet/freescale/fs_enet/mii-fec.c index cdf702a59485..55bb867258e6 100644 --- a/trunk/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +++ b/trunk/drivers/net/ethernet/freescale/fs_enet/mii-fec.c @@ -137,10 +137,8 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); fec->fecp = ioremap(res.start, resource_size(&res)); - if (!fec->fecp) { - ret = -ENOMEM; + if (!fec->fecp) goto out_fec; - } if (get_bus_freq) { clock = get_bus_freq(ofdev->dev.of_node); @@ -174,10 +172,8 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) new_bus->phy_mask = ~0; new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (!new_bus->irq) { - ret = -ENOMEM; + if (!new_bus->irq) goto out_unmap_regs; - } new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/82571.c b/trunk/drivers/net/ethernet/intel/e1000e/82571.c index 080c89093feb..0b3bade957fd 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/82571.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/82571.c @@ -999,7 +999,7 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) **/ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) { - u32 ctrl, ctrl_ext, eecd, tctl; + u32 ctrl, ctrl_ext, eecd; s32 ret_val; /* @@ -1014,9 +1014,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) ew32(IMC, 0xffffffff); ew32(RCTL, 0); - tctl = er32(TCTL); - tctl &= ~E1000_TCTL_EN; - ew32(TCTL, tctl); + ew32(TCTL, E1000_TCTL_PSP); e1e_flush(); usleep_range(10000, 20000); @@ -1603,8 +1601,10 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) * auto-negotiation in the TXCW register and disable * forced link in the Device Control register in an * attempt to auto-negotiate with our link partner. + * If the partner code word is null, stop forcing + * and restart auto negotiation. */ - if (rxcw & E1000_RXCW_C) { + if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { /* Enable autoneg, and unforce link up */ ew32(TXCW, mac->txcw); ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 46c3b1f9ff89..95b245310f17 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -178,24 +178,6 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]); } -static void e1000e_dump_ps_pages(struct e1000_adapter *adapter, - struct e1000_buffer *bi) -{ - int i; - struct e1000_ps_page *ps_page; - - for (i = 0; i < adapter->rx_ps_pages; i++) { - ps_page = &bi->ps_pages[i]; - - if (ps_page->page) { - pr_info("packet dump for ps_page %d:\n", i); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, - 16, 1, page_address(ps_page->page), - PAGE_SIZE, true); - } - } -} - /* * e1000e_dump - Print registers, Tx-ring and Rx-ring */ @@ -317,10 +299,10 @@ static void e1000e_dump(struct e1000_adapter *adapter) (unsigned long long)buffer_info->time_stamp, buffer_info->skb, next_desc); - if (netif_msg_pktdata(adapter) && buffer_info->skb) + if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, - 16, 1, buffer_info->skb->data, - buffer_info->skb->len, true); + 16, 1, phys_to_virt(buffer_info->dma), + buffer_info->length, true); } /* Print Rx Ring Summary */ @@ -399,8 +381,10 @@ static void e1000e_dump(struct e1000_adapter *adapter) buffer_info->skb, next_desc); if (netif_msg_pktdata(adapter)) - e1000e_dump_ps_pages(adapter, - buffer_info); + print_hex_dump(KERN_INFO, "", + DUMP_PREFIX_ADDRESS, 16, 1, + phys_to_virt(buffer_info->dma), + adapter->rx_ps_bsize0, true); } } break; @@ -460,12 +444,12 @@ static void e1000e_dump(struct e1000_adapter *adapter) (unsigned long long)buffer_info->dma, buffer_info->skb, next_desc); - if (netif_msg_pktdata(adapter) && - buffer_info->skb) + if (netif_msg_pktdata(adapter)) print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 1, - buffer_info->skb->data, + phys_to_virt + (buffer_info->dma), adapter->rx_buffer_len, true); } diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c index ba994fb4cec6..5e84eaac48c1 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -254,14 +254,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) */ size += NVM_WORD_SIZE_BASE_SHIFT; - /* - * Check for invalid size - */ - if ((hw->mac.type == e1000_82576) && (size > 15)) { - pr_notice("The NVM size is not valid, defaulting to 32K\n"); - size = 15; - } - nvm->word_size = 1 << size; if (hw->mac.type < e1000_i210) { nvm->opcode_bits = 8; @@ -289,6 +281,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) } else nvm->type = e1000_nvm_flash_hw; + /* + * Check for invalid size + */ + if ((hw->mac.type == e1000_82576) && (size > 15)) { + pr_notice("The NVM size is not valid, defaulting to 32K\n"); + size = 15; + } + /* NVM Function Pointers */ switch (hw->mac.type) { case e1000_82580: diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h b/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h index 28394bea5253..10efcd88dca0 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h @@ -156,12 +156,8 @@ : (0x0E018 + ((_n) * 0x40))) #define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \ : (0x0E028 + ((_n) * 0x40))) -#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \ - (0x0C014 + ((_n) * 0x40))) -#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n) -#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \ - (0x0E014 + ((_n) * 0x40))) -#define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n) +#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8)) +#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8)) #define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \ : (0x0E038 + ((_n) * 0x40))) #define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \ diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c b/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c index 70591117051b..a19c84cad0e9 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -209,8 +209,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) /* When SoL/IDER sessions are active, autoneg/speed/duplex * cannot be changed */ if (igb_check_reset_block(hw)) { - dev_err(&adapter->pdev->dev, - "Cannot change link characteristics when SoL/IDER is active.\n"); + dev_err(&adapter->pdev->dev, "Cannot change link " + "characteristics when SoL/IDER is active.\n"); return -EINVAL; } @@ -1089,8 +1089,8 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, wr32(reg, (_test[pat] & write)); val = rd32(reg) & mask; if (val != (_test[pat] & write & mask)) { - dev_err(&adapter->pdev->dev, - "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", + dev_err(&adapter->pdev->dev, "pattern test reg %04X " + "failed: got 0x%08X expected 0x%08X\n", reg, val, (_test[pat] & write & mask)); *data = reg; return 1; @@ -1108,8 +1108,8 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data, wr32(reg, write & mask); val = rd32(reg); if ((write & mask) != (val & mask)) { - dev_err(&adapter->pdev->dev, - "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg, + dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:" + " got 0x%08X expected 0x%08X\n", reg, (val & mask), (write & mask)); *data = reg; return 1; @@ -1171,9 +1171,8 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data) wr32(E1000_STATUS, toggle); after = rd32(E1000_STATUS) & toggle; if (value != after) { - dev_err(&adapter->pdev->dev, - "failed STATUS register test got: 0x%08X expected: 0x%08X\n", - after, value); + dev_err(&adapter->pdev->dev, "failed STATUS register test " + "got: 0x%08X expected: 0x%08X\n", after, value); *data = 1; return 1; } @@ -1498,9 +1497,6 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter) break; } - /* add small delay to avoid loopback test failure */ - msleep(50); - /* force 1000, set loopback */ igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); @@ -1781,14 +1777,16 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data) * sessions are active */ if (igb_check_reset_block(&adapter->hw)) { dev_err(&adapter->pdev->dev, - "Cannot do PHY loopback test when SoL/IDER is active.\n"); + "Cannot do PHY loopback test " + "when SoL/IDER is active.\n"); *data = 0; goto out; } if ((adapter->hw.mac.type == e1000_i210) - || (adapter->hw.mac.type == e1000_i211)) { + || (adapter->hw.mac.type == e1000_i210)) { dev_err(&adapter->pdev->dev, - "Loopback test not supported on this part at this time.\n"); + "Loopback test not supported " + "on this part at this time.\n"); *data = 0; goto out; } diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_main.c b/trunk/drivers/net/ethernet/intel/igb/igb_main.c index 48cc4fb1a307..b7c2d5050572 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_main.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_main.c @@ -462,10 +462,10 @@ static void igb_dump(struct igb_adapter *adapter) (u64)buffer_info->time_stamp, buffer_info->skb, next_desc); - if (netif_msg_pktdata(adapter) && buffer_info->skb) + if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, - 16, 1, buffer_info->skb->data, + 16, 1, phys_to_virt(buffer_info->dma), buffer_info->length, true); } } @@ -547,17 +547,18 @@ static void igb_dump(struct igb_adapter *adapter) (u64)buffer_info->dma, buffer_info->skb, next_desc); - if (netif_msg_pktdata(adapter) && - buffer_info->dma && buffer_info->skb) { + if (netif_msg_pktdata(adapter)) { print_hex_dump(KERN_INFO, "", - DUMP_PREFIX_ADDRESS, - 16, 1, buffer_info->skb->data, - IGB_RX_HDR_LEN, true); + DUMP_PREFIX_ADDRESS, + 16, 1, + phys_to_virt(buffer_info->dma), + IGB_RX_HDR_LEN, true); print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 1, - page_address(buffer_info->page) + - buffer_info->page_offset, + phys_to_virt( + buffer_info->page_dma + + buffer_info->page_offset), PAGE_SIZE/2, true); } } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 18bf08c9d7a4..50fc137501da 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -804,13 +804,12 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { /* Set KX4/KX/KR support according to speed requested */ autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); - if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + if (speed & IXGBE_LINK_SPEED_10GB_FULL) if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) autoc |= IXGBE_AUTOC_KX4_SUPP; if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) && (hw->phy.smart_speed_active == false)) autoc |= IXGBE_AUTOC_KR_SUPP; - } if (speed & IXGBE_LINK_SPEED_1GB_FULL) autoc |= IXGBE_AUTOC_KX_SUPP; } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) && diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 5aba5ecdf1e2..f32e70300770 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -614,8 +614,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud /* If source MAC is equal to our own MAC and not performing * the selftest or flb disabled - drop the packet */ if (s_mac == priv->mac && - !((dev->features & NETIF_F_LOOPBACK) || - priv->validate_loopback)) + (!(dev->features & NETIF_F_LOOPBACK) || + !priv->validate_loopback)) goto next; /* diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 10bba09c44ea..019d856b1334 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -164,6 +164,7 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv, ring->cons = 0xffffffff; ring->last_nr_txbb = 1; ring->poll_cnt = 0; + ring->blocked = 0; memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info)); memset(ring->buf, 0, ring->buf_size); @@ -364,13 +365,14 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) ring->cons += txbbs_skipped; netdev_tx_completed_queue(ring->tx_queue, packets, bytes); - /* - * Wakeup Tx queue if this stopped, and at least 1 packet - * was completed - */ - if (netif_tx_queue_stopped(ring->tx_queue) && txbbs_skipped > 0) { - netif_tx_wake_queue(ring->tx_queue); - priv->port_stats.wake_queue++; + /* Wakeup Tx queue if this ring stopped it */ + if (unlikely(ring->blocked)) { + if ((u32) (ring->prod - ring->cons) <= + ring->size - HEADROOM - MAX_DESC_TXBBS) { + ring->blocked = 0; + netif_tx_wake_queue(ring->tx_queue); + priv->port_stats.wake_queue++; + } } } @@ -590,6 +592,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) ring->size - HEADROOM - MAX_DESC_TXBBS)) { /* every full Tx ring stops queue */ netif_tx_stop_queue(ring->tx_queue); + ring->blocked = 1; priv->port_stats.queue_stopped++; return NETDEV_TX_BUSY; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c index 827b72dfce99..48d0e90194cb 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c @@ -157,6 +157,9 @@ int mlx4_check_port_params(struct mlx4_dev *dev, "on this HCA, aborting.\n"); return -EINVAL; } + if (port_type[i] == MLX4_PORT_TYPE_ETH && + port_type[i + 1] == MLX4_PORT_TYPE_IB) + return -EINVAL; } } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c b/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c index a018ea2a43de..4ec3835e1bc2 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -432,10 +432,8 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { /* Entry already exists, add to duplicates */ dqp = kmalloc(sizeof *dqp, GFP_KERNEL); - if (!dqp) { - err = -ENOMEM; + if (!dqp) goto out_mailbox; - } dqp->qpn = qpn; list_add_tail(&dqp->list, &entry->duplicates); found = true; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 9d27e42264e2..5f1ab105debc 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -248,6 +248,7 @@ struct mlx4_en_tx_ring { u32 doorbell_qpn; void *buf; u16 poll_cnt; + int blocked; struct mlx4_en_tx_info *tx_info; u8 *bounce_buf; u32 last_nr_txbb; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/sense.c b/trunk/drivers/net/ethernet/mellanox/mlx4/sense.c index 34ee09bae36e..802498293528 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/sense.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/sense.c @@ -80,6 +80,20 @@ void mlx4_do_sense_ports(struct mlx4_dev *dev, stype[i - 1] = defaults[i - 1]; } + /* + * Adjust port configuration: + * If port 1 sensed nothing and port 2 is IB, set both as IB + * If port 2 sensed nothing and port 1 is Eth, set both as Eth + */ + if (stype[0] == MLX4_PORT_TYPE_ETH) { + for (i = 1; i < dev->caps.num_ports; i++) + stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_ETH; + } + if (stype[dev->caps.num_ports - 1] == MLX4_PORT_TYPE_IB) { + for (i = 0; i < dev->caps.num_ports - 1; i++) + stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_IB; + } + /* * If sensed nothing, remain in current configuration. */ diff --git a/trunk/drivers/net/ethernet/nxp/lpc_eth.c b/trunk/drivers/net/ethernet/nxp/lpc_eth.c index 53743f7a2ca9..4069edab229e 100644 --- a/trunk/drivers/net/ethernet/nxp/lpc_eth.c +++ b/trunk/drivers/net/ethernet/nxp/lpc_eth.c @@ -346,15 +346,28 @@ static phy_interface_t lpc_phy_interface_mode(struct device *dev) "phy-mode", NULL); if (mode && !strcmp(mode, "mii")) return PHY_INTERFACE_MODE_MII; + return PHY_INTERFACE_MODE_RMII; } + + /* non-DT */ +#ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT + return PHY_INTERFACE_MODE_MII; +#else return PHY_INTERFACE_MODE_RMII; +#endif } static bool use_iram_for_net(struct device *dev) { if (dev && dev->of_node) return of_property_read_bool(dev->of_node, "use-iram"); + + /* non-DT */ +#ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET + return true; +#else return false; +#endif } /* Receive Status information word */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index b93245c11995..cd01ee7ecef1 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -74,7 +74,7 @@ static int __devinit stmmac_probe_config_dt(struct platform_device *pdev, * the necessary resources and invokes the main to init * the net device, register the mdio bus etc. */ -static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) +static int stmmac_pltfr_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; diff --git a/trunk/drivers/net/ethernet/ti/davinci_cpdma.c b/trunk/drivers/net/ethernet/ti/davinci_cpdma.c index d15c888e9df8..3b5c4571b55e 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/trunk/drivers/net/ethernet/ti/davinci_cpdma.c @@ -538,12 +538,11 @@ EXPORT_SYMBOL_GPL(cpdma_chan_create); int cpdma_chan_destroy(struct cpdma_chan *chan) { - struct cpdma_ctlr *ctlr; + struct cpdma_ctlr *ctlr = chan->ctlr; unsigned long flags; if (!chan) return -EINVAL; - ctlr = chan->ctlr; spin_lock_irqsave(&ctlr->lock, flags); if (chan->state != CPDMA_STATE_IDLE) diff --git a/trunk/drivers/net/ethernet/xscale/ixp4xx_eth.c b/trunk/drivers/net/ethernet/xscale/ixp4xx_eth.c index 98934bdf6acf..482648fcf0b6 100644 --- a/trunk/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/trunk/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -1003,7 +1003,6 @@ static int ixp4xx_nway_reset(struct net_device *dev) } int ixp46x_phc_index = -1; -EXPORT_SYMBOL_GPL(ixp46x_phc_index); static int ixp4xx_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) diff --git a/trunk/drivers/net/hyperv/netvsc.c b/trunk/drivers/net/hyperv/netvsc.c index 4a1a5f58fa73..6cee2917eb02 100644 --- a/trunk/drivers/net/hyperv/netvsc.c +++ b/trunk/drivers/net/hyperv/netvsc.c @@ -383,6 +383,13 @@ int netvsc_device_remove(struct hv_device *device) unsigned long flags; net_device = hv_get_drvdata(device); + spin_lock_irqsave(&device->channel->inbound_lock, flags); + net_device->destroy = true; + spin_unlock_irqrestore(&device->channel->inbound_lock, flags); + + /* Wait for all send completions */ + wait_event(net_device->wait_drain, + atomic_read(&net_device->num_outstanding_sends) == 0); netvsc_disconnect_vsp(net_device); diff --git a/trunk/drivers/net/hyperv/rndis_filter.c b/trunk/drivers/net/hyperv/rndis_filter.c index 1e88a1095934..e5d6146937fa 100644 --- a/trunk/drivers/net/hyperv/rndis_filter.c +++ b/trunk/drivers/net/hyperv/rndis_filter.c @@ -718,9 +718,6 @@ static void rndis_filter_halt_device(struct rndis_device *dev) { struct rndis_request *request; struct rndis_halt_request *halt; - struct netvsc_device *nvdev = dev->net_dev; - struct hv_device *hdev = nvdev->dev; - ulong flags; /* Attempt to do a rndis device halt */ request = get_rndis_request(dev, RNDIS_MSG_HALT, @@ -738,14 +735,6 @@ static void rndis_filter_halt_device(struct rndis_device *dev) dev->state = RNDIS_DEV_UNINITIALIZED; cleanup: - spin_lock_irqsave(&hdev->channel->inbound_lock, flags); - nvdev->destroy = true; - spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags); - - /* Wait for all send completions */ - wait_event(nvdev->wait_drain, - atomic_read(&nvdev->num_outstanding_sends) == 0); - if (request) put_rndis_request(dev, request); return; diff --git a/trunk/drivers/net/irda/bfin_sir.c b/trunk/drivers/net/irda/bfin_sir.c index c6a0299aa9f9..a561ae44a9ac 100644 --- a/trunk/drivers/net/irda/bfin_sir.c +++ b/trunk/drivers/net/irda/bfin_sir.c @@ -158,7 +158,7 @@ static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed) /* If not add the 'RPOLC', we can't catch the receive interrupt. * It's related with the HW layout and the IR transiver. */ - val |= UMOD_IRDA | RPOLC; + val |= IREN | RPOLC; UART_PUT_GCTL(port, val); return ret; } @@ -432,7 +432,7 @@ static void bfin_sir_shutdown(struct bfin_sir_port *port, struct net_device *dev bfin_sir_stop_rx(port); val = UART_GET_GCTL(port); - val &= ~(UCEN | UMOD_MASK | RPOLC); + val &= ~(UCEN | IREN | RPOLC); UART_PUT_GCTL(port, val); #ifdef CONFIG_SIR_BFIN_DMA @@ -518,10 +518,10 @@ static void bfin_sir_send_work(struct work_struct *work) * reset all the UART. */ val = UART_GET_GCTL(port); - val &= ~(UMOD_MASK | RPOLC); + val &= ~(IREN | RPOLC); UART_PUT_GCTL(port, val); SSYNC(); - val |= UMOD_IRDA | RPOLC; + val |= IREN | RPOLC; UART_PUT_GCTL(port, val); SSYNC(); /* bfin_sir_set_speed(port, self->speed); */ diff --git a/trunk/drivers/net/macvtap.c b/trunk/drivers/net/macvtap.c index 0f0f9ce3a776..0737bd4d1669 100644 --- a/trunk/drivers/net/macvtap.c +++ b/trunk/drivers/net/macvtap.c @@ -94,8 +94,7 @@ static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q) int i; for (i = 0; i < MAX_MACVTAP_QUEUES; i++) { - if (rcu_dereference_protected(vlan->taps[i], - lockdep_is_held(&macvtap_lock)) == q) + if (rcu_dereference(vlan->taps[i]) == q) return i; } diff --git a/trunk/drivers/net/netconsole.c b/trunk/drivers/net/netconsole.c index f0ad56c13933..f9347ea3d381 100644 --- a/trunk/drivers/net/netconsole.c +++ b/trunk/drivers/net/netconsole.c @@ -640,7 +640,12 @@ static int netconsole_netdev_event(struct notifier_block *this, * rtnl_lock already held */ if (nt->np.dev) { + spin_unlock_irqrestore( + &target_list_lock, + flags); __netpoll_cleanup(&nt->np); + spin_lock_irqsave(&target_list_lock, + flags); dev_put(nt->np.dev); nt->np.dev = NULL; netconsole_target_put(nt); diff --git a/trunk/drivers/net/phy/mdio-mux-gpio.c b/trunk/drivers/net/phy/mdio-mux-gpio.c index eefe49e8713c..e0cc4ef33dee 100644 --- a/trunk/drivers/net/phy/mdio-mux-gpio.c +++ b/trunk/drivers/net/phy/mdio-mux-gpio.c @@ -101,6 +101,7 @@ static int __devinit mdio_mux_gpio_probe(struct platform_device *pdev) n--; gpio_free(s->gpio[n]); } + devm_kfree(&pdev->dev, s); return r; } diff --git a/trunk/drivers/net/ppp/pptp.c b/trunk/drivers/net/ppp/pptp.c index 162464fe86bf..1c98321b56cc 100644 --- a/trunk/drivers/net/ppp/pptp.c +++ b/trunk/drivers/net/ppp/pptp.c @@ -189,7 +189,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) if (sk_pppox(po)->sk_state & PPPOX_DEAD) goto tx_error; - rt = ip_route_output_ports(sock_net(sk), &fl4, NULL, + rt = ip_route_output_ports(&init_net, &fl4, NULL, opt->dst_addr.sin_addr.s_addr, opt->src_addr.sin_addr.s_addr, 0, 0, IPPROTO_GRE, @@ -468,7 +468,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.private = sk; po->chan.ops = &pptp_chan_ops; - rt = ip_route_output_ports(sock_net(sk), &fl4, sk, + rt = ip_route_output_ports(&init_net, &fl4, sk, opt->dst_addr.sin_addr.s_addr, opt->src_addr.sin_addr.s_addr, 0, 0, diff --git a/trunk/drivers/net/team/team.c b/trunk/drivers/net/team/team.c index 341b65dbbcd3..87707ab39430 100644 --- a/trunk/drivers/net/team/team.c +++ b/trunk/drivers/net/team/team.c @@ -795,17 +795,16 @@ static void team_port_leave(struct team *team, struct team_port *port) } #ifdef CONFIG_NET_POLL_CONTROLLER -static int team_port_enable_netpoll(struct team *team, struct team_port *port, - gfp_t gfp) +static int team_port_enable_netpoll(struct team *team, struct team_port *port) { struct netpoll *np; int err; - np = kzalloc(sizeof(*np), gfp); + np = kzalloc(sizeof(*np), GFP_KERNEL); if (!np) return -ENOMEM; - err = __netpoll_setup(np, port->dev, gfp); + err = __netpoll_setup(np, port->dev); if (err) { kfree(np); return err; @@ -834,8 +833,7 @@ static struct netpoll_info *team_netpoll_info(struct team *team) } #else -static int team_port_enable_netpoll(struct team *team, struct team_port *port, - gfp_t gfp) +static int team_port_enable_netpoll(struct team *team, struct team_port *port) { return 0; } @@ -915,7 +913,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) } if (team_netpoll_info(team)) { - err = team_port_enable_netpoll(team, port, GFP_KERNEL); + err = team_port_enable_netpoll(team, port); if (err) { netdev_err(dev, "Failed to enable netpoll on device %s\n", portname); @@ -1445,7 +1443,7 @@ static void team_netpoll_cleanup(struct net_device *dev) } static int team_netpoll_setup(struct net_device *dev, - struct netpoll_info *npifo, gfp_t gfp) + struct netpoll_info *npifo) { struct team *team = netdev_priv(dev); struct team_port *port; @@ -1453,7 +1451,7 @@ static int team_netpoll_setup(struct net_device *dev, mutex_lock(&team->lock); list_for_each_entry(port, &team->port_list, list) { - err = team_port_enable_netpoll(team, port, gfp); + err = team_port_enable_netpoll(team, port); if (err) { __team_netpoll_cleanup(team); break; diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 3a16d4fdaa05..926d4db5cb38 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -187,6 +187,7 @@ static void __tun_detach(struct tun_struct *tun) netif_tx_lock_bh(tun->dev); netif_carrier_off(tun->dev); tun->tfile = NULL; + tun->socket.file = NULL; netif_tx_unlock_bh(tun->dev); /* Drop read queue */ diff --git a/trunk/drivers/net/usb/cdc-phonet.c b/trunk/drivers/net/usb/cdc-phonet.c index 7d78669000d7..64610048ce87 100644 --- a/trunk/drivers/net/usb/cdc-phonet.c +++ b/trunk/drivers/net/usb/cdc-phonet.c @@ -232,7 +232,6 @@ static int usbpn_open(struct net_device *dev) struct urb *req = usb_alloc_urb(0, GFP_KERNEL); if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { - usb_free_urb(req); usbpn_close(dev); return -ENOMEM; } diff --git a/trunk/drivers/net/usb/cdc_ncm.c b/trunk/drivers/net/usb/cdc_ncm.c index 4cd582a4f625..f4ce5957df32 100644 --- a/trunk/drivers/net/usb/cdc_ncm.c +++ b/trunk/drivers/net/usb/cdc_ncm.c @@ -1225,26 +1225,6 @@ static const struct usb_device_id cdc_devs[] = { .driver_info = (unsigned long) &wwan_info, }, - /* Dell branded MBM devices like DW5550 */ - { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_VENDOR, - .idVendor = 0x413c, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long) &wwan_info, - }, - - /* Toshiba branded MBM devices */ - { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_VENDOR, - .idVendor = 0x0930, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long) &wwan_info, - }, - /* Generic CDC-NCM devices */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index aaa061b7355d..2ea126a16d79 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -247,12 +247,30 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) */ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) { + int rv; struct qmi_wwan_state *info = (void *)&dev->data; + /* ZTE makes devices where the interface descriptors and endpoint + * configurations of two or more interfaces are identical, even + * though the functions are completely different. If set, then + * driver_info->data is a bitmap of acceptable interface numbers + * allowing us to bind to one such interface without binding to + * all of them + */ + if (dev->driver_info->data && + !test_bit(intf->cur_altsetting->desc.bInterfaceNumber, &dev->driver_info->data)) { + dev_info(&intf->dev, "not on our whitelist - ignored"); + rv = -ENODEV; + goto err; + } + /* control and data is shared */ info->control = intf; info->data = intf; - return qmi_wwan_register_subdriver(dev); + rv = qmi_wwan_register_subdriver(dev); + +err: + return rv; } static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf) @@ -338,59 +356,214 @@ static const struct driver_info qmi_wwan_shared = { .manage_power = qmi_wwan_manage_power, }; -#define HUAWEI_VENDOR_ID 0x12D1 +static const struct driver_info qmi_wwan_force_int0 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind, + .manage_power = qmi_wwan_manage_power, + .data = BIT(0), /* interface whitelist bitmap */ +}; -/* map QMI/wwan function by a fixed interface number */ -#define QMI_FIXED_INTF(vend, prod, num) \ - USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \ - .driver_info = (unsigned long)&qmi_wwan_shared +static const struct driver_info qmi_wwan_force_int1 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind, + .manage_power = qmi_wwan_manage_power, + .data = BIT(1), /* interface whitelist bitmap */ +}; + +static const struct driver_info qmi_wwan_force_int2 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind, + .manage_power = qmi_wwan_manage_power, + .data = BIT(2), /* interface whitelist bitmap */ +}; + +static const struct driver_info qmi_wwan_force_int3 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind, + .manage_power = qmi_wwan_manage_power, + .data = BIT(3), /* interface whitelist bitmap */ +}; + +static const struct driver_info qmi_wwan_force_int4 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind, + .manage_power = qmi_wwan_manage_power, + .data = BIT(4), /* interface whitelist bitmap */ +}; + +/* Sierra Wireless provide equally useless interface descriptors + * Devices in QMI mode can be switched between two different + * configurations: + * a) USB interface #8 is QMI/wwan + * b) USB interfaces #8, #19 and #20 are QMI/wwan + * + * Both configurations provide a number of other interfaces (serial++), + * some of which have the same endpoint configuration as we expect, so + * a whitelist or blacklist is necessary. + * + * FIXME: The below whitelist should include BIT(20). It does not + * because I cannot get it to work... + */ +static const struct driver_info qmi_wwan_sierra = { + .description = "Sierra Wireless wwan/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind, + .manage_power = qmi_wwan_manage_power, + .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ +}; + +#define HUAWEI_VENDOR_ID 0x12D1 /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ #define QMI_GOBI1K_DEVICE(vend, prod) \ - QMI_FIXED_INTF(vend, prod, 3) + USB_DEVICE(vend, prod), \ + .driver_info = (unsigned long)&qmi_wwan_force_int3 -/* Gobi 2000/3000 QMI/wwan interface number is 0 according to qcserial */ +/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ #define QMI_GOBI_DEVICE(vend, prod) \ - QMI_FIXED_INTF(vend, prod, 0) + USB_DEVICE(vend, prod), \ + .driver_info = (unsigned long)&qmi_wwan_force_int0 static const struct usb_device_id products[] = { - /* 1. CDC ECM like devices match on the control interface */ { /* Huawei E392, E398 and possibly others sharing both device id and more... */ - USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 9), + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 9, /* CDC Ethernet *control* interface */ .driver_info = (unsigned long)&qmi_wwan_info, }, { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ - USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 57, /* CDC Ethernet *control* interface */ .driver_info = (unsigned long)&qmi_wwan_info, }, - - /* 2. Combined interface devices matching on class+protocol */ - { /* Huawei E392, E398 and possibly others in "Windows mode" */ - USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17), + { /* Huawei E392, E398 and possibly others in "Windows mode" + * using a combined control and data interface without any CDC + * functional descriptors + */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 17, .driver_info = (unsigned long)&qmi_wwan_shared, }, { /* Pantech UML290 */ - USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff), + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x106c, + .idProduct = 0x3718, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xf0, + .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_shared, }, + { /* ZTE MF820D */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x0167, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, + { /* ZTE MF821D */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x0326, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, + { /* ZTE (Vodafone) K3520-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x0055, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int1, + }, + { /* ZTE (Vodafone) K3565-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x0063, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, + { /* ZTE (Vodafone) K3570-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x1008, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, + { /* ZTE (Vodafone) K3571-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x1010, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, + { /* ZTE (Vodafone) K3765-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x2002, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, + { /* ZTE (Vodafone) K4505-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x0104, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, + { /* ZTE MF60 */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x1402, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int2, + }, + { /* Sierra Wireless MC77xx in QMI mode */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x1199, + .idProduct = 0x68a2, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_sierra, + }, - /* 3. Combined interface devices matching on interface number */ - {QMI_FIXED_INTF(0x19d2, 0x0055, 1)}, /* ZTE (Vodafone) K3520-Z */ - {QMI_FIXED_INTF(0x19d2, 0x0063, 4)}, /* ZTE (Vodafone) K3565-Z */ - {QMI_FIXED_INTF(0x19d2, 0x0104, 4)}, /* ZTE (Vodafone) K4505-Z */ - {QMI_FIXED_INTF(0x19d2, 0x0167, 4)}, /* ZTE MF820D */ - {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ - {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ - {QMI_FIXED_INTF(0x19d2, 0x1010, 4)}, /* ZTE (Vodafone) K3571-Z */ - {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ - {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ - {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ - {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ - {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ - {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ - {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ - - /* 4. Gobi 1000 devices */ + /* Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ @@ -406,7 +579,7 @@ static const struct usb_device_id products[] = { {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ - /* 5. Gobi 2000 and 3000 devices */ + /* Gobi 2000 and 3000 devices */ {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ @@ -416,8 +589,6 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ - {QMI_GOBI_DEVICE(0x1199, 0x68a5)}, /* Sierra Wireless Modem */ - {QMI_GOBI_DEVICE(0x1199, 0x68a9)}, /* Sierra Wireless Modem */ {QMI_GOBI_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {QMI_GOBI_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {QMI_GOBI_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ @@ -429,14 +600,11 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {QMI_GOBI_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {QMI_GOBI_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ - {QMI_FIXED_INTF(0x1199, 0x9011, 5)}, /* alternate interface number!? */ {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ - {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ - { } /* END */ }; MODULE_DEVICE_TABLE(usb, products); diff --git a/trunk/drivers/net/usb/sierra_net.c b/trunk/drivers/net/usb/sierra_net.c index 7be49ea60b6d..d75d1f56becf 100644 --- a/trunk/drivers/net/usb/sierra_net.c +++ b/trunk/drivers/net/usb/sierra_net.c @@ -68,8 +68,15 @@ static atomic_t iface_counter = ATOMIC_INIT(0); */ #define SIERRA_NET_USBCTL_BUF_LEN 1024 +/* list of interface numbers - used for constructing interface lists */ +struct sierra_net_iface_info { + const u32 infolen; /* number of interface numbers on list */ + const u8 *ifaceinfo; /* pointer to the array holding the numbers */ +}; + struct sierra_net_info_data { u16 rx_urb_size; + struct sierra_net_iface_info whitelist; }; /* Private data structure */ @@ -630,6 +637,21 @@ static int sierra_net_change_mtu(struct net_device *net, int new_mtu) return usbnet_change_mtu(net, new_mtu); } +static int is_whitelisted(const u8 ifnum, + const struct sierra_net_iface_info *whitelist) +{ + if (whitelist) { + const u8 *list = whitelist->ifaceinfo; + int i; + + for (i = 0; i < whitelist->infolen; i++) { + if (list[i] == ifnum) + return 1; + } + } + return 0; +} + static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) { int result = 0; @@ -684,6 +706,11 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) dev_dbg(&dev->udev->dev, "%s", __func__); ifacenum = intf->cur_altsetting->desc.bInterfaceNumber; + /* We only accept certain interfaces */ + if (!is_whitelisted(ifacenum, &data->whitelist)) { + dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum); + return -ENODEV; + } numendpoints = intf->cur_altsetting->desc.bNumEndpoints; /* We have three endpoints, bulk in and out, and a status */ if (numendpoints != 3) { @@ -918,8 +945,13 @@ struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, return NULL; } +static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { .rx_urb_size = 8 * 1024, + .whitelist = { + .infolen = ARRAY_SIZE(sierra_net_ifnum_list), + .ifaceinfo = sierra_net_ifnum_list + } }; static const struct driver_info sierra_net_info_direct_ip = { @@ -933,19 +965,15 @@ static const struct driver_info sierra_net_info_direct_ip = { .data = (unsigned long)&sierra_net_info_data_direct_ip, }; -#define DIRECT_IP_DEVICE(vend, prod) \ - {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \ - .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \ - {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 10), \ - .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \ - {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 11), \ - .driver_info = (unsigned long)&sierra_net_info_direct_ip} - static const struct usb_device_id products[] = { - DIRECT_IP_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ - DIRECT_IP_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ - DIRECT_IP_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ - DIRECT_IP_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ + {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ + .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ + .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ + .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ + .driver_info = (unsigned long) &sierra_net_info_direct_ip}, {}, /* last item */ }; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/rs.c b/trunk/drivers/net/wireless/iwlwifi/dvm/rs.c index a82f46c10f5e..6fddd2785e6e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/rs.c @@ -707,14 +707,11 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, */ static bool rs_use_green(struct ieee80211_sta *sta) { - /* - * There's a bug somewhere in this code that causes the - * scaling to get stuck because GF+SGI can't be combined - * in SISO rates. Until we find that bug, disable GF, it - * has only limited benefit and we still interoperate with - * GF APs since we can always receive GF transmissions. - */ - return false; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->ctx; + + return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && + !(ctx->ht.non_gf_sta_present); } /** diff --git a/trunk/drivers/net/wireless/libertas/if_usb.c b/trunk/drivers/net/wireless/libertas/if_usb.c index 27980778d992..55a77e41170a 100644 --- a/trunk/drivers/net/wireless/libertas/if_usb.c +++ b/trunk/drivers/net/wireless/libertas/if_usb.c @@ -10,7 +10,6 @@ #include #include #include -#include #ifdef CONFIG_OLPC #include diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c index 3f7bc5cadf9a..f32259686b45 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c @@ -2243,7 +2243,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) { - struct rt2x00lib_conf libconf = { .conf = &rt2x00dev->hw->conf }; + struct ieee80211_conf conf = { .flags = 0 }; + struct rt2x00lib_conf libconf = { .conf = &conf }; rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } diff --git a/trunk/drivers/pinctrl/pinctrl-imx23.c b/trunk/drivers/pinctrl/pinctrl-imx23.c index 3674d877ed7c..75d3eff94296 100644 --- a/trunk/drivers/pinctrl/pinctrl-imx23.c +++ b/trunk/drivers/pinctrl/pinctrl-imx23.c @@ -292,7 +292,7 @@ static int __init imx23_pinctrl_init(void) { return platform_driver_register(&imx23_pinctrl_driver); } -postcore_initcall(imx23_pinctrl_init); +arch_initcall(imx23_pinctrl_init); static void __exit imx23_pinctrl_exit(void) { diff --git a/trunk/drivers/pinctrl/pinctrl-imx28.c b/trunk/drivers/pinctrl/pinctrl-imx28.c index 0f5b2122b1ba..b973026811a2 100644 --- a/trunk/drivers/pinctrl/pinctrl-imx28.c +++ b/trunk/drivers/pinctrl/pinctrl-imx28.c @@ -408,7 +408,7 @@ static int __init imx28_pinctrl_init(void) { return platform_driver_register(&imx28_pinctrl_driver); } -postcore_initcall(imx28_pinctrl_init); +arch_initcall(imx28_pinctrl_init); static void __exit imx28_pinctrl_exit(void) { diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c b/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c index 5f3e9d0221e1..6f99769c6733 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c @@ -766,7 +766,7 @@ DB8500_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio1_a_1", "ipgpio7_b_1", DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1"); DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1dir_a_1"); -DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); +DB8500_FUNC_GROUPS(hsi, "hsir1_a_1", "hsit1_a_1", "hsit_a_2"); DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1"); DB8500_FUNC_GROUPS(usb, "usb_a_1"); DB8500_FUNC_GROUPS(trig, "trig_b_1"); diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik.c b/trunk/drivers/pinctrl/pinctrl-nomadik.c index ec6ac501b23a..53b0d49a7a1c 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik.c @@ -1731,6 +1731,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) for (i = 0; i < npct->soc->gpio_num_ranges; i++) { if (!nmk_gpio_chips[i]) { dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); + devm_kfree(&pdev->dev, npct); return -EPROBE_DEFER; } npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip; diff --git a/trunk/drivers/pinctrl/pinctrl-sirf.c b/trunk/drivers/pinctrl/pinctrl-sirf.c index 7fca6ce5952b..2aae8a8978e9 100644 --- a/trunk/drivers/pinctrl/pinctrl-sirf.c +++ b/trunk/drivers/pinctrl/pinctrl-sirf.c @@ -1217,6 +1217,7 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) iounmap(spmx->gpio_virtbase); out_no_gpio_remap: platform_set_drvdata(pdev, NULL); + devm_kfree(&pdev->dev, spmx); return ret; } diff --git a/trunk/drivers/pinctrl/pinctrl-u300.c b/trunk/drivers/pinctrl/pinctrl-u300.c index 309f5b9a70ec..a7ad8c112d91 100644 --- a/trunk/drivers/pinctrl/pinctrl-u300.c +++ b/trunk/drivers/pinctrl/pinctrl-u300.c @@ -1121,8 +1121,10 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) upmx->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENOENT; + if (!res) { + ret = -ENOENT; + goto out_no_resource; + } upmx->phybase = res->start; upmx->physize = resource_size(res); @@ -1163,6 +1165,8 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); out_no_memregion: release_mem_region(upmx->phybase, upmx->physize); +out_no_resource: + devm_kfree(&pdev->dev, upmx); return ret; } diff --git a/trunk/drivers/platform/Makefile b/trunk/drivers/platform/Makefile index b17c16ce54ad..782953ae4c03 100644 --- a/trunk/drivers/platform/Makefile +++ b/trunk/drivers/platform/Makefile @@ -3,4 +3,3 @@ # obj-$(CONFIG_X86) += x86/ -obj-$(CONFIG_OLPC) += olpc/ diff --git a/trunk/drivers/platform/olpc/Makefile b/trunk/drivers/platform/olpc/Makefile deleted file mode 100644 index dc8b26bc7209..000000000000 --- a/trunk/drivers/platform/olpc/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# -# OLPC XO platform-specific drivers -# -obj-$(CONFIG_OLPC) += olpc-ec.o diff --git a/trunk/drivers/platform/olpc/olpc-ec.c b/trunk/drivers/platform/olpc/olpc-ec.c deleted file mode 100644 index 0f9f8596b300..000000000000 --- a/trunk/drivers/platform/olpc/olpc-ec.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Generic driver for the OLPC Embedded Controller. - * - * Copyright (C) 2011-2012 One Laptop per Child Foundation. - * - * Licensed under the GPL v2 or later. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct ec_cmd_desc { - u8 cmd; - u8 *inbuf, *outbuf; - size_t inlen, outlen; - - int err; - struct completion finished; - struct list_head node; - - void *priv; -}; - -struct olpc_ec_priv { - struct olpc_ec_driver *drv; - struct work_struct worker; - struct mutex cmd_lock; - - /* Pending EC commands */ - struct list_head cmd_q; - spinlock_t cmd_q_lock; - - struct dentry *dbgfs_dir; - - /* - * Running an EC command while suspending means we don't always finish - * the command before the machine suspends. This means that the EC - * is expecting the command protocol to finish, but we after a period - * of time (while the OS is asleep) the EC times out and restarts its - * idle loop. Meanwhile, the OS wakes up, thinks it's still in the - * middle of the command protocol, starts throwing random things at - * the EC... and everyone's uphappy. - */ - bool suspended; -}; - -static struct olpc_ec_driver *ec_driver; -static struct olpc_ec_priv *ec_priv; -static void *ec_cb_arg; - -void olpc_ec_driver_register(struct olpc_ec_driver *drv, void *arg) -{ - ec_driver = drv; - ec_cb_arg = arg; -} -EXPORT_SYMBOL_GPL(olpc_ec_driver_register); - -static void olpc_ec_worker(struct work_struct *w) -{ - struct olpc_ec_priv *ec = container_of(w, struct olpc_ec_priv, worker); - struct ec_cmd_desc *desc = NULL; - unsigned long flags; - - /* Grab the first pending command from the queue */ - spin_lock_irqsave(&ec->cmd_q_lock, flags); - if (!list_empty(&ec->cmd_q)) { - desc = list_first_entry(&ec->cmd_q, struct ec_cmd_desc, node); - list_del(&desc->node); - } - spin_unlock_irqrestore(&ec->cmd_q_lock, flags); - - /* Do we actually have anything to do? */ - if (!desc) - return; - - /* Protect the EC hw with a mutex; only run one cmd at a time */ - mutex_lock(&ec->cmd_lock); - desc->err = ec_driver->ec_cmd(desc->cmd, desc->inbuf, desc->inlen, - desc->outbuf, desc->outlen, ec_cb_arg); - mutex_unlock(&ec->cmd_lock); - - /* Finished, wake up olpc_ec_cmd() */ - complete(&desc->finished); - - /* Run the worker thread again in case there are more cmds pending */ - schedule_work(&ec->worker); -} - -/* - * Throw a cmd descripter onto the list. We now have SMP OLPC machines, so - * locking is pretty critical. - */ -static void queue_ec_descriptor(struct ec_cmd_desc *desc, - struct olpc_ec_priv *ec) -{ - unsigned long flags; - - INIT_LIST_HEAD(&desc->node); - - spin_lock_irqsave(&ec->cmd_q_lock, flags); - list_add_tail(&desc->node, &ec->cmd_q); - spin_unlock_irqrestore(&ec->cmd_q_lock, flags); - - schedule_work(&ec->worker); -} - -int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, size_t outlen) -{ - struct olpc_ec_priv *ec = ec_priv; - struct ec_cmd_desc desc; - - /* Ensure a driver and ec hook have been registered */ - if (WARN_ON(!ec_driver || !ec_driver->ec_cmd)) - return -ENODEV; - - if (!ec) - return -ENOMEM; - - /* Suspending in the middle of a command hoses things really badly */ - if (WARN_ON(ec->suspended)) - return -EBUSY; - - might_sleep(); - - desc.cmd = cmd; - desc.inbuf = inbuf; - desc.outbuf = outbuf; - desc.inlen = inlen; - desc.outlen = outlen; - desc.err = 0; - init_completion(&desc.finished); - - queue_ec_descriptor(&desc, ec); - - /* Timeouts must be handled in the platform-specific EC hook */ - wait_for_completion(&desc.finished); - - /* The worker thread dequeues the cmd; no need to do anything here */ - return desc.err; -} -EXPORT_SYMBOL_GPL(olpc_ec_cmd); - -#ifdef CONFIG_DEBUG_FS - -/* - * debugfs support for "generic commands", to allow sending - * arbitrary EC commands from userspace. - */ - -#define EC_MAX_CMD_ARGS (5 + 1) /* cmd byte + 5 args */ -#define EC_MAX_CMD_REPLY (8) - -static DEFINE_MUTEX(ec_dbgfs_lock); -static unsigned char ec_dbgfs_resp[EC_MAX_CMD_REPLY]; -static unsigned int ec_dbgfs_resp_bytes; - -static ssize_t ec_dbgfs_cmd_write(struct file *file, const char __user *buf, - size_t size, loff_t *ppos) -{ - int i, m; - unsigned char ec_cmd[EC_MAX_CMD_ARGS]; - unsigned int ec_cmd_int[EC_MAX_CMD_ARGS]; - char cmdbuf[64]; - int ec_cmd_bytes; - - mutex_lock(&ec_dbgfs_lock); - - size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size); - - m = sscanf(cmdbuf, "%x:%u %x %x %x %x %x", &ec_cmd_int[0], - &ec_dbgfs_resp_bytes, &ec_cmd_int[1], &ec_cmd_int[2], - &ec_cmd_int[3], &ec_cmd_int[4], &ec_cmd_int[5]); - if (m < 2 || ec_dbgfs_resp_bytes > EC_MAX_CMD_REPLY) { - /* reset to prevent overflow on read */ - ec_dbgfs_resp_bytes = 0; - - pr_debug("olpc-ec: bad ec cmd: cmd:response-count [arg1 [arg2 ...]]\n"); - size = -EINVAL; - goto out; - } - - /* convert scanf'd ints to char */ - ec_cmd_bytes = m - 2; - for (i = 0; i <= ec_cmd_bytes; i++) - ec_cmd[i] = ec_cmd_int[i]; - - pr_debug("olpc-ec: debugfs cmd 0x%02x with %d args %02x %02x %02x %02x %02x, want %d returns\n", - ec_cmd[0], ec_cmd_bytes, ec_cmd[1], ec_cmd[2], - ec_cmd[3], ec_cmd[4], ec_cmd[5], ec_dbgfs_resp_bytes); - - olpc_ec_cmd(ec_cmd[0], (ec_cmd_bytes == 0) ? NULL : &ec_cmd[1], - ec_cmd_bytes, ec_dbgfs_resp, ec_dbgfs_resp_bytes); - - pr_debug("olpc-ec: response %02x %02x %02x %02x %02x %02x %02x %02x (%d bytes expected)\n", - ec_dbgfs_resp[0], ec_dbgfs_resp[1], ec_dbgfs_resp[2], - ec_dbgfs_resp[3], ec_dbgfs_resp[4], ec_dbgfs_resp[5], - ec_dbgfs_resp[6], ec_dbgfs_resp[7], - ec_dbgfs_resp_bytes); - -out: - mutex_unlock(&ec_dbgfs_lock); - return size; -} - -static ssize_t ec_dbgfs_cmd_read(struct file *file, char __user *buf, - size_t size, loff_t *ppos) -{ - unsigned int i, r; - char *rp; - char respbuf[64]; - - mutex_lock(&ec_dbgfs_lock); - rp = respbuf; - rp += sprintf(rp, "%02x", ec_dbgfs_resp[0]); - for (i = 1; i < ec_dbgfs_resp_bytes; i++) - rp += sprintf(rp, ", %02x", ec_dbgfs_resp[i]); - mutex_unlock(&ec_dbgfs_lock); - rp += sprintf(rp, "\n"); - - r = rp - respbuf; - return simple_read_from_buffer(buf, size, ppos, respbuf, r); -} - -static const struct file_operations ec_dbgfs_ops = { - .write = ec_dbgfs_cmd_write, - .read = ec_dbgfs_cmd_read, -}; - -static struct dentry *olpc_ec_setup_debugfs(void) -{ - struct dentry *dbgfs_dir; - - dbgfs_dir = debugfs_create_dir("olpc-ec", NULL); - if (IS_ERR_OR_NULL(dbgfs_dir)) - return NULL; - - debugfs_create_file("cmd", 0600, dbgfs_dir, NULL, &ec_dbgfs_ops); - - return dbgfs_dir; -} - -#else - -static struct dentry *olpc_ec_setup_debugfs(void) -{ - return NULL; -} - -#endif /* CONFIG_DEBUG_FS */ - -static int olpc_ec_probe(struct platform_device *pdev) -{ - struct olpc_ec_priv *ec; - int err; - - if (!ec_driver) - return -ENODEV; - - ec = kzalloc(sizeof(*ec), GFP_KERNEL); - if (!ec) - return -ENOMEM; - - ec->drv = ec_driver; - INIT_WORK(&ec->worker, olpc_ec_worker); - mutex_init(&ec->cmd_lock); - - INIT_LIST_HEAD(&ec->cmd_q); - spin_lock_init(&ec->cmd_q_lock); - - ec_priv = ec; - platform_set_drvdata(pdev, ec); - - err = ec_driver->probe ? ec_driver->probe(pdev) : 0; - if (err) { - ec_priv = NULL; - kfree(ec); - } else { - ec->dbgfs_dir = olpc_ec_setup_debugfs(); - } - - return err; -} - -static int olpc_ec_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct olpc_ec_priv *ec = platform_get_drvdata(pdev); - int err = 0; - - if (ec_driver->suspend) - err = ec_driver->suspend(pdev); - if (!err) - ec->suspended = true; - - return err; -} - -static int olpc_ec_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct olpc_ec_priv *ec = platform_get_drvdata(pdev); - - ec->suspended = false; - return ec_driver->resume ? ec_driver->resume(pdev) : 0; -} - -static const struct dev_pm_ops olpc_ec_pm_ops = { - .suspend_late = olpc_ec_suspend, - .resume_early = olpc_ec_resume, -}; - -static struct platform_driver olpc_ec_plat_driver = { - .probe = olpc_ec_probe, - .driver = { - .name = "olpc-ec", - .pm = &olpc_ec_pm_ops, - }, -}; - -static int __init olpc_ec_init_module(void) -{ - return platform_driver_register(&olpc_ec_plat_driver); -} - -module_init(olpc_ec_init_module); - -MODULE_AUTHOR("Andres Salomon "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/platform/x86/classmate-laptop.c b/trunk/drivers/platform/x86/classmate-laptop.c index cd33add118ce..2ca7dd1ab3e4 100644 --- a/trunk/drivers/platform/x86/classmate-laptop.c +++ b/trunk/drivers/platform/x86/classmate-laptop.c @@ -350,7 +350,6 @@ static void cmpc_accel_idev_init_v4(struct input_dev *inputdev) inputdev->close = cmpc_accel_close_v4; } -#ifdef CONFIG_PM_SLEEP static int cmpc_accel_suspend_v4(struct device *dev) { struct input_dev *inputdev; @@ -385,7 +384,6 @@ static int cmpc_accel_resume_v4(struct device *dev) return 0; } -#endif static int cmpc_accel_add_v4(struct acpi_device *acpi) { @@ -754,7 +752,6 @@ static int cmpc_tablet_remove(struct acpi_device *acpi, int type) return cmpc_remove_acpi_notify_device(acpi); } -#ifdef CONFIG_PM_SLEEP static int cmpc_tablet_resume(struct device *dev) { struct input_dev *inputdev = dev_get_drvdata(dev); @@ -764,7 +761,6 @@ static int cmpc_tablet_resume(struct device *dev) input_report_switch(inputdev, SW_TABLET_MODE, !val); return 0; } -#endif static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume); diff --git a/trunk/drivers/platform/x86/fujitsu-tablet.c b/trunk/drivers/platform/x86/fujitsu-tablet.c index 7acae3f85f3b..d2e41735a47b 100644 --- a/trunk/drivers/platform/x86/fujitsu-tablet.c +++ b/trunk/drivers/platform/x86/fujitsu-tablet.c @@ -440,13 +440,11 @@ static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type) return 0; } -#ifdef CONFIG_PM_SLEEP static int acpi_fujitsu_resume(struct device *dev) { fujitsu_reset(); return 0; } -#endif static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume); diff --git a/trunk/drivers/platform/x86/hdaps.c b/trunk/drivers/platform/x86/hdaps.c index 777c7e3dda51..d9ab6f64dcec 100644 --- a/trunk/drivers/platform/x86/hdaps.c +++ b/trunk/drivers/platform/x86/hdaps.c @@ -305,12 +305,10 @@ static int hdaps_probe(struct platform_device *dev) return 0; } -#ifdef CONFIG_PM_SLEEP static int hdaps_resume(struct device *dev) { return hdaps_device_init(); } -#endif static SIMPLE_DEV_PM_OPS(hdaps_pm, NULL, hdaps_resume); diff --git a/trunk/drivers/platform/x86/hp_accel.c b/trunk/drivers/platform/x86/hp_accel.c index 6b9af989632b..f4d91154ad67 100644 --- a/trunk/drivers/platform/x86/hp_accel.c +++ b/trunk/drivers/platform/x86/hp_accel.c @@ -352,7 +352,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int lis3lv02d_suspend(struct device *dev) { /* make sure the device is off when we suspend */ diff --git a/trunk/drivers/platform/x86/msi-laptop.c b/trunk/drivers/platform/x86/msi-laptop.c index 2111dbb7e1e3..f64441844317 100644 --- a/trunk/drivers/platform/x86/msi-laptop.c +++ b/trunk/drivers/platform/x86/msi-laptop.c @@ -85,9 +85,7 @@ #define MSI_STANDARD_EC_TOUCHPAD_ADDRESS 0xe4 #define MSI_STANDARD_EC_TOUCHPAD_MASK (1 << 4) -#ifdef CONFIG_PM_SLEEP static int msi_laptop_resume(struct device *device); -#endif static SIMPLE_DEV_PM_OPS(msi_laptop_pm, NULL, msi_laptop_resume); #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f @@ -755,7 +753,6 @@ static int rfkill_init(struct platform_device *sdev) return retval; } -#ifdef CONFIG_PM_SLEEP static int msi_laptop_resume(struct device *device) { u8 data; @@ -776,7 +773,6 @@ static int msi_laptop_resume(struct device *device) return 0; } -#endif static int __init msi_laptop_input_setup(void) { diff --git a/trunk/drivers/platform/x86/panasonic-laptop.c b/trunk/drivers/platform/x86/panasonic-laptop.c index 8e8caa767d6a..24480074bcf0 100644 --- a/trunk/drivers/platform/x86/panasonic-laptop.c +++ b/trunk/drivers/platform/x86/panasonic-laptop.c @@ -188,9 +188,7 @@ static const struct acpi_device_id pcc_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, pcc_device_ids); -#ifdef CONFIG_PM_SLEEP static int acpi_pcc_hotkey_resume(struct device *dev); -#endif static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume); static struct acpi_driver acpi_pcc_driver = { @@ -542,7 +540,6 @@ static void acpi_pcc_destroy_input(struct pcc_acpi *pcc) /* kernel module interface */ -#ifdef CONFIG_PM_SLEEP static int acpi_pcc_hotkey_resume(struct device *dev) { struct pcc_acpi *pcc; @@ -559,7 +556,6 @@ static int acpi_pcc_hotkey_resume(struct device *dev) return acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode); } -#endif static int acpi_pcc_hotkey_add(struct acpi_device *device) { diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index daaddec68def..9363969ad07a 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -140,10 +140,7 @@ MODULE_PARM_DESC(kbd_backlight_timeout, "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " "(default: 0)"); -#ifdef CONFIG_PM_SLEEP static void sony_nc_kbd_backlight_resume(void); -static void sony_nc_thermal_resume(void); -#endif static int sony_nc_kbd_backlight_setup(struct platform_device *pd, unsigned int handle); static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd); @@ -154,6 +151,7 @@ static void sony_nc_battery_care_cleanup(struct platform_device *pd); static int sony_nc_thermal_setup(struct platform_device *pd); static void sony_nc_thermal_cleanup(struct platform_device *pd); +static void sony_nc_thermal_resume(void); static int sony_nc_lid_resume_setup(struct platform_device *pd); static void sony_nc_lid_resume_cleanup(struct platform_device *pd); @@ -1433,7 +1431,6 @@ static void sony_nc_function_cleanup(struct platform_device *pd) sony_nc_handles_cleanup(pd); } -#ifdef CONFIG_PM_SLEEP static void sony_nc_function_resume(void) { unsigned int i, result, bitmask, arg; @@ -1511,7 +1508,6 @@ static int sony_nc_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume); @@ -1876,7 +1872,6 @@ static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd) } } -#ifdef CONFIG_PM_SLEEP static void sony_nc_kbd_backlight_resume(void) { int ignore = 0; @@ -1893,7 +1888,6 @@ static void sony_nc_kbd_backlight_resume(void) (kbdbl_ctl->base + 0x200) | (kbdbl_ctl->timeout << 0x10), &ignore); } -#endif struct battery_care_control { struct device_attribute attrs[2]; @@ -2216,7 +2210,6 @@ static void sony_nc_thermal_cleanup(struct platform_device *pd) } } -#ifdef CONFIG_PM_SLEEP static void sony_nc_thermal_resume(void) { unsigned int status = sony_nc_thermal_mode_get(); @@ -2224,7 +2217,6 @@ static void sony_nc_thermal_resume(void) if (status != th_handle->mode) sony_nc_thermal_mode_set(th_handle->mode); } -#endif /* resume on LID open */ struct snc_lid_resume_control { @@ -4295,7 +4287,6 @@ static int sony_pic_add(struct acpi_device *device) return result; } -#ifdef CONFIG_PM_SLEEP static int sony_pic_suspend(struct device *dev) { if (sony_pic_disable(to_acpi_device(dev))) @@ -4309,7 +4300,6 @@ static int sony_pic_resume(struct device *dev) spic_dev.cur_ioport, spic_dev.cur_irq); return 0; } -#endif static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume); diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index f28f36ccdcf4..e7f73287636c 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -922,7 +922,6 @@ static struct input_dev *tpacpi_inputdev; static struct mutex tpacpi_inputdev_send_mutex; static LIST_HEAD(tpacpi_all_drivers); -#ifdef CONFIG_PM_SLEEP static int tpacpi_suspend_handler(struct device *dev) { struct ibm_struct *ibm, *itmp; @@ -950,7 +949,6 @@ static int tpacpi_resume_handler(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(tpacpi_pm, tpacpi_suspend_handler, tpacpi_resume_handler); diff --git a/trunk/drivers/platform/x86/toshiba_acpi.c b/trunk/drivers/platform/x86/toshiba_acpi.c index 5f1256d5e933..c13ba5bac93f 100644 --- a/trunk/drivers/platform/x86/toshiba_acpi.c +++ b/trunk/drivers/platform/x86/toshiba_acpi.c @@ -1296,7 +1296,6 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) } } -#ifdef CONFIG_PM_SLEEP static int toshiba_acpi_suspend(struct device *device) { struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); @@ -1318,7 +1317,6 @@ static int toshiba_acpi_resume(struct device *device) return 0; } -#endif static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm, toshiba_acpi_suspend, toshiba_acpi_resume); diff --git a/trunk/drivers/platform/x86/toshiba_bluetooth.c b/trunk/drivers/platform/x86/toshiba_bluetooth.c index 5e5d6317d690..715a43cb5e3c 100644 --- a/trunk/drivers/platform/x86/toshiba_bluetooth.c +++ b/trunk/drivers/platform/x86/toshiba_bluetooth.c @@ -41,9 +41,7 @@ static const struct acpi_device_id bt_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, bt_device_ids); -#ifdef CONFIG_PM_SLEEP static int toshiba_bt_resume(struct device *dev); -#endif static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume); static struct acpi_driver toshiba_bt_rfkill_driver = { @@ -92,12 +90,10 @@ static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) toshiba_bluetooth_enable(device->handle); } -#ifdef CONFIG_PM_SLEEP static int toshiba_bt_resume(struct device *dev) { return toshiba_bluetooth_enable(to_acpi_device(dev)->handle); } -#endif static int toshiba_bt_rfkill_add(struct acpi_device *device) { diff --git a/trunk/drivers/platform/x86/xo1-rfkill.c b/trunk/drivers/platform/x86/xo1-rfkill.c index 1da13ed34b04..b57ad8641480 100644 --- a/trunk/drivers/platform/x86/xo1-rfkill.c +++ b/trunk/drivers/platform/x86/xo1-rfkill.c @@ -12,7 +12,8 @@ #include #include #include -#include + +#include static bool card_blocked; diff --git a/trunk/drivers/platform/x86/xo15-ebook.c b/trunk/drivers/platform/x86/xo15-ebook.c index 38ba39d7ca7d..849c07c13bf6 100644 --- a/trunk/drivers/platform/x86/xo15-ebook.c +++ b/trunk/drivers/platform/x86/xo15-ebook.c @@ -77,12 +77,10 @@ static void ebook_switch_notify(struct acpi_device *device, u32 event) } } -#ifdef CONFIG_PM_SLEEP static int ebook_switch_resume(struct device *dev) { return ebook_send_state(to_acpi_device(dev)); } -#endif static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume); diff --git a/trunk/drivers/power/olpc_battery.c b/trunk/drivers/power/olpc_battery.c index a89a41acf9c5..55b10b813353 100644 --- a/trunk/drivers/power/olpc_battery.c +++ b/trunk/drivers/power/olpc_battery.c @@ -17,7 +17,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/rtc/interface.c b/trunk/drivers/rtc/interface.c index 9592b936b71b..eb415bd76494 100644 --- a/trunk/drivers/rtc/interface.c +++ b/trunk/drivers/rtc/interface.c @@ -582,7 +582,6 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) void rtc_update_irq(struct rtc_device *rtc, unsigned long num, unsigned long events) { - pm_stay_awake(rtc->dev.parent); schedule_work(&rtc->irqwork); } EXPORT_SYMBOL_GPL(rtc_update_irq); @@ -845,7 +844,6 @@ void rtc_timer_do_work(struct work_struct *work) mutex_lock(&rtc->ops_lock); again: - pm_relax(rtc->dev.parent); __rtc_read_time(rtc, &tm); now = rtc_tm_to_ktime(tm); while ((next = timerqueue_getnext(&rtc->timerqueue))) { diff --git a/trunk/drivers/rtc/rtc-cmos.c b/trunk/drivers/rtc/rtc-cmos.c index 4267789ca995..132333d75408 100644 --- a/trunk/drivers/rtc/rtc-cmos.c +++ b/trunk/drivers/rtc/rtc-cmos.c @@ -568,6 +568,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p) hpet_mask_rtc_irq_bit(RTC_AIE); CMOS_READ(RTC_INTR_FLAGS); + pm_wakeup_event(cmos_rtc.dev, 0); } spin_unlock(&rtc_lock); diff --git a/trunk/drivers/s390/char/sclp_sdias.c b/trunk/drivers/s390/char/sclp_sdias.c index b1032931a1c4..6a6f76bf6e3d 100644 --- a/trunk/drivers/s390/char/sclp_sdias.c +++ b/trunk/drivers/s390/char/sclp_sdias.c @@ -242,13 +242,11 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks) switch (sdias_evbuf.event_status) { case EVSTATE_ALL_STORED: TRACE("all stored\n"); - break; case EVSTATE_PART_STORED: TRACE("part stored: %i\n", sdias_evbuf.blk_cnt); break; case EVSTATE_NO_DATA: TRACE("no data\n"); - /* fall through */ default: pr_err("Error from SCLP while copying hsa. " "Event status = %x\n", diff --git a/trunk/drivers/sh/intc/Kconfig b/trunk/drivers/sh/intc/Kconfig index a305731742a9..c88cbccc62b0 100644 --- a/trunk/drivers/sh/intc/Kconfig +++ b/trunk/drivers/sh/intc/Kconfig @@ -1,7 +1,3 @@ -config SH_INTC - def_bool y - select IRQ_DOMAIN - comment "Interrupt controller options" config INTC_USERIMASK diff --git a/trunk/drivers/sh/intc/Makefile b/trunk/drivers/sh/intc/Makefile index 54ec2a0643df..44f006d09471 100644 --- a/trunk/drivers/sh/intc/Makefile +++ b/trunk/drivers/sh/intc/Makefile @@ -1,4 +1,4 @@ -obj-y := access.o chip.o core.o handle.o irqdomain.o virq.o +obj-y := access.o chip.o core.o handle.o virq.o obj-$(CONFIG_INTC_BALANCING) += balancing.o obj-$(CONFIG_INTC_USERIMASK) += userimask.o diff --git a/trunk/drivers/sh/intc/core.c b/trunk/drivers/sh/intc/core.c index 2374468615ed..7e562ccb6997 100644 --- a/trunk/drivers/sh/intc/core.c +++ b/trunk/drivers/sh/intc/core.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -311,8 +310,6 @@ int __init register_intc_controller(struct intc_desc *desc) BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ - intc_irq_domain_init(d, hw); - /* register the vectors one by one */ for (i = 0; i < hw->nr_vectors; i++) { struct intc_vect *vect = hw->vectors + i; @@ -322,8 +319,8 @@ int __init register_intc_controller(struct intc_desc *desc) if (!vect->enum_id) continue; - res = irq_create_identity_mapping(d->domain, irq); - if (unlikely(res)) { + res = irq_alloc_desc_at(irq, numa_node_id()); + if (res != irq && res != -EEXIST) { pr_err("can't get irq_desc for %d\n", irq); continue; } @@ -343,8 +340,8 @@ int __init register_intc_controller(struct intc_desc *desc) * IRQ support, each vector still needs to have * its own backing irq_desc. */ - res = irq_create_identity_mapping(d->domain, irq2); - if (unlikely(res)) { + res = irq_alloc_desc_at(irq2, numa_node_id()); + if (res != irq2 && res != -EEXIST) { pr_err("can't get irq_desc for %d\n", irq2); continue; } diff --git a/trunk/drivers/sh/intc/internals.h b/trunk/drivers/sh/intc/internals.h index 7dff08e2a071..f034a979a16f 100644 --- a/trunk/drivers/sh/intc/internals.h +++ b/trunk/drivers/sh/intc/internals.h @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -67,7 +66,6 @@ struct intc_desc_int { unsigned int nr_sense; struct intc_window *window; unsigned int nr_windows; - struct irq_domain *domain; struct irq_chip chip; bool skip_suspend; }; @@ -189,9 +187,6 @@ unsigned long intc_get_ack_handle(unsigned int irq); void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d, intc_enum enum_id, int enable); -/* irqdomain.c */ -void intc_irq_domain_init(struct intc_desc_int *d, struct intc_hw_desc *hw); - /* virq.c */ void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d); void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d); diff --git a/trunk/drivers/sh/intc/irqdomain.c b/trunk/drivers/sh/intc/irqdomain.c deleted file mode 100644 index 3968f1c3c5c3..000000000000 --- a/trunk/drivers/sh/intc/irqdomain.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * IRQ domain support for SH INTC subsystem - * - * Copyright (C) 2012 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "intc: " fmt - -#include -#include -#include -#include "internals.h" - -/** - * intc_irq_domain_evt_xlate() - Generic xlate for vectored IRQs. - * - * This takes care of exception vector to hwirq translation through - * by way of evt2irq() translation. - * - * Note: For platforms that use a flat vector space without INTEVT this - * basically just mimics irq_domain_xlate_onecell() by way of a nopped - * out evt2irq() implementation. - */ -static int intc_evt_xlate(struct irq_domain *d, struct device_node *ctrlr, - const u32 *intspec, unsigned int intsize, - unsigned long *out_hwirq, unsigned int *out_type) -{ - if (WARN_ON(intsize < 1)) - return -EINVAL; - - *out_hwirq = evt2irq(intspec[0]); - *out_type = IRQ_TYPE_NONE; - - return 0; -} - -static const struct irq_domain_ops intc_evt_ops = { - .xlate = intc_evt_xlate, -}; - -void __init intc_irq_domain_init(struct intc_desc_int *d, - struct intc_hw_desc *hw) -{ - unsigned int irq_base, irq_end; - - /* - * Quick linear revmap check - */ - irq_base = evt2irq(hw->vectors[0].vect); - irq_end = evt2irq(hw->vectors[hw->nr_vectors - 1].vect); - - /* - * Linear domains have a hard-wired assertion that IRQs start at - * 0 in order to make some performance optimizations. Lamely - * restrict the linear case to these conditions here, taking the - * tree penalty for linear cases with non-zero hwirq bases. - */ - if (irq_base == 0 && irq_end == (irq_base + hw->nr_vectors - 1)) - d->domain = irq_domain_add_linear(NULL, hw->nr_vectors, - &intc_evt_ops, NULL); - else - d->domain = irq_domain_add_tree(NULL, &intc_evt_ops, NULL); - - BUG_ON(!d->domain); -} diff --git a/trunk/drivers/sh/pfc/pinctrl.c b/trunk/drivers/sh/pfc/pinctrl.c index 2804eaae804e..0802b6c0d653 100644 --- a/trunk/drivers/sh/pfc/pinctrl.c +++ b/trunk/drivers/sh/pfc/pinctrl.c @@ -276,6 +276,7 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, unsigned long config) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + struct sh_pfc *pfc = pmx->pfc; /* Validate the new type */ if (config >= PINMUX_FLAG_TYPE) @@ -325,6 +326,20 @@ static struct pinctrl_desc sh_pfc_pinctrl_desc = { .confops = &sh_pfc_pinconf_ops, }; +int sh_pfc_register_pinctrl(struct sh_pfc *pfc) +{ + sh_pfc_pmx = kzalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL); + if (unlikely(!sh_pfc_pmx)) + return -ENOMEM; + + spin_lock_init(&sh_pfc_pmx->lock); + + sh_pfc_pmx->pfc = pfc; + + return 0; +} +EXPORT_SYMBOL_GPL(sh_pfc_register_pinctrl); + static inline void __devinit sh_pfc_map_one_gpio(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx, struct pinmux_gpio *gpio, @@ -466,6 +481,7 @@ static int __devexit sh_pfc_pinctrl_remove(struct platform_device *pdev) { struct sh_pfc_pinctrl *pmx = platform_get_drvdata(pdev); + pinctrl_remove_gpio_range(pmx->pctl, &sh_pfc_gpio_range); pinctrl_unregister(pmx->pctl); platform_set_drvdata(pdev, NULL); @@ -491,7 +507,7 @@ static struct platform_device sh_pfc_pinctrl_device = { .id = -1, }; -static int sh_pfc_pinctrl_init(void) +static int __init sh_pfc_pinctrl_init(void) { int rc; @@ -505,22 +521,10 @@ static int sh_pfc_pinctrl_init(void) return rc; } -int sh_pfc_register_pinctrl(struct sh_pfc *pfc) -{ - sh_pfc_pmx = kzalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL); - if (unlikely(!sh_pfc_pmx)) - return -ENOMEM; - - spin_lock_init(&sh_pfc_pmx->lock); - - sh_pfc_pmx->pfc = pfc; - - return sh_pfc_pinctrl_init(); -} -EXPORT_SYMBOL_GPL(sh_pfc_register_pinctrl); - static void __exit sh_pfc_pinctrl_exit(void) { platform_driver_unregister(&sh_pfc_pinctrl_driver); } + +subsys_initcall(sh_pfc_pinctrl_init); module_exit(sh_pfc_pinctrl_exit); diff --git a/trunk/drivers/spi/spi-s3c64xx.c b/trunk/drivers/spi/spi-s3c64xx.c index cfa2c35dfeed..646a7657fe62 100644 --- a/trunk/drivers/spi/spi-s3c64xx.c +++ b/trunk/drivers/spi/spi-s3c64xx.c @@ -826,7 +826,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( struct spi_device *spi) { struct s3c64xx_spi_csinfo *cs; - struct device_node *slave_np, *data_np = NULL; + struct device_node *slave_np, *data_np; u32 fb_delay = 0; slave_np = spi->dev.of_node; diff --git a/trunk/drivers/staging/olpc_dcon/olpc_dcon.c b/trunk/drivers/staging/olpc_dcon/olpc_dcon.c index 2c4bd746715a..992275c0d87c 100644 --- a/trunk/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/trunk/drivers/staging/olpc_dcon/olpc_dcon.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/tty/serial/sh-sci.c b/trunk/drivers/tty/serial/sh-sci.c index 9be296cf7295..d4d8c9453cd8 100644 --- a/trunk/drivers/tty/serial/sh-sci.c +++ b/trunk/drivers/tty/serial/sh-sci.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -1411,8 +1410,8 @@ static void work_fn_rx(struct work_struct *work) /* Handle incomplete DMA receive */ struct tty_struct *tty = port->state->port.tty; struct dma_chan *chan = s->chan_rx; - struct shdma_desc *sh_desc = container_of(desc, - struct shdma_desc, async_tx); + struct sh_desc *sh_desc = container_of(desc, struct sh_desc, + async_tx); unsigned long flags; int count; diff --git a/trunk/drivers/usb/early/ehci-dbgp.c b/trunk/drivers/usb/early/ehci-dbgp.c index 89dcf155d57e..ee0ebacf8227 100644 --- a/trunk/drivers/usb/early/ehci-dbgp.c +++ b/trunk/drivers/usb/early/ehci-dbgp.c @@ -450,7 +450,7 @@ static int dbgp_ehci_startup(void) writel(FLAG_CF, &ehci_regs->configured_flag); /* Wait until the controller is no longer halted */ - loop = 1000; + loop = 10; do { status = readl(&ehci_regs->status); if (!(status & STS_HALT)) diff --git a/trunk/drivers/usb/host/ohci-omap.c b/trunk/drivers/usb/host/ohci-omap.c index f8b2d91851f7..e7d75d295988 100644 --- a/trunk/drivers/usb/host/ohci-omap.c +++ b/trunk/drivers/usb/host/ohci-omap.c @@ -403,6 +403,8 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver, static inline void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { + struct ohci_hcd *ohci = hcd_to_ohci (hcd); + usb_remove_hcd(hcd); if (!IS_ERR_OR_NULL(hcd->phy)) { (void) otg_set_host(hcd->phy->otg, 0); diff --git a/trunk/drivers/vhost/Kconfig b/trunk/drivers/vhost/Kconfig index 202bba6c997c..e4e2fd1b5107 100644 --- a/trunk/drivers/vhost/Kconfig +++ b/trunk/drivers/vhost/Kconfig @@ -9,6 +9,3 @@ config VHOST_NET To compile this driver as a module, choose M here: the module will be called vhost_net. -if STAGING -source "drivers/vhost/Kconfig.tcm" -endif diff --git a/trunk/drivers/vhost/Kconfig.tcm b/trunk/drivers/vhost/Kconfig.tcm deleted file mode 100644 index a9c6f76e3208..000000000000 --- a/trunk/drivers/vhost/Kconfig.tcm +++ /dev/null @@ -1,6 +0,0 @@ -config TCM_VHOST - tristate "TCM_VHOST fabric module (EXPERIMENTAL)" - depends on TARGET_CORE && EVENTFD && EXPERIMENTAL && m - default n - ---help--- - Say M here to enable the TCM_VHOST fabric module for use with virtio-scsi guests diff --git a/trunk/drivers/vhost/Makefile b/trunk/drivers/vhost/Makefile index a27b053bc9ab..72dd02050bb9 100644 --- a/trunk/drivers/vhost/Makefile +++ b/trunk/drivers/vhost/Makefile @@ -1,4 +1,2 @@ obj-$(CONFIG_VHOST_NET) += vhost_net.o vhost_net-y := vhost.o net.o - -obj-$(CONFIG_TCM_VHOST) += tcm_vhost.o diff --git a/trunk/drivers/vhost/tcm_vhost.c b/trunk/drivers/vhost/tcm_vhost.c deleted file mode 100644 index fb366540ed54..000000000000 --- a/trunk/drivers/vhost/tcm_vhost.c +++ /dev/null @@ -1,1628 +0,0 @@ -/******************************************************************************* - * Vhost kernel TCM fabric driver for virtio SCSI initiators - * - * (C) Copyright 2010-2012 RisingTide Systems LLC. - * (C) Copyright 2010-2012 IBM Corp. - * - * Licensed to the Linux Foundation under the General Public License (GPL) version 2. - * - * Authors: Nicholas A. Bellinger - * Stefan Hajnoczi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - ****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* TODO vhost.h currently depends on this */ -#include - -#include "vhost.c" -#include "vhost.h" -#include "tcm_vhost.h" - -struct vhost_scsi { - atomic_t vhost_ref_cnt; - struct tcm_vhost_tpg *vs_tpg; - struct vhost_dev dev; - struct vhost_virtqueue vqs[3]; - - struct vhost_work vs_completion_work; /* cmd completion work item */ - struct list_head vs_completion_list; /* cmd completion queue */ - spinlock_t vs_completion_lock; /* protects s_completion_list */ -}; - -/* Local pointer to allocated TCM configfs fabric module */ -static struct target_fabric_configfs *tcm_vhost_fabric_configfs; - -static struct workqueue_struct *tcm_vhost_workqueue; - -/* Global spinlock to protect tcm_vhost TPG list for vhost IOCTL access */ -static DEFINE_MUTEX(tcm_vhost_mutex); -static LIST_HEAD(tcm_vhost_list); - -static int tcm_vhost_check_true(struct se_portal_group *se_tpg) -{ - return 1; -} - -static int tcm_vhost_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - -static char *tcm_vhost_get_fabric_name(void) -{ - return "vhost"; -} - -static u8 tcm_vhost_get_fabric_proto_ident(struct se_portal_group *se_tpg) -{ - struct tcm_vhost_tpg *tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - struct tcm_vhost_tport *tport = tpg->tport; - - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - return sas_get_fabric_proto_ident(se_tpg); - case SCSI_PROTOCOL_FCP: - return fc_get_fabric_proto_ident(se_tpg); - case SCSI_PROTOCOL_ISCSI: - return iscsi_get_fabric_proto_ident(se_tpg); - default: - pr_err("Unknown tport_proto_id: 0x%02x, using" - " SAS emulation\n", tport->tport_proto_id); - break; - } - - return sas_get_fabric_proto_ident(se_tpg); -} - -static char *tcm_vhost_get_fabric_wwn(struct se_portal_group *se_tpg) -{ - struct tcm_vhost_tpg *tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - struct tcm_vhost_tport *tport = tpg->tport; - - return &tport->tport_name[0]; -} - -static u16 tcm_vhost_get_tag(struct se_portal_group *se_tpg) -{ - struct tcm_vhost_tpg *tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - return tpg->tport_tpgt; -} - -static u32 tcm_vhost_get_default_depth(struct se_portal_group *se_tpg) -{ - return 1; -} - -static u32 tcm_vhost_get_pr_transport_id( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct t10_pr_registration *pr_reg, - int *format_code, - unsigned char *buf) -{ - struct tcm_vhost_tpg *tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - struct tcm_vhost_tport *tport = tpg->tport; - - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, - format_code, buf); - case SCSI_PROTOCOL_FCP: - return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg, - format_code, buf); - case SCSI_PROTOCOL_ISCSI: - return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg, - format_code, buf); - default: - pr_err("Unknown tport_proto_id: 0x%02x, using" - " SAS emulation\n", tport->tport_proto_id); - break; - } - - return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, - format_code, buf); -} - -static u32 tcm_vhost_get_pr_transport_id_len( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct t10_pr_registration *pr_reg, - int *format_code) -{ - struct tcm_vhost_tpg *tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - struct tcm_vhost_tport *tport = tpg->tport; - - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, - format_code); - case SCSI_PROTOCOL_FCP: - return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, - format_code); - case SCSI_PROTOCOL_ISCSI: - return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, - format_code); - default: - pr_err("Unknown tport_proto_id: 0x%02x, using" - " SAS emulation\n", tport->tport_proto_id); - break; - } - - return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, - format_code); -} - -static char *tcm_vhost_parse_pr_out_transport_id( - struct se_portal_group *se_tpg, - const char *buf, - u32 *out_tid_len, - char **port_nexus_ptr) -{ - struct tcm_vhost_tpg *tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - struct tcm_vhost_tport *tport = tpg->tport; - - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, - port_nexus_ptr); - case SCSI_PROTOCOL_FCP: - return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, - port_nexus_ptr); - case SCSI_PROTOCOL_ISCSI: - return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, - port_nexus_ptr); - default: - pr_err("Unknown tport_proto_id: 0x%02x, using" - " SAS emulation\n", tport->tport_proto_id); - break; - } - - return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, - port_nexus_ptr); -} - -static struct se_node_acl *tcm_vhost_alloc_fabric_acl( - struct se_portal_group *se_tpg) -{ - struct tcm_vhost_nacl *nacl; - - nacl = kzalloc(sizeof(struct tcm_vhost_nacl), GFP_KERNEL); - if (!nacl) { - pr_err("Unable to alocate struct tcm_vhost_nacl\n"); - return NULL; - } - - return &nacl->se_node_acl; -} - -static void tcm_vhost_release_fabric_acl( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl) -{ - struct tcm_vhost_nacl *nacl = container_of(se_nacl, - struct tcm_vhost_nacl, se_node_acl); - kfree(nacl); -} - -static u32 tcm_vhost_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - -static void tcm_vhost_release_cmd(struct se_cmd *se_cmd) -{ - return; -} - -static int tcm_vhost_shutdown_session(struct se_session *se_sess) -{ - return 0; -} - -static void tcm_vhost_close_session(struct se_session *se_sess) -{ - return; -} - -static u32 tcm_vhost_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - -static int tcm_vhost_write_pending(struct se_cmd *se_cmd) -{ - /* Go ahead and process the write immediately */ - target_execute_cmd(se_cmd); - return 0; -} - -static int tcm_vhost_write_pending_status(struct se_cmd *se_cmd) -{ - return 0; -} - -static void tcm_vhost_set_default_node_attrs(struct se_node_acl *nacl) -{ - return; -} - -static u32 tcm_vhost_get_task_tag(struct se_cmd *se_cmd) -{ - return 0; -} - -static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - -static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *); - -static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd) -{ - struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, - struct tcm_vhost_cmd, tvc_se_cmd); - vhost_scsi_complete_cmd(tv_cmd); - return 0; -} - -static int tcm_vhost_queue_status(struct se_cmd *se_cmd) -{ - struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, - struct tcm_vhost_cmd, tvc_se_cmd); - vhost_scsi_complete_cmd(tv_cmd); - return 0; -} - -static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) -{ - return 0; -} - -static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd, - u32 sense_length) -{ - return 0; -} - -static u16 tcm_vhost_get_fabric_sense_len(void) -{ - return 0; -} - -static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) -{ - struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; - - /* TODO locking against target/backend threads? */ - transport_generic_free_cmd(se_cmd, 1); - - if (tv_cmd->tvc_sgl_count) { - u32 i; - for (i = 0; i < tv_cmd->tvc_sgl_count; i++) - put_page(sg_page(&tv_cmd->tvc_sgl[i])); - - kfree(tv_cmd->tvc_sgl); - } - - kfree(tv_cmd); -} - -/* Dequeue a command from the completion list */ -static struct tcm_vhost_cmd *vhost_scsi_get_cmd_from_completion( - struct vhost_scsi *vs) -{ - struct tcm_vhost_cmd *tv_cmd = NULL; - - spin_lock_bh(&vs->vs_completion_lock); - if (list_empty(&vs->vs_completion_list)) { - spin_unlock_bh(&vs->vs_completion_lock); - return NULL; - } - - list_for_each_entry(tv_cmd, &vs->vs_completion_list, - tvc_completion_list) { - list_del(&tv_cmd->tvc_completion_list); - break; - } - spin_unlock_bh(&vs->vs_completion_lock); - return tv_cmd; -} - -/* Fill in status and signal that we are done processing this command - * - * This is scheduled in the vhost work queue so we are called with the owner - * process mm and can access the vring. - */ -static void vhost_scsi_complete_cmd_work(struct vhost_work *work) -{ - struct vhost_scsi *vs = container_of(work, struct vhost_scsi, - vs_completion_work); - struct tcm_vhost_cmd *tv_cmd; - - while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs)) != NULL) { - struct virtio_scsi_cmd_resp v_rsp; - struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; - int ret; - - pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__, - tv_cmd, se_cmd->residual_count, se_cmd->scsi_status); - - memset(&v_rsp, 0, sizeof(v_rsp)); - v_rsp.resid = se_cmd->residual_count; - /* TODO is status_qualifier field needed? */ - v_rsp.status = se_cmd->scsi_status; - v_rsp.sense_len = se_cmd->scsi_sense_length; - memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf, - v_rsp.sense_len); - ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp)); - if (likely(ret == 0)) - vhost_add_used(&vs->vqs[2], tv_cmd->tvc_vq_desc, 0); - else - pr_err("Faulted on virtio_scsi_cmd_resp\n"); - - vhost_scsi_free_cmd(tv_cmd); - } - - vhost_signal(&vs->dev, &vs->vqs[2]); -} - -static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd) -{ - struct vhost_scsi *vs = tv_cmd->tvc_vhost; - - pr_debug("%s tv_cmd %p\n", __func__, tv_cmd); - - spin_lock_bh(&vs->vs_completion_lock); - list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list); - spin_unlock_bh(&vs->vs_completion_lock); - - vhost_work_queue(&vs->dev, &vs->vs_completion_work); -} - -static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( - struct tcm_vhost_tpg *tv_tpg, - struct virtio_scsi_cmd_req *v_req, - u32 exp_data_len, - int data_direction) -{ - struct tcm_vhost_cmd *tv_cmd; - struct tcm_vhost_nexus *tv_nexus; - struct se_portal_group *se_tpg = &tv_tpg->se_tpg; - struct se_session *se_sess; - struct se_cmd *se_cmd; - int sam_task_attr; - - tv_nexus = tv_tpg->tpg_nexus; - if (!tv_nexus) { - pr_err("Unable to locate active struct tcm_vhost_nexus\n"); - return ERR_PTR(-EIO); - } - se_sess = tv_nexus->tvn_se_sess; - - tv_cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC); - if (!tv_cmd) { - pr_err("Unable to allocate struct tcm_vhost_cmd\n"); - return ERR_PTR(-ENOMEM); - } - INIT_LIST_HEAD(&tv_cmd->tvc_completion_list); - tv_cmd->tvc_tag = v_req->tag; - - se_cmd = &tv_cmd->tvc_se_cmd; - /* - * Locate the SAM Task Attr from virtio_scsi_cmd_req - */ - sam_task_attr = v_req->task_attr; - /* - * Initialize struct se_cmd descriptor from TCM infrastructure - */ - transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len, - data_direction, sam_task_attr, - &tv_cmd->tvc_sense_buf[0]); - -#if 0 /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */ - if (bidi) - se_cmd->se_cmd_flags |= SCF_BIDI; -#endif - return tv_cmd; -} - -/* - * Map a user memory range into a scatterlist - * - * Returns the number of scatterlist entries used or -errno on error. - */ -static int vhost_scsi_map_to_sgl(struct scatterlist *sgl, - unsigned int sgl_count, void __user *ptr, size_t len, int write) -{ - struct scatterlist *sg = sgl; - unsigned int npages = 0; - int ret; - - while (len > 0) { - struct page *page; - unsigned int offset = (uintptr_t)ptr & ~PAGE_MASK; - unsigned int nbytes = min_t(unsigned int, - PAGE_SIZE - offset, len); - - if (npages == sgl_count) { - ret = -ENOBUFS; - goto err; - } - - ret = get_user_pages_fast((unsigned long)ptr, 1, write, &page); - BUG_ON(ret == 0); /* we should either get our page or fail */ - if (ret < 0) - goto err; - - sg_set_page(sg, page, nbytes, offset); - ptr += nbytes; - len -= nbytes; - sg++; - npages++; - } - return npages; - -err: - /* Put pages that we hold */ - for (sg = sgl; sg != &sgl[npages]; sg++) - put_page(sg_page(sg)); - return ret; -} - -static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd, - struct iovec *iov, unsigned int niov, int write) -{ - int ret; - unsigned int i; - u32 sgl_count; - struct scatterlist *sg; - - /* - * Find out how long sglist needs to be - */ - sgl_count = 0; - for (i = 0; i < niov; i++) { - sgl_count += (((uintptr_t)iov[i].iov_base + iov[i].iov_len + - PAGE_SIZE - 1) >> PAGE_SHIFT) - - ((uintptr_t)iov[i].iov_base >> PAGE_SHIFT); - } - /* TODO overflow checking */ - - sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC); - if (!sg) - return -ENOMEM; - pr_debug("%s sg %p sgl_count %u is_err %ld\n", __func__, - sg, sgl_count, IS_ERR(sg)); - sg_init_table(sg, sgl_count); - - tv_cmd->tvc_sgl = sg; - tv_cmd->tvc_sgl_count = sgl_count; - - pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count); - for (i = 0; i < niov; i++) { - ret = vhost_scsi_map_to_sgl(sg, sgl_count, iov[i].iov_base, - iov[i].iov_len, write); - if (ret < 0) { - for (i = 0; i < tv_cmd->tvc_sgl_count; i++) - put_page(sg_page(&tv_cmd->tvc_sgl[i])); - kfree(tv_cmd->tvc_sgl); - tv_cmd->tvc_sgl = NULL; - tv_cmd->tvc_sgl_count = 0; - return ret; - } - - sg += ret; - sgl_count -= ret; - } - return 0; -} - -static void tcm_vhost_submission_work(struct work_struct *work) -{ - struct tcm_vhost_cmd *tv_cmd = - container_of(work, struct tcm_vhost_cmd, work); - struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; - struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; - int rc, sg_no_bidi = 0; - /* - * Locate the struct se_lun pointer based on v_req->lun, and - * attach it to struct se_cmd - */ - rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun); - if (rc < 0) { - pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun); - transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd, - tv_cmd->tvc_se_cmd.scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - - rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb); - if (rc == -ENOMEM) { - transport_send_check_condition_and_sense(se_cmd, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } else if (rc < 0) { - if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) - tcm_vhost_queue_status(se_cmd); - else - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - - if (tv_cmd->tvc_sgl_count) { - sg_ptr = tv_cmd->tvc_sgl; - /* - * For BIDI commands, pass in the extra READ buffer - * to transport_generic_map_mem_to_cmd() below.. - */ -/* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */ -#if 0 - if (se_cmd->se_cmd_flags & SCF_BIDI) { - sg_bidi_ptr = NULL; - sg_no_bidi = 0; - } -#endif - } else { - sg_ptr = NULL; - } - - rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr, - tv_cmd->tvc_sgl_count, sg_bidi_ptr, - sg_no_bidi); - if (rc < 0) { - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - transport_handle_cdb_direct(se_cmd); -} - -static void vhost_scsi_handle_vq(struct vhost_scsi *vs) -{ - struct vhost_virtqueue *vq = &vs->vqs[2]; - struct virtio_scsi_cmd_req v_req; - struct tcm_vhost_tpg *tv_tpg; - struct tcm_vhost_cmd *tv_cmd; - u32 exp_data_len, data_first, data_num, data_direction; - unsigned out, in, i; - int head, ret; - - /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */ - tv_tpg = vs->vs_tpg; - if (unlikely(!tv_tpg)) { - pr_err("%s endpoint not set\n", __func__); - return; - } - - mutex_lock(&vq->mutex); - vhost_disable_notify(&vs->dev, vq); - - for (;;) { - head = vhost_get_vq_desc(&vs->dev, vq, vq->iov, - ARRAY_SIZE(vq->iov), &out, &in, - NULL, NULL); - pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n", - head, out, in); - /* On error, stop handling until the next kick. */ - if (unlikely(head < 0)) - break; - /* Nothing new? Wait for eventfd to tell us they refilled. */ - if (head == vq->num) { - if (unlikely(vhost_enable_notify(&vs->dev, vq))) { - vhost_disable_notify(&vs->dev, vq); - continue; - } - break; - } - -/* FIXME: BIDI operation */ - if (out == 1 && in == 1) { - data_direction = DMA_NONE; - data_first = 0; - data_num = 0; - } else if (out == 1 && in > 1) { - data_direction = DMA_FROM_DEVICE; - data_first = out + 1; - data_num = in - 1; - } else if (out > 1 && in == 1) { - data_direction = DMA_TO_DEVICE; - data_first = 1; - data_num = out - 1; - } else { - vq_err(vq, "Invalid buffer layout out: %u in: %u\n", - out, in); - break; - } - - /* - * Check for a sane resp buffer so we can report errors to - * the guest. - */ - if (unlikely(vq->iov[out].iov_len != - sizeof(struct virtio_scsi_cmd_resp))) { - vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu" - " bytes\n", vq->iov[out].iov_len); - break; - } - - if (unlikely(vq->iov[0].iov_len != sizeof(v_req))) { - vq_err(vq, "Expecting virtio_scsi_cmd_req, got %zu" - " bytes\n", vq->iov[0].iov_len); - break; - } - pr_debug("Calling __copy_from_user: vq->iov[0].iov_base: %p," - " len: %zu\n", vq->iov[0].iov_base, sizeof(v_req)); - ret = __copy_from_user(&v_req, vq->iov[0].iov_base, - sizeof(v_req)); - if (unlikely(ret)) { - vq_err(vq, "Faulted on virtio_scsi_cmd_req\n"); - break; - } - - exp_data_len = 0; - for (i = 0; i < data_num; i++) - exp_data_len += vq->iov[data_first + i].iov_len; - - tv_cmd = vhost_scsi_allocate_cmd(tv_tpg, &v_req, - exp_data_len, data_direction); - if (IS_ERR(tv_cmd)) { - vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n", - PTR_ERR(tv_cmd)); - break; - } - pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction" - ": %d\n", tv_cmd, exp_data_len, data_direction); - - tv_cmd->tvc_vhost = vs; - - if (unlikely(vq->iov[out].iov_len != - sizeof(struct virtio_scsi_cmd_resp))) { - vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu" - " bytes, out: %d, in: %d\n", - vq->iov[out].iov_len, out, in); - break; - } - - tv_cmd->tvc_resp = vq->iov[out].iov_base; - - /* - * Copy in the recieved CDB descriptor into tv_cmd->tvc_cdb - * that will be used by tcm_vhost_new_cmd_map() and down into - * target_setup_cmd_from_cdb() - */ - memcpy(tv_cmd->tvc_cdb, v_req.cdb, TCM_VHOST_MAX_CDB_SIZE); - /* - * Check that the recieved CDB size does not exceeded our - * hardcoded max for tcm_vhost - */ - /* TODO what if cdb was too small for varlen cdb header? */ - if (unlikely(scsi_command_size(tv_cmd->tvc_cdb) > - TCM_VHOST_MAX_CDB_SIZE)) { - vq_err(vq, "Received SCSI CDB with command_size: %d that" - " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", - scsi_command_size(tv_cmd->tvc_cdb), - TCM_VHOST_MAX_CDB_SIZE); - break; /* TODO */ - } - tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF; - - pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", - tv_cmd->tvc_cdb[0], tv_cmd->tvc_lun); - - if (data_direction != DMA_NONE) { - ret = vhost_scsi_map_iov_to_sgl(tv_cmd, - &vq->iov[data_first], data_num, - data_direction == DMA_TO_DEVICE); - if (unlikely(ret)) { - vq_err(vq, "Failed to map iov to sgl\n"); - break; /* TODO */ - } - } - - /* - * Save the descriptor from vhost_get_vq_desc() to be used to - * complete the virtio-scsi request in TCM callback context via - * tcm_vhost_queue_data_in() and tcm_vhost_queue_status() - */ - tv_cmd->tvc_vq_desc = head; - /* - * Dispatch tv_cmd descriptor for cmwq execution in process - * context provided by tcm_vhost_workqueue. This also ensures - * tv_cmd is executed on the same kworker CPU as this vhost - * thread to gain positive L2 cache locality effects.. - */ - INIT_WORK(&tv_cmd->work, tcm_vhost_submission_work); - queue_work(tcm_vhost_workqueue, &tv_cmd->work); - } - - mutex_unlock(&vq->mutex); -} - -static void vhost_scsi_ctl_handle_kick(struct vhost_work *work) -{ - pr_err("%s: The handling func for control queue.\n", __func__); -} - -static void vhost_scsi_evt_handle_kick(struct vhost_work *work) -{ - pr_err("%s: The handling func for event queue.\n", __func__); -} - -static void vhost_scsi_handle_kick(struct vhost_work *work) -{ - struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue, - poll.work); - struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev); - - vhost_scsi_handle_vq(vs); -} - -/* - * Called from vhost_scsi_ioctl() context to walk the list of available - * tcm_vhost_tpg with an active struct tcm_vhost_nexus - */ -static int vhost_scsi_set_endpoint( - struct vhost_scsi *vs, - struct vhost_scsi_target *t) -{ - struct tcm_vhost_tport *tv_tport; - struct tcm_vhost_tpg *tv_tpg; - int index; - - mutex_lock(&vs->dev.mutex); - /* Verify that ring has been setup correctly. */ - for (index = 0; index < vs->dev.nvqs; ++index) { - /* Verify that ring has been setup correctly. */ - if (!vhost_vq_access_ok(&vs->vqs[index])) { - mutex_unlock(&vs->dev.mutex); - return -EFAULT; - } - } - - if (vs->vs_tpg) { - mutex_unlock(&vs->dev.mutex); - return -EEXIST; - } - mutex_unlock(&vs->dev.mutex); - - mutex_lock(&tcm_vhost_mutex); - list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { - mutex_lock(&tv_tpg->tv_tpg_mutex); - if (!tv_tpg->tpg_nexus) { - mutex_unlock(&tv_tpg->tv_tpg_mutex); - continue; - } - if (atomic_read(&tv_tpg->tv_tpg_vhost_count)) { - mutex_unlock(&tv_tpg->tv_tpg_mutex); - continue; - } - tv_tport = tv_tpg->tport; - - if (!strcmp(tv_tport->tport_name, t->vhost_wwpn) && - (tv_tpg->tport_tpgt == t->vhost_tpgt)) { - atomic_inc(&tv_tpg->tv_tpg_vhost_count); - smp_mb__after_atomic_inc(); - mutex_unlock(&tv_tpg->tv_tpg_mutex); - mutex_unlock(&tcm_vhost_mutex); - - mutex_lock(&vs->dev.mutex); - vs->vs_tpg = tv_tpg; - atomic_inc(&vs->vhost_ref_cnt); - smp_mb__after_atomic_inc(); - mutex_unlock(&vs->dev.mutex); - return 0; - } - mutex_unlock(&tv_tpg->tv_tpg_mutex); - } - mutex_unlock(&tcm_vhost_mutex); - return -EINVAL; -} - -static int vhost_scsi_clear_endpoint( - struct vhost_scsi *vs, - struct vhost_scsi_target *t) -{ - struct tcm_vhost_tport *tv_tport; - struct tcm_vhost_tpg *tv_tpg; - int index; - - mutex_lock(&vs->dev.mutex); - /* Verify that ring has been setup correctly. */ - for (index = 0; index < vs->dev.nvqs; ++index) { - if (!vhost_vq_access_ok(&vs->vqs[index])) { - mutex_unlock(&vs->dev.mutex); - return -EFAULT; - } - } - - if (!vs->vs_tpg) { - mutex_unlock(&vs->dev.mutex); - return -ENODEV; - } - tv_tpg = vs->vs_tpg; - tv_tport = tv_tpg->tport; - - if (strcmp(tv_tport->tport_name, t->vhost_wwpn) || - (tv_tpg->tport_tpgt != t->vhost_tpgt)) { - mutex_unlock(&vs->dev.mutex); - pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu" - " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n", - tv_tport->tport_name, tv_tpg->tport_tpgt, - t->vhost_wwpn, t->vhost_tpgt); - return -EINVAL; - } - atomic_dec(&tv_tpg->tv_tpg_vhost_count); - vs->vs_tpg = NULL; - mutex_unlock(&vs->dev.mutex); - - return 0; -} - -static int vhost_scsi_open(struct inode *inode, struct file *f) -{ - struct vhost_scsi *s; - int r; - - s = kzalloc(sizeof(*s), GFP_KERNEL); - if (!s) - return -ENOMEM; - - vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work); - INIT_LIST_HEAD(&s->vs_completion_list); - spin_lock_init(&s->vs_completion_lock); - - s->vqs[0].handle_kick = vhost_scsi_ctl_handle_kick; - s->vqs[1].handle_kick = vhost_scsi_evt_handle_kick; - s->vqs[2].handle_kick = vhost_scsi_handle_kick; - r = vhost_dev_init(&s->dev, s->vqs, 3); - if (r < 0) { - kfree(s); - return r; - } - - f->private_data = s; - return 0; -} - -static int vhost_scsi_release(struct inode *inode, struct file *f) -{ - struct vhost_scsi *s = f->private_data; - - if (s->vs_tpg && s->vs_tpg->tport) { - struct vhost_scsi_target backend; - - memcpy(backend.vhost_wwpn, s->vs_tpg->tport->tport_name, - sizeof(backend.vhost_wwpn)); - backend.vhost_tpgt = s->vs_tpg->tport_tpgt; - vhost_scsi_clear_endpoint(s, &backend); - } - - vhost_dev_cleanup(&s->dev, false); - kfree(s); - return 0; -} - -static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) -{ - if (features & ~VHOST_FEATURES) - return -EOPNOTSUPP; - - mutex_lock(&vs->dev.mutex); - if ((features & (1 << VHOST_F_LOG_ALL)) && - !vhost_log_access_ok(&vs->dev)) { - mutex_unlock(&vs->dev.mutex); - return -EFAULT; - } - vs->dev.acked_features = features; - /* TODO possibly smp_wmb() and flush vqs */ - mutex_unlock(&vs->dev.mutex); - return 0; -} - -static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, - unsigned long arg) -{ - struct vhost_scsi *vs = f->private_data; - struct vhost_scsi_target backend; - void __user *argp = (void __user *)arg; - u64 __user *featurep = argp; - u64 features; - int r; - - switch (ioctl) { - case VHOST_SCSI_SET_ENDPOINT: - if (copy_from_user(&backend, argp, sizeof backend)) - return -EFAULT; - - return vhost_scsi_set_endpoint(vs, &backend); - case VHOST_SCSI_CLEAR_ENDPOINT: - if (copy_from_user(&backend, argp, sizeof backend)) - return -EFAULT; - - return vhost_scsi_clear_endpoint(vs, &backend); - case VHOST_SCSI_GET_ABI_VERSION: - if (copy_from_user(&backend, argp, sizeof backend)) - return -EFAULT; - - backend.abi_version = VHOST_SCSI_ABI_VERSION; - - if (copy_to_user(argp, &backend, sizeof backend)) - return -EFAULT; - return 0; - case VHOST_GET_FEATURES: - features = VHOST_FEATURES; - if (copy_to_user(featurep, &features, sizeof features)) - return -EFAULT; - return 0; - case VHOST_SET_FEATURES: - if (copy_from_user(&features, featurep, sizeof features)) - return -EFAULT; - return vhost_scsi_set_features(vs, features); - default: - mutex_lock(&vs->dev.mutex); - r = vhost_dev_ioctl(&vs->dev, ioctl, arg); - mutex_unlock(&vs->dev.mutex); - return r; - } -} - -static const struct file_operations vhost_scsi_fops = { - .owner = THIS_MODULE, - .release = vhost_scsi_release, - .unlocked_ioctl = vhost_scsi_ioctl, - /* TODO compat ioctl? */ - .open = vhost_scsi_open, - .llseek = noop_llseek, -}; - -static struct miscdevice vhost_scsi_misc = { - MISC_DYNAMIC_MINOR, - "vhost-scsi", - &vhost_scsi_fops, -}; - -static int __init vhost_scsi_register(void) -{ - return misc_register(&vhost_scsi_misc); -} - -static int vhost_scsi_deregister(void) -{ - return misc_deregister(&vhost_scsi_misc); -} - -static char *tcm_vhost_dump_proto_id(struct tcm_vhost_tport *tport) -{ - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - return "SAS"; - case SCSI_PROTOCOL_FCP: - return "FCP"; - case SCSI_PROTOCOL_ISCSI: - return "iSCSI"; - default: - break; - } - - return "Unknown"; -} - -static int tcm_vhost_port_link( - struct se_portal_group *se_tpg, - struct se_lun *lun) -{ - struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - - atomic_inc(&tv_tpg->tv_tpg_port_count); - smp_mb__after_atomic_inc(); - - return 0; -} - -static void tcm_vhost_port_unlink( - struct se_portal_group *se_tpg, - struct se_lun *se_lun) -{ - struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - - atomic_dec(&tv_tpg->tv_tpg_port_count); - smp_mb__after_atomic_dec(); -} - -static struct se_node_acl *tcm_vhost_make_nodeacl( - struct se_portal_group *se_tpg, - struct config_group *group, - const char *name) -{ - struct se_node_acl *se_nacl, *se_nacl_new; - struct tcm_vhost_nacl *nacl; - u64 wwpn = 0; - u32 nexus_depth; - - /* tcm_vhost_parse_wwn(name, &wwpn, 1) < 0) - return ERR_PTR(-EINVAL); */ - se_nacl_new = tcm_vhost_alloc_fabric_acl(se_tpg); - if (!se_nacl_new) - return ERR_PTR(-ENOMEM); - - nexus_depth = 1; - /* - * se_nacl_new may be released by core_tpg_add_initiator_node_acl() - * when converting a NodeACL from demo mode -> explict - */ - se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new, - name, nexus_depth); - if (IS_ERR(se_nacl)) { - tcm_vhost_release_fabric_acl(se_tpg, se_nacl_new); - return se_nacl; - } - /* - * Locate our struct tcm_vhost_nacl and set the FC Nport WWPN - */ - nacl = container_of(se_nacl, struct tcm_vhost_nacl, se_node_acl); - nacl->iport_wwpn = wwpn; - - return se_nacl; -} - -static void tcm_vhost_drop_nodeacl(struct se_node_acl *se_acl) -{ - struct tcm_vhost_nacl *nacl = container_of(se_acl, - struct tcm_vhost_nacl, se_node_acl); - core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1); - kfree(nacl); -} - -static int tcm_vhost_make_nexus( - struct tcm_vhost_tpg *tv_tpg, - const char *name) -{ - struct se_portal_group *se_tpg; - struct tcm_vhost_nexus *tv_nexus; - - mutex_lock(&tv_tpg->tv_tpg_mutex); - if (tv_tpg->tpg_nexus) { - mutex_unlock(&tv_tpg->tv_tpg_mutex); - pr_debug("tv_tpg->tpg_nexus already exists\n"); - return -EEXIST; - } - se_tpg = &tv_tpg->se_tpg; - - tv_nexus = kzalloc(sizeof(struct tcm_vhost_nexus), GFP_KERNEL); - if (!tv_nexus) { - mutex_unlock(&tv_tpg->tv_tpg_mutex); - pr_err("Unable to allocate struct tcm_vhost_nexus\n"); - return -ENOMEM; - } - /* - * Initialize the struct se_session pointer - */ - tv_nexus->tvn_se_sess = transport_init_session(); - if (IS_ERR(tv_nexus->tvn_se_sess)) { - mutex_unlock(&tv_tpg->tv_tpg_mutex); - kfree(tv_nexus); - return -ENOMEM; - } - /* - * Since we are running in 'demo mode' this call with generate a - * struct se_node_acl for the tcm_vhost struct se_portal_group with - * the SCSI Initiator port name of the passed configfs group 'name'. - */ - tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl( - se_tpg, (unsigned char *)name); - if (!tv_nexus->tvn_se_sess->se_node_acl) { - mutex_unlock(&tv_tpg->tv_tpg_mutex); - pr_debug("core_tpg_check_initiator_node_acl() failed" - " for %s\n", name); - transport_free_session(tv_nexus->tvn_se_sess); - kfree(tv_nexus); - return -ENOMEM; - } - /* - * Now register the TCM vHost virtual I_T Nexus as active with the - * call to __transport_register_session() - */ - __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, - tv_nexus->tvn_se_sess, tv_nexus); - tv_tpg->tpg_nexus = tv_nexus; - - mutex_unlock(&tv_tpg->tv_tpg_mutex); - return 0; -} - -static int tcm_vhost_drop_nexus( - struct tcm_vhost_tpg *tpg) -{ - struct se_session *se_sess; - struct tcm_vhost_nexus *tv_nexus; - - mutex_lock(&tpg->tv_tpg_mutex); - tv_nexus = tpg->tpg_nexus; - if (!tv_nexus) { - mutex_unlock(&tpg->tv_tpg_mutex); - return -ENODEV; - } - - se_sess = tv_nexus->tvn_se_sess; - if (!se_sess) { - mutex_unlock(&tpg->tv_tpg_mutex); - return -ENODEV; - } - - if (atomic_read(&tpg->tv_tpg_port_count)) { - mutex_unlock(&tpg->tv_tpg_mutex); - pr_err("Unable to remove TCM_vHost I_T Nexus with" - " active TPG port count: %d\n", - atomic_read(&tpg->tv_tpg_port_count)); - return -EPERM; - } - - if (atomic_read(&tpg->tv_tpg_vhost_count)) { - mutex_unlock(&tpg->tv_tpg_mutex); - pr_err("Unable to remove TCM_vHost I_T Nexus with" - " active TPG vhost count: %d\n", - atomic_read(&tpg->tv_tpg_vhost_count)); - return -EPERM; - } - - pr_debug("TCM_vHost_ConfigFS: Removing I_T Nexus to emulated" - " %s Initiator Port: %s\n", tcm_vhost_dump_proto_id(tpg->tport), - tv_nexus->tvn_se_sess->se_node_acl->initiatorname); - /* - * Release the SCSI I_T Nexus to the emulated vHost Target Port - */ - transport_deregister_session(tv_nexus->tvn_se_sess); - tpg->tpg_nexus = NULL; - mutex_unlock(&tpg->tv_tpg_mutex); - - kfree(tv_nexus); - return 0; -} - -static ssize_t tcm_vhost_tpg_show_nexus( - struct se_portal_group *se_tpg, - char *page) -{ - struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - struct tcm_vhost_nexus *tv_nexus; - ssize_t ret; - - mutex_lock(&tv_tpg->tv_tpg_mutex); - tv_nexus = tv_tpg->tpg_nexus; - if (!tv_nexus) { - mutex_unlock(&tv_tpg->tv_tpg_mutex); - return -ENODEV; - } - ret = snprintf(page, PAGE_SIZE, "%s\n", - tv_nexus->tvn_se_sess->se_node_acl->initiatorname); - mutex_unlock(&tv_tpg->tv_tpg_mutex); - - return ret; -} - -static ssize_t tcm_vhost_tpg_store_nexus( - struct se_portal_group *se_tpg, - const char *page, - size_t count) -{ - struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - struct tcm_vhost_tport *tport_wwn = tv_tpg->tport; - unsigned char i_port[TCM_VHOST_NAMELEN], *ptr, *port_ptr; - int ret; - /* - * Shutdown the active I_T nexus if 'NULL' is passed.. - */ - if (!strncmp(page, "NULL", 4)) { - ret = tcm_vhost_drop_nexus(tv_tpg); - return (!ret) ? count : ret; - } - /* - * Otherwise make sure the passed virtual Initiator port WWN matches - * the fabric protocol_id set in tcm_vhost_make_tport(), and call - * tcm_vhost_make_nexus(). - */ - if (strlen(page) >= TCM_VHOST_NAMELEN) { - pr_err("Emulated NAA Sas Address: %s, exceeds" - " max: %d\n", page, TCM_VHOST_NAMELEN); - return -EINVAL; - } - snprintf(&i_port[0], TCM_VHOST_NAMELEN, "%s", page); - - ptr = strstr(i_port, "naa."); - if (ptr) { - if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) { - pr_err("Passed SAS Initiator Port %s does not" - " match target port protoid: %s\n", i_port, - tcm_vhost_dump_proto_id(tport_wwn)); - return -EINVAL; - } - port_ptr = &i_port[0]; - goto check_newline; - } - ptr = strstr(i_port, "fc."); - if (ptr) { - if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) { - pr_err("Passed FCP Initiator Port %s does not" - " match target port protoid: %s\n", i_port, - tcm_vhost_dump_proto_id(tport_wwn)); - return -EINVAL; - } - port_ptr = &i_port[3]; /* Skip over "fc." */ - goto check_newline; - } - ptr = strstr(i_port, "iqn."); - if (ptr) { - if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) { - pr_err("Passed iSCSI Initiator Port %s does not" - " match target port protoid: %s\n", i_port, - tcm_vhost_dump_proto_id(tport_wwn)); - return -EINVAL; - } - port_ptr = &i_port[0]; - goto check_newline; - } - pr_err("Unable to locate prefix for emulated Initiator Port:" - " %s\n", i_port); - return -EINVAL; - /* - * Clear any trailing newline for the NAA WWN - */ -check_newline: - if (i_port[strlen(i_port)-1] == '\n') - i_port[strlen(i_port)-1] = '\0'; - - ret = tcm_vhost_make_nexus(tv_tpg, port_ptr); - if (ret < 0) - return ret; - - return count; -} - -TF_TPG_BASE_ATTR(tcm_vhost, nexus, S_IRUGO | S_IWUSR); - -static struct configfs_attribute *tcm_vhost_tpg_attrs[] = { - &tcm_vhost_tpg_nexus.attr, - NULL, -}; - -static struct se_portal_group *tcm_vhost_make_tpg( - struct se_wwn *wwn, - struct config_group *group, - const char *name) -{ - struct tcm_vhost_tport *tport = container_of(wwn, - struct tcm_vhost_tport, tport_wwn); - - struct tcm_vhost_tpg *tpg; - unsigned long tpgt; - int ret; - - if (strstr(name, "tpgt_") != name) - return ERR_PTR(-EINVAL); - if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX) - return ERR_PTR(-EINVAL); - - tpg = kzalloc(sizeof(struct tcm_vhost_tpg), GFP_KERNEL); - if (!tpg) { - pr_err("Unable to allocate struct tcm_vhost_tpg"); - return ERR_PTR(-ENOMEM); - } - mutex_init(&tpg->tv_tpg_mutex); - INIT_LIST_HEAD(&tpg->tv_tpg_list); - tpg->tport = tport; - tpg->tport_tpgt = tpgt; - - ret = core_tpg_register(&tcm_vhost_fabric_configfs->tf_ops, wwn, - &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); - if (ret < 0) { - kfree(tpg); - return NULL; - } - mutex_lock(&tcm_vhost_mutex); - list_add_tail(&tpg->tv_tpg_list, &tcm_vhost_list); - mutex_unlock(&tcm_vhost_mutex); - - return &tpg->se_tpg; -} - -static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg) -{ - struct tcm_vhost_tpg *tpg = container_of(se_tpg, - struct tcm_vhost_tpg, se_tpg); - - mutex_lock(&tcm_vhost_mutex); - list_del(&tpg->tv_tpg_list); - mutex_unlock(&tcm_vhost_mutex); - /* - * Release the virtual I_T Nexus for this vHost TPG - */ - tcm_vhost_drop_nexus(tpg); - /* - * Deregister the se_tpg from TCM.. - */ - core_tpg_deregister(se_tpg); - kfree(tpg); -} - -static struct se_wwn *tcm_vhost_make_tport( - struct target_fabric_configfs *tf, - struct config_group *group, - const char *name) -{ - struct tcm_vhost_tport *tport; - char *ptr; - u64 wwpn = 0; - int off = 0; - - /* if (tcm_vhost_parse_wwn(name, &wwpn, 1) < 0) - return ERR_PTR(-EINVAL); */ - - tport = kzalloc(sizeof(struct tcm_vhost_tport), GFP_KERNEL); - if (!tport) { - pr_err("Unable to allocate struct tcm_vhost_tport"); - return ERR_PTR(-ENOMEM); - } - tport->tport_wwpn = wwpn; - /* - * Determine the emulated Protocol Identifier and Target Port Name - * based on the incoming configfs directory name. - */ - ptr = strstr(name, "naa."); - if (ptr) { - tport->tport_proto_id = SCSI_PROTOCOL_SAS; - goto check_len; - } - ptr = strstr(name, "fc."); - if (ptr) { - tport->tport_proto_id = SCSI_PROTOCOL_FCP; - off = 3; /* Skip over "fc." */ - goto check_len; - } - ptr = strstr(name, "iqn."); - if (ptr) { - tport->tport_proto_id = SCSI_PROTOCOL_ISCSI; - goto check_len; - } - - pr_err("Unable to locate prefix for emulated Target Port:" - " %s\n", name); - kfree(tport); - return ERR_PTR(-EINVAL); - -check_len: - if (strlen(name) >= TCM_VHOST_NAMELEN) { - pr_err("Emulated %s Address: %s, exceeds" - " max: %d\n", name, tcm_vhost_dump_proto_id(tport), - TCM_VHOST_NAMELEN); - kfree(tport); - return ERR_PTR(-EINVAL); - } - snprintf(&tport->tport_name[0], TCM_VHOST_NAMELEN, "%s", &name[off]); - - pr_debug("TCM_VHost_ConfigFS: Allocated emulated Target" - " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), name); - - return &tport->tport_wwn; -} - -static void tcm_vhost_drop_tport(struct se_wwn *wwn) -{ - struct tcm_vhost_tport *tport = container_of(wwn, - struct tcm_vhost_tport, tport_wwn); - - pr_debug("TCM_VHost_ConfigFS: Deallocating emulated Target" - " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), - tport->tport_name); - - kfree(tport); -} - -static ssize_t tcm_vhost_wwn_show_attr_version( - struct target_fabric_configfs *tf, - char *page) -{ - return sprintf(page, "TCM_VHOST fabric module %s on %s/%s" - "on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname, - utsname()->machine); -} - -TF_WWN_ATTR_RO(tcm_vhost, version); - -static struct configfs_attribute *tcm_vhost_wwn_attrs[] = { - &tcm_vhost_wwn_version.attr, - NULL, -}; - -static struct target_core_fabric_ops tcm_vhost_ops = { - .get_fabric_name = tcm_vhost_get_fabric_name, - .get_fabric_proto_ident = tcm_vhost_get_fabric_proto_ident, - .tpg_get_wwn = tcm_vhost_get_fabric_wwn, - .tpg_get_tag = tcm_vhost_get_tag, - .tpg_get_default_depth = tcm_vhost_get_default_depth, - .tpg_get_pr_transport_id = tcm_vhost_get_pr_transport_id, - .tpg_get_pr_transport_id_len = tcm_vhost_get_pr_transport_id_len, - .tpg_parse_pr_out_transport_id = tcm_vhost_parse_pr_out_transport_id, - .tpg_check_demo_mode = tcm_vhost_check_true, - .tpg_check_demo_mode_cache = tcm_vhost_check_true, - .tpg_check_demo_mode_write_protect = tcm_vhost_check_false, - .tpg_check_prod_mode_write_protect = tcm_vhost_check_false, - .tpg_alloc_fabric_acl = tcm_vhost_alloc_fabric_acl, - .tpg_release_fabric_acl = tcm_vhost_release_fabric_acl, - .tpg_get_inst_index = tcm_vhost_tpg_get_inst_index, - .release_cmd = tcm_vhost_release_cmd, - .shutdown_session = tcm_vhost_shutdown_session, - .close_session = tcm_vhost_close_session, - .sess_get_index = tcm_vhost_sess_get_index, - .sess_get_initiator_sid = NULL, - .write_pending = tcm_vhost_write_pending, - .write_pending_status = tcm_vhost_write_pending_status, - .set_default_node_attributes = tcm_vhost_set_default_node_attrs, - .get_task_tag = tcm_vhost_get_task_tag, - .get_cmd_state = tcm_vhost_get_cmd_state, - .queue_data_in = tcm_vhost_queue_data_in, - .queue_status = tcm_vhost_queue_status, - .queue_tm_rsp = tcm_vhost_queue_tm_rsp, - .get_fabric_sense_len = tcm_vhost_get_fabric_sense_len, - .set_fabric_sense_len = tcm_vhost_set_fabric_sense_len, - /* - * Setup callers for generic logic in target_core_fabric_configfs.c - */ - .fabric_make_wwn = tcm_vhost_make_tport, - .fabric_drop_wwn = tcm_vhost_drop_tport, - .fabric_make_tpg = tcm_vhost_make_tpg, - .fabric_drop_tpg = tcm_vhost_drop_tpg, - .fabric_post_link = tcm_vhost_port_link, - .fabric_pre_unlink = tcm_vhost_port_unlink, - .fabric_make_np = NULL, - .fabric_drop_np = NULL, - .fabric_make_nodeacl = tcm_vhost_make_nodeacl, - .fabric_drop_nodeacl = tcm_vhost_drop_nodeacl, -}; - -static int tcm_vhost_register_configfs(void) -{ - struct target_fabric_configfs *fabric; - int ret; - - pr_debug("TCM_VHOST fabric module %s on %s/%s" - " on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname, - utsname()->machine); - /* - * Register the top level struct config_item_type with TCM core - */ - fabric = target_fabric_configfs_init(THIS_MODULE, "vhost"); - if (IS_ERR(fabric)) { - pr_err("target_fabric_configfs_init() failed\n"); - return PTR_ERR(fabric); - } - /* - * Setup fabric->tf_ops from our local tcm_vhost_ops - */ - fabric->tf_ops = tcm_vhost_ops; - /* - * Setup default attribute lists for various fabric->tf_cit_tmpl - */ - TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_vhost_wwn_attrs; - TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_vhost_tpg_attrs; - TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL; - /* - * Register the fabric for use within TCM - */ - ret = target_fabric_configfs_register(fabric); - if (ret < 0) { - pr_err("target_fabric_configfs_register() failed" - " for TCM_VHOST\n"); - return ret; - } - /* - * Setup our local pointer to *fabric - */ - tcm_vhost_fabric_configfs = fabric; - pr_debug("TCM_VHOST[0] - Set fabric -> tcm_vhost_fabric_configfs\n"); - return 0; -}; - -static void tcm_vhost_deregister_configfs(void) -{ - if (!tcm_vhost_fabric_configfs) - return; - - target_fabric_configfs_deregister(tcm_vhost_fabric_configfs); - tcm_vhost_fabric_configfs = NULL; - pr_debug("TCM_VHOST[0] - Cleared tcm_vhost_fabric_configfs\n"); -}; - -static int __init tcm_vhost_init(void) -{ - int ret = -ENOMEM; - - tcm_vhost_workqueue = alloc_workqueue("tcm_vhost", 0, 0); - if (!tcm_vhost_workqueue) - goto out; - - ret = vhost_scsi_register(); - if (ret < 0) - goto out_destroy_workqueue; - - ret = tcm_vhost_register_configfs(); - if (ret < 0) - goto out_vhost_scsi_deregister; - - return 0; - -out_vhost_scsi_deregister: - vhost_scsi_deregister(); -out_destroy_workqueue: - destroy_workqueue(tcm_vhost_workqueue); -out: - return ret; -}; - -static void tcm_vhost_exit(void) -{ - tcm_vhost_deregister_configfs(); - vhost_scsi_deregister(); - destroy_workqueue(tcm_vhost_workqueue); -}; - -MODULE_DESCRIPTION("TCM_VHOST series fabric driver"); -MODULE_LICENSE("GPL"); -module_init(tcm_vhost_init); -module_exit(tcm_vhost_exit); diff --git a/trunk/drivers/vhost/tcm_vhost.h b/trunk/drivers/vhost/tcm_vhost.h deleted file mode 100644 index c983ed21e413..000000000000 --- a/trunk/drivers/vhost/tcm_vhost.h +++ /dev/null @@ -1,101 +0,0 @@ -#define TCM_VHOST_VERSION "v0.1" -#define TCM_VHOST_NAMELEN 256 -#define TCM_VHOST_MAX_CDB_SIZE 32 - -struct tcm_vhost_cmd { - /* Descriptor from vhost_get_vq_desc() for virt_queue segment */ - int tvc_vq_desc; - /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */ - u64 tvc_tag; - /* The number of scatterlists associated with this cmd */ - u32 tvc_sgl_count; - /* Saved unpacked SCSI LUN for tcm_vhost_submission_work() */ - u32 tvc_lun; - /* Pointer to the SGL formatted memory from virtio-scsi */ - struct scatterlist *tvc_sgl; - /* Pointer to response */ - struct virtio_scsi_cmd_resp __user *tvc_resp; - /* Pointer to vhost_scsi for our device */ - struct vhost_scsi *tvc_vhost; - /* The TCM I/O descriptor that is accessed via container_of() */ - struct se_cmd tvc_se_cmd; - /* work item used for cmwq dispatch to tcm_vhost_submission_work() */ - struct work_struct work; - /* Copy of the incoming SCSI command descriptor block (CDB) */ - unsigned char tvc_cdb[TCM_VHOST_MAX_CDB_SIZE]; - /* Sense buffer that will be mapped into outgoing status */ - unsigned char tvc_sense_buf[TRANSPORT_SENSE_BUFFER]; - /* Completed commands list, serviced from vhost worker thread */ - struct list_head tvc_completion_list; -}; - -struct tcm_vhost_nexus { - /* Pointer to TCM session for I_T Nexus */ - struct se_session *tvn_se_sess; -}; - -struct tcm_vhost_nacl { - /* Binary World Wide unique Port Name for Vhost Initiator port */ - u64 iport_wwpn; - /* ASCII formatted WWPN for Sas Initiator port */ - char iport_name[TCM_VHOST_NAMELEN]; - /* Returned by tcm_vhost_make_nodeacl() */ - struct se_node_acl se_node_acl; -}; - -struct tcm_vhost_tpg { - /* Vhost port target portal group tag for TCM */ - u16 tport_tpgt; - /* Used to track number of TPG Port/Lun Links wrt to explict I_T Nexus shutdown */ - atomic_t tv_tpg_port_count; - /* Used for vhost_scsi device reference to tpg_nexus */ - atomic_t tv_tpg_vhost_count; - /* list for tcm_vhost_list */ - struct list_head tv_tpg_list; - /* Used to protect access for tpg_nexus */ - struct mutex tv_tpg_mutex; - /* Pointer to the TCM VHost I_T Nexus for this TPG endpoint */ - struct tcm_vhost_nexus *tpg_nexus; - /* Pointer back to tcm_vhost_tport */ - struct tcm_vhost_tport *tport; - /* Returned by tcm_vhost_make_tpg() */ - struct se_portal_group se_tpg; -}; - -struct tcm_vhost_tport { - /* SCSI protocol the tport is providing */ - u8 tport_proto_id; - /* Binary World Wide unique Port Name for Vhost Target port */ - u64 tport_wwpn; - /* ASCII formatted WWPN for Vhost Target port */ - char tport_name[TCM_VHOST_NAMELEN]; - /* Returned by tcm_vhost_make_tport() */ - struct se_wwn tport_wwn; -}; - -/* - * As per request from MST, keep TCM_VHOST related ioctl defines out of - * linux/vhost.h (user-space) for now.. - */ - -#include - -/* - * Used by QEMU userspace to ensure a consistent vhost-scsi ABI. - * - * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate + - * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage - */ - -#define VHOST_SCSI_ABI_VERSION 0 - -struct vhost_scsi_target { - int abi_version; - unsigned char vhost_wwpn[TRANSPORT_IQN_LEN]; - unsigned short vhost_tpgt; -}; - -/* VHOST_SCSI specific defines */ -#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target) -#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target) -#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, struct vhost_scsi_target) diff --git a/trunk/drivers/watchdog/orion_wdt.c b/trunk/drivers/watchdog/orion_wdt.c index c20f96b579d9..a73bea4aa1ba 100644 --- a/trunk/drivers/watchdog/orion_wdt.c +++ b/trunk/drivers/watchdog/orion_wdt.c @@ -24,7 +24,6 @@ #include #include #include -#include #include /* @@ -193,12 +192,6 @@ static void orion_wdt_shutdown(struct platform_device *pdev) orion_wdt_stop(&orion_wdt); } -static const struct of_device_id orion_wdt_of_match_table[] __devinitdata = { - { .compatible = "marvell,orion-wdt", }, - {}, -}; -MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table); - static struct platform_driver orion_wdt_driver = { .probe = orion_wdt_probe, .remove = __devexit_p(orion_wdt_remove), @@ -206,7 +199,6 @@ static struct platform_driver orion_wdt_driver = { .driver = { .owner = THIS_MODULE, .name = "orion_wdt", - .of_match_table = of_match_ptr(orion_wdt_of_match_table), }, }; diff --git a/trunk/drivers/zorro/zorro.c b/trunk/drivers/zorro/zorro.c index 858c9714b2f3..181fa8158a8b 100644 --- a/trunk/drivers/zorro/zorro.c +++ b/trunk/drivers/zorro/zorro.c @@ -37,6 +37,7 @@ struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO]; */ struct zorro_bus { + struct list_head devices; /* list of devices on this bus */ struct device dev; }; @@ -135,6 +136,7 @@ static int __init amiga_zorro_probe(struct platform_device *pdev) if (!bus) return -ENOMEM; + INIT_LIST_HEAD(&bus->devices); bus->dev.parent = &pdev->dev; dev_set_name(&bus->dev, "zorro"); error = device_register(&bus->dev); diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 5eaa70c9d96e..73922abba832 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -1312,7 +1312,7 @@ EXPORT_SYMBOL(bio_copy_kern); * Note that this code is very hard to test under normal circumstances because * direct-io pins the pages with get_user_pages(). This makes * is_page_cache_freeable return false, and the VM will not clean the pages. - * But other code (eg, flusher threads) could clean the pages if they are mapped + * But other code (eg, pdflush) could clean the pages if they are mapped * pagecache. * * Simply disabling the call to bio_set_pages_dirty() is a good way to test the diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 6e8f416773d4..83baec24946d 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -324,8 +324,7 @@ static noinline int add_async_extent(struct async_cow *cow, * If this code finds it can't get good compression, it puts an * entry onto the work queue to write the uncompressed bytes. This * makes sure that both compressed inodes and uncompressed inodes - * are written in the same order that the flusher thread sent them - * down. + * are written in the same order that pdflush sent them down. */ static noinline int compress_file_range(struct inode *inode, struct page *locked_page, diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 7bb755677a22..bc2f6ffff3cf 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -664,6 +664,10 @@ static noinline int btrfs_mksubvol(struct path *parent, struct dentry *dentry; int error; + error = mnt_want_write(parent->mnt); + if (error) + return error; + mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); dentry = lookup_one_len(name, parent->dentry, namelen); @@ -699,6 +703,7 @@ static noinline int btrfs_mksubvol(struct path *parent, dput(dentry); out_unlock: mutex_unlock(&dir->i_mutex); + mnt_drop_write(parent->mnt); return error; } diff --git a/trunk/fs/btrfs/ordered-data.c b/trunk/fs/btrfs/ordered-data.c index 051c7fe551dd..643335a4fe3c 100644 --- a/trunk/fs/btrfs/ordered-data.c +++ b/trunk/fs/btrfs/ordered-data.c @@ -596,7 +596,7 @@ void btrfs_start_ordered_extent(struct inode *inode, /* * pages in the range can be dirty, clean or writeback. We * start IO on any dirty ones so the wait doesn't stall waiting - * for the flusher thread to find them + * for pdflush to find them */ if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags)) filemap_fdatawrite_range(inode->i_mapping, start, end); diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index f2eb24c477a3..8c6e61d6eed5 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -100,6 +100,10 @@ static void __save_error_info(struct btrfs_fs_info *fs_info) fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; } +/* NOTE: + * We move write_super stuff at umount in order to avoid deadlock + * for umount hold all lock. + */ static void save_error_info(struct btrfs_fs_info *fs_info) { __save_error_info(fs_info); diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index e86ae04abe6a..b8708f994e67 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -1744,6 +1744,10 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) device->fs_devices = root->fs_info->fs_devices; + /* + * we don't want write_supers to jump in here with our device + * half setup + */ mutex_lock(&root->fs_info->fs_devices->device_list_mutex); list_add_rcu(&device->dev_list, &root->fs_info->fs_devices->devices); list_add(&device->dev_alloc_list, diff --git a/trunk/fs/ceph/dir.c b/trunk/fs/ceph/dir.c index e5b77319c97b..f391f1e75414 100644 --- a/trunk/fs/ceph/dir.c +++ b/trunk/fs/ceph/dir.c @@ -633,6 +633,44 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, return dentry; } +int ceph_atomic_open(struct inode *dir, struct dentry *dentry, + struct file *file, unsigned flags, umode_t mode, + int *opened) +{ + int err; + struct dentry *res = NULL; + + if (!(flags & O_CREAT)) { + if (dentry->d_name.len > NAME_MAX) + return -ENAMETOOLONG; + + err = ceph_init_dentry(dentry); + if (err < 0) + return err; + + return ceph_lookup_open(dir, dentry, file, flags, mode, opened); + } + + if (d_unhashed(dentry)) { + res = ceph_lookup(dir, dentry, 0); + if (IS_ERR(res)) + return PTR_ERR(res); + + if (res) + dentry = res; + } + + /* We don't deal with positive dentries here */ + if (dentry->d_inode) + return finish_no_open(file, res); + + *opened |= FILE_CREATED; + err = ceph_lookup_open(dir, dentry, file, flags, mode, opened); + dput(res); + + return err; +} + /* * If we do a create but get no trace back from the MDS, follow up with * a lookup (the VFS expects us to link up the provided dentry). diff --git a/trunk/fs/ceph/file.c b/trunk/fs/ceph/file.c index ecebbc09bfc7..1b81d6c31878 100644 --- a/trunk/fs/ceph/file.c +++ b/trunk/fs/ceph/file.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -107,6 +106,9 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode) } /* + * If the filp already has private_data, that means the file was + * already opened by intent during lookup, and we do nothing. + * * If we already have the requisite capabilities, we can satisfy * the open request locally (no need to request new caps from the * MDS). We do, however, need to inform the MDS (asynchronously) @@ -205,29 +207,24 @@ int ceph_open(struct inode *inode, struct file *file) /* - * Do a lookup + open with a single request. If we get a non-existent - * file or symlink, return 1 so the VFS can retry. + * Do a lookup + open with a single request. + * + * If this succeeds, but some subsequent check in the vfs + * may_open() fails, the struct *file gets cleaned up (i.e. + * ceph_release gets called). So fear not! */ -int ceph_atomic_open(struct inode *dir, struct dentry *dentry, +int ceph_lookup_open(struct inode *dir, struct dentry *dentry, struct file *file, unsigned flags, umode_t mode, int *opened) { struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); struct ceph_mds_client *mdsc = fsc->mdsc; struct ceph_mds_request *req; - struct dentry *dn; + struct dentry *ret; int err; - dout("atomic_open %p dentry %p '%.*s' %s flags %d mode 0%o\n", - dir, dentry, dentry->d_name.len, dentry->d_name.name, - d_unhashed(dentry) ? "unhashed" : "hashed", flags, mode); - - if (dentry->d_name.len > NAME_MAX) - return -ENAMETOOLONG; - - err = ceph_init_dentry(dentry); - if (err < 0) - return err; + dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n", + dentry, dentry->d_name.len, dentry->d_name.name, flags, mode); /* do the open */ req = prepare_open_request(dir->i_sb, flags, mode); @@ -244,31 +241,22 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, req); err = ceph_handle_snapdir(req, dentry, err); - if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry) + if (err) + goto out; + if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry) err = ceph_handle_notrace_create(dir, dentry); - - if (d_unhashed(dentry)) { - dn = ceph_finish_lookup(req, dentry, err); - if (IS_ERR(dn)) - err = PTR_ERR(dn); - } else { - /* we were given a hashed negative dentry */ - dn = NULL; - } if (err) - goto out_err; - if (dn || dentry->d_inode == NULL || S_ISLNK(dentry->d_inode->i_mode)) { - /* make vfs retry on splice, ENOENT, or symlink */ - dout("atomic_open finish_no_open on dn %p\n", dn); - err = finish_no_open(file, dn); - } else { - dout("atomic_open finish_open on dn %p\n", dn); - err = finish_open(file, dentry, ceph_open, opened); - } - -out_err: + goto out; + err = finish_open(file, req->r_dentry, ceph_open, opened); +out: + ret = ceph_finish_lookup(req, dentry, err); ceph_mdsc_put_request(req); - dout("atomic_open result=%d\n", err); + dout("ceph_lookup_open result=%p\n", ret); + + if (IS_ERR(ret)) + return PTR_ERR(ret); + + dput(ret); return err; } diff --git a/trunk/fs/ceph/super.h b/trunk/fs/ceph/super.h index 66ebe720e40d..ebc95cc652be 100644 --- a/trunk/fs/ceph/super.h +++ b/trunk/fs/ceph/super.h @@ -806,9 +806,9 @@ extern int ceph_copy_from_page_vector(struct page **pages, loff_t off, size_t len); extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); extern int ceph_open(struct inode *inode, struct file *file); -extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry, - struct file *file, unsigned flags, umode_t mode, - int *opened); +extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry, + struct file *od, unsigned flags, + umode_t mode, int *opened); extern int ceph_release(struct inode *inode, struct file *filp); /* dir.c */ diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index 977dc0e85ccb..497da5ce704c 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -246,16 +246,6 @@ struct smb_version_operations { bool (*can_echo)(struct TCP_Server_Info *); /* send echo request */ int (*echo)(struct TCP_Server_Info *); - /* create directory */ - int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *, - struct cifs_sb_info *); - /* set info on created directory */ - void (*mkdir_setinfo)(struct inode *, const char *, - struct cifs_sb_info *, struct cifs_tcon *, - const unsigned int); - /* remove directory */ - int (*rmdir)(const unsigned int, struct cifs_tcon *, const char *, - struct cifs_sb_info *); }; struct smb_version_values { diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index f1bbf8305d3a..cf7fb185103c 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -289,15 +289,18 @@ extern int CIFSSMBUnixSetFileInfo(const unsigned int xid, u16 fid, u32 pid_of_opener); extern int CIFSSMBUnixSetPathInfo(const unsigned int xid, - struct cifs_tcon *tcon, const char *file_name, + struct cifs_tcon *tcon, char *file_name, const struct cifs_unix_set_info_args *args, const struct nls_table *nls_codepage, - int remap); + int remap_special_chars); extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, - const char *name, struct cifs_sb_info *cifs_sb); + const char *newName, + const struct nls_table *nls_codepage, + int remap_special_chars); extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, - const char *name, struct cifs_sb_info *cifs_sb); + const char *name, const struct nls_table *nls_codepage, + int remap_special_chars); extern int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name, __u16 type, const struct nls_table *nls_codepage, diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 074923ce593d..cabc7a01f5df 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -948,15 +948,15 @@ CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, } int -CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, - struct cifs_sb_info *cifs_sb) +CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, + const char *dirName, const struct nls_table *nls_codepage, + int remap) { DELETE_DIRECTORY_REQ *pSMB = NULL; DELETE_DIRECTORY_RSP *pSMBr = NULL; int rc = 0; int bytes_returned; int name_len; - int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; cFYI(1, "In CIFSSMBRmDir"); RmDirRetry: @@ -966,15 +966,14 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, return rc; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { - name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, - PATH_MAX, cifs_sb->local_nls, - remap); + name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, dirName, + PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve check for buffer overruns BB */ - name_len = strnlen(name, PATH_MAX); + name_len = strnlen(dirName, PATH_MAX); name_len++; /* trailing null */ - strncpy(pSMB->DirName, name, name_len); + strncpy(pSMB->DirName, dirName, name_len); } pSMB->BufferFormat = 0x04; @@ -993,15 +992,14 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, } int -CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, - struct cifs_sb_info *cifs_sb) +CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, + const char *name, const struct nls_table *nls_codepage, int remap) { int rc = 0; CREATE_DIRECTORY_REQ *pSMB = NULL; CREATE_DIRECTORY_RSP *pSMBr = NULL; int bytes_returned; int name_len; - int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; cFYI(1, "In CIFSSMBMkDir"); MkDirRetry: @@ -1012,8 +1010,7 @@ CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, - PATH_MAX, cifs_sb->local_nls, - remap); + PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve check for buffer overruns BB */ @@ -5946,7 +5943,7 @@ CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, int CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, - const char *file_name, + char *fileName, const struct cifs_unix_set_info_args *args, const struct nls_table *nls_codepage, int remap) { @@ -5967,14 +5964,14 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, + cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(file_name, PATH_MAX); + name_len = strnlen(fileName, PATH_MAX); name_len++; /* trailing null */ - strncpy(pSMB->FileName, file_name, name_len); + strncpy(pSMB->FileName, fileName, name_len); } params = 6 + name_len; diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 7354877fa3bd..35cb6a374a45 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -1219,153 +1219,16 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) return rc; } -static int -cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, - const char *full_path, struct cifs_sb_info *cifs_sb, - struct cifs_tcon *tcon, const unsigned int xid) -{ - int rc = 0; - struct inode *newinode = NULL; - - if (tcon->unix_ext) - rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, - xid); - else - rc = cifs_get_inode_info(&newinode, full_path, NULL, - inode->i_sb, xid, NULL); - if (rc) - return rc; - - d_instantiate(dentry, newinode); - /* - * setting nlink not necessary except in cases where we failed to get it - * from the server or was set bogus - */ - if ((dentry->d_inode) && (dentry->d_inode->i_nlink < 2)) - set_nlink(dentry->d_inode, 2); - - mode &= ~current_umask(); - /* must turn on setgid bit if parent dir has it */ - if (inode->i_mode & S_ISGID) - mode |= S_ISGID; - - if (tcon->unix_ext) { - struct cifs_unix_set_info_args args = { - .mode = mode, - .ctime = NO_CHANGE_64, - .atime = NO_CHANGE_64, - .mtime = NO_CHANGE_64, - .device = 0, - }; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { - args.uid = (__u64)current_fsuid(); - if (inode->i_mode & S_ISGID) - args.gid = (__u64)inode->i_gid; - else - args.gid = (__u64)current_fsgid(); - } else { - args.uid = NO_CHANGE_64; - args.gid = NO_CHANGE_64; - } - CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - } else { - struct TCP_Server_Info *server = tcon->ses->server; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && - (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) - server->ops->mkdir_setinfo(newinode, full_path, cifs_sb, - tcon, xid); - if (dentry->d_inode) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) - dentry->d_inode->i_mode = (mode | S_IFDIR); - - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { - dentry->d_inode->i_uid = current_fsuid(); - if (inode->i_mode & S_ISGID) - dentry->d_inode->i_gid = inode->i_gid; - else - dentry->d_inode->i_gid = - current_fsgid(); - } - } - } - return rc; -} - -static int -cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode, - const char *full_path, struct cifs_sb_info *cifs_sb, - struct cifs_tcon *tcon, const unsigned int xid) -{ - int rc = 0; - u32 oplock = 0; - FILE_UNIX_BASIC_INFO *info = NULL; - struct inode *newinode = NULL; - struct cifs_fattr fattr; - - info = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); - if (info == NULL) { - rc = -ENOMEM; - goto posix_mkdir_out; - } - - mode &= ~current_umask(); - rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT, mode, - NULL /* netfid */, info, &oplock, full_path, - cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - if (rc == -EOPNOTSUPP) - goto posix_mkdir_out; - else if (rc) { - cFYI(1, "posix mkdir returned 0x%x", rc); - d_drop(dentry); - goto posix_mkdir_out; - } - - if (info->Type == cpu_to_le32(-1)) - /* no return info, go query for it */ - goto posix_mkdir_get_info; - /* - * BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if - * need to set uid/gid. - */ - - cifs_unix_basic_to_fattr(&fattr, info, cifs_sb); - cifs_fill_uniqueid(inode->i_sb, &fattr); - newinode = cifs_iget(inode->i_sb, &fattr); - if (!newinode) - goto posix_mkdir_get_info; - - d_instantiate(dentry, newinode); - -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, "instantiated dentry %p %s to inode %p", dentry, - dentry->d_name.name, newinode); - - if (newinode->i_nlink != 2) - cFYI(1, "unexpected number of links %d", newinode->i_nlink); -#endif - -posix_mkdir_out: - kfree(info); - return rc; -posix_mkdir_get_info: - rc = cifs_mkdir_qinfo(inode, dentry, mode, full_path, cifs_sb, tcon, - xid); - goto posix_mkdir_out; -} - int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) { - int rc = 0; + int rc = 0, tmprc; unsigned int xid; struct cifs_sb_info *cifs_sb; struct tcon_link *tlink; struct cifs_tcon *tcon; - struct TCP_Server_Info *server; - char *full_path; + char *full_path = NULL; + struct inode *newinode = NULL; + struct cifs_fattr fattr; cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode); @@ -1385,29 +1248,145 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))) { - rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb, - tcon, xid); - if (rc != -EOPNOTSUPP) + u32 oplock = 0; + FILE_UNIX_BASIC_INFO *pInfo = + kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); + if (pInfo == NULL) { + rc = -ENOMEM; goto mkdir_out; - } + } - server = tcon->ses->server; + mode &= ~current_umask(); + rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT, + mode, NULL /* netfid */, pInfo, &oplock, + full_path, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc == -EOPNOTSUPP) { + kfree(pInfo); + goto mkdir_retry_old; + } else if (rc) { + cFYI(1, "posix mkdir returned 0x%x", rc); + d_drop(direntry); + } else { + if (pInfo->Type == cpu_to_le32(-1)) { + /* no return info, go query for it */ + kfree(pInfo); + goto mkdir_get_info; + } +/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need + to set uid/gid */ + + cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); + cifs_fill_uniqueid(inode->i_sb, &fattr); + newinode = cifs_iget(inode->i_sb, &fattr); + if (!newinode) { + kfree(pInfo); + goto mkdir_get_info; + } + + d_instantiate(direntry, newinode); - if (!server->ops->mkdir) { - rc = -ENOSYS; +#ifdef CONFIG_CIFS_DEBUG2 + cFYI(1, "instantiated dentry %p %s to inode %p", + direntry, direntry->d_name.name, newinode); + + if (newinode->i_nlink != 2) + cFYI(1, "unexpected number of links %d", + newinode->i_nlink); +#endif + } + kfree(pInfo); goto mkdir_out; } - +mkdir_retry_old: /* BB add setting the equivalent of mode via CreateX w/ACLs */ - rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb); + rc = CIFSSMBMkDir(xid, tcon, full_path, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc) { cFYI(1, "cifs_mkdir returned 0x%x", rc); d_drop(direntry); - goto mkdir_out; + } else { +mkdir_get_info: + if (tcon->unix_ext) + rc = cifs_get_inode_info_unix(&newinode, full_path, + inode->i_sb, xid); + else + rc = cifs_get_inode_info(&newinode, full_path, NULL, + inode->i_sb, xid, NULL); + + d_instantiate(direntry, newinode); + /* setting nlink not necessary except in cases where we + * failed to get it from the server or was set bogus */ + if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) + set_nlink(direntry->d_inode, 2); + + mode &= ~current_umask(); + /* must turn on setgid bit if parent dir has it */ + if (inode->i_mode & S_ISGID) + mode |= S_ISGID; + + if (tcon->unix_ext) { + struct cifs_unix_set_info_args args = { + .mode = mode, + .ctime = NO_CHANGE_64, + .atime = NO_CHANGE_64, + .mtime = NO_CHANGE_64, + .device = 0, + }; + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + args.uid = (__u64)current_fsuid(); + if (inode->i_mode & S_ISGID) + args.gid = (__u64)inode->i_gid; + else + args.gid = (__u64)current_fsgid(); + } else { + args.uid = NO_CHANGE_64; + args.gid = NO_CHANGE_64; + } + CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + } else { + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && + (mode & S_IWUGO) == 0) { + FILE_BASIC_INFO pInfo; + struct cifsInodeInfo *cifsInode; + u32 dosattrs; + + memset(&pInfo, 0, sizeof(pInfo)); + cifsInode = CIFS_I(newinode); + dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; + pInfo.Attributes = cpu_to_le32(dosattrs); + tmprc = CIFSSMBSetPathInfo(xid, tcon, + full_path, &pInfo, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (tmprc == 0) + cifsInode->cifsAttrs = dosattrs; + } + if (direntry->d_inode) { + if (cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_DYNPERM) + direntry->d_inode->i_mode = + (mode | S_IFDIR); + + if (cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_SET_UID) { + direntry->d_inode->i_uid = + current_fsuid(); + if (inode->i_mode & S_ISGID) + direntry->d_inode->i_gid = + inode->i_gid; + else + direntry->d_inode->i_gid = + current_fsgid(); + } + } + } } - - rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon, - xid); mkdir_out: /* * Force revalidate to get parent dir info when needed since cached @@ -1426,8 +1405,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) unsigned int xid; struct cifs_sb_info *cifs_sb; struct tcon_link *tlink; - struct cifs_tcon *tcon; - struct TCP_Server_Info *server; + struct cifs_tcon *pTcon; char *full_path = NULL; struct cifsInodeInfo *cifsInode; @@ -1447,16 +1425,10 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) rc = PTR_ERR(tlink); goto rmdir_exit; } - tcon = tlink_tcon(tlink); - server = tcon->ses->server; - - if (!server->ops->rmdir) { - rc = -ENOSYS; - cifs_put_tlink(tlink); - goto rmdir_exit; - } + pTcon = tlink_tcon(tlink); - rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb); + rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); cifs_put_tlink(tlink); if (!rc) { diff --git a/trunk/fs/cifs/smb1ops.c b/trunk/fs/cifs/smb1ops.c index 3129ac74b819..c40356d24c5c 100644 --- a/trunk/fs/cifs/smb1ops.c +++ b/trunk/fs/cifs/smb1ops.c @@ -586,27 +586,6 @@ cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon) #endif } -static void -cifs_mkdir_setinfo(struct inode *inode, const char *full_path, - struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, - const unsigned int xid) -{ - FILE_BASIC_INFO info; - struct cifsInodeInfo *cifsInode; - u32 dosattrs; - int rc; - - memset(&info, 0, sizeof(info)); - cifsInode = CIFS_I(inode); - dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; - info.Attributes = cpu_to_le32(dosattrs); - rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - if (rc == 0) - cifsInode->cifsAttrs = dosattrs; -} - struct smb_version_operations smb1_operations = { .send_cancel = send_nt_cancel, .compare_fids = cifs_compare_fids, @@ -641,9 +620,6 @@ struct smb_version_operations smb1_operations = { .get_srv_inum = cifs_get_srv_inum, .build_path_to_root = cifs_build_path_to_root, .echo = CIFSSMBEcho, - .mkdir = CIFSSMBMkDir, - .mkdir_setinfo = cifs_mkdir_setinfo, - .rmdir = CIFSSMBRmDir, }; struct smb_version_values smb1_values = { diff --git a/trunk/fs/cifs/smb2inode.c b/trunk/fs/cifs/smb2inode.c index 2aa5cb08c526..1ba5c405315c 100644 --- a/trunk/fs/cifs/smb2inode.c +++ b/trunk/fs/cifs/smb2inode.c @@ -122,42 +122,3 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, kfree(smb2_data); return rc; } - -int -smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, - struct cifs_sb_info *cifs_sb) -{ - return smb2_open_op_close(xid, tcon, cifs_sb, name, - FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0, - CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR); -} - -void -smb2_mkdir_setinfo(struct inode *inode, const char *name, - struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, - const unsigned int xid) -{ - FILE_BASIC_INFO data; - struct cifsInodeInfo *cifs_i; - u32 dosattrs; - int tmprc; - - memset(&data, 0, sizeof(data)); - cifs_i = CIFS_I(inode); - dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; - data.Attributes = cpu_to_le32(dosattrs); - tmprc = smb2_open_op_close(xid, tcon, cifs_sb, name, - FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0, - CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO); - if (tmprc == 0) - cifs_i->cifsAttrs = dosattrs; -} - -int -smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, - struct cifs_sb_info *cifs_sb) -{ - return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, - 0, CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE, - NULL, SMB2_OP_DELETE); -} diff --git a/trunk/fs/cifs/smb2ops.c b/trunk/fs/cifs/smb2ops.c index 826209bf3684..410cf925ea26 100644 --- a/trunk/fs/cifs/smb2ops.c +++ b/trunk/fs/cifs/smb2ops.c @@ -318,9 +318,6 @@ struct smb_version_operations smb21_operations = { .query_path_info = smb2_query_path_info, .get_srv_inum = smb2_get_srv_inum, .build_path_to_root = smb2_build_path_to_root, - .mkdir = smb2_mkdir, - .mkdir_setinfo = smb2_mkdir_setinfo, - .rmdir = smb2_rmdir, }; struct smb_version_values smb21_values = { diff --git a/trunk/fs/cifs/smb2proto.h b/trunk/fs/cifs/smb2proto.h index bfaa7b148afd..902bbe2b5ad3 100644 --- a/trunk/fs/cifs/smb2proto.h +++ b/trunk/fs/cifs/smb2proto.h @@ -52,14 +52,6 @@ extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, FILE_ALL_INFO *data, bool *adjust_tz); -extern int smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, - const char *name, struct cifs_sb_info *cifs_sb); -extern void smb2_mkdir_setinfo(struct inode *inode, const char *full_path, - struct cifs_sb_info *cifs_sb, - struct cifs_tcon *tcon, const unsigned int xid); -extern int smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, - const char *name, struct cifs_sb_info *cifs_sb); - /* * SMB2 Worker functions - most of protocol specific implementation details * are contained within these calls. diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index cfb4b9fed520..989e034f02bd 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -385,6 +385,8 @@ struct ecryptfs_msg_ctx { struct mutex mux; }; +struct ecryptfs_daemon; + struct ecryptfs_daemon { #define ECRYPTFS_DAEMON_IN_READ 0x00000001 #define ECRYPTFS_DAEMON_IN_POLL 0x00000002 @@ -392,7 +394,10 @@ struct ecryptfs_daemon { #define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008 u32 flags; u32 num_queued_msg_ctx; - struct file *file; + struct pid *pid; + uid_t euid; + struct user_namespace *user_ns; + struct task_struct *task; struct mutex mux; struct list_head msg_ctx_out_queue; wait_queue_head_t wait; @@ -549,8 +554,6 @@ extern struct kmem_cache *ecryptfs_key_tfm_cache; struct inode *ecryptfs_get_inode(struct inode *lower_inode, struct super_block *sb); void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); -int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, - struct inode *ecryptfs_inode); int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, size_t *decrypted_name_size, struct dentry *ecryptfs_dentry, @@ -604,8 +607,13 @@ int ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); -int ecryptfs_process_response(struct ecryptfs_daemon *daemon, - struct ecryptfs_message *msg, u32 seq); +int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns, + struct pid *pid); +int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, + struct pid *pid); +int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, + struct user_namespace *user_ns, struct pid *pid, + u32 seq); int ecryptfs_send_message(char *data, int data_len, struct ecryptfs_msg_ctx **msg_ctx); int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, @@ -650,7 +658,8 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, struct inode *ecryptfs_inode); struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index); int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); -int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon); +int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, + struct user_namespace *user_ns); int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, size_t *length_size); int ecryptfs_write_packet_length(char *dest, size_t size, @@ -662,7 +671,8 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, u16 msg_flags, struct ecryptfs_daemon *daemon); void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); int -ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file); +ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, + struct user_namespace *user_ns, struct pid *pid); int ecryptfs_init_kthread(void); void ecryptfs_destroy_kthread(void); int ecryptfs_privileged_open(struct file **lower_file, diff --git a/trunk/fs/ecryptfs/file.c b/trunk/fs/ecryptfs/file.c index 44ce5c6a541d..2b17f2f9b121 100644 --- a/trunk/fs/ecryptfs/file.c +++ b/trunk/fs/ecryptfs/file.c @@ -138,50 +138,29 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) return rc; } -struct kmem_cache *ecryptfs_file_info_cache; - -static int read_or_initialize_metadata(struct dentry *dentry) +static void ecryptfs_vma_close(struct vm_area_struct *vma) { - struct inode *inode = dentry->d_inode; - struct ecryptfs_mount_crypt_stat *mount_crypt_stat; - struct ecryptfs_crypt_stat *crypt_stat; - int rc; + filemap_write_and_wait(vma->vm_file->f_mapping); +} - crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; - mount_crypt_stat = &ecryptfs_superblock_to_private( - inode->i_sb)->mount_crypt_stat; - mutex_lock(&crypt_stat->cs_mutex); +static const struct vm_operations_struct ecryptfs_file_vm_ops = { + .close = ecryptfs_vma_close, + .fault = filemap_fault, +}; - if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED && - crypt_stat->flags & ECRYPTFS_KEY_VALID) { - rc = 0; - goto out; - } +static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + int rc; - rc = ecryptfs_read_metadata(dentry); + rc = generic_file_mmap(file, vma); if (!rc) - goto out; - - if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) { - crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED - | ECRYPTFS_ENCRYPTED); - rc = 0; - goto out; - } + vma->vm_ops = &ecryptfs_file_vm_ops; - if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) && - !i_size_read(ecryptfs_inode_to_lower(inode))) { - rc = ecryptfs_initialize_file(dentry, inode); - if (!rc) - goto out; - } - - rc = -EIO; -out: - mutex_unlock(&crypt_stat->cs_mutex); return rc; } +struct kmem_cache *ecryptfs_file_info_cache; + /** * ecryptfs_open * @inode: inode speciying file to open @@ -257,9 +236,32 @@ static int ecryptfs_open(struct inode *inode, struct file *file) rc = 0; goto out; } - rc = read_or_initialize_metadata(ecryptfs_dentry); - if (rc) - goto out_put; + mutex_lock(&crypt_stat->cs_mutex); + if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) + || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { + rc = ecryptfs_read_metadata(ecryptfs_dentry); + if (rc) { + ecryptfs_printk(KERN_DEBUG, + "Valid headers not found\n"); + if (!(mount_crypt_stat->flags + & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { + rc = -EIO; + printk(KERN_WARNING "Either the lower file " + "is not in a valid eCryptfs format, " + "or the key could not be retrieved. " + "Plaintext passthrough mode is not " + "enabled; returning -EIO\n"); + mutex_unlock(&crypt_stat->cs_mutex); + goto out_put; + } + rc = 0; + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED + | ECRYPTFS_ENCRYPTED); + mutex_unlock(&crypt_stat->cs_mutex); + goto out; + } + } + mutex_unlock(&crypt_stat->cs_mutex); ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, (unsigned long long)i_size_read(inode)); @@ -290,7 +292,15 @@ static int ecryptfs_release(struct inode *inode, struct file *file) static int ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) { - return vfs_fsync(ecryptfs_file_to_lower(file), datasync); + int rc = 0; + + rc = generic_file_fsync(file, start, end, datasync); + if (rc) + goto out; + rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end, + datasync); +out: + return rc; } static int ecryptfs_fasync(int fd, struct file *file, int flag) @@ -359,7 +369,7 @@ const struct file_operations ecryptfs_main_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = ecryptfs_compat_ioctl, #endif - .mmap = generic_file_mmap, + .mmap = ecryptfs_file_mmap, .open = ecryptfs_open, .flush = ecryptfs_flush, .release = ecryptfs_release, diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 534b129ea676..c3ca12c33ca2 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -143,31 +143,6 @@ static int ecryptfs_interpose(struct dentry *lower_dentry, return 0; } -static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, - struct inode *inode) -{ - struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); - struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); - struct dentry *lower_dir_dentry; - int rc; - - dget(lower_dentry); - lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_unlink(lower_dir_inode, lower_dentry); - if (rc) { - printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); - goto out_unlock; - } - fsstack_copy_attr_times(dir, lower_dir_inode); - set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); - inode->i_ctime = dir->i_ctime; - d_drop(dentry); -out_unlock: - unlock_dir(lower_dir_dentry); - dput(lower_dentry); - return rc; -} - /** * ecryptfs_do_create * @directory_inode: inode of the new file's dentry's parent in ecryptfs @@ -207,10 +182,8 @@ ecryptfs_do_create(struct inode *directory_inode, } inode = __ecryptfs_get_inode(lower_dentry->d_inode, directory_inode->i_sb); - if (IS_ERR(inode)) { - vfs_unlink(lower_dir_dentry->d_inode, lower_dentry); + if (IS_ERR(inode)) goto out_lock; - } fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); out_lock: @@ -227,8 +200,8 @@ ecryptfs_do_create(struct inode *directory_inode, * * Returns zero on success */ -int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, - struct inode *ecryptfs_inode) +static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, + struct inode *ecryptfs_inode) { struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; @@ -291,9 +264,7 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, * that this on disk file is prepared to be an ecryptfs file */ rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); if (rc) { - ecryptfs_do_unlink(directory_inode, ecryptfs_dentry, - ecryptfs_inode); - make_bad_inode(ecryptfs_inode); + drop_nlink(ecryptfs_inode); unlock_new_inode(ecryptfs_inode); iput(ecryptfs_inode); goto out; @@ -495,7 +466,27 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) { - return ecryptfs_do_unlink(dir, dentry, dentry->d_inode); + int rc = 0; + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); + struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); + struct dentry *lower_dir_dentry; + + dget(lower_dentry); + lower_dir_dentry = lock_parent(lower_dentry); + rc = vfs_unlink(lower_dir_inode, lower_dentry); + if (rc) { + printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); + goto out_unlock; + } + fsstack_copy_attr_times(dir, lower_dir_inode); + set_nlink(dentry->d_inode, + ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink); + dentry->d_inode->i_ctime = dir->i_ctime; + d_drop(dentry); +out_unlock: + unlock_dir(lower_dir_dentry); + dput(lower_dentry); + return rc; } static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, @@ -970,6 +961,12 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) goto out; } + if (S_ISREG(inode->i_mode)) { + rc = filemap_write_and_wait(inode->i_mapping); + if (rc) + goto out; + fsstack_copy_attr_all(inode, lower_inode); + } memcpy(&lower_ia, ia, sizeof(lower_ia)); if (ia->ia_valid & ATTR_FILE) lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index 2768138eefee..1c0b3b6b75c6 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -279,7 +279,6 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, char *fnek_src; char *cipher_key_bytes_src; char *fn_cipher_key_bytes_src; - u8 cipher_code; *check_ruid = 0; @@ -421,18 +420,6 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, && !fn_cipher_key_bytes_set) mount_crypt_stat->global_default_fn_cipher_key_bytes = mount_crypt_stat->global_default_cipher_key_size; - - cipher_code = ecryptfs_code_for_cipher_string( - mount_crypt_stat->global_default_cipher_name, - mount_crypt_stat->global_default_cipher_key_size); - if (!cipher_code) { - ecryptfs_printk(KERN_ERR, - "eCryptfs doesn't support cipher: %s", - mount_crypt_stat->global_default_cipher_name); - rc = -EINVAL; - goto out; - } - mutex_lock(&key_tfm_list_mutex); if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, NULL)) { @@ -553,15 +540,6 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags } ecryptfs_set_superblock_lower(s, path.dentry->d_sb); - - /** - * Set the POSIX ACL flag based on whether they're enabled in the lower - * mount. Force a read-only eCryptfs mount if the lower mount is ro. - * Allow a ro eCryptfs mount even when the lower mount is rw. - */ - s->s_flags = flags & ~MS_POSIXACL; - s->s_flags |= path.dentry->d_sb->s_flags & (MS_RDONLY | MS_POSIXACL); - s->s_maxbytes = path.dentry->d_sb->s_maxbytes; s->s_blocksize = path.dentry->d_sb->s_blocksize; s->s_magic = ECRYPTFS_SUPER_MAGIC; diff --git a/trunk/fs/ecryptfs/messaging.c b/trunk/fs/ecryptfs/messaging.c index b29bb8bfa8d9..a750f957b145 100644 --- a/trunk/fs/ecryptfs/messaging.c +++ b/trunk/fs/ecryptfs/messaging.c @@ -32,8 +32,8 @@ static struct mutex ecryptfs_msg_ctx_lists_mux; static struct hlist_head *ecryptfs_daemon_hash; struct mutex ecryptfs_daemon_hash_mux; static int ecryptfs_hash_bits; -#define ecryptfs_current_euid_hash(uid) \ - hash_long((unsigned long)current_euid(), ecryptfs_hash_bits) +#define ecryptfs_uid_hash(uid) \ + hash_long((unsigned long)uid, ecryptfs_hash_bits) static u32 ecryptfs_msg_counter; static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; @@ -105,24 +105,26 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) /** * ecryptfs_find_daemon_by_euid + * @euid: The effective user id which maps to the desired daemon id + * @user_ns: The namespace in which @euid applies * @daemon: If return value is zero, points to the desired daemon pointer * * Must be called with ecryptfs_daemon_hash_mux held. * - * Search the hash list for the current effective user id. + * Search the hash list for the given user id. * * Returns zero if the user id exists in the list; non-zero otherwise. */ -int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon) +int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, + struct user_namespace *user_ns) { struct hlist_node *elem; int rc; hlist_for_each_entry(*daemon, elem, - &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()], - euid_chain) { - if ((*daemon)->file->f_cred->euid == current_euid() && - (*daemon)->file->f_cred->user_ns == current_user_ns()) { + &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], + euid_chain) { + if ((*daemon)->euid == euid && (*daemon)->user_ns == user_ns) { rc = 0; goto out; } @@ -135,7 +137,9 @@ int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon) /** * ecryptfs_spawn_daemon - Create and initialize a new daemon struct * @daemon: Pointer to set to newly allocated daemon struct - * @file: File used when opening /dev/ecryptfs + * @euid: Effective user id for the daemon + * @user_ns: The namespace in which @euid applies + * @pid: Process id for the daemon * * Must be called ceremoniously while in possession of * ecryptfs_sacred_daemon_hash_mux @@ -143,7 +147,8 @@ int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon) * Returns zero on success; non-zero otherwise */ int -ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file) +ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, + struct user_namespace *user_ns, struct pid *pid) { int rc = 0; @@ -154,13 +159,16 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file) "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); goto out; } - (*daemon)->file = file; + (*daemon)->euid = euid; + (*daemon)->user_ns = get_user_ns(user_ns); + (*daemon)->pid = get_pid(pid); + (*daemon)->task = current; mutex_init(&(*daemon)->mux); INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); init_waitqueue_head(&(*daemon)->wait); (*daemon)->num_queued_msg_ctx = 0; hlist_add_head(&(*daemon)->euid_chain, - &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()]); + &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)]); out: return rc; } @@ -180,6 +188,9 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { rc = -EBUSY; + printk(KERN_WARNING "%s: Attempt to destroy daemon with pid " + "[0x%p], but it is in the midst of a read or a poll\n", + __func__, daemon->pid); mutex_unlock(&daemon->mux); goto out; } @@ -192,16 +203,55 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) ecryptfs_msg_ctx_alloc_to_free(msg_ctx); } hlist_del(&daemon->euid_chain); + if (daemon->task) + wake_up_process(daemon->task); + if (daemon->pid) + put_pid(daemon->pid); + if (daemon->user_ns) + put_user_ns(daemon->user_ns); mutex_unlock(&daemon->mux); kzfree(daemon); out: return rc; } +/** + * ecryptfs_process_quit + * @euid: The user ID owner of the message + * @user_ns: The namespace in which @euid applies + * @pid: The process ID for the userspace program that sent the + * message + * + * Deletes the corresponding daemon for the given euid and pid, if + * it is the registered that is requesting the deletion. Returns zero + * after deleting the desired daemon; non-zero otherwise. + */ +int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, + struct pid *pid) +{ + struct ecryptfs_daemon *daemon; + int rc; + + mutex_lock(&ecryptfs_daemon_hash_mux); + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, user_ns); + if (rc || !daemon) { + rc = -EINVAL; + printk(KERN_ERR "Received request from user [%d] to " + "unregister unrecognized daemon [0x%p]\n", euid, pid); + goto out_unlock; + } + rc = ecryptfs_exorcise_daemon(daemon); +out_unlock: + mutex_unlock(&ecryptfs_daemon_hash_mux); + return rc; +} + /** * ecryptfs_process_reponse * @msg: The ecryptfs message received; the caller should sanity check * msg->data_len and free the memory + * @pid: The process ID of the userspace application that sent the + * message * @seq: The sequence number of the message; must match the sequence * number for the existing message context waiting for this * response @@ -220,11 +270,16 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) * * Returns zero on success; non-zero otherwise */ -int ecryptfs_process_response(struct ecryptfs_daemon *daemon, - struct ecryptfs_message *msg, u32 seq) +int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, + struct user_namespace *user_ns, struct pid *pid, + u32 seq) { + struct ecryptfs_daemon *uninitialized_var(daemon); struct ecryptfs_msg_ctx *msg_ctx; size_t msg_size; + struct nsproxy *nsproxy; + struct user_namespace *tsk_user_ns; + uid_t ctx_euid; int rc; if (msg->index >= ecryptfs_message_buf_len) { @@ -237,6 +292,51 @@ int ecryptfs_process_response(struct ecryptfs_daemon *daemon, } msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; mutex_lock(&msg_ctx->mux); + mutex_lock(&ecryptfs_daemon_hash_mux); + rcu_read_lock(); + nsproxy = task_nsproxy(msg_ctx->task); + if (nsproxy == NULL) { + rc = -EBADMSG; + printk(KERN_ERR "%s: Receiving process is a zombie. Dropping " + "message.\n", __func__); + rcu_read_unlock(); + mutex_unlock(&ecryptfs_daemon_hash_mux); + goto wake_up; + } + tsk_user_ns = __task_cred(msg_ctx->task)->user_ns; + ctx_euid = task_euid(msg_ctx->task); + rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns); + rcu_read_unlock(); + mutex_unlock(&ecryptfs_daemon_hash_mux); + if (rc) { + rc = -EBADMSG; + printk(KERN_WARNING "%s: User [%d] received a " + "message response from process [0x%p] but does " + "not have a registered daemon\n", __func__, + ctx_euid, pid); + goto wake_up; + } + if (ctx_euid != euid) { + rc = -EBADMSG; + printk(KERN_WARNING "%s: Received message from user " + "[%d]; expected message from user [%d]\n", __func__, + euid, ctx_euid); + goto unlock; + } + if (tsk_user_ns != user_ns) { + rc = -EBADMSG; + printk(KERN_WARNING "%s: Received message from user_ns " + "[0x%p]; expected message from user_ns [0x%p]\n", + __func__, user_ns, tsk_user_ns); + goto unlock; + } + if (daemon->pid != pid) { + rc = -EBADMSG; + printk(KERN_ERR "%s: User [%d] sent a message response " + "from an unrecognized process [0x%p]\n", + __func__, ctx_euid, pid); + goto unlock; + } if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { rc = -EINVAL; printk(KERN_WARNING "%s: Desired context element is not " @@ -259,8 +359,9 @@ int ecryptfs_process_response(struct ecryptfs_daemon *daemon, } memcpy(msg_ctx->msg, msg, msg_size); msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; - wake_up_process(msg_ctx->task); rc = 0; +wake_up: + wake_up_process(msg_ctx->task); unlock: mutex_unlock(&msg_ctx->mux); out: @@ -282,11 +383,14 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx) { struct ecryptfs_daemon *daemon; + uid_t euid = current_euid(); int rc; - rc = ecryptfs_find_daemon_by_euid(&daemon); + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); if (rc || !daemon) { rc = -ENOTCONN; + printk(KERN_ERR "%s: User [%d] does not have a daemon " + "registered\n", __func__, euid); goto out; } mutex_lock(&ecryptfs_msg_ctx_lists_mux); diff --git a/trunk/fs/ecryptfs/miscdev.c b/trunk/fs/ecryptfs/miscdev.c index 412e6eda25f8..c0038f6566d4 100644 --- a/trunk/fs/ecryptfs/miscdev.c +++ b/trunk/fs/ecryptfs/miscdev.c @@ -33,7 +33,7 @@ static atomic_t ecryptfs_num_miscdev_opens; /** * ecryptfs_miscdev_poll - * @file: dev file + * @file: dev file (ignored) * @pt: dev poll table (ignored) * * Returns the poll mask @@ -41,10 +41,20 @@ static atomic_t ecryptfs_num_miscdev_opens; static unsigned int ecryptfs_miscdev_poll(struct file *file, poll_table *pt) { - struct ecryptfs_daemon *daemon = file->private_data; + struct ecryptfs_daemon *daemon; unsigned int mask = 0; + uid_t euid = current_euid(); + int rc; + mutex_lock(&ecryptfs_daemon_hash_mux); + /* TODO: Just use file->private_data? */ + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); + if (rc || !daemon) { + mutex_unlock(&ecryptfs_daemon_hash_mux); + return -EINVAL; + } mutex_lock(&daemon->mux); + mutex_unlock(&ecryptfs_daemon_hash_mux); if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { printk(KERN_WARNING "%s: Attempt to poll on zombified " "daemon\n", __func__); @@ -69,7 +79,7 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt) /** * ecryptfs_miscdev_open * @inode: inode of miscdev handle (ignored) - * @file: file for miscdev handle + * @file: file for miscdev handle (ignored) * * Returns zero on success; non-zero otherwise */ @@ -77,6 +87,7 @@ static int ecryptfs_miscdev_open(struct inode *inode, struct file *file) { struct ecryptfs_daemon *daemon = NULL; + uid_t euid = current_euid(); int rc; mutex_lock(&ecryptfs_daemon_hash_mux); @@ -87,20 +98,30 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) "count; rc = [%d]\n", __func__, rc); goto out_unlock_daemon_list; } - rc = ecryptfs_find_daemon_by_euid(&daemon); - if (!rc) { - rc = -EINVAL; - goto out_unlock_daemon_list; - } - rc = ecryptfs_spawn_daemon(&daemon, file); - if (rc) { - printk(KERN_ERR "%s: Error attempting to spawn daemon; " - "rc = [%d]\n", __func__, rc); - goto out_module_put_unlock_daemon_list; + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); + if (rc || !daemon) { + rc = ecryptfs_spawn_daemon(&daemon, euid, current_user_ns(), + task_pid(current)); + if (rc) { + printk(KERN_ERR "%s: Error attempting to spawn daemon; " + "rc = [%d]\n", __func__, rc); + goto out_module_put_unlock_daemon_list; + } } mutex_lock(&daemon->mux); + if (daemon->pid != task_pid(current)) { + rc = -EINVAL; + printk(KERN_ERR "%s: pid [0x%p] has registered with euid [%d], " + "but pid [0x%p] has attempted to open the handle " + "instead\n", __func__, daemon->pid, daemon->euid, + task_pid(current)); + goto out_unlock_daemon; + } if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { rc = -EBUSY; + printk(KERN_ERR "%s: Miscellaneous device handle may only be " + "opened once per daemon; pid [0x%p] already has this " + "handle open\n", __func__, daemon->pid); goto out_unlock_daemon; } daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; @@ -119,7 +140,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) /** * ecryptfs_miscdev_release * @inode: inode of fs/ecryptfs/euid handle (ignored) - * @file: file for fs/ecryptfs/euid handle + * @file: file for fs/ecryptfs/euid handle (ignored) * * This keeps the daemon registered until the daemon sends another * ioctl to fs/ecryptfs/ctl or until the kernel module unregisters. @@ -129,18 +150,20 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) static int ecryptfs_miscdev_release(struct inode *inode, struct file *file) { - struct ecryptfs_daemon *daemon = file->private_data; + struct ecryptfs_daemon *daemon = NULL; + uid_t euid = current_euid(); int rc; + mutex_lock(&ecryptfs_daemon_hash_mux); + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); + if (rc || !daemon) + daemon = file->private_data; mutex_lock(&daemon->mux); BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; atomic_dec(&ecryptfs_num_miscdev_opens); mutex_unlock(&daemon->mux); - - mutex_lock(&ecryptfs_daemon_hash_mux); rc = ecryptfs_exorcise_daemon(daemon); - mutex_unlock(&ecryptfs_daemon_hash_mux); if (rc) { printk(KERN_CRIT "%s: Fatal error whilst attempting to " "shut down daemon; rc = [%d]. Please report this " @@ -148,6 +171,7 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) BUG(); } module_put(THIS_MODULE); + mutex_unlock(&ecryptfs_daemon_hash_mux); return rc; } @@ -224,7 +248,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, /** * ecryptfs_miscdev_read - format and send message from queue - * @file: miscdevfs handle + * @file: fs/ecryptfs/euid miscdevfs handle (ignored) * @buf: User buffer into which to copy the next message on the daemon queue * @count: Amount of space available in @buf * @ppos: Offset in file (ignored) @@ -238,27 +262,43 @@ static ssize_t ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct ecryptfs_daemon *daemon = file->private_data; + struct ecryptfs_daemon *daemon; struct ecryptfs_msg_ctx *msg_ctx; size_t packet_length_size; char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE]; size_t i; size_t total_length; + uid_t euid = current_euid(); int rc; + mutex_lock(&ecryptfs_daemon_hash_mux); + /* TODO: Just use file->private_data? */ + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); + if (rc || !daemon) { + mutex_unlock(&ecryptfs_daemon_hash_mux); + return -EINVAL; + } mutex_lock(&daemon->mux); + if (task_pid(current) != daemon->pid) { + mutex_unlock(&daemon->mux); + mutex_unlock(&ecryptfs_daemon_hash_mux); + return -EPERM; + } if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { rc = 0; + mutex_unlock(&ecryptfs_daemon_hash_mux); printk(KERN_WARNING "%s: Attempt to read from zombified " "daemon\n", __func__); goto out_unlock_daemon; } if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) { rc = 0; + mutex_unlock(&ecryptfs_daemon_hash_mux); goto out_unlock_daemon; } /* This daemon will not go away so long as this flag is set */ daemon->flags |= ECRYPTFS_DAEMON_IN_READ; + mutex_unlock(&ecryptfs_daemon_hash_mux); check_list: if (list_empty(&daemon->msg_ctx_out_queue)) { mutex_unlock(&daemon->mux); @@ -342,12 +382,16 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon * @data: Bytes comprising struct ecryptfs_message * @data_size: sizeof(struct ecryptfs_message) + data len + * @euid: Effective user id of miscdevess sending the miscdev response + * @user_ns: The namespace in which @euid applies + * @pid: Miscdevess id of miscdevess sending the miscdev response * @seq: Sequence number for miscdev response packet * * Returns zero on success; non-zero otherwise */ -static int ecryptfs_miscdev_response(struct ecryptfs_daemon *daemon, char *data, - size_t data_size, u32 seq) +static int ecryptfs_miscdev_response(char *data, size_t data_size, + uid_t euid, struct user_namespace *user_ns, + struct pid *pid, u32 seq) { struct ecryptfs_message *msg = (struct ecryptfs_message *)data; int rc; @@ -359,7 +403,7 @@ static int ecryptfs_miscdev_response(struct ecryptfs_daemon *daemon, char *data, rc = -EINVAL; goto out; } - rc = ecryptfs_process_response(daemon, msg, seq); + rc = ecryptfs_process_response(msg, euid, user_ns, pid, seq); if (rc) printk(KERN_ERR "Error processing response message; rc = [%d]\n", rc); @@ -369,7 +413,7 @@ static int ecryptfs_miscdev_response(struct ecryptfs_daemon *daemon, char *data, /** * ecryptfs_miscdev_write - handle write to daemon miscdev handle - * @file: File for misc dev handle + * @file: File for misc dev handle (ignored) * @buf: Buffer containing user data * @count: Amount of data in @buf * @ppos: Pointer to offset in file (ignored) @@ -384,6 +428,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, u32 seq; size_t packet_size, packet_size_length; char *data; + uid_t euid = current_euid(); unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE]; ssize_t rc; @@ -443,9 +488,10 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, } memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE); seq = be32_to_cpu(counter_nbo); - rc = ecryptfs_miscdev_response(file->private_data, + rc = ecryptfs_miscdev_response( &data[PKT_LEN_OFFSET + packet_size_length], - packet_size, seq); + 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 = [%zd]\n", diff --git a/trunk/fs/ecryptfs/mmap.c b/trunk/fs/ecryptfs/mmap.c index bd1d57f98f74..a46b3a8fee1e 100644 --- a/trunk/fs/ecryptfs/mmap.c +++ b/trunk/fs/ecryptfs/mmap.c @@ -66,6 +66,18 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) { int rc; + /* + * Refuse to write the page out if we are called from reclaim context + * since our writepage() path may potentially allocate memory when + * calling into the lower fs vfs_write() which may in turn invoke + * us again. + */ + if (current->flags & PF_MEMALLOC) { + redirty_page_for_writepage(wbc, page); + rc = 0; + goto out; + } + rc = ecryptfs_encrypt_page(page); if (rc) { ecryptfs_printk(KERN_WARNING, "Error encrypting " @@ -486,6 +498,7 @@ static int ecryptfs_write_end(struct file *file, struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; int rc; + int need_unlock_page = 1; ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); @@ -506,26 +519,26 @@ static int ecryptfs_write_end(struct file *file, "zeros in page with index = [0x%.16lx]\n", index); goto out; } - rc = ecryptfs_encrypt_page(page); - if (rc) { - ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " - "index [0x%.16lx])\n", index); - goto out; - } + set_page_dirty(page); + unlock_page(page); + need_unlock_page = 0; if (pos + copied > i_size_read(ecryptfs_inode)) { i_size_write(ecryptfs_inode, pos + copied); ecryptfs_printk(KERN_DEBUG, "Expanded file size to " "[0x%.16llx]\n", (unsigned long long)i_size_read(ecryptfs_inode)); + balance_dirty_pages_ratelimited(mapping); + rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); + if (rc) { + printk(KERN_ERR "Error writing inode size to metadata; " + "rc = [%d]\n", rc); + goto out; + } } - rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); - if (rc) - printk(KERN_ERR "Error writing inode size to metadata; " - "rc = [%d]\n", rc); - else - rc = copied; + rc = copied; out: - unlock_page(page); + if (need_unlock_page) + unlock_page(page); page_cache_release(page); return rc; } diff --git a/trunk/fs/exofs/inode.c b/trunk/fs/exofs/inode.c index 1562c27a2fab..5badb0c039de 100644 --- a/trunk/fs/exofs/inode.c +++ b/trunk/fs/exofs/inode.c @@ -37,12 +37,15 @@ #define EXOFS_DBGMSG2(M...) do {} while (0) +enum {MAX_PAGES_KMALLOC = PAGE_SIZE / sizeof(struct page *), }; + unsigned exofs_max_io_pages(struct ore_layout *layout, unsigned expected_pages) { - unsigned pages = min_t(unsigned, expected_pages, - layout->max_io_length / PAGE_SIZE); + unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC); + /* TODO: easily support bio chaining */ + pages = min_t(unsigned, pages, layout->max_io_length / PAGE_SIZE); return pages; } @@ -98,8 +101,7 @@ static void _pcol_reset(struct page_collect *pcol) * it might not end here. don't be left with nothing */ if (!pcol->expected_pages) - pcol->expected_pages = - exofs_max_io_pages(&pcol->sbi->layout, ~0); + pcol->expected_pages = MAX_PAGES_KMALLOC; } static int pcol_try_alloc(struct page_collect *pcol) @@ -387,8 +389,6 @@ static int readpage_strip(void *data, struct page *page) size_t len; int ret; - BUG_ON(!PageLocked(page)); - /* FIXME: Just for debugging, will be removed */ if (PageUptodate(page)) EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino, @@ -572,16 +572,8 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) if (!pcol->that_locked_page || (pcol->that_locked_page->index != index)) { - struct page *page; - loff_t i_size = i_size_read(pcol->inode); - - if (offset >= i_size) { - *uptodate = true; - EXOFS_DBGMSG("offset >= i_size index=0x%lx\n", index); - return ZERO_PAGE(0); - } + struct page *page = find_get_page(pcol->inode->i_mapping, index); - page = find_get_page(pcol->inode->i_mapping, index); if (!page) { page = find_or_create_page(pcol->inode->i_mapping, index, GFP_NOFS); @@ -610,13 +602,12 @@ static void __r4w_put_page(void *priv, struct page *page) { struct page_collect *pcol = priv; - if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) { + if (pcol->that_locked_page != page) { EXOFS_DBGMSG("index=0x%lx\n", page->index); page_cache_release(page); return; } - EXOFS_DBGMSG("that_locked_page index=0x%lx\n", - ZERO_PAGE(0) == page ? -1 : page->index); + EXOFS_DBGMSG("that_locked_page index=0x%lx\n", page->index); } static const struct _ore_r4w_op _r4w_op = { diff --git a/trunk/fs/exofs/ore.c b/trunk/fs/exofs/ore.c index 1585db1aa365..24a49d47e935 100644 --- a/trunk/fs/exofs/ore.c +++ b/trunk/fs/exofs/ore.c @@ -837,11 +837,11 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) bio->bi_rw |= REQ_WRITE; } - osd_req_write(or, _ios_obj(ios, cur_comp), - per_dev->offset, bio, per_dev->length); + osd_req_write(or, _ios_obj(ios, dev), per_dev->offset, + bio, per_dev->length); ORE_DBGMSG("write(0x%llx) offset=0x%llx " "length=0x%llx dev=%d\n", - _LLU(_ios_obj(ios, cur_comp)->id), + _LLU(_ios_obj(ios, dev)->id), _LLU(per_dev->offset), _LLU(per_dev->length), dev); } else if (ios->kern_buff) { @@ -853,20 +853,20 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) (ios->si.unit_off + ios->length > ios->layout->stripe_unit)); - ret = osd_req_write_kern(or, _ios_obj(ios, cur_comp), + ret = osd_req_write_kern(or, _ios_obj(ios, per_dev->dev), per_dev->offset, ios->kern_buff, ios->length); if (unlikely(ret)) goto out; ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx " "length=0x%llx dev=%d\n", - _LLU(_ios_obj(ios, cur_comp)->id), + _LLU(_ios_obj(ios, dev)->id), _LLU(per_dev->offset), _LLU(ios->length), per_dev->dev); } else { - osd_req_set_attributes(or, _ios_obj(ios, cur_comp)); + osd_req_set_attributes(or, _ios_obj(ios, dev)); ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", - _LLU(_ios_obj(ios, cur_comp)->id), + _LLU(_ios_obj(ios, dev)->id), ios->out_attr_len, dev); } diff --git a/trunk/fs/exofs/super.c b/trunk/fs/exofs/super.c index dde41a75c7c8..433783624d10 100644 --- a/trunk/fs/exofs/super.c +++ b/trunk/fs/exofs/super.c @@ -400,6 +400,8 @@ static int exofs_sync_fs(struct super_block *sb, int wait) ret = ore_write(ios); if (unlikely(ret)) EXOFS_ERR("%s: ore_write failed.\n", __func__); + else + sb->s_dirt = 0; unlock_super(sb); @@ -410,6 +412,14 @@ static int exofs_sync_fs(struct super_block *sb, int wait) return ret; } +static void exofs_write_super(struct super_block *sb) +{ + if (!(sb->s_flags & MS_RDONLY)) + exofs_sync_fs(sb, 1); + else + sb->s_dirt = 0; +} + static void _exofs_print_device(const char *msg, const char *dev_path, struct osd_dev *od, u64 pid) { @@ -942,6 +952,7 @@ static const struct super_operations exofs_sops = { .write_inode = exofs_write_inode, .evict_inode = exofs_evict_inode, .put_super = exofs_put_super, + .write_super = exofs_write_super, .sync_fs = exofs_sync_fs, .statfs = exofs_statfs, }; diff --git a/trunk/fs/ext3/inode.c b/trunk/fs/ext3/inode.c index a07597307fd1..9a4a5c48b1c9 100644 --- a/trunk/fs/ext3/inode.c +++ b/trunk/fs/ext3/inode.c @@ -3459,6 +3459,14 @@ ext3_reserve_inode_write(handle_t *handle, struct inode *inode, * inode out, but prune_icache isn't a user-visible syncing function. * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) * we start and wait on commits. + * + * Is this efficient/effective? Well, we're being nice to the system + * by cleaning up our inodes proactively so they can be reaped + * without I/O. But we are potentially leaving up to five seconds' + * worth of inodes floating about which prune_icache wants us to + * write out. One way to fix that would be to get prune_icache() + * to do a write_super() to free up some memory. It has the desired + * effect. */ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) { diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 8c892e93d8e7..ff9bcdc5b0d5 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -64,6 +64,11 @@ static int ext3_freeze(struct super_block *sb); /* * Wrappers for journal_start/end. + * + * The only special thing we need to do here is to make sure that all + * journal_end calls result in the superblock being marked dirty, so + * that sync() will call the filesystem's write_super callback if + * appropriate. */ handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks) { @@ -85,6 +90,12 @@ handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks) return journal_start(journal, nblocks); } +/* + * The only special thing we need to do here is to make sure that all + * journal_stop calls result in the superblock being marked dirty, so + * that sync() will call the filesystem's write_super callback if + * appropriate. + */ int __ext3_journal_stop(const char *where, handle_t *handle) { struct super_block *sb; diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index dff171c3a123..6324f74e0342 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -1970,7 +1970,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate); * This function can get called via... * - ext4_da_writepages after taking page lock (have journal handle) * - journal_submit_inode_data_buffers (no journal handle) - * - shrink_page_list via the kswapd/direct reclaim (no journal handle) + * - shrink_page_list via pdflush (no journal handle) * - grab_page_cache when doing write_begin (have journal handle) * * We don't do any block allocation in this function. If we have page with @@ -4589,6 +4589,14 @@ static int ext4_expand_extra_isize(struct inode *inode, * inode out, but prune_icache isn't a user-visible syncing function. * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) * we start and wait on commits. + * + * Is this efficient/effective? Well, we're being nice to the system + * by cleaning up our inodes proactively so they can be reaped + * without I/O. But we are potentially leaving up to five seconds' + * worth of inodes floating about which prune_icache wants us to + * write out. One way to fix that would be to get prune_icache() + * to do a write_super() to free up some memory. It has the desired + * effect. */ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) { diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 3e0851e4f468..d76ec8277d3f 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -326,6 +326,11 @@ static void ext4_put_nojournal(handle_t *handle) /* * Wrappers for jbd2_journal_start/end. + * + * The only special thing we need to do here is to make sure that all + * journal_end calls result in the superblock being marked dirty, so + * that sync() will call the filesystem's write_super callback if + * appropriate. */ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) { @@ -351,6 +356,12 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) return jbd2_journal_start(journal, nblocks); } +/* + * The only special thing we need to do here is to make sure that all + * jbd2_journal_stop calls result in the superblock being marked dirty, so + * that sync() will call the filesystem's write_super callback if + * appropriate. + */ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) { struct super_block *sb; diff --git a/trunk/fs/gfs2/meta_io.c b/trunk/fs/gfs2/meta_io.c index 22255d96b27e..3a56c8d94de0 100644 --- a/trunk/fs/gfs2/meta_io.c +++ b/trunk/fs/gfs2/meta_io.c @@ -52,7 +52,7 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb /* * If it's a fully non-blocking write attempt and we cannot * lock the buffer then redirty the page. Note that this can - * potentially cause a busy-wait loop from flusher thread and kswapd + * potentially cause a busy-wait loop from pdflush and kswapd * activity, but those code paths have their own higher-level * throttling. */ diff --git a/trunk/fs/hfs/mdb.c b/trunk/fs/hfs/mdb.c index b7ec224910c5..5fd51a5833ff 100644 --- a/trunk/fs/hfs/mdb.c +++ b/trunk/fs/hfs/mdb.c @@ -236,10 +236,10 @@ int hfs_mdb_get(struct super_block *sb) * hfs_mdb_commit() * * Description: - * This updates the MDB on disk. + * This updates the MDB on disk (look also at hfs_write_super()). * It does not check, if the superblock has been modified, or * if the filesystem has been mounted read-only. It is mainly - * called by hfs_sync_fs() and flush_mdb(). + * called by hfs_write_super() and hfs_btree_extend(). * Input Variable(s): * struct hfs_mdb *mdb: Pointer to the hfs MDB * int backup; diff --git a/trunk/fs/jbd/journal.c b/trunk/fs/jbd/journal.c index 09357508ec9a..425c2f2cf170 100644 --- a/trunk/fs/jbd/journal.c +++ b/trunk/fs/jbd/journal.c @@ -534,8 +534,8 @@ int journal_start_commit(journal_t *journal, tid_t *ptid) ret = 1; } else if (journal->j_committing_transaction) { /* - * If commit has been started, then we have to wait for - * completion of that transaction. + * If ext3_write_super() recently started a commit, then we + * have to wait for completion of that transaction */ if (ptid) *ptid = journal->j_committing_transaction->t_tid; diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c index 8625da27eccf..e9a3c4c85594 100644 --- a/trunk/fs/jbd2/journal.c +++ b/trunk/fs/jbd2/journal.c @@ -612,8 +612,8 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) ret = 1; } else if (journal->j_committing_transaction) { /* - * If commit has been started, then we have to wait for - * completion of that transaction. + * If ext3_write_super() recently started a commit, then we + * have to wait for completion of that transaction */ if (ptid) *ptid = journal->j_committing_transaction->t_tid; diff --git a/trunk/fs/nilfs2/super.c b/trunk/fs/nilfs2/super.c index 6a10812711c1..6522cac6057c 100644 --- a/trunk/fs/nilfs2/super.c +++ b/trunk/fs/nilfs2/super.c @@ -676,13 +676,17 @@ static const struct super_operations nilfs_sops = { .alloc_inode = nilfs_alloc_inode, .destroy_inode = nilfs_destroy_inode, .dirty_inode = nilfs_dirty_inode, + /* .write_inode = nilfs_write_inode, */ + /* .drop_inode = nilfs_drop_inode, */ .evict_inode = nilfs_evict_inode, .put_super = nilfs_put_super, + /* .write_super = nilfs_write_super, */ .sync_fs = nilfs_sync_fs, .freeze_fs = nilfs_freeze, .unfreeze_fs = nilfs_unfreeze, .statfs = nilfs_statfs, .remount_fs = nilfs_remount, + /* .umount_begin */ .show_options = nilfs_show_options }; diff --git a/trunk/fs/nilfs2/the_nilfs.h b/trunk/fs/nilfs2/the_nilfs.h index be1267a34cea..6eee4177807b 100644 --- a/trunk/fs/nilfs2/the_nilfs.h +++ b/trunk/fs/nilfs2/the_nilfs.h @@ -107,6 +107,8 @@ struct the_nilfs { * used for * - loading the latest checkpoint exclusively. * - allocating a new full segment. + * - protecting s_dirt in the super_block struct + * (see nilfs_write_super) and the following fields. */ struct buffer_head *ns_sbh[2]; struct nilfs_super_block *ns_sbp[2]; diff --git a/trunk/fs/open.c b/trunk/fs/open.c index bc132e167d2d..f3d96e7e7b19 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -717,7 +717,7 @@ static int do_dentry_open(struct file *f, * here, so just reset the state. */ file_reset_write(f); - __mnt_drop_write(f->f_path.mnt); + mnt_drop_write(f->f_path.mnt); } } cleanup_file: diff --git a/trunk/fs/super.c b/trunk/fs/super.c index 0902cfa6a12e..b05cf47463d0 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -536,6 +536,46 @@ void drop_super(struct super_block *sb) EXPORT_SYMBOL(drop_super); +/** + * sync_supers - helper for periodic superblock writeback + * + * Call the write_super method if present on all dirty superblocks in + * the system. This is for the periodic writeback used by most older + * filesystems. For data integrity superblock writeback use + * sync_filesystems() instead. + * + * Note: check the dirty flag before waiting, so we don't + * hold up the sync while mounting a device. (The newly + * mounted device won't need syncing.) + */ +void sync_supers(void) +{ + struct super_block *sb, *p = NULL; + + spin_lock(&sb_lock); + list_for_each_entry(sb, &super_blocks, s_list) { + if (hlist_unhashed(&sb->s_instances)) + continue; + if (sb->s_op->write_super && sb->s_dirt) { + sb->s_count++; + spin_unlock(&sb_lock); + + down_read(&sb->s_umount); + if (sb->s_root && sb->s_dirt && (sb->s_flags & MS_BORN)) + sb->s_op->write_super(sb); + up_read(&sb->s_umount); + + spin_lock(&sb_lock); + if (p) + __put_super(p); + p = sb; + } + } + if (p) + __put_super(p); + spin_unlock(&sb_lock); +} + /** * iterate_supers - call function for all active superblocks * @f: function to call diff --git a/trunk/fs/ubifs/file.c b/trunk/fs/ubifs/file.c index 7bd6e72afd11..35389ca2d267 100644 --- a/trunk/fs/ubifs/file.c +++ b/trunk/fs/ubifs/file.c @@ -37,11 +37,11 @@ * * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we * implement. However, this is not true for 'ubifs_writepage()', which may be - * called with @i_mutex unlocked. For example, when flusher thread is doing - * background write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. - * At "normal" work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. - * in the "sys_write -> alloc_pages -> direct reclaim path". So, in - * 'ubifs_writepage()' we are only guaranteed that the page is locked. + * called with @i_mutex unlocked. For example, when pdflush is doing background + * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal" + * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the + * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()' + * we are only guaranteed that the page is locked. * * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> diff --git a/trunk/fs/ubifs/super.c b/trunk/fs/ubifs/super.c index c3fa6c5327a3..1c766c39c038 100644 --- a/trunk/fs/ubifs/super.c +++ b/trunk/fs/ubifs/super.c @@ -303,7 +303,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc) mutex_lock(&ui->ui_mutex); /* * Due to races between write-back forced by budgeting - * (see 'sync_some_inodes()') and background write-back, the inode may + * (see 'sync_some_inodes()') and pdflush write-back, the inode may * have already been synchronized, do not do this again. This might * also happen if it was synchronized in an VFS operation, e.g. * 'ubifs_link()'. diff --git a/trunk/include/acpi/acpixf.h b/trunk/include/acpi/acpixf.h index 26a92fc28a59..2c744c7a5b3d 100644 --- a/trunk/include/acpi/acpixf.h +++ b/trunk/include/acpi/acpixf.h @@ -491,11 +491,11 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); acpi_status acpi_enter_sleep_state_prep(u8 sleep_state); -acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state); +acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags); ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)) -acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); +acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags); acpi_status acpi_leave_sleep_state(u8 sleep_state); diff --git a/trunk/include/acpi/actypes.h b/trunk/include/acpi/actypes.h index 3d00bd5bd7e3..3af87de6a68c 100644 --- a/trunk/include/acpi/actypes.h +++ b/trunk/include/acpi/actypes.h @@ -803,7 +803,7 @@ typedef u8 acpi_adr_space_type; /* Sleep function dispatch */ -typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state); +typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state, u8 flags); struct acpi_sleep_functions { ACPI_SLEEP_FUNCTION legacy_function; diff --git a/trunk/include/drm/drm_pciids.h b/trunk/include/drm/drm_pciids.h index c78bb997e2c6..7ff5c99b1638 100644 --- a/trunk/include/drm/drm_pciids.h +++ b/trunk/include/drm/drm_pciids.h @@ -213,12 +213,9 @@ {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6806, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6819, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ diff --git a/trunk/include/drm/radeon_drm.h b/trunk/include/drm/radeon_drm.h index dc3a8cd7db8a..58056865b8e9 100644 --- a/trunk/include/drm/radeon_drm.h +++ b/trunk/include/drm/radeon_drm.h @@ -964,8 +964,6 @@ struct drm_radeon_cs { #define RADEON_INFO_IB_VM_MAX_SIZE 0x0f /* max pipes - needed for compute shaders */ #define RADEON_INFO_MAX_PIPES 0x10 -/* timestamp for GL_ARB_timer_query (OpenGL), returns the current GPU clock */ -#define RADEON_INFO_TIMESTAMP 0x11 struct drm_radeon_info { uint32_t request; diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 4f2a76224509..3ad510b25283 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -96,7 +96,7 @@ void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); void acpi_numa_slit_init (struct acpi_table_slit *slit); void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa); -int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); +void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); void acpi_numa_arch_fixup(void); #ifdef CONFIG_ACPI_HOTPLUG_CPU diff --git a/trunk/include/linux/backing-dev.h b/trunk/include/linux/backing-dev.h index 2a9a9abc9126..c97c6b9cd38e 100644 --- a/trunk/include/linux/backing-dev.h +++ b/trunk/include/linux/backing-dev.h @@ -124,6 +124,7 @@ void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, void bdi_start_background_writeback(struct backing_dev_info *bdi); int bdi_writeback_thread(void *data); int bdi_has_dirty_io(struct backing_dev_info *bdi); +void bdi_arm_supers_timer(void); void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi); void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2); diff --git a/trunk/include/linux/can.h b/trunk/include/linux/can.h index e52958d7c2d1..018055efc034 100644 --- a/trunk/include/linux/can.h +++ b/trunk/include/linux/can.h @@ -74,21 +74,20 @@ struct can_frame { /* * defined bits for canfd_frame.flags * - * The use of struct canfd_frame implies the Extended Data Length (EDL) bit to - * be set in the CAN frame bitstream on the wire. The EDL bit switch turns - * the CAN controllers bitstream processor into the CAN FD mode which creates - * two new options within the CAN FD frame specification: + * As the default for CAN FD should be to support the high data rate in the + * payload section of the frame (HDR) and to support up to 64 byte in the + * data section (EDL) the bits are only set in the non-default case. + * Btw. as long as there's no real implementation for CAN FD network driver + * these bits are only preliminary. * - * Bit Rate Switch - to indicate a second bitrate is/was used for the payload - * Error State Indicator - represents the error state of the transmitting node - * - * As the CANFD_ESI bit is internally generated by the transmitting CAN - * controller only the CANFD_BRS bit is relevant for real CAN controllers when - * building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make - * sense for virtual CAN interfaces to test applications with echoed frames. + * RX: NOHDR/NOEDL - info about received CAN FD frame + * ESI - bit from originating CAN controller + * TX: NOHDR/NOEDL - control per-frame settings if supported by CAN controller + * ESI - bit is set by local CAN controller */ -#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */ -#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */ +#define CANFD_NOHDR 0x01 /* frame without high data rate */ +#define CANFD_NOEDL 0x02 /* frame without extended data length */ +#define CANFD_ESI 0x04 /* error state indicator */ /** * struct canfd_frame - CAN flexible data rate frame structure diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index aa110476a95b..38dba16c4176 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1491,6 +1491,7 @@ struct sb_writers { struct super_block { struct list_head s_list; /* Keep this first */ dev_t s_dev; /* search index; _not_ kdev_t */ + unsigned char s_dirt; unsigned char s_blocksize_bits; unsigned long s_blocksize; loff_t s_maxbytes; /* Max file size */ @@ -1860,6 +1861,7 @@ struct super_operations { int (*drop_inode) (struct inode *); void (*evict_inode) (struct inode *); void (*put_super) (struct super_block *); + void (*write_super) (struct super_block *); int (*sync_fs)(struct super_block *sb, int wait); int (*freeze_fs) (struct super_block *); int (*unfreeze_fs) (struct super_block *); @@ -2395,6 +2397,7 @@ extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync); extern int vfs_fsync(struct file *file, int datasync); extern int generic_write_sync(struct file *file, loff_t pos, loff_t count); +extern void sync_supers(void); extern void emergency_sync(void); extern void emergency_remount(void); #ifdef CONFIG_BLOCK diff --git a/trunk/include/linux/ftrace_event.h b/trunk/include/linux/ftrace_event.h index 642928cf57b4..af961d6f7ab1 100644 --- a/trunk/include/linux/ftrace_event.h +++ b/trunk/include/linux/ftrace_event.h @@ -306,10 +306,9 @@ extern void *perf_trace_buf_prepare(int size, unsigned short type, static inline void perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr, - u64 count, struct pt_regs *regs, void *head, - struct task_struct *task) + u64 count, struct pt_regs *regs, void *head) { - perf_tp_event(addr, count, raw_data, size, regs, head, rctx, task); + perf_tp_event(addr, count, raw_data, size, regs, head, rctx); } #endif diff --git a/trunk/include/linux/hardirq.h b/trunk/include/linux/hardirq.h index 305f23cd7cff..bb7f30971858 100644 --- a/trunk/include/linux/hardirq.h +++ b/trunk/include/linux/hardirq.h @@ -22,7 +22,7 @@ * * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024) * - bit 26 is the NMI_MASK - * - bit 27 is the PREEMPT_ACTIVE flag + * - bit 28 is the PREEMPT_ACTIVE flag * * PREEMPT_MASK: 0x000000ff * SOFTIRQ_MASK: 0x0000ff00 diff --git a/trunk/include/linux/if_team.h b/trunk/include/linux/if_team.h index aa2e167e1ef4..6960fc1841a7 100644 --- a/trunk/include/linux/if_team.h +++ b/trunk/include/linux/if_team.h @@ -96,6 +96,21 @@ static inline void team_netpoll_send_skb(struct team_port *port, } #endif +static inline int team_dev_queue_xmit(struct team *team, struct team_port *port, + struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(skb->queue_mapping) != + sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); + skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping); + + skb->dev = port->dev; + if (unlikely(netpoll_tx_running(port->dev))) { + team_netpoll_send_skb(port, skb); + return 0; + } + return dev_queue_xmit(skb); +} + struct team_mode_ops { int (*init)(struct team *team); void (*exit)(struct team *team); @@ -185,21 +200,6 @@ struct team { long mode_priv[TEAM_MODE_PRIV_LONGS]; }; -static inline int team_dev_queue_xmit(struct team *team, struct team_port *port, - struct sk_buff *skb) -{ - BUILD_BUG_ON(sizeof(skb->queue_mapping) != - sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); - skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping); - - skb->dev = port->dev; - if (unlikely(netpoll_tx_running(team->dev))) { - team_netpoll_send_skb(port, skb); - return 0; - } - return dev_queue_xmit(skb); -} - static inline struct hlist_head *team_port_index_hash(struct team *team, int port_index) { diff --git a/trunk/include/linux/input/eeti_ts.h b/trunk/include/linux/input/eeti_ts.h index 16625d799b6f..f875b316249d 100644 --- a/trunk/include/linux/input/eeti_ts.h +++ b/trunk/include/linux/input/eeti_ts.h @@ -2,7 +2,6 @@ #define LINUX_INPUT_EETI_TS_H struct eeti_ts_platform_data { - int irq_gpio; unsigned int irq_active_high; }; diff --git a/trunk/include/linux/iommu.h b/trunk/include/linux/iommu.h index 7e83370e6fd2..54d6d690073c 100644 --- a/trunk/include/linux/iommu.h +++ b/trunk/include/linux/iommu.h @@ -20,7 +20,6 @@ #define __LINUX_IOMMU_H #include -#include #define IOMMU_READ (1) #define IOMMU_WRITE (2) @@ -31,7 +30,6 @@ struct iommu_group; struct bus_type; struct device; struct iommu_domain; -struct notifier_block; /* iommu fault flags */ #define IOMMU_FAULT_READ 0x0 diff --git a/trunk/include/linux/ipv6.h b/trunk/include/linux/ipv6.h index 879db26ec401..379e433e15e0 100644 --- a/trunk/include/linux/ipv6.h +++ b/trunk/include/linux/ipv6.h @@ -369,7 +369,6 @@ struct ipv6_pinfo { __u8 rcv_tclass; __u32 dst_cookie; - __u32 rx_dst_cookie; struct ipv6_mc_socklist __rcu *ipv6_mc_list; struct ipv6_ac_socklist *ipv6_ac_list; diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 216b0ba109d7..553fb66da130 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -349,7 +349,6 @@ enum { IRQCHIP_MASK_ON_SUSPEND = (1 << 2), IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), IRQCHIP_SKIP_SET_WAKE = (1 << 4), - IRQCHIP_ONESHOT_SAFE = (1 << 5), }; /* This include will go away once we isolated irq_desc usage to core code */ diff --git a/trunk/include/linux/jiffies.h b/trunk/include/linux/jiffies.h index 82680541576d..265e2c3cbd1c 100644 --- a/trunk/include/linux/jiffies.h +++ b/trunk/include/linux/jiffies.h @@ -39,6 +39,9 @@ # error Invalid value of HZ. #endif +/* LATCH is used in the interval timer and ftape setup. */ +#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ + /* Suppose we want to divide two numbers NOM and DEN: NOM/DEN, then we can * improve accuracy by shifting LSH bits, hence calculating: * (NOM << LSH) / DEN @@ -51,30 +54,18 @@ #define SH_DIV(NOM,DEN,LSH) ( (((NOM) / (DEN)) << (LSH)) \ + ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN)) -#ifdef CLOCK_TICK_RATE -/* LATCH is used in the interval timer and ftape setup. */ -# define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ - -/* - * HZ is the requested value. However the CLOCK_TICK_RATE may not allow - * for exactly HZ. So SHIFTED_HZ is high res HZ ("<< 8" is for accuracy) - */ -# define SHIFTED_HZ (SH_DIV(CLOCK_TICK_RATE, LATCH, 8)) -#else -# define SHIFTED_HZ (HZ << 8) -#endif +/* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */ +#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8)) -/* TICK_NSEC is the time between ticks in nsec assuming SHIFTED_HZ */ -#define TICK_NSEC (SH_DIV(1000000UL * 1000, SHIFTED_HZ, 8)) +/* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */ +#define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8)) /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */ #define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ) -/* - * TICK_USEC_TO_NSEC is the time between ticks in nsec assuming SHIFTED_HZ and - * a value TUSEC for TICK_USEC (can be set bij adjtimex) - */ -#define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV(TUSEC * USER_HZ * 1000, SHIFTED_HZ, 8)) +/* TICK_USEC_TO_NSEC is the time between ticks in nsec assuming real ACTHZ and */ +/* a value TUSEC for TICK_USEC (can be set bij adjtimex) */ +#define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8)) /* some arch's have a small-data section that can be accessed register-relative * but that can only take up to, say, 4-byte variables. jiffies being part of diff --git a/trunk/include/linux/kdb.h b/trunk/include/linux/kdb.h index 42d9e863a313..064725854db8 100644 --- a/trunk/include/linux/kdb.h +++ b/trunk/include/linux/kdb.h @@ -75,6 +75,8 @@ extern const char *kdb_diemsg; #define KDB_FLAG_CATASTROPHIC (1 << 1) /* A catastrophic event has occurred */ #define KDB_FLAG_CMD_INTERRUPT (1 << 2) /* Previous command was interrupted */ #define KDB_FLAG_NOIPI (1 << 3) /* Do not send IPIs */ +#define KDB_FLAG_ONLY_DO_DUMP (1 << 4) /* Only do a dump, used when + * kdb is off */ #define KDB_FLAG_NO_CONSOLE (1 << 5) /* No console is available, * kdb is disabled */ #define KDB_FLAG_NO_VT_CONSOLE (1 << 6) /* No VT console is available, do diff --git a/trunk/include/linux/mfd/ezx-pcap.h b/trunk/include/linux/mfd/ezx-pcap.h index 32a1b5cfeba1..40c372165f3e 100644 --- a/trunk/include/linux/mfd/ezx-pcap.h +++ b/trunk/include/linux/mfd/ezx-pcap.h @@ -16,7 +16,6 @@ struct pcap_subdev { struct pcap_platform_data { unsigned int irq_base; unsigned int config; - int gpio; void (*init) (void *); /* board specific init */ int num_subdevs; struct pcap_subdev *subdevs; diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 3560d688161e..a9db4f33407f 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -953,8 +953,7 @@ struct net_device_ops { #ifdef CONFIG_NET_POLL_CONTROLLER void (*ndo_poll_controller)(struct net_device *dev); int (*ndo_netpoll_setup)(struct net_device *dev, - struct netpoll_info *info, - gfp_t gfp); + struct netpoll_info *info); void (*ndo_netpoll_cleanup)(struct net_device *dev); #endif int (*ndo_set_vf_mac)(struct net_device *dev, diff --git a/trunk/include/linux/netpoll.h b/trunk/include/linux/netpoll.h index 66d5379c305e..28f5389c924b 100644 --- a/trunk/include/linux/netpoll.h +++ b/trunk/include/linux/netpoll.h @@ -23,7 +23,6 @@ struct netpoll { u8 remote_mac[ETH_ALEN]; struct list_head rx; /* rx_np list element */ - struct rcu_head rcu; }; struct netpoll_info { @@ -39,40 +38,28 @@ struct netpoll_info { struct delayed_work tx_work; struct netpoll *netpoll; - struct rcu_head rcu; }; void netpoll_send_udp(struct netpoll *np, const char *msg, int len); void netpoll_print_options(struct netpoll *np); int netpoll_parse_options(struct netpoll *np, char *opt); -int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp); +int __netpoll_setup(struct netpoll *np, struct net_device *ndev); int netpoll_setup(struct netpoll *np); int netpoll_trap(void); void netpoll_set_trap(int trap); void __netpoll_cleanup(struct netpoll *np); -void __netpoll_free_rcu(struct netpoll *np); void netpoll_cleanup(struct netpoll *np); -int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo); +int __netpoll_rx(struct sk_buff *skb); void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, struct net_device *dev); static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) { - unsigned long flags; - local_irq_save(flags); netpoll_send_skb_on_dev(np, skb, np->dev); - local_irq_restore(flags); } #ifdef CONFIG_NETPOLL -static inline bool netpoll_rx_on(struct sk_buff *skb) -{ - struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo); - - return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags); -} - static inline bool netpoll_rx(struct sk_buff *skb) { struct netpoll_info *npinfo; @@ -80,14 +67,14 @@ static inline bool netpoll_rx(struct sk_buff *skb) bool ret = false; local_irq_save(flags); + npinfo = rcu_dereference_bh(skb->dev->npinfo); - if (!netpoll_rx_on(skb)) + if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags)) goto out; - npinfo = rcu_dereference_bh(skb->dev->npinfo); spin_lock(&npinfo->rx_lock); /* check rx_flags again with the lock held */ - if (npinfo->rx_flags && __netpoll_rx(skb, npinfo)) + if (npinfo->rx_flags && __netpoll_rx(skb)) ret = true; spin_unlock(&npinfo->rx_lock); @@ -96,6 +83,13 @@ static inline bool netpoll_rx(struct sk_buff *skb) return ret; } +static inline int netpoll_rx_on(struct sk_buff *skb) +{ + struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo); + + return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags); +} + static inline int netpoll_receive_skb(struct sk_buff *skb) { if (!list_empty(&skb->dev->napi_list)) @@ -125,7 +119,7 @@ static inline void netpoll_poll_unlock(void *have) } } -static inline bool netpoll_tx_running(struct net_device *dev) +static inline int netpoll_tx_running(struct net_device *dev) { return irqs_disabled(); } @@ -133,11 +127,11 @@ static inline bool netpoll_tx_running(struct net_device *dev) #else static inline bool netpoll_rx(struct sk_buff *skb) { - return false; + return 0; } -static inline bool netpoll_rx_on(struct sk_buff *skb) +static inline int netpoll_rx_on(struct sk_buff *skb) { - return false; + return 0; } static inline int netpoll_receive_skb(struct sk_buff *skb) { @@ -153,9 +147,9 @@ static inline void netpoll_poll_unlock(void *have) static inline void netpoll_netdev_init(struct net_device *dev) { } -static inline bool netpoll_tx_running(struct net_device *dev) +static inline int netpoll_tx_running(struct net_device *dev) { - return false; + return 0; } #endif diff --git a/trunk/include/linux/olpc-ec.h b/trunk/include/linux/olpc-ec.h deleted file mode 100644 index 5bb6e760aa61..000000000000 --- a/trunk/include/linux/olpc-ec.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _LINUX_OLPC_EC_H -#define _LINUX_OLPC_EC_H - -/* XO-1 EC commands */ -#define EC_FIRMWARE_REV 0x08 -#define EC_WRITE_SCI_MASK 0x1b -#define EC_WAKE_UP_WLAN 0x24 -#define EC_WLAN_LEAVE_RESET 0x25 -#define EC_READ_EB_MODE 0x2a -#define EC_SET_SCI_INHIBIT 0x32 -#define EC_SET_SCI_INHIBIT_RELEASE 0x34 -#define EC_WLAN_ENTER_RESET 0x35 -#define EC_WRITE_EXT_SCI_MASK 0x38 -#define EC_SCI_QUERY 0x84 -#define EC_EXT_SCI_QUERY 0x85 - -struct platform_device; - -struct olpc_ec_driver { - int (*probe)(struct platform_device *); - int (*suspend)(struct platform_device *); - int (*resume)(struct platform_device *); - - int (*ec_cmd)(u8, u8 *, size_t, u8 *, size_t, void *); -}; - -#ifdef CONFIG_OLPC - -extern void olpc_ec_driver_register(struct olpc_ec_driver *drv, void *arg); - -extern int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, - size_t outlen); - -#else - -static inline int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, - size_t outlen) { return -ENODEV; } - -#endif /* CONFIG_OLPC */ - -#endif /* _LINUX_OLPC_EC_H */ diff --git a/trunk/include/linux/perf_event.h b/trunk/include/linux/perf_event.h index 7602ccb3f40e..76c5c8b724a7 100644 --- a/trunk/include/linux/perf_event.h +++ b/trunk/include/linux/perf_event.h @@ -1272,8 +1272,7 @@ static inline bool perf_paranoid_kernel(void) extern void perf_event_init(void); extern void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, struct pt_regs *regs, - struct hlist_head *head, int rctx, - struct task_struct *task); + struct hlist_head *head, int rctx); extern void perf_bp_event(struct perf_event *event, void *data); #ifndef perf_misc_flags diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index b8c86648a2f9..c147e7024f11 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -334,6 +334,14 @@ static inline void lockup_detector_init(void) } #endif +#if defined(CONFIG_LOCKUP_DETECTOR) && defined(CONFIG_SUSPEND) +void lockup_detector_bootcpu_resume(void); +#else +static inline void lockup_detector_bootcpu_resume(void) +{ +} +#endif + #ifdef CONFIG_DETECT_HUNG_TASK extern unsigned int sysctl_hung_task_panic; extern unsigned long sysctl_hung_task_check_count; diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index 3dea6a9d568f..4e5a73cdbbef 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -1242,6 +1242,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * Check that the @parent process has sufficient permission to trace the * current process before allowing the current process to present itself * to the @parent process for tracing. + * The parent process will still have to undergo the ptrace_access_check + * checks before it is allowed to trace this one. * @parent contains the task_struct structure for debugger process. * Return 0 if permission is granted. * @capget: diff --git a/trunk/include/linux/shdma-base.h b/trunk/include/linux/shdma-base.h index a3728bf66f0e..93f9821554b6 100644 --- a/trunk/include/linux/shdma-base.h +++ b/trunk/include/linux/shdma-base.h @@ -50,7 +50,6 @@ struct shdma_desc { struct list_head node; struct dma_async_tx_descriptor async_tx; enum dma_transfer_direction direction; - size_t partial; dma_cookie_t cookie; int chunks; int mark; @@ -99,7 +98,6 @@ struct shdma_ops { void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); struct shdma_desc *(*embedded_desc)(void *, int); bool (*chan_irq)(struct shdma_chan *, int); - size_t (*get_partial)(struct shdma_chan *, struct shdma_desc *); }; struct shdma_dev { diff --git a/trunk/include/linux/timex.h b/trunk/include/linux/timex.h index 7c5ceb20e03a..99bc88b1fc02 100644 --- a/trunk/include/linux/timex.h +++ b/trunk/include/linux/timex.h @@ -232,7 +232,7 @@ struct timex { * estimated error = NTP dispersion. */ extern unsigned long tick_usec; /* USER_HZ period (usec) */ -extern unsigned long tick_nsec; /* SHIFTED_HZ period (nsec) */ +extern unsigned long tick_nsec; /* ACTHZ period (nsec) */ extern void ntp_init(void); extern void ntp_clear(void); diff --git a/trunk/include/linux/topology.h b/trunk/include/linux/topology.h index fec12d667211..e91cd43394df 100644 --- a/trunk/include/linux/topology.h +++ b/trunk/include/linux/topology.h @@ -164,7 +164,6 @@ int arch_update_cpu_topology(void); | 0*SD_SHARE_CPUPOWER \ | 0*SD_SHARE_PKG_RESOURCES \ | 0*SD_SERIALIZE \ - | 1*SD_PREFER_SIBLING \ , \ .last_balance = jiffies, \ .balance_interval = 1, \ diff --git a/trunk/include/linux/writeback.h b/trunk/include/linux/writeback.h index 50c3e8fa06a8..c66fe3332d83 100644 --- a/trunk/include/linux/writeback.h +++ b/trunk/include/linux/writeback.h @@ -104,6 +104,7 @@ static inline void wait_on_inode(struct inode *inode) wait_on_bit(&inode->i_state, __I_NEW, inode_wait, TASK_UNINTERRUPTIBLE); } + /* * mm/page-writeback.c */ diff --git a/trunk/include/net/codel.h b/trunk/include/net/codel.h index 389cf621161d..550debfc2403 100644 --- a/trunk/include/net/codel.h +++ b/trunk/include/net/codel.h @@ -305,8 +305,6 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch, } } } else if (drop) { - u32 delta; - if (params->ecn && INET_ECN_set_ce(skb)) { stats->ecn_mark++; } else { @@ -322,11 +320,9 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch, * assume that the drop rate that controlled the queue on the * last cycle is a good starting point to control it now. */ - delta = vars->count - vars->lastcount; - if (delta > 1 && - codel_time_before(now - vars->drop_next, + if (codel_time_before(now - vars->drop_next, 16 * params->interval)) { - vars->count = delta; + vars->count = (vars->count - vars->lastcount) | 1; /* we dont care if rec_inv_sqrt approximation * is not very precise : * Next Newton steps will correct it quadratically. diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index 621e3513ef5e..baf597890064 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -110,7 +110,7 @@ struct dst_entry { }; extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old); -extern const u32 dst_default_metrics[]; +extern const u32 dst_default_metrics[RTAX_MAX]; #define DST_METRICS_READ_ONLY 0x1UL #define __DST_METRICS_PTR(Y) \ diff --git a/trunk/include/net/inet_connection_sock.h b/trunk/include/net/inet_connection_sock.h index ba1d3615acbb..5ee66f517b4f 100644 --- a/trunk/include/net/inet_connection_sock.h +++ b/trunk/include/net/inet_connection_sock.h @@ -39,7 +39,6 @@ struct inet_connection_sock_af_ops { int (*queue_xmit)(struct sk_buff *skb, struct flowi *fl); void (*send_check)(struct sock *sk, struct sk_buff *skb); int (*rebuild_header)(struct sock *sk); - void (*sk_rx_dst_set)(struct sock *sk, const struct sk_buff *skb); int (*conn_request)(struct sock *sk, struct sk_buff *skb); struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb, struct request_sock *req, diff --git a/trunk/include/net/inet_sock.h b/trunk/include/net/inet_sock.h index 613cfa401672..83b567fe1941 100644 --- a/trunk/include/net/inet_sock.h +++ b/trunk/include/net/inet_sock.h @@ -249,4 +249,13 @@ static inline __u8 inet_sk_flowi_flags(const struct sock *sk) return flags; } +static inline void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) +{ + struct dst_entry *dst = skb_dst(skb); + + dst_hold(dst); + sk->sk_rx_dst = dst; + inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; +} + #endif /* _INET_SOCK_H */ diff --git a/trunk/include/net/ip.h b/trunk/include/net/ip.h index 5a5d84d3d2c6..bd5e444a19ce 100644 --- a/trunk/include/net/ip.h +++ b/trunk/include/net/ip.h @@ -120,7 +120,7 @@ extern struct sk_buff *__ip_make_skb(struct sock *sk, struct flowi4 *fl4, struct sk_buff_head *queue, struct inet_cork *cork); -extern int ip_send_skb(struct net *net, struct sk_buff *skb); +extern int ip_send_skb(struct sk_buff *skb); extern int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4); extern void ip_flush_pending_frames(struct sock *sk); extern struct sk_buff *ip_make_skb(struct sock *sk, diff --git a/trunk/include/net/llc.h b/trunk/include/net/llc.h index f2d0fc570527..226c846cab08 100644 --- a/trunk/include/net/llc.h +++ b/trunk/include/net/llc.h @@ -133,7 +133,7 @@ extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb, extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb); extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb); -extern void llc_station_init(void); +extern int llc_station_init(void); extern void llc_station_exit(void); #ifdef CONFIG_PROC_FS diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index 1f000ffe7075..e19124b84cd2 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -464,7 +464,6 @@ extern int tcp_disconnect(struct sock *sk, int flags); void tcp_connect_init(struct sock *sk); void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size); -void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb); /* From syncookies.c */ extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS]; diff --git a/trunk/include/trace/events/sched.h b/trunk/include/trace/events/sched.h index 5a8671e8a67f..ea7a2035456d 100644 --- a/trunk/include/trace/events/sched.h +++ b/trunk/include/trace/events/sched.h @@ -73,9 +73,6 @@ DECLARE_EVENT_CLASS(sched_wakeup_template, __entry->prio = p->prio; __entry->success = success; __entry->target_cpu = task_cpu(p); - ) - TP_perf_assign( - __perf_task(p); ), TP_printk("comm=%s pid=%d prio=%d success=%d target_cpu=%03d", @@ -328,7 +325,6 @@ DECLARE_EVENT_CLASS(sched_stat_template, ) TP_perf_assign( __perf_count(delay); - __perf_task(tsk); ), TP_printk("comm=%s pid=%d delay=%Lu [ns]", diff --git a/trunk/include/trace/ftrace.h b/trunk/include/trace/ftrace.h index a763888a36f9..c6bc2faaf261 100644 --- a/trunk/include/trace/ftrace.h +++ b/trunk/include/trace/ftrace.h @@ -712,9 +712,6 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call #undef __perf_count #define __perf_count(c) __count = (c) -#undef __perf_task -#define __perf_task(t) __task = (t) - #undef TP_perf_assign #define TP_perf_assign(args...) args @@ -728,7 +725,6 @@ perf_trace_##call(void *__data, proto) \ struct ftrace_raw_##call *entry; \ struct pt_regs __regs; \ u64 __addr = 0, __count = 1; \ - struct task_struct *__task = NULL; \ struct hlist_head *head; \ int __entry_size; \ int __data_size; \ @@ -756,7 +752,7 @@ perf_trace_##call(void *__data, proto) \ \ head = this_cpu_ptr(event_call->perf_events); \ perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ - __count, &__regs, head, __task); \ + __count, &__regs, head); \ } /* diff --git a/trunk/kernel/debug/kdb/kdb_debugger.c b/trunk/kernel/debug/kdb/kdb_debugger.c index be7b33b73d30..8b68ce78ff17 100644 --- a/trunk/kernel/debug/kdb/kdb_debugger.c +++ b/trunk/kernel/debug/kdb/kdb_debugger.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "kdb_private.h" #include "../debug_core.h" @@ -53,9 +52,6 @@ int kdb_stub(struct kgdb_state *ks) if (atomic_read(&kgdb_setting_breakpoint)) reason = KDB_REASON_KEYBOARD; - if (in_nmi()) - reason = KDB_REASON_NMI; - for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { if ((bp->bp_enabled) && (bp->bp_addr == addr)) { reason = KDB_REASON_BREAK; diff --git a/trunk/kernel/debug/kdb/kdb_io.c b/trunk/kernel/debug/kdb/kdb_io.c index 0a69d2adc4f3..bb9520f0f6ff 100644 --- a/trunk/kernel/debug/kdb/kdb_io.c +++ b/trunk/kernel/debug/kdb/kdb_io.c @@ -715,6 +715,9 @@ int vkdb_printf(const char *fmt, va_list ap) /* check for having reached the LINES number of printed lines */ if (kdb_nextline == linecount) { char buf1[16] = ""; +#if defined(CONFIG_SMP) + char buf2[32]; +#endif /* Watch out for recursion here. Any routine that calls * kdb_printf will come back through here. And kdb_read @@ -729,6 +732,14 @@ int vkdb_printf(const char *fmt, va_list ap) if (moreprompt == NULL) moreprompt = "more> "; +#if defined(CONFIG_SMP) + if (strchr(moreprompt, '%')) { + sprintf(buf2, moreprompt, get_cpu()); + put_cpu(); + moreprompt = buf2; + } +#endif + kdb_input_flush(); c = console_drivers; diff --git a/trunk/kernel/debug/kdb/kdb_main.c b/trunk/kernel/debug/kdb/kdb_main.c index 31df1706b9a9..1f91413edb87 100644 --- a/trunk/kernel/debug/kdb/kdb_main.c +++ b/trunk/kernel/debug/kdb/kdb_main.c @@ -139,10 +139,11 @@ static const int __nkdb_err = sizeof(kdbmsgs) / sizeof(kdbmsg_t); static char *__env[] = { #if defined(CONFIG_SMP) "PROMPT=[%d]kdb> ", + "MOREPROMPT=[%d]more> ", #else "PROMPT=kdb> ", -#endif "MOREPROMPT=more> ", +#endif "RADIX=16", "MDCOUNT=8", /* lines of md output */ KDB_PLATFORM_ENV, @@ -1235,6 +1236,18 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, *cmdbuf = '\0'; *(cmd_hist[cmd_head]) = '\0'; + if (KDB_FLAG(ONLY_DO_DUMP)) { + /* kdb is off but a catastrophic error requires a dump. + * Take the dump and reboot. + * Turn on logging so the kdb output appears in the log + * buffer in the dump. + */ + const char *setargs[] = { "set", "LOGGING", "1" }; + kdb_set(2, setargs); + kdb_reboot(0, NULL); + /*NOTREACHED*/ + } + do_full_getstr: #if defined(CONFIG_SMP) snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), diff --git a/trunk/kernel/events/callchain.c b/trunk/kernel/events/callchain.c index 98d4597f43d6..6581a040f399 100644 --- a/trunk/kernel/events/callchain.c +++ b/trunk/kernel/events/callchain.c @@ -153,8 +153,7 @@ put_callchain_entry(int rctx) put_recursion_context(__get_cpu_var(callchain_recursion), rctx); } -struct perf_callchain_entry * -perf_callchain(struct perf_event *event, struct pt_regs *regs) +struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) { int rctx; struct perf_callchain_entry *entry; @@ -179,12 +178,6 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs) } if (regs) { - /* - * Disallow cross-task user callchains. - */ - if (event->ctx->task && event->ctx->task != current) - goto exit_put; - perf_callchain_store(entry, PERF_CONTEXT_USER); perf_callchain_user(entry, regs); } diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index b7935fcec7d9..f1cf0edeb39a 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -4039,7 +4039,7 @@ void perf_prepare_sample(struct perf_event_header *header, if (sample_type & PERF_SAMPLE_CALLCHAIN) { int size = 1; - data->callchain = perf_callchain(event, regs); + data->callchain = perf_callchain(regs); if (data->callchain) size += data->callchain->nr; @@ -5209,8 +5209,7 @@ static int perf_tp_event_match(struct perf_event *event, } void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, - struct pt_regs *regs, struct hlist_head *head, int rctx, - struct task_struct *task) + struct pt_regs *regs, struct hlist_head *head, int rctx) { struct perf_sample_data data; struct perf_event *event; @@ -5229,31 +5228,6 @@ void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, perf_swevent_event(event, count, &data, regs); } - /* - * If we got specified a target task, also iterate its context and - * deliver this event there too. - */ - if (task && task != current) { - struct perf_event_context *ctx; - struct trace_entry *entry = record; - - rcu_read_lock(); - ctx = rcu_dereference(task->perf_event_ctxp[perf_sw_context]); - if (!ctx) - goto unlock; - - list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { - if (event->attr.type != PERF_TYPE_TRACEPOINT) - continue; - if (event->attr.config != entry->type) - continue; - if (perf_tp_event_match(event, &data, regs)) - perf_swevent_event(event, count, &data, regs); - } -unlock: - rcu_read_unlock(); - } - perf_swevent_put_recursion_context(rctx); } EXPORT_SYMBOL_GPL(perf_tp_event); diff --git a/trunk/kernel/events/internal.h b/trunk/kernel/events/internal.h index a096c19f2c2a..b0b107f90afc 100644 --- a/trunk/kernel/events/internal.h +++ b/trunk/kernel/events/internal.h @@ -101,8 +101,7 @@ __output_copy(struct perf_output_handle *handle, } /* Callchain handling */ -extern struct perf_callchain_entry * -perf_callchain(struct perf_event *event, struct pt_regs *regs); +extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs); extern int get_callchain_buffers(void); extern void put_callchain_buffers(void); diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 3717e7b306e0..e2b0fb9a0b3b 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -2231,11 +2231,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, * @uaddr2: the pi futex we will take prior to returning to user-space * * The caller will wait on uaddr and will be requeued by futex_requeue() to - * uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake - * on uaddr2 and complete the acquisition of the rt_mutex prior to returning to - * userspace. This ensures the rt_mutex maintains an owner when it has waiters; - * without one, the pi logic would not know which task to boost/deboost, if - * there was a need to. + * uaddr2 which must be PI aware. Normal wakeup will wake on uaddr2 and + * complete the acquisition of the rt_mutex prior to returning to userspace. + * This ensures the rt_mutex maintains an owner when it has waiters; without + * one, the pi logic wouldn't know which task to boost/deboost, if there was a + * need to. * * We call schedule in futex_wait_queue_me() when we enqueue and return there * via the following: @@ -2272,9 +2272,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, struct futex_q q = futex_q_init; int res, ret; - if (uaddr == uaddr2) - return -EINVAL; - if (!bitset) return -EINVAL; @@ -2346,7 +2343,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, * signal. futex_unlock_pi() will not destroy the lock_ptr nor * the pi_state. */ - WARN_ON(!q.pi_state); + WARN_ON(!&q.pi_state); pi_mutex = &q.pi_state->pi_mutex; ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); debug_rt_mutex_free_waiter(&rt_waiter); @@ -2373,7 +2370,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, * fault, unlock the rt_mutex and return the fault to userspace. */ if (ret == -EFAULT) { - if (pi_mutex && rt_mutex_owner(pi_mutex) == current) + if (rt_mutex_owner(pi_mutex) == current) rt_mutex_unlock(pi_mutex); } else if (ret == -EINTR) { /* diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 4c69326aa773..0a8e8f059627 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -943,18 +943,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) goto out_thread; } - /* - * Drivers are often written to work w/o knowledge about the - * underlying irq chip implementation, so a request for a - * threaded irq without a primary hard irq context handler - * requires the ONESHOT flag to be set. Some irq chips like - * MSI based interrupts are per se one shot safe. Check the - * chip flags, so we can avoid the unmask dance at the end of - * the threaded handler for those. - */ - if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE) - new->flags &= ~IRQF_ONESHOT; - /* * The following block of code has to be executed atomically */ @@ -1029,8 +1017,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) */ new->thread_mask = 1 << ffz(thread_mask); - } else if (new->handler == irq_default_primary_handler && - !(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) { + } else if (new->handler == irq_default_primary_handler) { /* * The interrupt was requested with handler = NULL, so * we use the default primary handler for it. But it diff --git a/trunk/kernel/power/suspend.c b/trunk/kernel/power/suspend.c index c8b7446b27df..1da39ea248fd 100644 --- a/trunk/kernel/power/suspend.c +++ b/trunk/kernel/power/suspend.c @@ -178,6 +178,9 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); + /* Kick the lockup detector */ + lockup_detector_bootcpu_resume(); + Enable_cpus: enable_nonboot_cpus(); diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 66a2ea37b576..6a76ab9d4476 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -1034,7 +1034,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear) struct log *msg = log_from_idx(idx); len += msg_print_text(msg, prev, true, NULL, 0); - prev = msg->flags; idx = log_next(idx); seq++; } @@ -1047,7 +1046,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear) struct log *msg = log_from_idx(idx); len -= msg_print_text(msg, prev, true, NULL, 0); - prev = msg->flags; idx = log_next(idx); seq++; } diff --git a/trunk/kernel/sched/core.c b/trunk/kernel/sched/core.c index 82ad284f823b..d325c4b2dcbb 100644 --- a/trunk/kernel/sched/core.c +++ b/trunk/kernel/sched/core.c @@ -4340,7 +4340,9 @@ static int __sched_setscheduler(struct task_struct *p, int policy, */ if (unlikely(policy == p->policy && (!rt_policy(policy) || param->sched_priority == p->rt_priority))) { - task_rq_unlock(rq, p, &flags); + + __task_rq_unlock(rq); + raw_spin_unlock_irqrestore(&p->pi_lock, flags); return 0; } diff --git a/trunk/kernel/sched/cpupri.c b/trunk/kernel/sched/cpupri.c index 23aa789c53ee..d72586fdf660 100644 --- a/trunk/kernel/sched/cpupri.c +++ b/trunk/kernel/sched/cpupri.c @@ -65,8 +65,8 @@ static int convert_prio(int prio) int cpupri_find(struct cpupri *cp, struct task_struct *p, struct cpumask *lowest_mask) { - int idx = 0; - int task_pri = convert_prio(p->prio); + int idx = 0; + int task_pri = convert_prio(p->prio); if (task_pri >= MAX_RT_PRIO) return 0; @@ -137,9 +137,9 @@ int cpupri_find(struct cpupri *cp, struct task_struct *p, */ void cpupri_set(struct cpupri *cp, int cpu, int newpri) { - int *currpri = &cp->cpu_to_pri[cpu]; - int oldpri = *currpri; - int do_mb = 0; + int *currpri = &cp->cpu_to_pri[cpu]; + int oldpri = *currpri; + int do_mb = 0; newpri = convert_prio(newpri); diff --git a/trunk/kernel/sched/fair.c b/trunk/kernel/sched/fair.c index d0cc03b3e70b..22321db64952 100644 --- a/trunk/kernel/sched/fair.c +++ b/trunk/kernel/sched/fair.c @@ -3069,9 +3069,6 @@ struct lb_env { int new_dst_cpu; enum cpu_idle_type idle; long imbalance; - /* The set of CPUs under consideration for load-balancing */ - struct cpumask *cpus; - unsigned int flags; unsigned int loop; @@ -3656,7 +3653,8 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group) */ static inline void update_sg_lb_stats(struct lb_env *env, struct sched_group *group, int load_idx, - int local_group, int *balance, struct sg_lb_stats *sgs) + int local_group, const struct cpumask *cpus, + int *balance, struct sg_lb_stats *sgs) { unsigned long nr_running, max_nr_running, min_nr_running; unsigned long load, max_cpu_load, min_cpu_load; @@ -3673,7 +3671,7 @@ static inline void update_sg_lb_stats(struct lb_env *env, max_nr_running = 0; min_nr_running = ~0UL; - for_each_cpu_and(i, sched_group_cpus(group), env->cpus) { + for_each_cpu_and(i, sched_group_cpus(group), cpus) { struct rq *rq = cpu_rq(i); nr_running = rq->nr_running; @@ -3802,7 +3800,8 @@ static bool update_sd_pick_busiest(struct lb_env *env, * @sds: variable to hold the statistics for this sched_domain. */ static inline void update_sd_lb_stats(struct lb_env *env, - int *balance, struct sd_lb_stats *sds) + const struct cpumask *cpus, + int *balance, struct sd_lb_stats *sds) { struct sched_domain *child = env->sd->child; struct sched_group *sg = env->sd->groups; @@ -3819,7 +3818,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, local_group = cpumask_test_cpu(env->dst_cpu, sched_group_cpus(sg)); memset(&sgs, 0, sizeof(sgs)); - update_sg_lb_stats(env, sg, load_idx, local_group, balance, &sgs); + update_sg_lb_stats(env, sg, load_idx, local_group, + cpus, balance, &sgs); if (local_group && !(*balance)) return; @@ -4055,6 +4055,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s * to restore balance. * * @env: The load balancing environment. + * @cpus: The set of CPUs under consideration for load-balancing. * @balance: Pointer to a variable indicating if this_cpu * is the appropriate cpu to perform load balancing at this_level. * @@ -4064,7 +4065,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s * put to idle by rebalancing its tasks onto our group. */ static struct sched_group * -find_busiest_group(struct lb_env *env, int *balance) +find_busiest_group(struct lb_env *env, const struct cpumask *cpus, int *balance) { struct sd_lb_stats sds; @@ -4074,7 +4075,7 @@ find_busiest_group(struct lb_env *env, int *balance) * Compute the various statistics relavent for load balancing at * this level. */ - update_sd_lb_stats(env, balance, &sds); + update_sd_lb_stats(env, cpus, balance, &sds); /* * this_cpu is not the appropriate cpu to perform load balancing at @@ -4154,7 +4155,8 @@ find_busiest_group(struct lb_env *env, int *balance) * find_busiest_queue - find the busiest runqueue among the cpus in group. */ static struct rq *find_busiest_queue(struct lb_env *env, - struct sched_group *group) + struct sched_group *group, + const struct cpumask *cpus) { struct rq *busiest = NULL, *rq; unsigned long max_load = 0; @@ -4169,7 +4171,7 @@ static struct rq *find_busiest_queue(struct lb_env *env, if (!capacity) capacity = fix_small_capacity(env->sd, group); - if (!cpumask_test_cpu(i, env->cpus)) + if (!cpumask_test_cpu(i, cpus)) continue; rq = cpu_rq(i); @@ -4250,7 +4252,6 @@ static int load_balance(int this_cpu, struct rq *this_rq, .dst_grpmask = sched_group_cpus(sd->groups), .idle = idle, .loop_break = sched_nr_migrate_break, - .cpus = cpus, }; cpumask_copy(cpus, cpu_active_mask); @@ -4259,7 +4260,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, schedstat_inc(sd, lb_count[idle]); redo: - group = find_busiest_group(&env, balance); + group = find_busiest_group(&env, cpus, balance); if (*balance == 0) goto out_balanced; @@ -4269,7 +4270,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, goto out_balanced; } - busiest = find_busiest_queue(&env, group); + busiest = find_busiest_queue(&env, group, cpus); if (!busiest) { schedstat_inc(sd, lb_nobusyq[idle]); goto out_balanced; diff --git a/trunk/kernel/time/jiffies.c b/trunk/kernel/time/jiffies.c index 46da0537c10b..a470154e0408 100644 --- a/trunk/kernel/time/jiffies.c +++ b/trunk/kernel/time/jiffies.c @@ -37,7 +37,7 @@ * requested HZ value. It is also not recommended * for "tick-less" systems. */ -#define NSEC_PER_JIFFY ((u32)((((u64)NSEC_PER_SEC)<<8)/SHIFTED_HZ)) +#define NSEC_PER_JIFFY ((u32)((((u64)NSEC_PER_SEC)<<8)/ACTHZ)) /* Since jiffies uses a simple NSEC_PER_JIFFY multiplier * conversion, the .shift value could be zero. However diff --git a/trunk/kernel/time/ntp.c b/trunk/kernel/time/ntp.c index 24174b4d669b..b7fbadc5c973 100644 --- a/trunk/kernel/time/ntp.c +++ b/trunk/kernel/time/ntp.c @@ -28,7 +28,7 @@ DEFINE_SPINLOCK(ntp_lock); /* USER_HZ period (usecs): */ unsigned long tick_usec = TICK_USEC; -/* SHIFTED_HZ period (nsecs): */ +/* ACTHZ period (nsecs): */ unsigned long tick_nsec; static u64 tick_length; diff --git a/trunk/kernel/time/timekeeping.c b/trunk/kernel/time/timekeeping.c index e16af197a2bc..f045cc50832d 100644 --- a/trunk/kernel/time/timekeeping.c +++ b/trunk/kernel/time/timekeeping.c @@ -65,14 +65,14 @@ struct timekeeper { * used instead. */ struct timespec wall_to_monotonic; - /* Offset clock monotonic -> clock realtime */ - ktime_t offs_real; /* time spent in suspend */ struct timespec total_sleep_time; - /* Offset clock monotonic -> clock boottime */ - ktime_t offs_boot; /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */ struct timespec raw_time; + /* Offset clock monotonic -> clock realtime */ + ktime_t offs_real; + /* Offset clock monotonic -> clock boottime */ + ktime_t offs_boot; /* Seqlock for all timekeeper values */ seqlock_t lock; }; @@ -108,38 +108,13 @@ static struct timespec tk_xtime(struct timekeeper *tk) static void tk_set_xtime(struct timekeeper *tk, const struct timespec *ts) { tk->xtime_sec = ts->tv_sec; - tk->xtime_nsec = (u64)ts->tv_nsec << tk->shift; + tk->xtime_nsec = ts->tv_nsec << tk->shift; } static void tk_xtime_add(struct timekeeper *tk, const struct timespec *ts) { tk->xtime_sec += ts->tv_sec; - tk->xtime_nsec += (u64)ts->tv_nsec << tk->shift; -} - -static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec wtm) -{ - struct timespec tmp; - - /* - * Verify consistency of: offset_real = -wall_to_monotonic - * before modifying anything - */ - set_normalized_timespec(&tmp, -tk->wall_to_monotonic.tv_sec, - -tk->wall_to_monotonic.tv_nsec); - WARN_ON_ONCE(tk->offs_real.tv64 != timespec_to_ktime(tmp).tv64); - tk->wall_to_monotonic = wtm; - set_normalized_timespec(&tmp, -wtm.tv_sec, -wtm.tv_nsec); - tk->offs_real = timespec_to_ktime(tmp); -} - -static void tk_set_sleep_time(struct timekeeper *tk, struct timespec t) -{ - /* Verify consistency before modifying */ - WARN_ON_ONCE(tk->offs_boot.tv64 != timespec_to_ktime(tk->total_sleep_time).tv64); - - tk->total_sleep_time = t; - tk->offs_boot = timespec_to_ktime(t); + tk->xtime_nsec += ts->tv_nsec << tk->shift; } /** @@ -242,6 +217,14 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) return nsec + arch_gettimeoffset(); } +static void update_rt_offset(struct timekeeper *tk) +{ + struct timespec tmp, *wtm = &tk->wall_to_monotonic; + + set_normalized_timespec(&tmp, -wtm->tv_sec, -wtm->tv_nsec); + tk->offs_real = timespec_to_ktime(tmp); +} + /* must hold write on timekeeper.lock */ static void timekeeping_update(struct timekeeper *tk, bool clearntp) { @@ -251,10 +234,12 @@ static void timekeeping_update(struct timekeeper *tk, bool clearntp) tk->ntp_error = 0; ntp_clear(); } + update_rt_offset(tk); xt = tk_xtime(tk); update_vsyscall(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult); } + /** * timekeeping_forward_now - update clock to the current time * @@ -292,19 +277,18 @@ static void timekeeping_forward_now(struct timekeeper *tk) */ void getnstimeofday(struct timespec *ts) { - struct timekeeper *tk = &timekeeper; unsigned long seq; s64 nsecs = 0; WARN_ON(timekeeping_suspended); do { - seq = read_seqbegin(&tk->lock); + seq = read_seqbegin(&timekeeper.lock); - ts->tv_sec = tk->xtime_sec; - ts->tv_nsec = timekeeping_get_ns(tk); + ts->tv_sec = timekeeper.xtime_sec; + ts->tv_nsec = timekeeping_get_ns(&timekeeper); - } while (read_seqretry(&tk->lock, seq)); + } while (read_seqretry(&timekeeper.lock, seq)); timespec_add_ns(ts, nsecs); } @@ -312,18 +296,19 @@ EXPORT_SYMBOL(getnstimeofday); ktime_t ktime_get(void) { - struct timekeeper *tk = &timekeeper; unsigned int seq; s64 secs, nsecs; WARN_ON(timekeeping_suspended); do { - seq = read_seqbegin(&tk->lock); - secs = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - nsecs = timekeeping_get_ns(tk) + tk->wall_to_monotonic.tv_nsec; + seq = read_seqbegin(&timekeeper.lock); + secs = timekeeper.xtime_sec + + timekeeper.wall_to_monotonic.tv_sec; + nsecs = timekeeping_get_ns(&timekeeper) + + timekeeper.wall_to_monotonic.tv_nsec; - } while (read_seqretry(&tk->lock, seq)); + } while (read_seqretry(&timekeeper.lock, seq)); /* * Use ktime_set/ktime_add_ns to create a proper ktime on * 32-bit architectures without CONFIG_KTIME_SCALAR. @@ -342,19 +327,18 @@ EXPORT_SYMBOL_GPL(ktime_get); */ void ktime_get_ts(struct timespec *ts) { - struct timekeeper *tk = &timekeeper; struct timespec tomono; unsigned int seq; WARN_ON(timekeeping_suspended); do { - seq = read_seqbegin(&tk->lock); - ts->tv_sec = tk->xtime_sec; - ts->tv_nsec = timekeeping_get_ns(tk); - tomono = tk->wall_to_monotonic; + seq = read_seqbegin(&timekeeper.lock); + ts->tv_sec = timekeeper.xtime_sec; + ts->tv_nsec = timekeeping_get_ns(&timekeeper); + tomono = timekeeper.wall_to_monotonic; - } while (read_seqretry(&tk->lock, seq)); + } while (read_seqretry(&timekeeper.lock, seq)); set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, ts->tv_nsec + tomono.tv_nsec); @@ -374,23 +358,22 @@ EXPORT_SYMBOL_GPL(ktime_get_ts); */ void getnstime_raw_and_real(struct timespec *ts_raw, struct timespec *ts_real) { - struct timekeeper *tk = &timekeeper; unsigned long seq; s64 nsecs_raw, nsecs_real; WARN_ON_ONCE(timekeeping_suspended); do { - seq = read_seqbegin(&tk->lock); + seq = read_seqbegin(&timekeeper.lock); - *ts_raw = tk->raw_time; - ts_real->tv_sec = tk->xtime_sec; + *ts_raw = timekeeper.raw_time; + ts_real->tv_sec = timekeeper.xtime_sec; ts_real->tv_nsec = 0; - nsecs_raw = timekeeping_get_ns_raw(tk); - nsecs_real = timekeeping_get_ns(tk); + nsecs_raw = timekeeping_get_ns_raw(&timekeeper); + nsecs_real = timekeeping_get_ns(&timekeeper); - } while (read_seqretry(&tk->lock, seq)); + } while (read_seqretry(&timekeeper.lock, seq)); timespec_add_ns(ts_raw, nsecs_raw); timespec_add_ns(ts_real, nsecs_real); @@ -423,28 +406,28 @@ EXPORT_SYMBOL(do_gettimeofday); */ int do_settimeofday(const struct timespec *tv) { - struct timekeeper *tk = &timekeeper; struct timespec ts_delta, xt; unsigned long flags; if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; - write_seqlock_irqsave(&tk->lock, flags); + write_seqlock_irqsave(&timekeeper.lock, flags); - timekeeping_forward_now(tk); + timekeeping_forward_now(&timekeeper); - xt = tk_xtime(tk); + xt = tk_xtime(&timekeeper); ts_delta.tv_sec = tv->tv_sec - xt.tv_sec; ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec; - tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, ts_delta)); + timekeeper.wall_to_monotonic = + timespec_sub(timekeeper.wall_to_monotonic, ts_delta); - tk_set_xtime(tk, tv); + tk_set_xtime(&timekeeper, tv); - timekeeping_update(tk, true); + timekeeping_update(&timekeeper, true); - write_sequnlock_irqrestore(&tk->lock, flags); + write_sequnlock_irqrestore(&timekeeper.lock, flags); /* signal hrtimers about time change */ clock_was_set(); @@ -453,6 +436,7 @@ int do_settimeofday(const struct timespec *tv) } EXPORT_SYMBOL(do_settimeofday); + /** * timekeeping_inject_offset - Adds or subtracts from the current time. * @tv: pointer to the timespec variable containing the offset @@ -461,23 +445,23 @@ EXPORT_SYMBOL(do_settimeofday); */ int timekeeping_inject_offset(struct timespec *ts) { - struct timekeeper *tk = &timekeeper; unsigned long flags; if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) return -EINVAL; - write_seqlock_irqsave(&tk->lock, flags); + write_seqlock_irqsave(&timekeeper.lock, flags); - timekeeping_forward_now(tk); + timekeeping_forward_now(&timekeeper); - tk_xtime_add(tk, ts); - tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); + tk_xtime_add(&timekeeper, ts); + timekeeper.wall_to_monotonic = + timespec_sub(timekeeper.wall_to_monotonic, *ts); - timekeeping_update(tk, true); + timekeeping_update(&timekeeper, true); - write_sequnlock_irqrestore(&tk->lock, flags); + write_sequnlock_irqrestore(&timekeeper.lock, flags); /* signal hrtimers about time change */ clock_was_set(); @@ -493,24 +477,23 @@ EXPORT_SYMBOL(timekeeping_inject_offset); */ static int change_clocksource(void *data) { - struct timekeeper *tk = &timekeeper; struct clocksource *new, *old; unsigned long flags; new = (struct clocksource *) data; - write_seqlock_irqsave(&tk->lock, flags); + write_seqlock_irqsave(&timekeeper.lock, flags); - timekeeping_forward_now(tk); + timekeeping_forward_now(&timekeeper); if (!new->enable || new->enable(new) == 0) { - old = tk->clock; - tk_setup_internals(tk, new); + old = timekeeper.clock; + tk_setup_internals(&timekeeper, new); if (old->disable) old->disable(old); } - timekeeping_update(tk, true); + timekeeping_update(&timekeeper, true); - write_sequnlock_irqrestore(&tk->lock, flags); + write_sequnlock_irqrestore(&timekeeper.lock, flags); return 0; } @@ -524,9 +507,7 @@ static int change_clocksource(void *data) */ void timekeeping_notify(struct clocksource *clock) { - struct timekeeper *tk = &timekeeper; - - if (tk->clock == clock) + if (timekeeper.clock == clock) return; stop_machine(change_clocksource, clock, NULL); tick_clock_notify(); @@ -555,36 +536,35 @@ EXPORT_SYMBOL_GPL(ktime_get_real); */ void getrawmonotonic(struct timespec *ts) { - struct timekeeper *tk = &timekeeper; unsigned long seq; s64 nsecs; do { - seq = read_seqbegin(&tk->lock); - nsecs = timekeeping_get_ns_raw(tk); - *ts = tk->raw_time; + seq = read_seqbegin(&timekeeper.lock); + nsecs = timekeeping_get_ns_raw(&timekeeper); + *ts = timekeeper.raw_time; - } while (read_seqretry(&tk->lock, seq)); + } while (read_seqretry(&timekeeper.lock, seq)); timespec_add_ns(ts, nsecs); } EXPORT_SYMBOL(getrawmonotonic); + /** * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres */ int timekeeping_valid_for_hres(void) { - struct timekeeper *tk = &timekeeper; unsigned long seq; int ret; do { - seq = read_seqbegin(&tk->lock); + seq = read_seqbegin(&timekeeper.lock); - ret = tk->clock->flags & CLOCK_SOURCE_VALID_FOR_HRES; + ret = timekeeper.clock->flags & CLOCK_SOURCE_VALID_FOR_HRES; - } while (read_seqretry(&tk->lock, seq)); + } while (read_seqretry(&timekeeper.lock, seq)); return ret; } @@ -594,16 +574,15 @@ int timekeeping_valid_for_hres(void) */ u64 timekeeping_max_deferment(void) { - struct timekeeper *tk = &timekeeper; unsigned long seq; u64 ret; do { - seq = read_seqbegin(&tk->lock); + seq = read_seqbegin(&timekeeper.lock); - ret = tk->clock->max_idle_ns; + ret = timekeeper.clock->max_idle_ns; - } while (read_seqretry(&tk->lock, seq)); + } while (read_seqretry(&timekeeper.lock, seq)); return ret; } @@ -643,43 +622,46 @@ void __attribute__((weak)) read_boot_clock(struct timespec *ts) */ void __init timekeeping_init(void) { - struct timekeeper *tk = &timekeeper; struct clocksource *clock; unsigned long flags; - struct timespec now, boot, tmp; + struct timespec now, boot; read_persistent_clock(&now); read_boot_clock(&boot); - seqlock_init(&tk->lock); + seqlock_init(&timekeeper.lock); ntp_init(); - write_seqlock_irqsave(&tk->lock, flags); + write_seqlock_irqsave(&timekeeper.lock, flags); clock = clocksource_default_clock(); if (clock->enable) clock->enable(clock); - tk_setup_internals(tk, clock); + tk_setup_internals(&timekeeper, clock); - tk_set_xtime(tk, &now); - tk->raw_time.tv_sec = 0; - tk->raw_time.tv_nsec = 0; + tk_set_xtime(&timekeeper, &now); + timekeeper.raw_time.tv_sec = 0; + timekeeper.raw_time.tv_nsec = 0; if (boot.tv_sec == 0 && boot.tv_nsec == 0) - boot = tk_xtime(tk); - - set_normalized_timespec(&tmp, -boot.tv_sec, -boot.tv_nsec); - tk_set_wall_to_mono(tk, tmp); - - tmp.tv_sec = 0; - tmp.tv_nsec = 0; - tk_set_sleep_time(tk, tmp); - - write_sequnlock_irqrestore(&tk->lock, flags); + boot = tk_xtime(&timekeeper); + + set_normalized_timespec(&timekeeper.wall_to_monotonic, + -boot.tv_sec, -boot.tv_nsec); + update_rt_offset(&timekeeper); + timekeeper.total_sleep_time.tv_sec = 0; + timekeeper.total_sleep_time.tv_nsec = 0; + write_sequnlock_irqrestore(&timekeeper.lock, flags); } /* time in seconds when suspend began */ static struct timespec timekeeping_suspend_time; +static void update_sleep_time(struct timespec t) +{ + timekeeper.total_sleep_time = t; + timekeeper.offs_boot = timespec_to_ktime(t); +} + /** * __timekeeping_inject_sleeptime - Internal function to add sleep interval * @delta: pointer to a timespec delta value @@ -695,11 +677,13 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk, "sleep delta value!\n"); return; } + tk_xtime_add(tk, delta); - tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *delta)); - tk_set_sleep_time(tk, timespec_add(tk->total_sleep_time, *delta)); + tk->wall_to_monotonic = timespec_sub(tk->wall_to_monotonic, *delta); + update_sleep_time(timespec_add(tk->total_sleep_time, *delta)); } + /** * timekeeping_inject_sleeptime - Adds suspend interval to timeekeeping values * @delta: pointer to a timespec delta value @@ -712,7 +696,6 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk, */ void timekeeping_inject_sleeptime(struct timespec *delta) { - struct timekeeper *tk = &timekeeper; unsigned long flags; struct timespec ts; @@ -721,20 +704,21 @@ void timekeeping_inject_sleeptime(struct timespec *delta) if (!(ts.tv_sec == 0 && ts.tv_nsec == 0)) return; - write_seqlock_irqsave(&tk->lock, flags); + write_seqlock_irqsave(&timekeeper.lock, flags); - timekeeping_forward_now(tk); + timekeeping_forward_now(&timekeeper); - __timekeeping_inject_sleeptime(tk, delta); + __timekeeping_inject_sleeptime(&timekeeper, delta); - timekeeping_update(tk, true); + timekeeping_update(&timekeeper, true); - write_sequnlock_irqrestore(&tk->lock, flags); + write_sequnlock_irqrestore(&timekeeper.lock, flags); /* signal hrtimers about time change */ clock_was_set(); } + /** * timekeeping_resume - Resumes the generic timekeeping subsystem. * @@ -744,7 +728,6 @@ void timekeeping_inject_sleeptime(struct timespec *delta) */ static void timekeeping_resume(void) { - struct timekeeper *tk = &timekeeper; unsigned long flags; struct timespec ts; @@ -752,18 +735,18 @@ static void timekeeping_resume(void) clocksource_resume(); - write_seqlock_irqsave(&tk->lock, flags); + write_seqlock_irqsave(&timekeeper.lock, flags); if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) { ts = timespec_sub(ts, timekeeping_suspend_time); - __timekeeping_inject_sleeptime(tk, &ts); + __timekeeping_inject_sleeptime(&timekeeper, &ts); } /* re-base the last cycle value */ - tk->clock->cycle_last = tk->clock->read(tk->clock); - tk->ntp_error = 0; + timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); + timekeeper.ntp_error = 0; timekeeping_suspended = 0; - timekeeping_update(tk, false); - write_sequnlock_irqrestore(&tk->lock, flags); + timekeeping_update(&timekeeper, false); + write_sequnlock_irqrestore(&timekeeper.lock, flags); touch_softlockup_watchdog(); @@ -775,15 +758,14 @@ static void timekeeping_resume(void) static int timekeeping_suspend(void) { - struct timekeeper *tk = &timekeeper; unsigned long flags; struct timespec delta, delta_delta; static struct timespec old_delta; read_persistent_clock(&timekeeping_suspend_time); - write_seqlock_irqsave(&tk->lock, flags); - timekeeping_forward_now(tk); + write_seqlock_irqsave(&timekeeper.lock, flags); + timekeeping_forward_now(&timekeeper); timekeeping_suspended = 1; /* @@ -792,7 +774,7 @@ static int timekeeping_suspend(void) * try to compensate so the difference in system time * and persistent_clock time stays close to constant. */ - delta = timespec_sub(tk_xtime(tk), timekeeping_suspend_time); + delta = timespec_sub(tk_xtime(&timekeeper), timekeeping_suspend_time); delta_delta = timespec_sub(delta, old_delta); if (abs(delta_delta.tv_sec) >= 2) { /* @@ -805,7 +787,7 @@ static int timekeeping_suspend(void) timekeeping_suspend_time = timespec_add(timekeeping_suspend_time, delta_delta); } - write_sequnlock_irqrestore(&tk->lock, flags); + write_sequnlock_irqrestore(&timekeeper.lock, flags); clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); clocksource_suspend(); @@ -916,29 +898,27 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset) * the error. This causes the likely below to be unlikely. * * The proper fix is to avoid rounding up by using - * the high precision tk->xtime_nsec instead of + * the high precision timekeeper.xtime_nsec instead of * xtime.tv_nsec everywhere. Fixing this will take some * time. */ if (likely(error <= interval)) adj = 1; else - adj = timekeeping_bigadjust(tk, error, &interval, &offset); - } else { - if (error < -interval) { - /* See comment above, this is just switched for the negative */ - error >>= 2; - if (likely(error >= -interval)) { - adj = -1; - interval = -interval; - offset = -offset; - } else { - adj = timekeeping_bigadjust(tk, error, &interval, &offset); - } - } else { - goto out_adjust; - } - } + adj = timekeeping_bigadjust(tk, error, &interval, + &offset); + } else if (error < -interval) { + /* See comment above, this is just switched for the negative */ + error >>= 2; + if (likely(error >= -interval)) { + adj = -1; + interval = -interval; + offset = -offset; + } else + adj = timekeeping_bigadjust(tk, error, &interval, + &offset); + } else + return; if (unlikely(tk->clock->maxadj && (tk->mult + adj > tk->clock->mult + tk->clock->maxadj))) { @@ -1001,7 +981,6 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset) tk->xtime_nsec -= offset; tk->ntp_error -= (interval - offset) << tk->ntp_error_shift; -out_adjust: /* * It may be possible that when we entered this function, xtime_nsec * was very small. Further, if we're slightly speeding the clocksource @@ -1024,6 +1003,7 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset) } + /** * accumulate_nsecs_to_secs - Accumulates nsecs into secs * @@ -1044,21 +1024,15 @@ static inline void accumulate_nsecs_to_secs(struct timekeeper *tk) /* Figure out if its a leap sec and apply if needed */ leap = second_overflow(tk->xtime_sec); - if (unlikely(leap)) { - struct timespec ts; - - tk->xtime_sec += leap; - - ts.tv_sec = leap; - ts.tv_nsec = 0; - tk_set_wall_to_mono(tk, - timespec_sub(tk->wall_to_monotonic, ts)); - + tk->xtime_sec += leap; + tk->wall_to_monotonic.tv_sec -= leap; + if (leap) clock_was_set_delayed(); - } + } } + /** * logarithmic_accumulation - shifted accumulation of cycles * @@ -1102,6 +1076,7 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, return offset; } + /** * update_wall_time - Uses the current clocksource to increment the wall time * @@ -1109,22 +1084,21 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, static void update_wall_time(void) { struct clocksource *clock; - struct timekeeper *tk = &timekeeper; cycle_t offset; int shift = 0, maxshift; unsigned long flags; s64 remainder; - write_seqlock_irqsave(&tk->lock, flags); + write_seqlock_irqsave(&timekeeper.lock, flags); /* Make sure we're fully resumed: */ if (unlikely(timekeeping_suspended)) goto out; - clock = tk->clock; + clock = timekeeper.clock; #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET - offset = tk->cycle_interval; + offset = timekeeper.cycle_interval; #else offset = (clock->read(clock) - clock->cycle_last) & clock->mask; #endif @@ -1137,19 +1111,19 @@ static void update_wall_time(void) * chunk in one go, and then try to consume the next smaller * doubled multiple. */ - shift = ilog2(offset) - ilog2(tk->cycle_interval); + shift = ilog2(offset) - ilog2(timekeeper.cycle_interval); shift = max(0, shift); /* Bound shift to one less than what overflows tick_length */ maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; shift = min(shift, maxshift); - while (offset >= tk->cycle_interval) { - offset = logarithmic_accumulation(tk, offset, shift); - if (offset < tk->cycle_interval<= timekeeper.cycle_interval) { + offset = logarithmic_accumulation(&timekeeper, offset, shift); + if(offset < timekeeper.cycle_interval<xtime_nsec & ((1 << tk->shift) - 1); - tk->xtime_nsec -= remainder; - tk->xtime_nsec += 1 << tk->shift; - tk->ntp_error += remainder << tk->ntp_error_shift; + remainder = timekeeper.xtime_nsec & ((1 << timekeeper.shift) - 1); + timekeeper.xtime_nsec -= remainder; + timekeeper.xtime_nsec += 1 << timekeeper.shift; + timekeeper.ntp_error += remainder << timekeeper.ntp_error_shift; /* * Finally, make sure that after the rounding * xtime_nsec isn't larger than NSEC_PER_SEC */ - accumulate_nsecs_to_secs(tk); + accumulate_nsecs_to_secs(&timekeeper); - timekeeping_update(tk, false); + timekeeping_update(&timekeeper, false); out: - write_sequnlock_irqrestore(&tk->lock, flags); + write_sequnlock_irqrestore(&timekeeper.lock, flags); } @@ -1192,18 +1166,18 @@ static void update_wall_time(void) */ void getboottime(struct timespec *ts) { - struct timekeeper *tk = &timekeeper; struct timespec boottime = { - .tv_sec = tk->wall_to_monotonic.tv_sec + - tk->total_sleep_time.tv_sec, - .tv_nsec = tk->wall_to_monotonic.tv_nsec + - tk->total_sleep_time.tv_nsec + .tv_sec = timekeeper.wall_to_monotonic.tv_sec + + timekeeper.total_sleep_time.tv_sec, + .tv_nsec = timekeeper.wall_to_monotonic.tv_nsec + + timekeeper.total_sleep_time.tv_nsec }; set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec); } EXPORT_SYMBOL_GPL(getboottime); + /** * get_monotonic_boottime - Returns monotonic time since boot * @ts: pointer to the timespec to be set @@ -1215,20 +1189,19 @@ EXPORT_SYMBOL_GPL(getboottime); */ void get_monotonic_boottime(struct timespec *ts) { - struct timekeeper *tk = &timekeeper; struct timespec tomono, sleep; unsigned int seq; WARN_ON(timekeeping_suspended); do { - seq = read_seqbegin(&tk->lock); - ts->tv_sec = tk->xtime_sec; - ts->tv_nsec = timekeeping_get_ns(tk); - tomono = tk->wall_to_monotonic; - sleep = tk->total_sleep_time; + seq = read_seqbegin(&timekeeper.lock); + ts->tv_sec = timekeeper.xtime_sec; + ts->tv_nsec = timekeeping_get_ns(&timekeeper); + tomono = timekeeper.wall_to_monotonic; + sleep = timekeeper.total_sleep_time; - } while (read_seqretry(&tk->lock, seq)); + } while (read_seqretry(&timekeeper.lock, seq)); set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec, ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec); @@ -1258,38 +1231,31 @@ EXPORT_SYMBOL_GPL(ktime_get_boottime); */ void monotonic_to_bootbased(struct timespec *ts) { - struct timekeeper *tk = &timekeeper; - - *ts = timespec_add(*ts, tk->total_sleep_time); + *ts = timespec_add(*ts, timekeeper.total_sleep_time); } EXPORT_SYMBOL_GPL(monotonic_to_bootbased); unsigned long get_seconds(void) { - struct timekeeper *tk = &timekeeper; - - return tk->xtime_sec; + return timekeeper.xtime_sec; } EXPORT_SYMBOL(get_seconds); struct timespec __current_kernel_time(void) { - struct timekeeper *tk = &timekeeper; - - return tk_xtime(tk); + return tk_xtime(&timekeeper); } struct timespec current_kernel_time(void) { - struct timekeeper *tk = &timekeeper; struct timespec now; unsigned long seq; do { - seq = read_seqbegin(&tk->lock); + seq = read_seqbegin(&timekeeper.lock); - now = tk_xtime(tk); - } while (read_seqretry(&tk->lock, seq)); + now = tk_xtime(&timekeeper); + } while (read_seqretry(&timekeeper.lock, seq)); return now; } @@ -1297,16 +1263,15 @@ EXPORT_SYMBOL(current_kernel_time); struct timespec get_monotonic_coarse(void) { - struct timekeeper *tk = &timekeeper; struct timespec now, mono; unsigned long seq; do { - seq = read_seqbegin(&tk->lock); + seq = read_seqbegin(&timekeeper.lock); - now = tk_xtime(tk); - mono = tk->wall_to_monotonic; - } while (read_seqretry(&tk->lock, seq)); + now = tk_xtime(&timekeeper); + mono = timekeeper.wall_to_monotonic; + } while (read_seqretry(&timekeeper.lock, seq)); set_normalized_timespec(&now, now.tv_sec + mono.tv_sec, now.tv_nsec + mono.tv_nsec); @@ -1335,15 +1300,14 @@ void do_timer(unsigned long ticks) void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, struct timespec *wtom, struct timespec *sleep) { - struct timekeeper *tk = &timekeeper; unsigned long seq; do { - seq = read_seqbegin(&tk->lock); - *xtim = tk_xtime(tk); - *wtom = tk->wall_to_monotonic; - *sleep = tk->total_sleep_time; - } while (read_seqretry(&tk->lock, seq)); + seq = read_seqbegin(&timekeeper.lock); + *xtim = tk_xtime(&timekeeper); + *wtom = timekeeper.wall_to_monotonic; + *sleep = timekeeper.total_sleep_time; + } while (read_seqretry(&timekeeper.lock, seq)); } #ifdef CONFIG_HIGH_RES_TIMERS @@ -1357,20 +1321,19 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, */ ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) { - struct timekeeper *tk = &timekeeper; ktime_t now; unsigned int seq; u64 secs, nsecs; do { - seq = read_seqbegin(&tk->lock); + seq = read_seqbegin(&timekeeper.lock); - secs = tk->xtime_sec; - nsecs = timekeeping_get_ns(tk); + secs = timekeeper.xtime_sec; + nsecs = timekeeping_get_ns(&timekeeper); - *offs_real = tk->offs_real; - *offs_boot = tk->offs_boot; - } while (read_seqretry(&tk->lock, seq)); + *offs_real = timekeeper.offs_real; + *offs_boot = timekeeper.offs_boot; + } while (read_seqretry(&timekeeper.lock, seq)); now = ktime_add_ns(ktime_set(secs, 0), nsecs); now = ktime_sub(now, *offs_real); @@ -1383,19 +1346,19 @@ ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) */ ktime_t ktime_get_monotonic_offset(void) { - struct timekeeper *tk = &timekeeper; unsigned long seq; struct timespec wtom; do { - seq = read_seqbegin(&tk->lock); - wtom = tk->wall_to_monotonic; - } while (read_seqretry(&tk->lock, seq)); + seq = read_seqbegin(&timekeeper.lock); + wtom = timekeeper.wall_to_monotonic; + } while (read_seqretry(&timekeeper.lock, seq)); return timespec_to_ktime(wtom); } EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset); + /** * xtime_update() - advances the timekeeping infrastructure * @ticks: number of ticks, that have elapsed since the last call. diff --git a/trunk/kernel/trace/trace_event_perf.c b/trunk/kernel/trace/trace_event_perf.c index 8a6d2ee2086c..fee3752ae8f6 100644 --- a/trunk/kernel/trace/trace_event_perf.c +++ b/trunk/kernel/trace/trace_event_perf.c @@ -281,7 +281,7 @@ perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip) head = this_cpu_ptr(event_function.perf_events); perf_trace_buf_submit(entry, ENTRY_SIZE, rctx, 0, - 1, ®s, head, NULL); + 1, ®s, head); #undef ENTRY_SIZE } diff --git a/trunk/kernel/trace/trace_kprobe.c b/trunk/kernel/trace/trace_kprobe.c index 1a2117043bb1..b31d3d5699fe 100644 --- a/trunk/kernel/trace/trace_kprobe.c +++ b/trunk/kernel/trace/trace_kprobe.c @@ -1002,8 +1002,7 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp, store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); head = this_cpu_ptr(call->perf_events); - perf_trace_buf_submit(entry, size, rctx, - entry->ip, 1, regs, head, NULL); + perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head); } /* Kretprobe profile handler */ @@ -1034,8 +1033,7 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri, store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); head = this_cpu_ptr(call->perf_events); - perf_trace_buf_submit(entry, size, rctx, - entry->ret_ip, 1, regs, head, NULL); + perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head); } #endif /* CONFIG_PERF_EVENTS */ diff --git a/trunk/kernel/trace/trace_syscalls.c b/trunk/kernel/trace/trace_syscalls.c index 60e4d7875672..96fc73369099 100644 --- a/trunk/kernel/trace/trace_syscalls.c +++ b/trunk/kernel/trace/trace_syscalls.c @@ -532,7 +532,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) (unsigned long *)&rec->args); head = this_cpu_ptr(sys_data->enter_event->perf_events); - perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); + perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head); } int perf_sysenter_enable(struct ftrace_event_call *call) @@ -608,7 +608,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) rec->ret = syscall_get_return_value(current, regs); head = this_cpu_ptr(sys_data->exit_event->perf_events); - perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); + perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head); } int perf_sysexit_enable(struct ftrace_event_call *call) diff --git a/trunk/kernel/trace/trace_uprobe.c b/trunk/kernel/trace/trace_uprobe.c index 03003cd7dd96..2b36ac68549e 100644 --- a/trunk/kernel/trace/trace_uprobe.c +++ b/trunk/kernel/trace/trace_uprobe.c @@ -670,7 +670,7 @@ static void uprobe_perf_func(struct trace_uprobe *tu, struct pt_regs *regs) call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset); head = this_cpu_ptr(call->perf_events); - perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head, NULL); + perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head); out: preempt_enable(); diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index 4b1dfba70f7c..69add8a9da68 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -575,7 +575,7 @@ int proc_dowatchdog(struct ctl_table *table, int write, /* * Create/destroy watchdog threads as CPUs come and go: */ -static int __cpuinit +static int cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { int hotcpu = (unsigned long)hcpu; @@ -610,10 +610,27 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cpu_nfb = { +static struct notifier_block cpu_nfb = { .notifier_call = cpu_callback }; +#ifdef CONFIG_SUSPEND +/* + * On exit from suspend we force an offline->online transition on the boot CPU + * so that the PMU state that was lost while in suspended state gets set up + * properly for the boot CPU. This information is required for restarting the + * NMI watchdog. + */ +void lockup_detector_bootcpu_resume(void) +{ + void *cpu = (void *)(long)smp_processor_id(); + + cpu_callback(&cpu_nfb, CPU_DEAD_FROZEN, cpu); + cpu_callback(&cpu_nfb, CPU_UP_PREPARE_FROZEN, cpu); + cpu_callback(&cpu_nfb, CPU_ONLINE_FROZEN, cpu); +} +#endif + void __init lockup_detector_init(void) { void *cpu = (void *)(long)smp_processor_id(); diff --git a/trunk/mm/backing-dev.c b/trunk/mm/backing-dev.c index b41823cc05e6..6b4718e2ee34 100644 --- a/trunk/mm/backing-dev.c +++ b/trunk/mm/backing-dev.c @@ -39,6 +39,12 @@ DEFINE_SPINLOCK(bdi_lock); LIST_HEAD(bdi_list); LIST_HEAD(bdi_pending_list); +static struct task_struct *sync_supers_tsk; +static struct timer_list sync_supers_timer; + +static int bdi_sync_supers(void *); +static void sync_supers_timer_fn(unsigned long); + void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2) { if (wb1 < wb2) { @@ -244,6 +250,12 @@ static int __init default_bdi_init(void) { int err; + sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers"); + BUG_ON(IS_ERR(sync_supers_tsk)); + + setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0); + bdi_arm_supers_timer(); + err = bdi_init(&default_backing_dev_info); if (!err) bdi_register(&default_backing_dev_info, NULL, "default"); @@ -258,6 +270,46 @@ int bdi_has_dirty_io(struct backing_dev_info *bdi) return wb_has_dirty_io(&bdi->wb); } +/* + * kupdated() used to do this. We cannot do it from the bdi_forker_thread() + * or we risk deadlocking on ->s_umount. The longer term solution would be + * to implement sync_supers_bdi() or similar and simply do it from the + * bdi writeback thread individually. + */ +static int bdi_sync_supers(void *unused) +{ + set_user_nice(current, 0); + + while (!kthread_should_stop()) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + + /* + * Do this periodically, like kupdated() did before. + */ + sync_supers(); + } + + return 0; +} + +void bdi_arm_supers_timer(void) +{ + unsigned long next; + + if (!dirty_writeback_interval) + return; + + next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies; + mod_timer(&sync_supers_timer, round_jiffies_up(next)); +} + +static void sync_supers_timer_fn(unsigned long unused) +{ + wake_up_process(sync_supers_tsk); + bdi_arm_supers_timer(); +} + static void wakeup_timer_fn(unsigned long data) { struct backing_dev_info *bdi = (struct backing_dev_info *)data; diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 5ad5ce23c1e0..e5363f34e025 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -1532,6 +1532,7 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { proc_dointvec(table, write, buffer, length, ppos); + bdi_arm_supers_timer(); return 0; } diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 009ac285fea7..889532b8e6c1 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -4511,7 +4511,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size, pg_data_t *pgdat = NODE_DATA(nid); /* pg_data_t should be reset to zero when it's allocated */ - WARN_ON(pgdat->nr_zones || pgdat->classzone_idx); + WARN_ON(pgdat->nr_zones || pgdat->node_start_pfn || pgdat->classzone_idx); pgdat->node_id = nid; pgdat->node_start_pfn = node_start_pfn; diff --git a/trunk/net/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c index 402442402af7..73a2a83ee2da 100644 --- a/trunk/net/8021q/vlan_dev.c +++ b/trunk/net/8021q/vlan_dev.c @@ -137,21 +137,9 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, return rc; } -static inline netdev_tx_t vlan_netpoll_send_skb(struct vlan_dev_priv *vlan, struct sk_buff *skb) -{ -#ifdef CONFIG_NET_POLL_CONTROLLER - if (vlan->netpoll) - netpoll_send_skb(vlan->netpoll, skb); -#else - BUG(); -#endif - return NETDEV_TX_OK; -} - static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct vlan_dev_priv *vlan = vlan_dev_priv(dev); struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); unsigned int len; int ret; @@ -162,30 +150,29 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ if (veth->h_vlan_proto != htons(ETH_P_8021Q) || - vlan->flags & VLAN_FLAG_REORDER_HDR) { + vlan_dev_priv(dev)->flags & VLAN_FLAG_REORDER_HDR) { u16 vlan_tci; - vlan_tci = vlan->vlan_id; + vlan_tci = vlan_dev_priv(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); skb = __vlan_hwaccel_put_tag(skb, vlan_tci); } - skb->dev = vlan->real_dev; + skb->dev = vlan_dev_priv(dev)->real_dev; len = skb->len; - if (unlikely(netpoll_tx_running(dev))) - return vlan_netpoll_send_skb(vlan, skb); - + if (netpoll_tx_running(dev)) + return skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev); ret = dev_queue_xmit(skb); if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { struct vlan_pcpu_stats *stats; - stats = this_cpu_ptr(vlan->vlan_pcpu_stats); + stats = this_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats); u64_stats_update_begin(&stats->syncp); stats->tx_packets++; stats->tx_bytes += len; u64_stats_update_end(&stats->syncp); } else { - this_cpu_inc(vlan->vlan_pcpu_stats->tx_dropped); + this_cpu_inc(vlan_dev_priv(dev)->vlan_pcpu_stats->tx_dropped); } return ret; @@ -682,26 +669,25 @@ static void vlan_dev_poll_controller(struct net_device *dev) return; } -static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo, - gfp_t gfp) +static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo) { - struct vlan_dev_priv *vlan = vlan_dev_priv(dev); - struct net_device *real_dev = vlan->real_dev; + struct vlan_dev_priv *info = vlan_dev_priv(dev); + struct net_device *real_dev = info->real_dev; struct netpoll *netpoll; int err = 0; - netpoll = kzalloc(sizeof(*netpoll), gfp); + netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL); err = -ENOMEM; if (!netpoll) goto out; - err = __netpoll_setup(netpoll, real_dev, gfp); + err = __netpoll_setup(netpoll, real_dev); if (err) { kfree(netpoll); goto out; } - vlan->netpoll = netpoll; + info->netpoll = netpoll; out: return err; @@ -709,15 +695,19 @@ static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *n static void vlan_dev_netpoll_cleanup(struct net_device *dev) { - struct vlan_dev_priv *vlan= vlan_dev_priv(dev); - struct netpoll *netpoll = vlan->netpoll; + struct vlan_dev_priv *info = vlan_dev_priv(dev); + struct netpoll *netpoll = info->netpoll; if (!netpoll) return; - vlan->netpoll = NULL; + info->netpoll = NULL; + + /* Wait for transmitting packets to finish before freeing. */ + synchronize_rcu_bh(); - __netpoll_free_rcu(netpoll); + __netpoll_cleanup(netpoll); + kfree(netpoll); } #endif /* CONFIG_NET_POLL_CONTROLLER */ diff --git a/trunk/net/batman-adv/gateway_client.c b/trunk/net/batman-adv/gateway_client.c index fc866f2e4528..b421cc49d2cd 100644 --- a/trunk/net/batman-adv/gateway_client.c +++ b/trunk/net/batman-adv/gateway_client.c @@ -200,11 +200,11 @@ void batadv_gw_election(struct batadv_priv *bat_priv) if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT) goto out; - curr_gw = batadv_gw_get_selected_gw_node(bat_priv); - - if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect) && curr_gw) + if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect)) goto out; + curr_gw = batadv_gw_get_selected_gw_node(bat_priv); + next_gw = batadv_gw_get_best_gw_node(bat_priv); if (curr_gw == next_gw) diff --git a/trunk/net/batman-adv/translation-table.c b/trunk/net/batman-adv/translation-table.c index 99dd8f75b3ff..a438f4b582fc 100644 --- a/trunk/net/batman-adv/translation-table.c +++ b/trunk/net/batman-adv/translation-table.c @@ -197,7 +197,6 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv, del: list_del(&entry->list); kfree(entry); - kfree(tt_change_node); event_removed = true; goto unlock; } diff --git a/trunk/net/bridge/br_device.c b/trunk/net/bridge/br_device.c index 32211fa5b506..333484537600 100644 --- a/trunk/net/bridge/br_device.c +++ b/trunk/net/bridge/br_device.c @@ -206,23 +206,24 @@ static void br_poll_controller(struct net_device *br_dev) static void br_netpoll_cleanup(struct net_device *dev) { struct net_bridge *br = netdev_priv(dev); - struct net_bridge_port *p; + struct net_bridge_port *p, *n; - list_for_each_entry(p, &br->port_list, list) + list_for_each_entry_safe(p, n, &br->port_list, list) { br_netpoll_disable(p); + } } -static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, - gfp_t gfp) +static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) { struct net_bridge *br = netdev_priv(dev); - struct net_bridge_port *p; + struct net_bridge_port *p, *n; int err = 0; - list_for_each_entry(p, &br->port_list, list) { + list_for_each_entry_safe(p, n, &br->port_list, list) { if (!p->dev) continue; - err = br_netpoll_enable(p, gfp); + + err = br_netpoll_enable(p); if (err) goto fail; } @@ -235,17 +236,17 @@ static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, goto out; } -int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) +int br_netpoll_enable(struct net_bridge_port *p) { struct netpoll *np; int err = 0; - np = kzalloc(sizeof(*p->np), gfp); + np = kzalloc(sizeof(*p->np), GFP_KERNEL); err = -ENOMEM; if (!np) goto out; - err = __netpoll_setup(np, p->dev, gfp); + err = __netpoll_setup(np, p->dev); if (err) { kfree(np); goto out; @@ -266,7 +267,11 @@ void br_netpoll_disable(struct net_bridge_port *p) p->np = NULL; - __netpoll_free_rcu(np); + /* Wait for transmitting packets to finish before freeing. */ + synchronize_rcu_bh(); + + __netpoll_cleanup(np); + kfree(np); } #endif diff --git a/trunk/net/bridge/br_forward.c b/trunk/net/bridge/br_forward.c index 02015a505d2a..e9466d412707 100644 --- a/trunk/net/bridge/br_forward.c +++ b/trunk/net/bridge/br_forward.c @@ -65,7 +65,7 @@ static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) { skb->dev = to->dev; - if (unlikely(netpoll_tx_running(to->br->dev))) { + if (unlikely(netpoll_tx_running(to->dev))) { if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) kfree_skb(skb); else { diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index 1c8fdc3558cd..e1144e1617be 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -361,7 +361,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) if (err) goto err2; - if (br_netpoll_info(br) && ((err = br_netpoll_enable(p, GFP_KERNEL)))) + if (br_netpoll_info(br) && ((err = br_netpoll_enable(p)))) goto err3; err = netdev_set_master(dev, br->dev); @@ -427,10 +427,6 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) if (!p || p->br != br) return -EINVAL; - /* Since more than one interface can be attached to a bridge, - * there still maybe an alternate path for netconsole to use; - * therefore there is no reason for a NETDEV_RELEASE event. - */ del_nbp(p); spin_lock_bh(&br->lock); diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index f507d2af9646..a768b2408edf 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -316,7 +316,7 @@ static inline void br_netpoll_send_skb(const struct net_bridge_port *p, netpoll_send_skb(np, skb); } -extern int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp); +extern int br_netpoll_enable(struct net_bridge_port *p); extern void br_netpoll_disable(struct net_bridge_port *p); #else static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br) @@ -329,7 +329,7 @@ static inline void br_netpoll_send_skb(const struct net_bridge_port *p, { } -static inline int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) +static inline int br_netpoll_enable(struct net_bridge_port *p) { return 0; } diff --git a/trunk/net/ceph/crypto.c b/trunk/net/ceph/crypto.c index 9da7fdd3cd8a..b780cb7947dd 100644 --- a/trunk/net/ceph/crypto.c +++ b/trunk/net/ceph/crypto.c @@ -466,7 +466,6 @@ void ceph_key_destroy(struct key *key) { struct ceph_crypto_key *ckey = key->payload.data; ceph_crypto_key_destroy(ckey); - kfree(ckey); } struct key_type key_type_ceph = { diff --git a/trunk/net/ceph/crypto.h b/trunk/net/ceph/crypto.h index 3572dc518bc9..1919d1550d75 100644 --- a/trunk/net/ceph/crypto.h +++ b/trunk/net/ceph/crypto.h @@ -16,8 +16,7 @@ struct ceph_crypto_key { static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key) { - if (key) - kfree(key->key); + kfree(key->key); } extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst, diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index a39354ee1432..f91abf800161 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1055,8 +1055,6 @@ int dev_change_name(struct net_device *dev, const char *newname) */ int dev_set_alias(struct net_device *dev, const char *alias, size_t len) { - char *new_ifalias; - ASSERT_RTNL(); if (len >= IFALIASZ) @@ -1070,10 +1068,9 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len) return 0; } - new_ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL); - if (!new_ifalias) + dev->ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL); + if (!dev->ifalias) return -ENOMEM; - dev->ifalias = new_ifalias; strlcpy(dev->ifalias, alias, len+1); return len; diff --git a/trunk/net/core/dst.c b/trunk/net/core/dst.c index 56d63612e1e4..069d51d29414 100644 --- a/trunk/net/core/dst.c +++ b/trunk/net/core/dst.c @@ -149,15 +149,7 @@ int dst_discard(struct sk_buff *skb) } EXPORT_SYMBOL(dst_discard); -const u32 dst_default_metrics[RTAX_MAX + 1] = { - /* This initializer is needed to force linker to place this variable - * into const section. Otherwise it might end into bss section. - * We really want to avoid false sharing on this variable, and catch - * any writes on it. - */ - [RTAX_MAX] = 0xdeadbeef, -}; - +const u32 dst_default_metrics[RTAX_MAX]; void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref, int initial_obsolete, unsigned short flags) diff --git a/trunk/net/core/netpoll.c b/trunk/net/core/netpoll.c index 346b1eb83a1f..b4c90e42b443 100644 --- a/trunk/net/core/netpoll.c +++ b/trunk/net/core/netpoll.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -55,7 +54,7 @@ static atomic_t trapped; MAX_UDP_CHUNK) static void zap_completion_queue(void); -static void netpoll_arp_reply(struct sk_buff *skb, struct netpoll_info *npinfo); +static void arp_reply(struct sk_buff *skb); static unsigned int carrier_timeout = 4; module_param(carrier_timeout, uint, 0644); @@ -168,24 +167,15 @@ static void poll_napi(struct net_device *dev) struct napi_struct *napi; int budget = 16; - WARN_ON_ONCE(!irqs_disabled()); - list_for_each_entry(napi, &dev->napi_list, dev_list) { - local_irq_enable(); if (napi->poll_owner != smp_processor_id() && spin_trylock(&napi->poll_lock)) { - rcu_read_lock_bh(); - budget = poll_one_napi(rcu_dereference_bh(dev->npinfo), - napi, budget); - rcu_read_unlock_bh(); + budget = poll_one_napi(dev->npinfo, napi, budget); spin_unlock(&napi->poll_lock); - if (!budget) { - local_irq_disable(); + if (!budget) break; - } } - local_irq_disable(); } } @@ -195,14 +185,13 @@ static void service_arp_queue(struct netpoll_info *npi) struct sk_buff *skb; while ((skb = skb_dequeue(&npi->arp_tx))) - netpoll_arp_reply(skb, npi); + arp_reply(skb); } } static void netpoll_poll_dev(struct net_device *dev) { const struct net_device_ops *ops; - struct netpoll_info *ni = rcu_dereference_bh(dev->npinfo); if (!dev || !netif_running(dev)) return; @@ -217,18 +206,17 @@ static void netpoll_poll_dev(struct net_device *dev) poll_napi(dev); if (dev->flags & IFF_SLAVE) { - if (ni) { + if (dev->npinfo) { struct net_device *bond_dev = dev->master; struct sk_buff *skb; - struct netpoll_info *bond_ni = rcu_dereference_bh(bond_dev->npinfo); - while ((skb = skb_dequeue(&ni->arp_tx))) { + while ((skb = skb_dequeue(&dev->npinfo->arp_tx))) { skb->dev = bond_dev; - skb_queue_tail(&bond_ni->arp_tx, skb); + skb_queue_tail(&bond_dev->npinfo->arp_tx, skb); } } } - service_arp_queue(ni); + service_arp_queue(dev->npinfo); zap_completion_queue(); } @@ -314,7 +302,6 @@ static int netpoll_owner_active(struct net_device *dev) return 0; } -/* call with IRQ disabled */ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, struct net_device *dev) { @@ -322,11 +309,8 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, unsigned long tries; const struct net_device_ops *ops = dev->netdev_ops; /* It is up to the caller to keep npinfo alive. */ - struct netpoll_info *npinfo; - - WARN_ON_ONCE(!irqs_disabled()); + struct netpoll_info *npinfo = np->dev->npinfo; - npinfo = rcu_dereference_bh(np->dev->npinfo); if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) { __kfree_skb(skb); return; @@ -335,22 +319,16 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, /* don't get messages out of order, and no recursion */ if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) { struct netdev_queue *txq; + unsigned long flags; txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); + local_irq_save(flags); /* try until next clock tick */ for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; tries > 0; --tries) { if (__netif_tx_trylock(txq)) { if (!netif_xmit_stopped(txq)) { - if (vlan_tx_tag_present(skb) && - !(netif_skb_features(skb) & NETIF_F_HW_VLAN_TX)) { - skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); - if (unlikely(!skb)) - break; - skb->vlan_tci = 0; - } - status = ops->ndo_start_xmit(skb, dev); if (status == NETDEV_TX_OK) txq_trans_update(txq); @@ -369,9 +347,10 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, } WARN_ONCE(!irqs_disabled(), - "netpoll_send_skb_on_dev(): %s enabled interrupts in poll (%pF)\n", + "netpoll_send_skb(): %s enabled interrupts in poll (%pF)\n", dev->name, ops->ndo_start_xmit); + local_irq_restore(flags); } if (status != NETDEV_TX_OK) { @@ -444,8 +423,9 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) } EXPORT_SYMBOL(netpoll_send_udp); -static void netpoll_arp_reply(struct sk_buff *skb, struct netpoll_info *npinfo) +static void arp_reply(struct sk_buff *skb) { + struct netpoll_info *npinfo = skb->dev->npinfo; struct arphdr *arp; unsigned char *arp_ptr; int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; @@ -563,12 +543,13 @@ static void netpoll_arp_reply(struct sk_buff *skb, struct netpoll_info *npinfo) spin_unlock_irqrestore(&npinfo->rx_lock, flags); } -int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo) +int __netpoll_rx(struct sk_buff *skb) { int proto, len, ulen; int hits = 0; const struct iphdr *iph; struct udphdr *uh; + struct netpoll_info *npinfo = skb->dev->npinfo; struct netpoll *np, *tmp; if (list_empty(&npinfo->rx_np)) @@ -584,12 +565,6 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo) return 1; } - if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { - skb = vlan_untag(skb); - if (unlikely(!skb)) - goto out; - } - proto = ntohs(eth_hdr(skb)->h_proto); if (proto != ETH_P_IP) goto out; @@ -740,7 +715,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) } EXPORT_SYMBOL(netpoll_parse_options); -int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp) +int __netpoll_setup(struct netpoll *np, struct net_device *ndev) { struct netpoll_info *npinfo; const struct net_device_ops *ops; @@ -759,7 +734,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp) } if (!ndev->npinfo) { - npinfo = kmalloc(sizeof(*npinfo), gfp); + npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); if (!npinfo) { err = -ENOMEM; goto out; @@ -777,7 +752,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp) ops = np->dev->netdev_ops; if (ops->ndo_netpoll_setup) { - err = ops->ndo_netpoll_setup(ndev, npinfo, gfp); + err = ops->ndo_netpoll_setup(ndev, npinfo); if (err) goto free_npinfo; } @@ -882,7 +857,7 @@ int netpoll_setup(struct netpoll *np) refill_skbs(); rtnl_lock(); - err = __netpoll_setup(np, ndev, GFP_KERNEL); + err = __netpoll_setup(np, ndev); rtnl_unlock(); if (err) @@ -903,24 +878,6 @@ static int __init netpoll_init(void) } core_initcall(netpoll_init); -static void rcu_cleanup_netpoll_info(struct rcu_head *rcu_head) -{ - struct netpoll_info *npinfo = - container_of(rcu_head, struct netpoll_info, rcu); - - skb_queue_purge(&npinfo->arp_tx); - skb_queue_purge(&npinfo->txq); - - /* we can't call cancel_delayed_work_sync here, as we are in softirq */ - cancel_delayed_work(&npinfo->tx_work); - - /* clean after last, unfinished work */ - __skb_queue_purge(&npinfo->txq); - /* now cancel it again */ - cancel_delayed_work(&npinfo->tx_work); - kfree(npinfo); -} - void __netpoll_cleanup(struct netpoll *np) { struct netpoll_info *npinfo; @@ -946,24 +903,20 @@ void __netpoll_cleanup(struct netpoll *np) ops->ndo_netpoll_cleanup(np->dev); RCU_INIT_POINTER(np->dev->npinfo, NULL); - call_rcu_bh(&npinfo->rcu, rcu_cleanup_netpoll_info); - } -} -EXPORT_SYMBOL_GPL(__netpoll_cleanup); -static void rcu_cleanup_netpoll(struct rcu_head *rcu_head) -{ - struct netpoll *np = container_of(rcu_head, struct netpoll, rcu); + /* avoid racing with NAPI reading npinfo */ + synchronize_rcu_bh(); - __netpoll_cleanup(np); - kfree(np); -} + skb_queue_purge(&npinfo->arp_tx); + skb_queue_purge(&npinfo->txq); + cancel_delayed_work_sync(&npinfo->tx_work); -void __netpoll_free_rcu(struct netpoll *np) -{ - call_rcu_bh(&np->rcu, rcu_cleanup_netpoll); + /* clean after last, unfinished work */ + __skb_queue_purge(&npinfo->txq); + kfree(npinfo); + } } -EXPORT_SYMBOL_GPL(__netpoll_free_rcu); +EXPORT_SYMBOL_GPL(__netpoll_cleanup); void netpoll_cleanup(struct netpoll *np) { diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index 57bd978483e1..f0cdb30921c0 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -367,7 +367,7 @@ static void __leaf_free_rcu(struct rcu_head *head) static inline void free_leaf(struct leaf *l) { - call_rcu(&l->rcu, __leaf_free_rcu); + call_rcu_bh(&l->rcu, __leaf_free_rcu); } static inline void free_leaf_info(struct leaf_info *leaf) diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 147ccc3e93db..ba39a52d18c1 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -197,7 +197,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) neigh = __ipv4_neigh_lookup_noref(dev, nexthop); if (unlikely(!neigh)) neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); - if (!IS_ERR(neigh)) { + if (neigh) { int res = dst_neigh_output(dst, neigh, skb); rcu_read_unlock_bh(); @@ -1366,8 +1366,9 @@ struct sk_buff *__ip_make_skb(struct sock *sk, return skb; } -int ip_send_skb(struct net *net, struct sk_buff *skb) +int ip_send_skb(struct sk_buff *skb) { + struct net *net = sock_net(skb->sk); int err; err = ip_local_out(skb); @@ -1390,7 +1391,7 @@ int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4) return 0; /* Netfilter gets whole the not fragmented skb. */ - return ip_send_skb(sock_net(sk), skb); + return ip_send_skb(skb); } /* @@ -1535,7 +1536,6 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, arg->csumoffset) = csum_fold(csum_add(nskb->csum, arg->csum)); nskb->ip_summed = CHECKSUM_NONE; - skb_orphan(nskb); skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); ip_push_pending_frames(sk, &fl4); } diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index fd9ecb52c66b..e4ba974f143c 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -2028,6 +2028,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4) } dev_out = net->loopback_dev; fl4->flowi4_oif = dev_out->ifindex; + res.fi = NULL; flags |= RTCF_LOCAL; goto make_route; } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 85308b90df80..2fd2bc9e3c64 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -5392,8 +5392,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, { struct tcp_sock *tp = tcp_sk(sk); - if (unlikely(sk->sk_rx_dst == NULL)) - inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb); /* * Header prediction. * The code loosely follows the one in the famous @@ -5607,7 +5605,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) tcp_set_state(sk, TCP_ESTABLISHED); if (skb != NULL) { - icsk->icsk_af_ops->sk_rx_dst_set(sk, skb); + inet_sk_rx_dst_set(sk, skb); security_inet_conn_established(sk, skb); } diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 767823764016..42b2a6a73092 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -1627,6 +1627,9 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) sk->sk_rx_dst = NULL; } } + if (unlikely(sk->sk_rx_dst == NULL)) + inet_sk_rx_dst_set(sk, skb); + if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { rsk = sk; goto reset; @@ -1869,21 +1872,10 @@ static struct timewait_sock_ops tcp_timewait_sock_ops = { .twsk_destructor= tcp_twsk_destructor, }; -void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) -{ - struct dst_entry *dst = skb_dst(skb); - - dst_hold(dst); - sk->sk_rx_dst = dst; - inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; -} -EXPORT_SYMBOL(inet_sk_rx_dst_set); - const struct inet_connection_sock_af_ops ipv4_specific = { .queue_xmit = ip_queue_xmit, .send_check = tcp_v4_send_check, .rebuild_header = inet_sk_rebuild_header, - .sk_rx_dst_set = inet_sk_rx_dst_set, .conn_request = tcp_v4_conn_request, .syn_recv_sock = tcp_v4_syn_recv_sock, .net_header_len = sizeof(struct iphdr), diff --git a/trunk/net/ipv4/tcp_metrics.c b/trunk/net/ipv4/tcp_metrics.c index 0abe67bb4d3a..2288a6399e1e 100644 --- a/trunk/net/ipv4/tcp_metrics.c +++ b/trunk/net/ipv4/tcp_metrics.c @@ -731,18 +731,6 @@ static int __net_init tcp_net_metrics_init(struct net *net) static void __net_exit tcp_net_metrics_exit(struct net *net) { - unsigned int i; - - for (i = 0; i < (1U << net->ipv4.tcp_metrics_hash_log) ; i++) { - struct tcp_metrics_block *tm, *next; - - tm = rcu_dereference_protected(net->ipv4.tcp_metrics_hash[i].chain, 1); - while (tm) { - next = rcu_dereference_protected(tm->tcpm_next, 1); - kfree(tm); - tm = next; - } - } kfree(net->ipv4.tcp_metrics_hash); } diff --git a/trunk/net/ipv4/tcp_minisocks.c b/trunk/net/ipv4/tcp_minisocks.c index d9c9dcef2de3..232a90c3ec86 100644 --- a/trunk/net/ipv4/tcp_minisocks.c +++ b/trunk/net/ipv4/tcp_minisocks.c @@ -387,7 +387,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct tcp_sock *oldtp = tcp_sk(sk); struct tcp_cookie_values *oldcvp = oldtp->cookie_values; - newicsk->icsk_af_ops->sk_rx_dst_set(newsk, skb); + inet_sk_rx_dst_set(newsk, skb); /* TCP Cookie Transactions require space for the cookie pair, * as it differs for each connection. There is no need to diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 20dfd892c86f..a7b3ec9b6c3e 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -940,7 +940,7 @@ void __init tcp_tasklet_init(void) * We cant xmit new skbs from this context, as we might already * hold qdisc lock. */ -static void tcp_wfree(struct sk_buff *skb) +void tcp_wfree(struct sk_buff *skb) { struct sock *sk = skb->sk; struct tcp_sock *tp = tcp_sk(sk); diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 6f6d1aca3c3d..b4c3582a991f 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -758,7 +758,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4) uh->check = CSUM_MANGLED_0; send: - err = ip_send_skb(sock_net(sk), skb); + err = ip_send_skb(skb); if (err) { if (err == -ENOBUFS && !inet->recverr) { UDP_INC_STATS_USER(sock_net(sk), diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 6bc85f7c31e3..79181819a24f 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -494,7 +494,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf) struct net_device *dev; struct inet6_dev *idev; - for_each_netdev(net, dev) { + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { idev = __in6_dev_get(dev); if (idev) { int changed = (!idev->cnf.forwarding) ^ (!newf); @@ -503,6 +504,7 @@ static void addrconf_forward_change(struct net *net, __s32 newf) dev_forward_change(idev); } } + rcu_read_unlock(); } static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) diff --git a/trunk/net/ipv6/proc.c b/trunk/net/ipv6/proc.c index 745a32042950..da2e92d05c15 100644 --- a/trunk/net/ipv6/proc.c +++ b/trunk/net/ipv6/proc.c @@ -307,10 +307,10 @@ static int __net_init ipv6_proc_init_net(struct net *net) goto proc_dev_snmp6_fail; return 0; -proc_dev_snmp6_fail: - proc_net_remove(net, "snmp6"); proc_snmp6_fail: proc_net_remove(net, "sockstat6"); +proc_dev_snmp6_fail: + proc_net_remove(net, "dev_snmp6"); return -ENOMEM; } diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index bb9ce2b2f377..c66b90f71c9b 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -1447,17 +1447,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) opt_skb = skb_clone(skb, sk_gfp_atomic(sk, GFP_ATOMIC)); if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ - struct dst_entry *dst = sk->sk_rx_dst; - sock_rps_save_rxhash(sk, skb); - if (dst) { - if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || - dst->ops->check(dst, np->rx_dst_cookie) == NULL) { - dst_release(dst); - sk->sk_rx_dst = NULL; - } - } - if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) goto reset; if (opt_skb) @@ -1715,9 +1705,9 @@ static void tcp_v6_early_demux(struct sk_buff *skb) struct dst_entry *dst = sk->sk_rx_dst; struct inet_sock *icsk = inet_sk(sk); if (dst) - dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); + dst = dst_check(dst, 0); if (dst && - icsk->rx_dst_ifindex == skb->skb_iif) + icsk->rx_dst_ifindex == inet6_iif(skb)) skb_dst_set_noref(skb, dst); } } @@ -1729,23 +1719,10 @@ static struct timewait_sock_ops tcp6_timewait_sock_ops = { .twsk_destructor= tcp_twsk_destructor, }; -static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) -{ - struct dst_entry *dst = skb_dst(skb); - const struct rt6_info *rt = (const struct rt6_info *)dst; - - dst_hold(dst); - sk->sk_rx_dst = dst; - inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; - if (rt->rt6i_node) - inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum; -} - static const struct inet_connection_sock_af_ops ipv6_specific = { .queue_xmit = inet6_csk_xmit, .send_check = tcp_v6_send_check, .rebuild_header = inet6_sk_rebuild_header, - .sk_rx_dst_set = inet6_sk_rx_dst_set, .conn_request = tcp_v6_conn_request, .syn_recv_sock = tcp_v6_syn_recv_sock, .net_header_len = sizeof(struct ipv6hdr), @@ -1777,7 +1754,6 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = { .queue_xmit = ip_queue_xmit, .send_check = tcp_v4_send_check, .rebuild_header = inet_sk_rebuild_header, - .sk_rx_dst_set = inet_sk_rx_dst_set, .conn_request = tcp_v6_conn_request, .syn_recv_sock = tcp_v6_syn_recv_sock, .net_header_len = sizeof(struct iphdr), diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index 8c2919ca36f6..f6fe4d400502 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -1206,7 +1206,7 @@ static int __init llc2_init(void) rc = llc_proc_init(); if (rc != 0) { printk(llc_proc_err_msg); - goto out_station; + goto out_unregister_llc_proto; } rc = llc_sysctl_init(); if (rc) { @@ -1226,8 +1226,7 @@ static int __init llc2_init(void) llc_sysctl_exit(); out_proc: llc_proc_exit(); -out_station: - llc_station_exit(); +out_unregister_llc_proto: proto_unregister(&llc_proto); goto out; } diff --git a/trunk/net/llc/llc_input.c b/trunk/net/llc/llc_input.c index dd3e83328ad5..e32cab44ea95 100644 --- a/trunk/net/llc/llc_input.c +++ b/trunk/net/llc/llc_input.c @@ -42,7 +42,6 @@ static void (*llc_type_handlers[2])(struct llc_sap *sap, void llc_add_pack(int type, void (*handler)(struct llc_sap *sap, struct sk_buff *skb)) { - smp_wmb(); /* ensure initialisation is complete before it's called */ if (type == LLC_DEST_SAP || type == LLC_DEST_CONN) llc_type_handlers[type - 1] = handler; } @@ -51,19 +50,11 @@ void llc_remove_pack(int type) { if (type == LLC_DEST_SAP || type == LLC_DEST_CONN) llc_type_handlers[type - 1] = NULL; - synchronize_net(); } void llc_set_station_handler(void (*handler)(struct sk_buff *skb)) { - /* Ensure initialisation is complete before it's called */ - if (handler) - smp_wmb(); - llc_station_handler = handler; - - if (!handler) - synchronize_net(); } /** @@ -159,8 +150,6 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, int dest; int (*rcv)(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *); - void (*sta_handler)(struct sk_buff *skb); - void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb); if (!net_eq(dev_net(dev), &init_net)) goto drop; @@ -193,8 +182,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, */ rcv = rcu_dereference(sap->rcv_func); dest = llc_pdu_type(skb); - sap_handler = dest ? ACCESS_ONCE(llc_type_handlers[dest - 1]) : NULL; - if (unlikely(!sap_handler)) { + if (unlikely(!dest || !llc_type_handlers[dest - 1])) { if (rcv) rcv(skb, dev, pt, orig_dev); else @@ -205,7 +193,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, if (cskb) rcv(cskb, dev, pt, orig_dev); } - sap_handler(sap, skb); + llc_type_handlers[dest - 1](sap, skb); } llc_sap_put(sap); out: @@ -214,10 +202,9 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, kfree_skb(skb); goto out; handle_station: - sta_handler = ACCESS_ONCE(llc_station_handler); - if (!sta_handler) + if (!llc_station_handler) goto drop; - sta_handler(skb); + llc_station_handler(skb); goto out; } diff --git a/trunk/net/llc/llc_station.c b/trunk/net/llc/llc_station.c index b2f2bac2c2a2..39a8d8924b9c 100644 --- a/trunk/net/llc/llc_station.c +++ b/trunk/net/llc/llc_station.c @@ -268,7 +268,7 @@ static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb) out: return rc; free: - kfree_skb(nskb); + kfree_skb(skb); goto out; } @@ -293,7 +293,7 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb) out: return rc; free: - kfree_skb(nskb); + kfree_skb(skb); goto out; } @@ -322,7 +322,7 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) out: return rc; free: - kfree_skb(nskb); + kfree_skb(skb); goto out; } @@ -687,8 +687,12 @@ static void llc_station_rcv(struct sk_buff *skb) llc_station_state_process(skb); } -void __init llc_station_init(void) +int __init llc_station_init(void) { + int rc = -ENOBUFS; + struct sk_buff *skb; + struct llc_station_state_ev *ev; + skb_queue_head_init(&llc_main_station.mac_pdu_q); skb_queue_head_init(&llc_main_station.ev_q.list); spin_lock_init(&llc_main_station.ev_q.lock); @@ -696,12 +700,23 @@ void __init llc_station_init(void) (unsigned long)&llc_main_station); llc_main_station.ack_timer.expires = jiffies + sysctl_llc_station_ack_timeout; - llc_main_station.maximum_retry = 1; - llc_main_station.state = LLC_STATION_STATE_UP; + skb = alloc_skb(0, GFP_ATOMIC); + if (!skb) + goto out; + rc = 0; llc_set_station_handler(llc_station_rcv); + ev = llc_station_ev(skb); + memset(ev, 0, sizeof(*ev)); + llc_main_station.maximum_retry = 1; + llc_main_station.state = LLC_STATION_STATE_DOWN; + ev->type = LLC_STATION_EV_TYPE_SIMPLE; + ev->prim_type = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK; + rc = llc_station_next_state(skb); +out: + return rc; } -void llc_station_exit(void) +void __exit llc_station_exit(void) { llc_set_station_handler(NULL); } diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index 8ac890a1a4c0..ceaca7c134a0 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -1079,7 +1079,7 @@ static void *packet_current_rx_frame(struct packet_sock *po, default: WARN(1, "TPACKET version not supported\n"); BUG(); - return NULL; + return 0; } } @@ -1936,6 +1936,7 @@ static void tpacket_destruct_skb(struct sk_buff *skb) if (likely(po->tx_ring.pg_vec)) { ph = skb_shinfo(skb)->destructor_arg; + BUG_ON(__packet_get_status(po, ph) != TP_STATUS_SENDING); BUG_ON(atomic_read(&po->tx_ring.pending) == 0); atomic_dec(&po->tx_ring.pending); __packet_set_status(po, ph, TP_STATUS_AVAILABLE); diff --git a/trunk/net/sched/act_gact.c b/trunk/net/sched/act_gact.c index 05d60859d8e3..f10fb8256442 100644 --- a/trunk/net/sched/act_gact.c +++ b/trunk/net/sched/act_gact.c @@ -67,9 +67,6 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est, struct tcf_common *pc; int ret = 0; int err; -#ifdef CONFIG_GACT_PROB - struct tc_gact_p *p_parm = NULL; -#endif if (nla == NULL) return -EINVAL; @@ -85,12 +82,6 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est, #ifndef CONFIG_GACT_PROB if (tb[TCA_GACT_PROB] != NULL) return -EOPNOTSUPP; -#else - if (tb[TCA_GACT_PROB]) { - p_parm = nla_data(tb[TCA_GACT_PROB]); - if (p_parm->ptype >= MAX_RAND) - return -EINVAL; - } #endif pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info); @@ -112,7 +103,8 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est, spin_lock_bh(&gact->tcf_lock); gact->tcf_action = parm->action; #ifdef CONFIG_GACT_PROB - if (p_parm) { + if (tb[TCA_GACT_PROB] != NULL) { + struct tc_gact_p *p_parm = nla_data(tb[TCA_GACT_PROB]); gact->tcfg_paction = p_parm->paction; gact->tcfg_pval = p_parm->pval; gact->tcfg_ptype = p_parm->ptype; @@ -141,7 +133,7 @@ static int tcf_gact(struct sk_buff *skb, const struct tc_action *a, spin_lock(&gact->tcf_lock); #ifdef CONFIG_GACT_PROB - if (gact->tcfg_ptype) + if (gact->tcfg_ptype && gact_rand[gact->tcfg_ptype] != NULL) action = gact_rand[gact->tcfg_ptype](gact); else action = gact->tcf_action; diff --git a/trunk/net/sched/act_ipt.c b/trunk/net/sched/act_ipt.c index 58fb3c7aab9e..60e281ad0f07 100644 --- a/trunk/net/sched/act_ipt.c +++ b/trunk/net/sched/act_ipt.c @@ -185,12 +185,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, err2: kfree(tname); err1: - if (ret == ACT_P_CREATED) { - if (est) - gen_kill_estimator(&pc->tcfc_bstats, - &pc->tcfc_rate_est); - kfree_rcu(pc, tcfc_rcu); - } + kfree(pc); return err; } diff --git a/trunk/net/sched/act_pedit.c b/trunk/net/sched/act_pedit.c index 45c53ab067a6..26aa2f6ce257 100644 --- a/trunk/net/sched/act_pedit.c +++ b/trunk/net/sched/act_pedit.c @@ -74,10 +74,7 @@ static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est, p = to_pedit(pc); keys = kmalloc(ksize, GFP_KERNEL); if (keys == NULL) { - if (est) - gen_kill_estimator(&pc->tcfc_bstats, - &pc->tcfc_rate_est); - kfree_rcu(pc, tcfc_rcu); + kfree(pc); return -ENOMEM; } ret = ACT_P_CREATED; diff --git a/trunk/net/sched/act_simple.c b/trunk/net/sched/act_simple.c index 3714f60f0b3c..3922f2a2821b 100644 --- a/trunk/net/sched/act_simple.c +++ b/trunk/net/sched/act_simple.c @@ -131,10 +131,7 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, d = to_defact(pc); ret = alloc_defdata(d, defdata); if (ret < 0) { - if (est) - gen_kill_estimator(&pc->tcfc_bstats, - &pc->tcfc_rate_est); - kfree_rcu(pc, tcfc_rcu); + kfree(pc); return ret; } d->tcf_action = parm->action; diff --git a/trunk/net/sched/sch_qfq.c b/trunk/net/sched/sch_qfq.c index e4723d31fdd5..9af01f3df18c 100644 --- a/trunk/net/sched/sch_qfq.c +++ b/trunk/net/sched/sch_qfq.c @@ -203,34 +203,6 @@ static int qfq_calc_index(u32 inv_w, unsigned int maxlen) return index; } -/* Length of the next packet (0 if the queue is empty). */ -static unsigned int qdisc_peek_len(struct Qdisc *sch) -{ - struct sk_buff *skb; - - skb = sch->ops->peek(sch); - return skb ? qdisc_pkt_len(skb) : 0; -} - -static void qfq_deactivate_class(struct qfq_sched *, struct qfq_class *); -static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl, - unsigned int len); - -static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl, - u32 lmax, u32 inv_w, int delta_w) -{ - int i; - - /* update qfq-specific data */ - cl->lmax = lmax; - cl->inv_w = inv_w; - i = qfq_calc_index(cl->inv_w, cl->lmax); - - cl->grp = &q->groups[i]; - - q->wsum += delta_w; -} - static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca, unsigned long *arg) { @@ -278,8 +250,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, lmax = 1UL << QFQ_MTU_SHIFT; if (cl != NULL) { - bool need_reactivation = false; - if (tca[TCA_RATE]) { err = gen_replace_estimator(&cl->bstats, &cl->rate_est, qdisc_root_sleeping_lock(sch), @@ -288,29 +258,12 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, return err; } - if (lmax == cl->lmax && inv_w == cl->inv_w) - return 0; /* nothing to update */ - - i = qfq_calc_index(inv_w, lmax); - sch_tree_lock(sch); - if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { - /* - * shift cl->F back, to not charge the - * class for the not-yet-served head - * packet - */ - cl->F = cl->S; - /* remove class from its slot in the old group */ - qfq_deactivate_class(q, cl); - need_reactivation = true; + if (inv_w != cl->inv_w) { + sch_tree_lock(sch); + q->wsum += delta_w; + cl->inv_w = inv_w; + sch_tree_unlock(sch); } - - qfq_update_class_params(q, cl, lmax, inv_w, delta_w); - - if (need_reactivation) /* activate in new group */ - qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); - sch_tree_unlock(sch); - return 0; } @@ -320,8 +273,11 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, cl->refcnt = 1; cl->common.classid = classid; + cl->lmax = lmax; + cl->inv_w = inv_w; + i = qfq_calc_index(cl->inv_w, cl->lmax); - qfq_update_class_params(q, cl, lmax, inv_w, delta_w); + cl->grp = &q->groups[i]; cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); @@ -338,6 +294,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, return err; } } + q->wsum += weight; sch_tree_lock(sch); qdisc_class_hash_insert(&q->clhash, &cl->common); @@ -754,6 +711,15 @@ static void qfq_update_eligible(struct qfq_sched *q, u64 old_V) } } +/* What is length of next packet in queue (0 if queue is empty) */ +static unsigned int qdisc_peek_len(struct Qdisc *sch) +{ + struct sk_buff *skb; + + skb = sch->ops->peek(sch); + return skb ? qdisc_pkt_len(skb) : 0; +} + /* * Updates the class, returns true if also the group needs to be updated. */ @@ -877,8 +843,11 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl) static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) { struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; struct qfq_class *cl; int err; + u64 roundedS; + int s; cl = qfq_classify(skb, sch, &err); if (cl == NULL) { @@ -907,25 +876,11 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) return err; /* If reach this point, queue q was idle */ - qfq_activate_class(q, cl, qdisc_pkt_len(skb)); - - return err; -} - -/* - * Handle class switch from idle to backlogged. - */ -static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl, - unsigned int pkt_len) -{ - struct qfq_group *grp = cl->grp; - u64 roundedS; - int s; - + grp = cl->grp; qfq_update_start(q, cl); /* compute new finish time and rounded start. */ - cl->F = cl->S + (u64)pkt_len * cl->inv_w; + cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w; roundedS = qfq_round_down(cl->S, grp->slot_shift); /* @@ -962,6 +917,8 @@ static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl, skip_update: qfq_slot_insert(grp, cl, roundedS); + + return err; } diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index dcd64d5b07aa..31b40cc4a9c3 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -952,11 +952,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, */ synchronize_rcu(); INIT_LIST_HEAD(&wdev->list); - /* - * Ensure that all events have been processed and - * freed. - */ - cfg80211_process_wdev_events(wdev); break; case NETDEV_PRE_UP: if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) diff --git a/trunk/net/wireless/core.h b/trunk/net/wireless/core.h index bc7430b54771..5206c6844fd7 100644 --- a/trunk/net/wireless/core.h +++ b/trunk/net/wireless/core.h @@ -426,7 +426,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, struct net_device *dev, enum nl80211_iftype ntype, u32 *flags, struct vif_params *params); void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); -void cfg80211_process_wdev_events(struct wireless_dev *wdev); int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 994e2f0cc7a8..26f8cd30f712 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -735,7 +735,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) wdev->connect_keys = NULL; } -void cfg80211_process_wdev_events(struct wireless_dev *wdev) +static void cfg80211_process_wdev_events(struct wireless_dev *wdev) { struct cfg80211_event *ev; unsigned long flags; diff --git a/trunk/security/yama/yama_lsm.c b/trunk/security/yama/yama_lsm.c index d51b7c76c37d..83554ee8a587 100644 --- a/trunk/security/yama/yama_lsm.c +++ b/trunk/security/yama/yama_lsm.c @@ -290,51 +290,10 @@ static int yama_ptrace_access_check(struct task_struct *child, return rc; } -/** - * yama_ptrace_traceme - validate PTRACE_TRACEME calls - * @parent: task that will become the ptracer of the current task - * - * Returns 0 if following the ptrace is allowed, -ve on error. - */ -static int yama_ptrace_traceme(struct task_struct *parent) -{ - int rc; - - /* If standard caps disallows it, so does Yama. We should - * only tighten restrictions further. - */ - rc = cap_ptrace_traceme(parent); - if (rc) - return rc; - - /* Only disallow PTRACE_TRACEME on more aggressive settings. */ - switch (ptrace_scope) { - case YAMA_SCOPE_CAPABILITY: - if (!ns_capable(task_user_ns(parent), CAP_SYS_PTRACE)) - rc = -EPERM; - break; - case YAMA_SCOPE_NO_ATTACH: - rc = -EPERM; - break; - } - - if (rc) { - char name[sizeof(current->comm)]; - printk_ratelimited(KERN_NOTICE - "ptraceme of pid %d was attempted by: %s (pid %d)\n", - current->pid, - get_task_comm(name, parent), - parent->pid); - } - - return rc; -} - static struct security_operations yama_ops = { .name = "yama", .ptrace_access_check = yama_ptrace_access_check, - .ptrace_traceme = yama_ptrace_traceme, .task_prctl = yama_task_prctl, .task_free = yama_task_free, }; diff --git a/trunk/sound/core/sgbuf.c b/trunk/sound/core/sgbuf.c index d0f00356fc11..4e7ec2b49873 100644 --- a/trunk/sound/core/sgbuf.c +++ b/trunk/sound/core/sgbuf.c @@ -101,7 +101,7 @@ void *snd_malloc_sgbuf_pages(struct device *device, if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device, chunk, &tmpb) < 0) { if (!sgbuf->pages) - goto _failed; + return NULL; if (!res_size) goto _failed; size = sgbuf->pages * PAGE_SIZE; diff --git a/trunk/sound/pci/emu10k1/memory.c b/trunk/sound/pci/emu10k1/memory.c index 0a436626182b..4f502a2bdc3c 100644 --- a/trunk/sound/pci/emu10k1/memory.c +++ b/trunk/sound/pci/emu10k1/memory.c @@ -326,10 +326,7 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst for (page = blk->first_page; page <= blk->last_page; page++, idx++) { unsigned long ofs = idx << PAGE_SHIFT; dma_addr_t addr; - if (ofs >= runtime->dma_bytes) - addr = emu->silent_page.addr; - else - addr = snd_pcm_sgbuf_get_addr(substream, ofs); + addr = snd_pcm_sgbuf_get_addr(substream, ofs); if (! is_valid_page(emu, addr)) { printk(KERN_ERR "emu: failure page = %d\n", idx); mutex_unlock(&hdr->block_mutex); diff --git a/trunk/sound/pci/hda/hda_auto_parser.c b/trunk/sound/pci/hda/hda_auto_parser.c index 4f7d2dfcef7b..647218d69f68 100644 --- a/trunk/sound/pci/hda/hda_auto_parser.c +++ b/trunk/sound/pci/hda/hda_auto_parser.c @@ -332,12 +332,13 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, if (cfg->dig_outs) snd_printd(" dig-out=0x%x/0x%x\n", cfg->dig_out_pins[0], cfg->dig_out_pins[1]); - snd_printd(" inputs:\n"); + snd_printd(" inputs:"); for (i = 0; i < cfg->num_inputs; i++) { - snd_printd(" %s=0x%x\n", + snd_printd(" %s=0x%x", hda_get_autocfg_input_label(codec, cfg, i), cfg->inputs[i].pin); } + snd_printd("\n"); if (cfg->dig_in_pin) snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index 5e22a8f43d2e..14361184ae1e 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -2967,10 +2967,12 @@ static const char * const cxt5066_models[CXT5066_MODELS] = { }; static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO), SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO), + SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD), @@ -2986,10 +2988,14 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), + SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO), + SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO), SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), + SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), + SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), {} }; diff --git a/trunk/sound/pci/hda/patch_hdmi.c b/trunk/sound/pci/hda/patch_hdmi.c index 8f23374fa642..69b928449789 100644 --- a/trunk/sound/pci/hda/patch_hdmi.c +++ b/trunk/sound/pci/hda/patch_hdmi.c @@ -877,6 +877,8 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, struct hdmi_eld *eld; struct hdmi_spec_per_cvt *per_cvt = NULL; + hinfo->nid = 0; /* clear the leftover value */ + /* Validate hinfo */ pin_idx = hinfo_to_pin_index(spec, hinfo); if (snd_BUG_ON(pin_idx < 0)) @@ -1161,14 +1163,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); } -static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - snd_hda_codec_cleanup_stream(codec, hinfo->nid); - return 0; -} - static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) @@ -1208,7 +1202,6 @@ static const struct hda_pcm_ops generic_ops = { .open = hdmi_pcm_open, .close = hdmi_pcm_close, .prepare = generic_hdmi_playback_pcm_prepare, - .cleanup = generic_hdmi_playback_pcm_cleanup, }; static int generic_hdmi_build_pcms(struct hda_codec *codec) @@ -1227,6 +1220,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; pstr->substreams = 1; pstr->ops = generic_ops; + pstr->nid = 1; /* FIXME: just for avoiding a debug WARNING */ /* other pstr fields are set in open */ } diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 4f81dd44c837..344b221d2102 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -6099,8 +6099,6 @@ static const struct alc_fixup alc269_fixups[] = { [ALC269_FIXUP_PCM_44K] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_pcm_44k, - .chained = true, - .chain_id = ALC269_FIXUP_QUANTA_MUTE }, [ALC269_FIXUP_STEREO_DMIC] = { .type = ALC_FIXUP_FUNC, @@ -6208,11 +6206,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), - SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE), + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), #if 0 diff --git a/trunk/sound/soc/codecs/ab8500-codec.c b/trunk/sound/soc/codecs/ab8500-codec.c index 23b40186f9b8..3c795921c5f6 100644 --- a/trunk/sound/soc/codecs/ab8500-codec.c +++ b/trunk/sound/soc/codecs/ab8500-codec.c @@ -2406,10 +2406,6 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) /* Setup AB8500 according to board-settings */ pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent); - - /* Inform SoC Core that we have our own I/O arrangements. */ - codec->control_data = (void *)true; - status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); if (status < 0) { pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); diff --git a/trunk/sound/soc/codecs/ad1980.c b/trunk/sound/soc/codecs/ad1980.c index 11b1b714b8b5..8c39dddd7d00 100644 --- a/trunk/sound/soc/codecs/ad1980.c +++ b/trunk/sound/soc/codecs/ad1980.c @@ -186,7 +186,6 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) printk(KERN_INFO "AD1980 SoC Audio Codec\n"); - codec->control_data = codec; /* we don't use regmap! */ ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); if (ret < 0) { printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); diff --git a/trunk/sound/soc/codecs/mc13783.c b/trunk/sound/soc/codecs/mc13783.c index 8f726c063f42..6276e352125f 100644 --- a/trunk/sound/soc/codecs/mc13783.c +++ b/trunk/sound/soc/codecs/mc13783.c @@ -581,8 +581,6 @@ static int mc13783_probe(struct snd_soc_codec *codec) { struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); - codec->control_data = priv->mc13xxx; - mc13xxx_lock(priv->mc13xxx); /* these are the reset values */ diff --git a/trunk/sound/soc/codecs/sgtl5000.c b/trunk/sound/soc/codecs/sgtl5000.c index df2f99d1d428..8af6a5245b18 100644 --- a/trunk/sound/soc/codecs/sgtl5000.c +++ b/trunk/sound/soc/codecs/sgtl5000.c @@ -239,7 +239,6 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = { {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ {"LO", NULL, "DAC"}, /* dac --> line_out */ - {"LINE_IN", NULL, "VAG_POWER"}, {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */ {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */ @@ -1358,6 +1357,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) if (ret) goto err; + snd_soc_dapm_new_widgets(&codec->dapm); + return 0; err: diff --git a/trunk/sound/soc/codecs/stac9766.c b/trunk/sound/soc/codecs/stac9766.c index 33c0f3d39c87..982e437799a8 100644 --- a/trunk/sound/soc/codecs/stac9766.c +++ b/trunk/sound/soc/codecs/stac9766.c @@ -340,7 +340,6 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); - codec->control_data = codec; /* we don't use regmap! */ ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); if (ret < 0) goto codec_err; diff --git a/trunk/sound/soc/codecs/wm8962.c b/trunk/sound/soc/codecs/wm8962.c index aa9ce9dd7d8a..eaf65863ec21 100644 --- a/trunk/sound/soc/codecs/wm8962.c +++ b/trunk/sound/soc/codecs/wm8962.c @@ -2501,9 +2501,6 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, /* VMID 2*250k */ snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, WM8962_VMID_SEL_MASK, 0x100); - - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) - msleep(100); break; case SND_SOC_BIAS_OFF: diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index 04ef03175c51..bb62f4b3d563 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -2649,7 +2649,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - bclk_rate = params_rate(params) * 4; + bclk_rate = params_rate(params) * 2; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: bclk_rate *= 16; @@ -3253,13 +3253,10 @@ static void wm8994_mic_work(struct work_struct *work) int ret; int report; - pm_runtime_get_sync(dev); - ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, ®); if (ret < 0) { dev_err(dev, "Failed to read microphone status: %d\n", ret); - pm_runtime_put(dev); return; } @@ -3302,8 +3299,6 @@ static void wm8994_mic_work(struct work_struct *work) snd_soc_jack_report(priv->micdet[1].jack, report, SND_JACK_HEADSET | SND_JACK_BTN_0); - - pm_runtime_put(dev); } static irqreturn_t wm8994_mic_irq(int irq, void *data) @@ -3426,15 +3421,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) int reg; bool present; - pm_runtime_get_sync(codec->dev); - mutex_lock(&wm8994->accdet_lock); reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); if (reg < 0) { dev_err(codec->dev, "Failed to read jack status: %d\n", reg); mutex_unlock(&wm8994->accdet_lock); - pm_runtime_put(codec->dev); return IRQ_NONE; } @@ -3499,7 +3491,6 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) SND_JACK_MECHANICAL | SND_JACK_HEADSET | wm8994->btn_mask); - pm_runtime_put(codec->dev); return IRQ_HANDLED; } @@ -3611,8 +3602,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) return IRQ_HANDLED; - pm_runtime_get_sync(codec->dev); - /* We may occasionally read a detection without an impedence * range being provided - if that happens loop again. */ @@ -3623,7 +3612,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) dev_err(codec->dev, "Failed to read mic detect status: %d\n", reg); - pm_runtime_put(codec->dev); return IRQ_NONE; } @@ -3651,7 +3639,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) dev_warn(codec->dev, "Accessory detection with no callback\n"); out: - pm_runtime_put(codec->dev); return IRQ_HANDLED; } diff --git a/trunk/sound/soc/codecs/wm9712.c b/trunk/sound/soc/codecs/wm9712.c index f16fb361a4eb..099e6ec32125 100644 --- a/trunk/sound/soc/codecs/wm9712.c +++ b/trunk/sound/soc/codecs/wm9712.c @@ -619,7 +619,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) { int ret = 0; - codec->control_data = codec; /* we don't use regmap! */ ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); if (ret < 0) { printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); diff --git a/trunk/sound/soc/codecs/wm9713.c b/trunk/sound/soc/codecs/wm9713.c index d0b8a3287a85..3eb19fb71d17 100644 --- a/trunk/sound/soc/codecs/wm9713.c +++ b/trunk/sound/soc/codecs/wm9713.c @@ -1196,7 +1196,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) if (wm9713 == NULL) return -ENOMEM; snd_soc_codec_set_drvdata(codec, wm9713); - codec->control_data = wm9713; /* we don't use regmap! */ ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); if (ret < 0) diff --git a/trunk/sound/soc/mxs/mxs-saif.c b/trunk/sound/soc/mxs/mxs-saif.c index b3030718c228..aba71bfa33b1 100644 --- a/trunk/sound/soc/mxs/mxs-saif.c +++ b/trunk/sound/soc/mxs/mxs-saif.c @@ -394,14 +394,9 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); - struct mxs_saif *master_saif; u32 scr, stat; int ret; - master_saif = mxs_saif_get_master(saif); - if (!master_saif) - return -EINVAL; - /* mclk should already be set */ if (!saif->mclk && saif->mclk_in_use) { dev_err(cpu_dai->dev, "set mclk first\n"); @@ -425,25 +420,6 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, return ret; } - /* prepare clk in hw_param, enable in trigger */ - clk_prepare(saif->clk); - if (saif != master_saif) { - /* - * Set an initial clock rate for the saif internal logic to work - * properly. This is important when working in EXTMASTER mode - * that uses the other saif's BITCLK&LRCLK but it still needs a - * basic clock which should be fast enough for the internal - * logic. - */ - clk_enable(saif->clk); - ret = clk_set_rate(saif->clk, 24000000); - clk_disable(saif->clk); - if (ret) - return ret; - - clk_prepare(master_saif->clk); - } - scr = __raw_readl(saif->base + SAIF_CTRL); scr &= ~BM_SAIF_CTRL_WORD_LENGTH; diff --git a/trunk/sound/soc/omap/omap-mcbsp.c b/trunk/sound/soc/omap/omap-mcbsp.c index acdd3ef14e08..1046083e90a0 100644 --- a/trunk/sound/soc/omap/omap-mcbsp.c +++ b/trunk/sound/soc/omap/omap-mcbsp.c @@ -820,4 +820,3 @@ module_platform_driver(asoc_mcbsp_driver); MODULE_AUTHOR("Jarkko Nikula "); MODULE_DESCRIPTION("OMAP I2S SoC Interface"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:omap-mcbsp"); diff --git a/trunk/sound/soc/omap/omap-pcm.c b/trunk/sound/soc/omap/omap-pcm.c index f0feb06615f8..5a649da9122a 100644 --- a/trunk/sound/soc/omap/omap-pcm.c +++ b/trunk/sound/soc/omap/omap-pcm.c @@ -441,4 +441,3 @@ module_platform_driver(omap_pcm_driver); MODULE_AUTHOR("Jarkko Nikula "); MODULE_DESCRIPTION("OMAP PCM DMA module"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:omap-pcm-audio"); diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index f81c5976b961..f219b2f7ee68 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -1096,7 +1096,7 @@ static int soc_probe_codec(struct snd_soc_card *card, } /* If the driver didn't set I/O up try regmap */ - if (!codec->write && dev_get_regmap(codec->dev, NULL)) + if (!codec->control_data) snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); if (driver->controls) diff --git a/trunk/sound/soc/tegra/tegra_alc5632.c b/trunk/sound/soc/tegra/tegra_alc5632.c index e463529b38bb..d684df294c0c 100644 --- a/trunk/sound/soc/tegra/tegra_alc5632.c +++ b/trunk/sound/soc/tegra/tegra_alc5632.c @@ -177,7 +177,7 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) } alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); - if (alc5632->gpio_hp_det == -EPROBE_DEFER) + if (alc5632->gpio_hp_det == -ENODEV) return -EPROBE_DEFER; ret = snd_soc_of_parse_card_name(card, "nvidia,model"); diff --git a/trunk/sound/soc/tegra/tegra_wm8903.c b/trunk/sound/soc/tegra/tegra_wm8903.c index d4f14e492341..0c5bb33d258e 100644 --- a/trunk/sound/soc/tegra/tegra_wm8903.c +++ b/trunk/sound/soc/tegra/tegra_wm8903.c @@ -284,27 +284,27 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) } else if (np) { pdata->gpio_spkr_en = of_get_named_gpio(np, "nvidia,spkr-en-gpios", 0); - if (pdata->gpio_spkr_en == -EPROBE_DEFER) + if (pdata->gpio_spkr_en == -ENODEV) return -EPROBE_DEFER; pdata->gpio_hp_mute = of_get_named_gpio(np, "nvidia,hp-mute-gpios", 0); - if (pdata->gpio_hp_mute == -EPROBE_DEFER) + if (pdata->gpio_hp_mute == -ENODEV) return -EPROBE_DEFER; pdata->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); - if (pdata->gpio_hp_det == -EPROBE_DEFER) + if (pdata->gpio_hp_det == -ENODEV) return -EPROBE_DEFER; pdata->gpio_int_mic_en = of_get_named_gpio(np, "nvidia,int-mic-en-gpios", 0); - if (pdata->gpio_int_mic_en == -EPROBE_DEFER) + if (pdata->gpio_int_mic_en == -ENODEV) return -EPROBE_DEFER; pdata->gpio_ext_mic_en = of_get_named_gpio(np, "nvidia,ext-mic-en-gpios", 0); - if (pdata->gpio_ext_mic_en == -EPROBE_DEFER) + if (pdata->gpio_ext_mic_en == -ENODEV) return -EPROBE_DEFER; } diff --git a/trunk/sound/soc/ux500/ux500_msp_dai.c b/trunk/sound/soc/ux500/ux500_msp_dai.c index 057e28ef770e..62ac0285bfaf 100644 --- a/trunk/sound/soc/ux500/ux500_msp_dai.c +++ b/trunk/sound/soc/ux500/ux500_msp_dai.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/trunk/sound/soc/ux500/ux500_msp_i2s.c b/trunk/sound/soc/ux500/ux500_msp_i2s.c index 5c472f335a64..ee14d2dac2f5 100644 --- a/trunk/sound/soc/ux500/ux500_msp_i2s.c +++ b/trunk/sound/soc/ux500/ux500_msp_i2s.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include diff --git a/trunk/sound/soc/ux500/ux500_msp_i2s.h b/trunk/sound/soc/ux500/ux500_msp_i2s.h index 2d9136da9865..7f71b4a0d4bc 100644 --- a/trunk/sound/soc/ux500/ux500_msp_i2s.h +++ b/trunk/sound/soc/ux500/ux500_msp_i2s.h @@ -17,7 +17,7 @@ #include -#include +#include #define MSP_INPUT_FREQ_APB 48000000 diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 35655c3a7b7a..77f124fe57ad 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -319,8 +319,6 @@ LIB_H += $(ARCH_INCLUDE) LIB_H += util/cgroup.h LIB_H += $(TRACE_EVENT_DIR)event-parse.h LIB_H += util/target.h -LIB_H += util/rblist.h -LIB_H += util/intlist.h LIB_OBJS += $(OUTPUT)util/abspath.o LIB_OBJS += $(OUTPUT)util/alias.o @@ -385,8 +383,6 @@ LIB_OBJS += $(OUTPUT)util/xyarray.o LIB_OBJS += $(OUTPUT)util/cpumap.o LIB_OBJS += $(OUTPUT)util/cgroup.o LIB_OBJS += $(OUTPUT)util/target.o -LIB_OBJS += $(OUTPUT)util/rblist.o -LIB_OBJS += $(OUTPUT)util/intlist.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o @@ -987,8 +983,7 @@ clean: $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(MAKE) -C Documentation/ clean $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS - $(RM) $(OUTPUT)util/*-bison* - $(RM) $(OUTPUT)util/*-flex* + $(RM) $(OUTPUT)util/*-{bison,flex}* $(python-clean) .PHONY: all install clean strip $(LIBTRACEEVENT) diff --git a/trunk/tools/perf/builtin-record.c b/trunk/tools/perf/builtin-record.c index 4db6e1ba54e3..f5a6452931e6 100644 --- a/trunk/tools/perf/builtin-record.c +++ b/trunk/tools/perf/builtin-record.c @@ -313,7 +313,7 @@ static void perf_record__open(struct perf_record *rec) } } - perf_session__set_id_hdr_size(session); + perf_session__update_sample_type(session); } static int process_buildids(struct perf_record *rec) @@ -844,6 +844,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) struct perf_record *rec = &record; char errbuf[BUFSIZ]; + perf_header__set_cmdline(argc, argv); + evsel_list = perf_evlist__new(NULL, NULL); if (evsel_list == NULL) return -ENOMEM; diff --git a/trunk/tools/perf/builtin-report.c b/trunk/tools/perf/builtin-report.c index 7c88a243b5db..69b1c1185159 100644 --- a/trunk/tools/perf/builtin-report.c +++ b/trunk/tools/perf/builtin-report.c @@ -249,9 +249,8 @@ static int process_read_event(struct perf_tool *tool, static int perf_report__setup_sample_type(struct perf_report *rep) { struct perf_session *self = rep->session; - u64 sample_type = perf_evlist__sample_type(self->evlist); - if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) { + if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { if (sort__has_parent) { ui__error("Selected --sort parent, but no " "callchain data. Did you call " @@ -275,7 +274,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep) if (sort__branch_mode == 1) { if (!self->fd_pipe && - !(sample_type & PERF_SAMPLE_BRANCH_STACK)) { + !(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { ui__error("Selected -b but no branch data. " "Did you call perf record without -b?\n"); return -1; diff --git a/trunk/tools/perf/builtin-test.c b/trunk/tools/perf/builtin-test.c index 1d592f5cbea9..d909eb74a0eb 100644 --- a/trunk/tools/perf/builtin-test.c +++ b/trunk/tools/perf/builtin-test.c @@ -478,6 +478,7 @@ static int test__basic_mmap(void) unsigned int nr_events[nsyscalls], expected_nr_events[nsyscalls], i, j; struct perf_evsel *evsels[nsyscalls], *evsel; + int sample_size = __perf_evsel__sample_size(attr.sample_type); for (i = 0; i < nsyscalls; ++i) { char name[64]; @@ -562,7 +563,8 @@ static int test__basic_mmap(void) goto out_munmap; } - err = perf_evlist__parse_sample(evlist, event, &sample, false); + err = perf_event__parse_sample(event, attr.sample_type, sample_size, + false, &sample, false); if (err) { pr_err("Can't parse sample, err = %d\n", err); goto out_munmap; @@ -659,12 +661,12 @@ static int test__PERF_RECORD(void) const char *cmd = "sleep"; const char *argv[] = { cmd, "1", NULL, }; char *bname; - u64 prev_time = 0; + u64 sample_type, prev_time = 0; bool found_cmd_mmap = false, found_libc_mmap = false, found_vdso_mmap = false, found_ld_mmap = false; - int err = -1, errs = 0, i, wakeups = 0; + int err = -1, errs = 0, i, wakeups = 0, sample_size; u32 cpu; int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; @@ -754,6 +756,13 @@ static int test__PERF_RECORD(void) goto out_delete_evlist; } + /* + * We'll need these two to parse the PERF_SAMPLE_* fields in each + * event. + */ + sample_type = perf_evlist__sample_type(evlist); + sample_size = __perf_evsel__sample_size(sample_type); + /* * Now that all is properly set up, enable the events, they will * count just on workload.pid, which will start... @@ -779,7 +788,9 @@ static int test__PERF_RECORD(void) if (type < PERF_RECORD_MAX) nr_events[type]++; - err = perf_evlist__parse_sample(evlist, event, &sample, false); + err = perf_event__parse_sample(event, sample_type, + sample_size, true, + &sample, false); if (err < 0) { if (verbose) perf_event__fprintf(event, stderr); diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index 68cd61ef6ac5..35e86c6df713 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -38,7 +38,6 @@ #include "util/cpumap.h" #include "util/xyarray.h" #include "util/sort.h" -#include "util/intlist.h" #include "util/debug.h" @@ -707,16 +706,8 @@ static void perf_event__process_sample(struct perf_tool *tool, int err; if (!machine && perf_guest) { - static struct intlist *seen; - - if (!seen) - seen = intlist__new(); - - if (!intlist__has_entry(seen, event->ip.pid)) { - pr_err("Can't find guest [%d]'s kernel information\n", - event->ip.pid); - intlist__add(seen, event->ip.pid); - } + pr_err("Can't find guest [%d]'s kernel information\n", + event->ip.pid); return; } @@ -820,7 +811,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) int ret; while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { - ret = perf_evlist__parse_sample(top->evlist, event, &sample, false); + ret = perf_session__parse_sample(session, event, &sample); if (ret) { pr_err("Can't parse sample, err = %d\n", ret); continue; @@ -952,10 +943,8 @@ static void perf_top__start_counters(struct perf_top *top) * based cpu-clock-tick sw counter, which * is always available even if no PMU support: */ - if ((err == ENOENT || err == ENXIO) && - (attr->type == PERF_TYPE_HARDWARE) && - (attr->config == PERF_COUNT_HW_CPU_CYCLES)) { - + if (attr->type == PERF_TYPE_HARDWARE && + attr->config == PERF_COUNT_HW_CPU_CYCLES) { if (verbose) ui__warning("Cycles event not supported,\n" "trying to fall back to cpu-clock-ticks\n"); @@ -1043,7 +1032,7 @@ static int __cmd_top(struct perf_top *top) &top->session->host_machine); perf_top__start_counters(top); top->session->evlist = top->evlist; - perf_session__set_id_hdr_size(top->session); + perf_session__update_sample_type(top->session); /* Wait for a minimal set of events before starting the snapshot */ poll(top->evlist->pollfd, top->evlist->nr_fds, 100); diff --git a/trunk/tools/perf/util/event.h b/trunk/tools/perf/util/event.h index d84870b06426..1b197280c621 100644 --- a/trunk/tools/perf/util/event.h +++ b/trunk/tools/perf/util/event.h @@ -197,6 +197,9 @@ int perf_event__preprocess_sample(const union perf_event *self, const char *perf_event__name(unsigned int id); +int perf_event__parse_sample(const union perf_event *event, u64 type, + int sample_size, bool sample_id_all, + struct perf_sample *sample, bool swapped); int perf_event__synthesize_sample(union perf_event *event, u64 type, const struct perf_sample *sample, bool swapped); diff --git a/trunk/tools/perf/util/evlist.c b/trunk/tools/perf/util/evlist.c index 9b38681add9e..3edfd3483816 100644 --- a/trunk/tools/perf/util/evlist.c +++ b/trunk/tools/perf/util/evlist.c @@ -881,10 +881,3 @@ int perf_evlist__start_workload(struct perf_evlist *evlist) return 0; } - -int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, - struct perf_sample *sample, bool swapped) -{ - struct perf_evsel *e = list_entry(evlist->entries.next, struct perf_evsel, node); - return perf_evsel__parse_sample(e, event, sample, swapped); -} diff --git a/trunk/tools/perf/util/evlist.h b/trunk/tools/perf/util/evlist.h index 528c1acd9298..40d4d3cdced0 100644 --- a/trunk/tools/perf/util/evlist.h +++ b/trunk/tools/perf/util/evlist.h @@ -122,9 +122,6 @@ u64 perf_evlist__sample_type(const struct perf_evlist *evlist); bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist); u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist); -int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, - struct perf_sample *sample, bool swapped); - bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); diff --git a/trunk/tools/perf/util/evsel.c b/trunk/tools/perf/util/evsel.c index 2eaae140def2..e81771364867 100644 --- a/trunk/tools/perf/util/evsel.c +++ b/trunk/tools/perf/util/evsel.c @@ -20,7 +20,7 @@ #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) -static int __perf_evsel__sample_size(u64 sample_type) +int __perf_evsel__sample_size(u64 sample_type) { u64 mask = sample_type & PERF_SAMPLE_MASK; int size = 0; @@ -53,7 +53,6 @@ void perf_evsel__init(struct perf_evsel *evsel, evsel->attr = *attr; INIT_LIST_HEAD(&evsel->node); hists__init(&evsel->hists); - evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); } struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) @@ -729,10 +728,10 @@ static bool sample_overlap(const union perf_event *event, return false; } -int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, +int perf_event__parse_sample(const union perf_event *event, u64 type, + int sample_size, bool sample_id_all, struct perf_sample *data, bool swapped) { - u64 type = evsel->attr.sample_type; const u64 *array; /* @@ -747,14 +746,14 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, data->period = 1; if (event->header.type != PERF_RECORD_SAMPLE) { - if (!evsel->attr.sample_id_all) + if (!sample_id_all) return 0; return perf_event__parse_id_sample(event, type, data, swapped); } array = event->sample.array; - if (evsel->sample_size + sizeof(event->header) > event->header.size) + if (sample_size + sizeof(event->header) > event->header.size) return -EFAULT; if (type & PERF_SAMPLE_IP) { @@ -896,7 +895,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u.val32[1] = sample->tid; if (swapped) { /* - * Inverse of what is done in perf_evsel__parse_sample + * Inverse of what is done in perf_event__parse_sample */ u.val32[0] = bswap_32(u.val32[0]); u.val32[1] = bswap_32(u.val32[1]); @@ -931,7 +930,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u.val32[0] = sample->cpu; if (swapped) { /* - * Inverse of what is done in perf_evsel__parse_sample + * Inverse of what is done in perf_event__parse_sample */ u.val32[0] = bswap_32(u.val32[0]); u.val64 = bswap_64(u.val64); diff --git a/trunk/tools/perf/util/evsel.h b/trunk/tools/perf/util/evsel.h index b559929983bb..67cc5033d192 100644 --- a/trunk/tools/perf/util/evsel.h +++ b/trunk/tools/perf/util/evsel.h @@ -65,7 +65,6 @@ struct perf_evsel { void *func; void *data; } handler; - unsigned int sample_size; bool supported; }; @@ -178,8 +177,13 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel, return __perf_evsel__read(evsel, ncpus, nthreads, true); } +int __perf_evsel__sample_size(u64 sample_type); + +static inline int perf_evsel__sample_size(struct perf_evsel *evsel) +{ + return __perf_evsel__sample_size(evsel->attr.sample_type); +} + void hists__init(struct hists *hists); -int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, - struct perf_sample *sample, bool swapped); #endif /* __PERF_EVSEL_H */ diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index 74ea3c2f8138..3a6d20443330 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -174,15 +174,6 @@ perf_header__set_cmdline(int argc, const char **argv) { int i; - /* - * If header_argv has already been set, do not override it. - * This allows a command to set the cmdline, parse args and - * then call another builtin function that implements a - * command -- e.g, cmd_kvm calling cmd_record. - */ - if (header_argv) - return 0; - header_argc = (u32)argc; /* do not include NULL termination */ diff --git a/trunk/tools/perf/util/intlist.c b/trunk/tools/perf/util/intlist.c deleted file mode 100644 index fd530dced9cb..000000000000 --- a/trunk/tools/perf/util/intlist.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Based on intlist.c by: - * (c) 2009 Arnaldo Carvalho de Melo - * - * Licensed under the GPLv2. - */ - -#include -#include -#include - -#include "intlist.h" - -static struct rb_node *intlist__node_new(struct rblist *rblist __used, - const void *entry) -{ - int i = (int)((long)entry); - struct rb_node *rc = NULL; - struct int_node *node = malloc(sizeof(*node)); - - if (node != NULL) { - node->i = i; - rc = &node->rb_node; - } - - return rc; -} - -static void int_node__delete(struct int_node *ilist) -{ - free(ilist); -} - -static void intlist__node_delete(struct rblist *rblist __used, - struct rb_node *rb_node) -{ - struct int_node *node = container_of(rb_node, struct int_node, rb_node); - - int_node__delete(node); -} - -static int intlist__node_cmp(struct rb_node *rb_node, const void *entry) -{ - int i = (int)((long)entry); - struct int_node *node = container_of(rb_node, struct int_node, rb_node); - - return node->i - i; -} - -int intlist__add(struct intlist *ilist, int i) -{ - return rblist__add_node(&ilist->rblist, (void *)((long)i)); -} - -void intlist__remove(struct intlist *ilist __used, struct int_node *node) -{ - int_node__delete(node); -} - -struct int_node *intlist__find(struct intlist *ilist, int i) -{ - struct int_node *node = NULL; - struct rb_node *rb_node = rblist__find(&ilist->rblist, (void *)((long)i)); - - if (rb_node) - node = container_of(rb_node, struct int_node, rb_node); - - return node; -} - -struct intlist *intlist__new(void) -{ - struct intlist *ilist = malloc(sizeof(*ilist)); - - if (ilist != NULL) { - rblist__init(&ilist->rblist); - ilist->rblist.node_cmp = intlist__node_cmp; - ilist->rblist.node_new = intlist__node_new; - ilist->rblist.node_delete = intlist__node_delete; - } - - return ilist; -} - -void intlist__delete(struct intlist *ilist) -{ - if (ilist != NULL) - rblist__delete(&ilist->rblist); -} - -struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx) -{ - struct int_node *node = NULL; - struct rb_node *rb_node; - - rb_node = rblist__entry(&ilist->rblist, idx); - if (rb_node) - node = container_of(rb_node, struct int_node, rb_node); - - return node; -} diff --git a/trunk/tools/perf/util/intlist.h b/trunk/tools/perf/util/intlist.h deleted file mode 100644 index 6d63ab90db50..000000000000 --- a/trunk/tools/perf/util/intlist.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef __PERF_INTLIST_H -#define __PERF_INTLIST_H - -#include -#include - -#include "rblist.h" - -struct int_node { - struct rb_node rb_node; - int i; -}; - -struct intlist { - struct rblist rblist; -}; - -struct intlist *intlist__new(void); -void intlist__delete(struct intlist *ilist); - -void intlist__remove(struct intlist *ilist, struct int_node *in); -int intlist__add(struct intlist *ilist, int i); - -struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx); -struct int_node *intlist__find(struct intlist *ilist, int i); - -static inline bool intlist__has_entry(struct intlist *ilist, int i) -{ - return intlist__find(ilist, i) != NULL; -} - -static inline bool intlist__empty(const struct intlist *ilist) -{ - return rblist__empty(&ilist->rblist); -} - -static inline unsigned int intlist__nr_entries(const struct intlist *ilist) -{ - return rblist__nr_entries(&ilist->rblist); -} - -/* For intlist iteration */ -static inline struct int_node *intlist__first(struct intlist *ilist) -{ - struct rb_node *rn = rb_first(&ilist->rblist.entries); - return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; -} -static inline struct int_node *intlist__next(struct int_node *in) -{ - struct rb_node *rn; - if (!in) - return NULL; - rn = rb_next(&in->rb_node); - return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; -} - -/** - * intlist_for_each - iterate over a intlist - * @pos: the &struct int_node to use as a loop cursor. - * @ilist: the &struct intlist for loop. - */ -#define intlist__for_each(pos, ilist) \ - for (pos = intlist__first(ilist); pos; pos = intlist__next(pos)) - -/** - * intlist_for_each_safe - iterate over a intlist safe against removal of - * int_node - * @pos: the &struct int_node to use as a loop cursor. - * @n: another &struct int_node to use as temporary storage. - * @ilist: the &struct intlist for loop. - */ -#define intlist__for_each_safe(pos, n, ilist) \ - for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\ - pos = n, n = intlist__next(n)) -#endif /* __PERF_INTLIST_H */ diff --git a/trunk/tools/perf/util/parse-events-test.c b/trunk/tools/perf/util/parse-events-test.c index 127d648cc548..1b997d2b89ce 100644 --- a/trunk/tools/perf/util/parse-events-test.c +++ b/trunk/tools/perf/util/parse-events-test.c @@ -13,9 +13,6 @@ do { \ } \ } while (0) -#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \ - PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) - static int test__checkevent_tracepoint(struct perf_evlist *evlist) { struct perf_evsel *evsel = list_entry(evlist->entries.next, @@ -24,7 +21,8 @@ static int test__checkevent_tracepoint(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); + (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == + evsel->attr.sample_type); TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); return 0; } @@ -39,7 +37,8 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); + (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) + == evsel->attr.sample_type); TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); } @@ -429,7 +428,8 @@ static int test__checkevent_list(struct perf_evlist *evlist) evsel = list_entry(evsel->node.next, struct perf_evsel, node); TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); + (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == + evsel->attr.sample_type); TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); diff --git a/trunk/tools/perf/util/parse-options.c b/trunk/tools/perf/util/parse-options.c index 594f8fad5ecd..99d02aa57dbf 100644 --- a/trunk/tools/perf/util/parse-options.c +++ b/trunk/tools/perf/util/parse-options.c @@ -1,7 +1,6 @@ #include "util.h" #include "parse-options.h" #include "cache.h" -#include "header.h" #define OPT_SHORT 1 #define OPT_UNSET 2 @@ -414,8 +413,6 @@ int parse_options(int argc, const char **argv, const struct option *options, { struct parse_opt_ctx_t ctx; - perf_header__set_cmdline(argc, argv); - parse_options_start(&ctx, argc, argv, flags); switch (parse_options_step(&ctx, options, usagestr)) { case PARSE_OPT_HELP: diff --git a/trunk/tools/perf/util/python.c b/trunk/tools/perf/util/python.c index 0688bfb6d280..e03b58a48424 100644 --- a/trunk/tools/perf/util/python.c +++ b/trunk/tools/perf/util/python.c @@ -797,13 +797,17 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, event = perf_evlist__mmap_read(evlist, cpu); if (event != NULL) { + struct perf_evsel *first; PyObject *pyevent = pyrf_event__new(event); struct pyrf_event *pevent = (struct pyrf_event *)pyevent; if (pyevent == NULL) return PyErr_NoMemory(); - err = perf_evlist__parse_sample(evlist, event, &pevent->sample, false); + first = list_entry(evlist->entries.next, struct perf_evsel, node); + err = perf_event__parse_sample(event, first->attr.sample_type, + perf_evsel__sample_size(first), + sample_id_all, &pevent->sample, false); if (err) return PyErr_Format(PyExc_OSError, "perf: can't parse sample, err=%d", err); diff --git a/trunk/tools/perf/util/rblist.c b/trunk/tools/perf/util/rblist.c deleted file mode 100644 index 0171fb611004..000000000000 --- a/trunk/tools/perf/util/rblist.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Based on strlist.c by: - * (c) 2009 Arnaldo Carvalho de Melo - * - * Licensed under the GPLv2. - */ - -#include -#include -#include - -#include "rblist.h" - -int rblist__add_node(struct rblist *rblist, const void *new_entry) -{ - struct rb_node **p = &rblist->entries.rb_node; - struct rb_node *parent = NULL, *new_node; - - while (*p != NULL) { - int rc; - - parent = *p; - - rc = rblist->node_cmp(parent, new_entry); - if (rc > 0) - p = &(*p)->rb_left; - else if (rc < 0) - p = &(*p)->rb_right; - else - return -EEXIST; - } - - new_node = rblist->node_new(rblist, new_entry); - if (new_node == NULL) - return -ENOMEM; - - rb_link_node(new_node, parent, p); - rb_insert_color(new_node, &rblist->entries); - ++rblist->nr_entries; - - return 0; -} - -void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node) -{ - rb_erase(rb_node, &rblist->entries); - rblist->node_delete(rblist, rb_node); -} - -struct rb_node *rblist__find(struct rblist *rblist, const void *entry) -{ - struct rb_node **p = &rblist->entries.rb_node; - struct rb_node *parent = NULL; - - while (*p != NULL) { - int rc; - - parent = *p; - - rc = rblist->node_cmp(parent, entry); - if (rc > 0) - p = &(*p)->rb_left; - else if (rc < 0) - p = &(*p)->rb_right; - else - return parent; - } - - return NULL; -} - -void rblist__init(struct rblist *rblist) -{ - if (rblist != NULL) { - rblist->entries = RB_ROOT; - rblist->nr_entries = 0; - } - - return; -} - -void rblist__delete(struct rblist *rblist) -{ - if (rblist != NULL) { - struct rb_node *pos, *next = rb_first(&rblist->entries); - - while (next) { - pos = next; - next = rb_next(pos); - rb_erase(pos, &rblist->entries); - rblist->node_delete(rblist, pos); - } - free(rblist); - } -} - -struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx) -{ - struct rb_node *node; - - for (node = rb_first(&rblist->entries); node; node = rb_next(node)) { - if (!idx--) - return node; - } - - return NULL; -} diff --git a/trunk/tools/perf/util/rblist.h b/trunk/tools/perf/util/rblist.h deleted file mode 100644 index 6d0cae5ae83d..000000000000 --- a/trunk/tools/perf/util/rblist.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __PERF_RBLIST_H -#define __PERF_RBLIST_H - -#include -#include - -/* - * create node structs of the form: - * struct my_node { - * struct rb_node rb_node; - * ... my data ... - * }; - * - * create list structs of the form: - * struct mylist { - * struct rblist rblist; - * ... my data ... - * }; - */ - -struct rblist { - struct rb_root entries; - unsigned int nr_entries; - - int (*node_cmp)(struct rb_node *rbn, const void *entry); - struct rb_node *(*node_new)(struct rblist *rlist, const void *new_entry); - void (*node_delete)(struct rblist *rblist, struct rb_node *rb_node); -}; - -void rblist__init(struct rblist *rblist); -void rblist__delete(struct rblist *rblist); -int rblist__add_node(struct rblist *rblist, const void *new_entry); -void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node); -struct rb_node *rblist__find(struct rblist *rblist, const void *entry); -struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx); - -static inline bool rblist__empty(const struct rblist *rblist) -{ - return rblist->nr_entries == 0; -} - -static inline unsigned int rblist__nr_entries(const struct rblist *rblist) -{ - return rblist->nr_entries; -} - -#endif /* __PERF_RBLIST_H */ diff --git a/trunk/tools/perf/util/session.c b/trunk/tools/perf/util/session.c index 2437fb0b463a..8e4f0755d2aa 100644 --- a/trunk/tools/perf/util/session.c +++ b/trunk/tools/perf/util/session.c @@ -80,12 +80,14 @@ static int perf_session__open(struct perf_session *self, bool force) return -1; } -void perf_session__set_id_hdr_size(struct perf_session *session) +void perf_session__update_sample_type(struct perf_session *self) { - u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist); - - session->host_machine.id_hdr_size = id_hdr_size; - machines__set_id_hdr_size(&session->machines, id_hdr_size); + self->sample_type = perf_evlist__sample_type(self->evlist); + self->sample_size = __perf_evsel__sample_size(self->sample_type); + self->sample_id_all = perf_evlist__sample_id_all(self->evlist); + self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); + self->host_machine.id_hdr_size = self->id_hdr_size; + machines__set_id_hdr_size(&self->machines, self->id_hdr_size); } int perf_session__create_kernel_maps(struct perf_session *self) @@ -145,7 +147,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, if (mode == O_RDONLY) { if (perf_session__open(self, force) < 0) goto out_delete; - perf_session__set_id_hdr_size(self); + perf_session__update_sample_type(self); } else if (mode == O_WRONLY) { /* * In O_RDONLY mode this will be performed when reading the @@ -156,7 +158,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, } if (tool && tool->ordering_requires_timestamps && - tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) { + tool->ordered_samples && !self->sample_id_all) { dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); tool->ordered_samples = false; } @@ -671,8 +673,7 @@ static void flush_sample_queue(struct perf_session *s, if (iter->timestamp > limit) break; - ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample, - s->header.needs_swap); + ret = perf_session__parse_sample(s, iter->event, &sample); if (ret) pr_err("Can't parse sample, err = %d\n", ret); else @@ -864,18 +865,16 @@ static void perf_session__print_tstamp(struct perf_session *session, union perf_event *event, struct perf_sample *sample) { - u64 sample_type = perf_evlist__sample_type(session->evlist); - if (event->header.type != PERF_RECORD_SAMPLE && - !perf_evlist__sample_id_all(session->evlist)) { + !session->sample_id_all) { fputs("-1 -1 ", stdout); return; } - if ((sample_type & PERF_SAMPLE_CPU)) + if ((session->sample_type & PERF_SAMPLE_CPU)) printf("%u ", sample->cpu); - if (sample_type & PERF_SAMPLE_TIME) + if (session->sample_type & PERF_SAMPLE_TIME) printf("%" PRIu64 " ", sample->time); } @@ -900,8 +899,6 @@ static void dump_event(struct perf_session *session, union perf_event *event, static void dump_sample(struct perf_session *session, union perf_event *event, struct perf_sample *sample) { - u64 sample_type; - if (!dump_trace) return; @@ -909,12 +906,10 @@ static void dump_sample(struct perf_session *session, union perf_event *event, event->header.misc, sample->pid, sample->tid, sample->ip, sample->period, sample->addr); - sample_type = perf_evlist__sample_type(session->evlist); - - if (sample_type & PERF_SAMPLE_CALLCHAIN) + if (session->sample_type & PERF_SAMPLE_CALLCHAIN) callchain__printf(sample); - if (sample_type & PERF_SAMPLE_BRANCH_STACK) + if (session->sample_type & PERF_SAMPLE_BRANCH_STACK) branch_stack__printf(sample); } @@ -1011,7 +1006,7 @@ static int perf_session__preprocess_sample(struct perf_session *session, union perf_event *event, struct perf_sample *sample) { if (event->header.type != PERF_RECORD_SAMPLE || - !(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_CALLCHAIN)) + !(session->sample_type & PERF_SAMPLE_CALLCHAIN)) return 0; if (!ip_callchain__valid(sample->callchain, event)) { @@ -1035,7 +1030,7 @@ static int perf_session__process_user_event(struct perf_session *session, union case PERF_RECORD_HEADER_ATTR: err = tool->attr(event, &session->evlist); if (err == 0) - perf_session__set_id_hdr_size(session); + perf_session__update_sample_type(session); return err; case PERF_RECORD_HEADER_EVENT_TYPE: return tool->event_type(tool, event); @@ -1070,7 +1065,7 @@ static int perf_session__process_event(struct perf_session *session, int ret; if (session->header.needs_swap) - event_swap(event, perf_evlist__sample_id_all(session->evlist)); + event_swap(event, session->sample_id_all); if (event->header.type >= PERF_RECORD_HEADER_MAX) return -EINVAL; @@ -1083,8 +1078,7 @@ static int perf_session__process_event(struct perf_session *session, /* * For all kernel events we get the sample data */ - ret = perf_evlist__parse_sample(session->evlist, event, &sample, - session->header.needs_swap); + ret = perf_session__parse_sample(session, event, &sample); if (ret) return ret; @@ -1395,9 +1389,9 @@ int perf_session__process_events(struct perf_session *self, return err; } -bool perf_session__has_traces(struct perf_session *session, const char *msg) +bool perf_session__has_traces(struct perf_session *self, const char *msg) { - if (!(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_RAW)) { + if (!(self->sample_type & PERF_SAMPLE_RAW)) { pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg); return false; } diff --git a/trunk/tools/perf/util/session.h b/trunk/tools/perf/util/session.h index 1f7ec87db7d7..7c435bde6eb0 100644 --- a/trunk/tools/perf/util/session.h +++ b/trunk/tools/perf/util/session.h @@ -41,9 +41,13 @@ struct perf_session { * perf.data file. */ struct hists hists; + u64 sample_type; + int sample_size; int fd; bool fd_pipe; bool repipe; + bool sample_id_all; + u16 id_hdr_size; int cwdlen; char *cwd; struct ordered_samples ordered_samples; @@ -82,7 +86,7 @@ void perf_event__attr_swap(struct perf_event_attr *attr); int perf_session__create_kernel_maps(struct perf_session *self); -void perf_session__set_id_hdr_size(struct perf_session *session); +void perf_session__update_sample_type(struct perf_session *self); void perf_session__remove_thread(struct perf_session *self, struct thread *th); static inline @@ -126,6 +130,24 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); +static inline int perf_session__parse_sample(struct perf_session *session, + const union perf_event *event, + struct perf_sample *sample) +{ + return perf_event__parse_sample(event, session->sample_type, + session->sample_size, + session->sample_id_all, sample, + session->header.needs_swap); +} + +static inline int perf_session__synthesize_sample(struct perf_session *session, + union perf_event *event, + const struct perf_sample *sample) +{ + return perf_event__synthesize_sample(event, session->sample_type, + sample, session->header.needs_swap); +} + struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type); diff --git a/trunk/tools/perf/util/strlist.c b/trunk/tools/perf/util/strlist.c index 95856ff3dda4..6783a2043555 100644 --- a/trunk/tools/perf/util/strlist.c +++ b/trunk/tools/perf/util/strlist.c @@ -10,28 +10,23 @@ #include #include -static -struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) +static struct str_node *str_node__new(const char *s, bool dupstr) { - const char *s = entry; - struct rb_node *rc = NULL; - struct strlist *strlist = container_of(rblist, struct strlist, rblist); - struct str_node *snode = malloc(sizeof(*snode)); + struct str_node *self = malloc(sizeof(*self)); - if (snode != NULL) { - if (strlist->dupstr) { + if (self != NULL) { + if (dupstr) { s = strdup(s); if (s == NULL) goto out_delete; } - snode->s = s; - rc = &snode->rb_node; + self->s = s; } - return rc; + return self; out_delete: - free(snode); + free(self); return NULL; } @@ -42,26 +37,36 @@ static void str_node__delete(struct str_node *self, bool dupstr) free(self); } -static -void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node) +int strlist__add(struct strlist *self, const char *new_entry) { - struct strlist *slist = container_of(rblist, struct strlist, rblist); - struct str_node *snode = container_of(rb_node, struct str_node, rb_node); - - str_node__delete(snode, slist->dupstr); -} + struct rb_node **p = &self->entries.rb_node; + struct rb_node *parent = NULL; + struct str_node *sn; + + while (*p != NULL) { + int rc; + + parent = *p; + sn = rb_entry(parent, struct str_node, rb_node); + rc = strcmp(sn->s, new_entry); + + if (rc > 0) + p = &(*p)->rb_left; + else if (rc < 0) + p = &(*p)->rb_right; + else + return -EEXIST; + } -static int strlist__node_cmp(struct rb_node *rb_node, const void *entry) -{ - const char *str = entry; - struct str_node *snode = container_of(rb_node, struct str_node, rb_node); + sn = str_node__new(new_entry, self->dupstr); + if (sn == NULL) + return -ENOMEM; - return strcmp(snode->s, str); -} + rb_link_node(&sn->rb_node, parent, p); + rb_insert_color(&sn->rb_node, &self->entries); + ++self->nr_entries; -int strlist__add(struct strlist *self, const char *new_entry) -{ - return rblist__add_node(&self->rblist, new_entry); + return 0; } int strlist__load(struct strlist *self, const char *filename) @@ -91,20 +96,34 @@ int strlist__load(struct strlist *self, const char *filename) return err; } -void strlist__remove(struct strlist *slist, struct str_node *snode) +void strlist__remove(struct strlist *self, struct str_node *sn) { - str_node__delete(snode, slist->dupstr); + rb_erase(&sn->rb_node, &self->entries); + str_node__delete(sn, self->dupstr); } -struct str_node *strlist__find(struct strlist *slist, const char *entry) +struct str_node *strlist__find(struct strlist *self, const char *entry) { - struct str_node *snode = NULL; - struct rb_node *rb_node = rblist__find(&slist->rblist, entry); - - if (rb_node) - snode = container_of(rb_node, struct str_node, rb_node); + struct rb_node **p = &self->entries.rb_node; + struct rb_node *parent = NULL; + + while (*p != NULL) { + struct str_node *sn; + int rc; + + parent = *p; + sn = rb_entry(parent, struct str_node, rb_node); + rc = strcmp(sn->s, entry); + + if (rc > 0) + p = &(*p)->rb_left; + else if (rc < 0) + p = &(*p)->rb_right; + else + return sn; + } - return snode; + return NULL; } static int strlist__parse_list_entry(struct strlist *self, const char *s) @@ -137,12 +156,9 @@ struct strlist *strlist__new(bool dupstr, const char *slist) struct strlist *self = malloc(sizeof(*self)); if (self != NULL) { - rblist__init(&self->rblist); - self->rblist.node_cmp = strlist__node_cmp; - self->rblist.node_new = strlist__node_new; - self->rblist.node_delete = strlist__node_delete; - + self->entries = RB_ROOT; self->dupstr = dupstr; + self->nr_entries = 0; if (slist && strlist__parse_list(self, slist) != 0) goto out_error; } @@ -155,18 +171,30 @@ struct strlist *strlist__new(bool dupstr, const char *slist) void strlist__delete(struct strlist *self) { - if (self != NULL) - rblist__delete(&self->rblist); + if (self != NULL) { + struct str_node *pos; + struct rb_node *next = rb_first(&self->entries); + + while (next) { + pos = rb_entry(next, struct str_node, rb_node); + next = rb_next(&pos->rb_node); + strlist__remove(self, pos); + } + self->entries = RB_ROOT; + free(self); + } } -struct str_node *strlist__entry(const struct strlist *slist, unsigned int idx) +struct str_node *strlist__entry(const struct strlist *self, unsigned int idx) { - struct str_node *snode = NULL; - struct rb_node *rb_node; + struct rb_node *nd; - rb_node = rblist__entry(&slist->rblist, idx); - if (rb_node) - snode = container_of(rb_node, struct str_node, rb_node); + for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { + struct str_node *pos = rb_entry(nd, struct str_node, rb_node); - return snode; + if (!idx--) + return pos; + } + + return NULL; } diff --git a/trunk/tools/perf/util/strlist.h b/trunk/tools/perf/util/strlist.h index dd9f922ec67c..3ba839007d2c 100644 --- a/trunk/tools/perf/util/strlist.h +++ b/trunk/tools/perf/util/strlist.h @@ -4,15 +4,14 @@ #include #include -#include "rblist.h" - struct str_node { struct rb_node rb_node; const char *s; }; struct strlist { - struct rblist rblist; + struct rb_root entries; + unsigned int nr_entries; bool dupstr; }; @@ -33,18 +32,18 @@ static inline bool strlist__has_entry(struct strlist *self, const char *entry) static inline bool strlist__empty(const struct strlist *self) { - return rblist__empty(&self->rblist); + return self->nr_entries == 0; } static inline unsigned int strlist__nr_entries(const struct strlist *self) { - return rblist__nr_entries(&self->rblist); + return self->nr_entries; } /* For strlist iteration */ static inline struct str_node *strlist__first(struct strlist *self) { - struct rb_node *rn = rb_first(&self->rblist.entries); + struct rb_node *rn = rb_first(&self->entries); return rn ? rb_entry(rn, struct str_node, rb_node) : NULL; } static inline struct str_node *strlist__next(struct str_node *sn) diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index 8b63b678e127..fdad4eeeb429 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -64,7 +64,7 @@ static enum dso_binary_type binary_type_symtab[] = { DSO_BINARY_TYPE__NOT_FOUND, }; -#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) +#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab) static enum dso_binary_type binary_type_data[] = { DSO_BINARY_TYPE__BUILD_ID_CACHE, @@ -72,7 +72,7 @@ static enum dso_binary_type binary_type_data[] = { DSO_BINARY_TYPE__NOT_FOUND, }; -#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data) +#define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data) int dso__name_len(const struct dso *dso) { @@ -2875,7 +2875,6 @@ int machines__create_guest_kernel_maps(struct rb_root *machines) int i, items = 0; char path[PATH_MAX]; pid_t pid; - char *endp; if (symbol_conf.default_guest_vmlinux_name || symbol_conf.default_guest_modules || @@ -2892,14 +2891,7 @@ int machines__create_guest_kernel_maps(struct rb_root *machines) /* Filter out . and .. */ continue; } - pid = (pid_t)strtol(namelist[i]->d_name, &endp, 10); - if ((*endp != '\0') || - (endp == namelist[i]->d_name) || - (errno == ERANGE)) { - pr_debug("invalid directory (%s). Skipping.\n", - namelist[i]->d_name); - continue; - } + pid = atoi(namelist[i]->d_name); sprintf(path, "%s/%s/proc/kallsyms", symbol_conf.guestmount, namelist[i]->d_name); diff --git a/trunk/tools/perf/util/target.c b/trunk/tools/perf/util/target.c index 051eaa68095e..3f59c496e64c 100644 --- a/trunk/tools/perf/util/target.c +++ b/trunk/tools/perf/util/target.c @@ -110,7 +110,7 @@ int perf_target__strerror(struct perf_target *target, int errnum, int idx; const char *msg; - BUG_ON(buflen == 0); + BUG_ON(buflen > 0); if (errnum >= 0) { const char *err = strerror_r(errnum, buf, buflen);