From c4e34140224481be69a8e502a37fefe9602b08f7 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:42:57 -0800 Subject: [PATCH] --- yaml --- r: 363257 b: refs/heads/master c: 7ad530bf2499c702a6dcbb279cf78b76845ed584 h: refs/heads/master i: 363255: 6872bcac75c93f3e38f4aefe0f5bf6e618e28273 v: v3 --- [refs] | 2 +- trunk/CREDITS | 14 +- trunk/Documentation/ABI/testing/sysfs-bus-mei | 7 - .../ABI/testing/sysfs-devices-system-cpu | 12 - .../Documentation/DocBook/device-drivers.tmpl | 2 +- trunk/Documentation/SubmittingPatches | 3 +- trunk/Documentation/device-mapper/dm-raid.txt | 44 +- .../devicetree/bindings/arm/msm/ssbi.txt | 18 - .../devicetree/bindings/gpio/gpio.txt | 6 +- .../bindings/hwmon/ntc_thermistor.txt | 29 - .../devicetree/bindings/mfd/ab8500.txt | 6 +- .../bindings/pinctrl/pinctrl-single.txt | 109 +- .../bindings/pinctrl/samsung-pinctrl.txt | 3 - .../bindings/tty/serial/of-serial.txt | 3 - .../bindings/video/via,vt8500-fb.txt | 48 +- .../bindings/video/wm,wm8505-fb.txt | 32 +- trunk/Documentation/hwmon/adm1275 | 2 +- trunk/Documentation/hwmon/adt7410 | 50 +- trunk/Documentation/hwmon/jc42 | 2 +- trunk/Documentation/hwmon/lineage-pem | 2 +- trunk/Documentation/hwmon/lm25066 | 36 +- trunk/Documentation/hwmon/lm75 | 2 +- trunk/Documentation/hwmon/lm95234 | 36 - trunk/Documentation/hwmon/ltc2978 | 149 +- trunk/Documentation/hwmon/ltc4261 | 2 +- trunk/Documentation/hwmon/max16064 | 2 +- trunk/Documentation/hwmon/max16065 | 2 +- trunk/Documentation/hwmon/max34440 | 2 +- trunk/Documentation/hwmon/max8688 | 2 +- trunk/Documentation/hwmon/nct6775 | 188 - trunk/Documentation/hwmon/pmbus | 2 +- trunk/Documentation/hwmon/sht15 | 2 +- trunk/Documentation/hwmon/smm665 | 2 +- trunk/Documentation/hwmon/tmp401 | 25 +- trunk/Documentation/hwmon/ucd9000 | 2 +- trunk/Documentation/hwmon/ucd9200 | 2 +- trunk/Documentation/hwmon/zl6100 | 4 +- trunk/Documentation/i2c/busses/i2c-diolan-u2c | 2 +- trunk/Documentation/ia64/err_inject.txt | 2 +- trunk/Documentation/input/alps.txt | 67 +- trunk/Documentation/kdump/kdump.txt | 1 - trunk/Documentation/kernel-parameters.txt | 29 +- .../misc-devices/mei/mei-client-bus.txt | 138 - .../Documentation/networking/ipvs-sysctl.txt | 7 - trunk/Documentation/networking/tuntap.txt | 77 - trunk/Documentation/pinctrl.txt | 112 - trunk/Documentation/power/opp.txt | 25 +- trunk/Documentation/printk-formats.txt | 2 +- trunk/Documentation/s390/s390dbf.txt | 3 +- trunk/Documentation/scsi/LICENSE.qla2xxx | 2 +- .../sound/alsa/ALSA-Configuration.txt | 7 +- trunk/Documentation/sound/alsa/seq_oss.html | 2 +- trunk/Documentation/trace/ftrace.txt | 2 +- trunk/MAINTAINERS | 128 +- trunk/Makefile | 5 +- trunk/arch/Kconfig | 7 + trunk/arch/alpha/Kconfig | 2 +- trunk/arch/alpha/Makefile | 2 +- trunk/arch/alpha/boot/head.S | 1 - trunk/arch/alpha/include/asm/floppy.h | 2 +- trunk/arch/alpha/kernel/irq.c | 7 + trunk/arch/alpha/kernel/irq_alpha.c | 10 +- trunk/arch/alpha/kernel/sys_nautilus.c | 5 - trunk/arch/alpha/kernel/sys_titan.c | 14 +- trunk/arch/arc/include/asm/dma-mapping.h | 2 +- trunk/arch/arc/include/asm/elf.h | 3 + trunk/arch/arc/include/asm/entry.h | 2 +- trunk/arch/arc/include/asm/irqflags.h | 12 +- trunk/arch/arc/include/asm/kgdb.h | 6 +- trunk/arch/arc/include/asm/ptrace.h | 2 +- trunk/arch/arc/include/asm/syscalls.h | 2 + trunk/arch/arc/include/uapi/asm/ptrace.h | 4 +- trunk/arch/arc/kernel/entry.S | 27 +- trunk/arch/arc/kernel/kgdb.c | 1 - trunk/arch/arc/kernel/setup.c | 4 +- trunk/arch/arc/kernel/sys.c | 2 + trunk/arch/arm/Kconfig | 36 +- trunk/arch/arm/Kconfig.debug | 3 +- trunk/arch/arm/boot/Makefile | 2 +- trunk/arch/arm/boot/compressed/Makefile | 2 +- .../arch/arm/boot/dts/armada-370-mirabox.dts | 2 +- trunk/arch/arm/boot/dts/armada-370-rd.dts | 8 - trunk/arch/arm/boot/dts/armada-370-xp.dtsi | 5 +- trunk/arch/arm/boot/dts/armada-370.dtsi | 6 - trunk/arch/arm/boot/dts/armada-xp.dtsi | 4 +- trunk/arch/arm/boot/dts/at91sam9x5.dtsi | 28 +- trunk/arch/arm/boot/dts/bcm2835.dtsi | 2 +- trunk/arch/arm/boot/dts/dbx5x0.dtsi | 7 +- trunk/arch/arm/boot/dts/dove.dtsi | 5 - trunk/arch/arm/boot/dts/exynos4.dtsi | 9 - trunk/arch/arm/boot/dts/exynos5440.dtsi | 6 - trunk/arch/arm/boot/dts/href.dtsi | 2 +- trunk/arch/arm/boot/dts/hrefv60plus.dts | 2 +- trunk/arch/arm/boot/dts/imx28-m28evk.dts | 1 + trunk/arch/arm/boot/dts/imx28-sps1.dts | 1 + trunk/arch/arm/boot/dts/imx53-mba53.dts | 3 +- trunk/arch/arm/boot/dts/imx6qdl.dtsi | 1 - trunk/arch/arm/boot/dts/kirkwood-dns320.dts | 2 + trunk/arch/arm/boot/dts/kirkwood-dns325.dts | 1 + trunk/arch/arm/boot/dts/kirkwood-dockstar.dts | 1 + .../arch/arm/boot/dts/kirkwood-dreamplug.dts | 1 + .../arch/arm/boot/dts/kirkwood-goflexnet.dts | 2 +- trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts | 1 + trunk/arch/arm/boot/dts/kirkwood-iconnect.dts | 1 + .../arm/boot/dts/kirkwood-iomega_ix2_200.dts | 15 +- .../arm/boot/dts/kirkwood-km_kirkwood.dts | 1 + trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts | 1 + trunk/arch/arm/boot/dts/kirkwood-lsxhl.dts | 1 + trunk/arch/arm/boot/dts/kirkwood-mplcec4.dts | 1 + .../arm/boot/dts/kirkwood-ns2-common.dtsi | 1 + trunk/arch/arm/boot/dts/kirkwood-nsa310.dts | 1 + .../arm/boot/dts/kirkwood-openblocks_a6.dts | 2 + trunk/arch/arm/boot/dts/kirkwood-topkick.dts | 1 + trunk/arch/arm/boot/dts/kirkwood.dtsi | 5 +- trunk/arch/arm/boot/dts/msm8660-surf.dts | 6 - trunk/arch/arm/boot/dts/msm8960-cdp.dts | 6 - .../orion5x-lacie-ethernet-disk-mini-v2.dts | 2 +- trunk/arch/arm/boot/dts/orion5x.dtsi | 9 +- trunk/arch/arm/boot/dts/snowball.dts | 2 +- trunk/arch/arm/boot/dts/socfpga.dtsi | 3 - trunk/arch/arm/boot/dts/spear1310.dtsi | 4 +- trunk/arch/arm/boot/dts/spear1340.dtsi | 4 +- trunk/arch/arm/boot/dts/spear310.dtsi | 4 +- trunk/arch/arm/boot/dts/spear320.dtsi | 4 +- trunk/arch/arm/boot/dts/tegra20.dtsi | 3 +- trunk/arch/arm/boot/dts/tegra30.dtsi | 3 +- trunk/arch/arm/boot/dts/vt8500-bv07.dts | 34 +- trunk/arch/arm/boot/dts/vt8500.dtsi | 4 +- trunk/arch/arm/boot/dts/wm8505-ref.dts | 34 +- trunk/arch/arm/boot/dts/wm8505.dtsi | 4 +- trunk/arch/arm/boot/dts/wm8650-mid.dts | 36 +- trunk/arch/arm/boot/dts/wm8650.dtsi | 4 +- trunk/arch/arm/boot/dts/wm8850-w70v2.dts | 40 +- trunk/arch/arm/boot/dts/wm8850.dtsi | 4 +- trunk/arch/arm/configs/mxs_defconfig | 1 - trunk/arch/arm/configs/omap2plus_defconfig | 2 - trunk/arch/arm/include/asm/delay.h | 2 +- trunk/arch/arm/include/asm/glue-cache.h | 8 + trunk/arch/arm/include/asm/hardware/iop3xx.h | 2 +- trunk/arch/arm/include/asm/highmem.h | 7 - trunk/arch/arm/include/asm/mmu.h | 8 +- trunk/arch/arm/include/asm/mmu_context.h | 4 +- trunk/arch/arm/include/asm/pgtable-3level.h | 2 +- trunk/arch/arm/include/asm/tlbflush.h | 60 +- trunk/arch/arm/include/asm/xen/events.h | 25 +- trunk/arch/arm/include/uapi/asm/unistd.h | 2 +- trunk/arch/arm/kernel/asm-offsets.c | 2 +- trunk/arch/arm/kernel/calls.S | 2 +- trunk/arch/arm/kernel/entry-common.S | 12 - trunk/arch/arm/kernel/head.S | 26 +- trunk/arch/arm/kernel/hw_breakpoint.c | 10 +- trunk/arch/arm/kernel/perf_event.c | 9 +- trunk/arch/arm/kernel/perf_event_v7.c | 2 +- trunk/arch/arm/kernel/sched_clock.c | 4 +- trunk/arch/arm/kernel/setup.c | 27 +- trunk/arch/arm/kernel/smp.c | 6 +- trunk/arch/arm/kernel/smp_tlb.c | 78 - trunk/arch/arm/kernel/smp_twd.c | 4 - trunk/arch/arm/kernel/suspend.c | 1 - trunk/arch/arm/kernel/tcm.c | 1 + trunk/arch/arm/{mm => kernel}/tcm.h | 0 trunk/arch/arm/kvm/arm.c | 1 - trunk/arch/arm/kvm/coproc.c | 4 +- trunk/arch/arm/kvm/vgic.c | 35 +- trunk/arch/arm/lib/delay.c | 8 +- trunk/arch/arm/lib/memset.S | 100 +- trunk/arch/arm/mach-at91/board-foxg20.c | 1 - trunk/arch/arm/mach-at91/board-stamp9g20.c | 1 - trunk/arch/arm/mach-at91/include/mach/gpio.h | 8 - trunk/arch/arm/mach-at91/irq.c | 20 +- trunk/arch/arm/mach-at91/pm.c | 10 +- trunk/arch/arm/mach-cns3xxx/core.c | 16 +- .../arm/mach-cns3xxx/include/mach/cns3xxx.h | 16 +- trunk/arch/arm/mach-davinci/dma.c | 3 - .../arm/mach-ep93xx/include/mach/uncompress.h | 10 +- trunk/arch/arm/mach-footbridge/Kconfig | 1 - trunk/arch/arm/mach-highbank/hotplug.c | 10 +- trunk/arch/arm/mach-imx/clk-imx35.c | 3 - trunk/arch/arm/mach-imx/clk-imx6q.c | 5 +- trunk/arch/arm/mach-imx/common.h | 2 - trunk/arch/arm/mach-imx/headsmp.S | 18 +- trunk/arch/arm/mach-imx/hotplug.c | 12 - trunk/arch/arm/mach-imx/imx25-dt.c | 5 - trunk/arch/arm/mach-imx/pm-imx6q.c | 15 + trunk/arch/arm/mach-imx/src.c | 12 - trunk/arch/arm/mach-ixp4xx/vulcan-setup.c | 1 - trunk/arch/arm/mach-kirkwood/board-dt.c | 25 +- .../arm/mach-kirkwood/board-iomega_ix2_200.c | 7 +- trunk/arch/arm/mach-kirkwood/guruplug-setup.c | 2 - trunk/arch/arm/mach-kirkwood/openrd-setup.c | 1 - .../arch/arm/mach-kirkwood/rd88f6281-setup.c | 1 - trunk/arch/arm/mach-mmp/gplugd.c | 1 - trunk/arch/arm/mach-msm/timer.c | 5 +- trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c | 24 +- trunk/arch/arm/mach-mxs/icoll.c | 2 +- trunk/arch/arm/mach-mxs/mach-mxs.c | 34 +- trunk/arch/arm/mach-mxs/mm.c | 1 - trunk/arch/arm/mach-mxs/ocotp.c | 1 - trunk/arch/arm/mach-netx/generic.c | 2 +- trunk/arch/arm/mach-netx/include/mach/irqs.h | 64 +- trunk/arch/arm/mach-omap1/clock_data.c | 12 +- trunk/arch/arm/mach-omap1/common.h | 2 - trunk/arch/arm/mach-omap2/Kconfig | 6 + trunk/arch/arm/mach-omap2/board-generic.c | 2 - trunk/arch/arm/mach-omap2/board-rx51.c | 2 - trunk/arch/arm/mach-omap2/cclock44xx_data.c | 20 - trunk/arch/arm/mach-omap2/common.h | 4 +- trunk/arch/arm/mach-omap2/gpmc.c | 6 +- trunk/arch/arm/mach-omap2/io.c | 18 +- trunk/arch/arm/mach-omap2/mux.c | 9 +- trunk/arch/arm/mach-omap2/omap_hwmod.c | 7 +- trunk/arch/arm/mach-omap2/omap_hwmod.h | 9 +- .../arm/mach-omap2/omap_hwmod_3xxx_data.c | 7 +- .../arm/mach-omap2/omap_hwmod_44xx_data.c | 12 +- trunk/arch/arm/mach-omap2/timer.c | 4 - trunk/arch/arm/mach-pxa/raumfeld.c | 1 - .../arch/arm/mach-s3c24xx/include/mach/irqs.h | 4 +- trunk/arch/arm/mach-s3c24xx/irq.c | 2 +- trunk/arch/arm/mach-s5pv210/clock.c | 36 +- trunk/arch/arm/mach-s5pv210/mach-goni.c | 2 +- trunk/arch/arm/mach-shmobile/board-marzen.c | 1 - trunk/arch/arm/mach-spear3xx/spear3xx.c | 2 +- trunk/arch/arm/mach-ux500/board-mop500-sdi.c | 1 + trunk/arch/arm/mach-ux500/board-mop500.c | 12 - trunk/arch/arm/mach-ux500/board-mop500.h | 1 - trunk/arch/arm/mach-ux500/cpu-db8500.c | 5 +- trunk/arch/arm/mm/Kconfig | 5 +- trunk/arch/arm/mm/Makefile | 1 + trunk/arch/arm/mm/cache-feroceon-l2.c | 1 - trunk/arch/arm/mm/cache-l2x0.c | 11 +- trunk/arch/arm/mm/cache-v3.S | 137 + trunk/arch/arm/mm/cache-v4.S | 2 +- trunk/arch/arm/mm/context.c | 32 +- trunk/arch/arm/mm/dma-mapping.c | 5 +- trunk/arch/arm/mm/idmap.c | 1 - trunk/arch/arm/mm/mmu.c | 75 +- trunk/arch/arm/mm/proc-arm740.S | 30 +- trunk/arch/arm/mm/proc-arm920.S | 2 +- trunk/arch/arm/mm/proc-arm926.S | 2 +- trunk/arch/arm/mm/proc-mohawk.S | 2 +- trunk/arch/arm/mm/proc-sa1100.S | 2 +- trunk/arch/arm/mm/proc-syms.c | 2 - trunk/arch/arm/mm/proc-v6.S | 2 +- trunk/arch/arm/mm/proc-v7-3level.S | 2 +- trunk/arch/arm/mm/proc-v7.S | 19 +- trunk/arch/arm/mm/proc-xsc3.S | 2 +- trunk/arch/arm/mm/proc-xscale.S | 2 +- trunk/arch/arm/net/bpf_jit_32.c | 2 +- trunk/arch/arm/plat-orion/addr-map.c | 7 +- trunk/arch/arm/plat-samsung/include/plat/fb.h | 50 +- trunk/arch/arm/plat-spear/Kconfig | 2 +- trunk/arch/arm64/Kconfig | 1 + trunk/arch/arm64/Kconfig.debug | 11 + trunk/arch/arm64/configs/defconfig | 1 + trunk/arch/arm64/include/asm/ucontext.h | 2 +- trunk/arch/arm64/kernel/arm64ksyms.c | 2 - trunk/arch/arm64/kernel/signal32.c | 1 + trunk/arch/arm64/mm/mmu.c | 2 +- trunk/arch/avr32/Kconfig | 2 +- trunk/arch/avr32/include/asm/io.h | 4 - trunk/arch/blackfin/Kconfig | 2 +- trunk/arch/c6x/include/asm/irqflags.h | 2 +- trunk/arch/cris/Kconfig | 2 +- trunk/arch/frv/Kconfig | 2 +- trunk/arch/h8300/Kconfig | 2 +- trunk/arch/ia64/Kconfig | 4 +- trunk/arch/ia64/include/asm/futex.h | 5 +- trunk/arch/ia64/include/asm/mca.h | 1 - trunk/arch/ia64/include/asm/numa.h | 5 +- trunk/arch/ia64/kernel/fsys.S | 49 +- trunk/arch/ia64/kernel/iosapic.c | 34 +- trunk/arch/ia64/kernel/irq.c | 8 - trunk/arch/ia64/kernel/mca.c | 37 +- trunk/arch/ia64/kernel/mca_drv.c | 2 +- trunk/arch/ia64/kernel/palinfo.c | 77 +- trunk/arch/ia64/kernel/perfmon.c | 1 - trunk/arch/ia64/kernel/process.c | 5 +- trunk/arch/ia64/kvm/vtlb.c | 2 +- trunk/arch/ia64/mm/ioremap.c | 14 +- trunk/arch/ia64/mm/numa.c | 5 - trunk/arch/ia64/pci/pci.c | 11 - trunk/arch/ia64/sn/kernel/tiocx.c | 5 +- trunk/arch/m32r/Kconfig | 2 +- trunk/arch/m32r/include/uapi/asm/stat.h | 4 +- trunk/arch/m68k/Kconfig | 2 +- trunk/arch/m68k/Kconfig.machine | 1 + trunk/arch/m68k/include/asm/MC68328.h | 10 +- trunk/arch/m68k/include/asm/gpio.h | 20 - trunk/arch/m68k/kernel/setup_no.c | 3 - trunk/arch/m68k/mm/init.c | 2 +- trunk/arch/m68k/platform/coldfire/m528x.c | 2 +- trunk/arch/metag/include/asm/elf.h | 3 + trunk/arch/metag/mm/Kconfig | 1 - trunk/arch/microblaze/Kconfig | 2 +- trunk/arch/mips/Kconfig | 9 +- .../arch/mips/bcm63xx/boards/board_bcm963xx.c | 5 +- trunk/arch/mips/bcm63xx/nvram.c | 7 +- trunk/arch/mips/bcm63xx/setup.c | 2 +- trunk/arch/mips/cavium-octeon/setup.c | 5 +- .../include/asm/mach-bcm63xx/bcm63xx_nvram.h | 4 +- .../asm/mach-sead3/cpu-feature-overrides.h | 4 + trunk/arch/mips/include/asm/mipsregs.h | 209 +- trunk/arch/mips/include/asm/page.h | 2 +- trunk/arch/mips/include/asm/signal.h | 2 +- trunk/arch/mips/include/uapi/asm/signal.h | 8 +- trunk/arch/mips/kernel/Makefile | 25 +- trunk/arch/mips/kernel/cpu-probe.c | 13 +- trunk/arch/mips/kernel/linux32.c | 2 +- trunk/arch/mips/kernel/mcount.S | 11 +- trunk/arch/mips/kernel/proc.c | 2 +- trunk/arch/mips/kernel/traps.c | 2 +- trunk/arch/mips/lib/bitops.c | 16 +- trunk/arch/mips/lib/csum_partial.S | 4 +- trunk/arch/mips/mm/c-r4k.c | 6 +- trunk/arch/mips/mm/sc-mips.c | 6 +- trunk/arch/mips/pci/pci-alchemy.c | 4 +- trunk/arch/mips/pci/pci.c | 8 +- trunk/arch/mn10300/Kconfig | 2 +- trunk/arch/openrisc/Kconfig | 3 +- trunk/arch/parisc/Kconfig | 2 +- trunk/arch/parisc/Makefile | 6 +- trunk/arch/parisc/include/asm/cacheflush.h | 5 +- trunk/arch/parisc/include/asm/pgtable.h | 47 +- trunk/arch/parisc/include/asm/uaccess.h | 14 +- trunk/arch/parisc/kernel/cache.c | 5 +- trunk/arch/parisc/kernel/parisc_ksyms.c | 2 - trunk/arch/parisc/lib/Makefile | 3 +- trunk/arch/parisc/lib/ucmpdi2.c | 25 - trunk/arch/powerpc/Kconfig | 3 +- trunk/arch/powerpc/crypto/sha1-powerpc-asm.S | 4 +- trunk/arch/powerpc/include/asm/bitops.h | 2 + trunk/arch/powerpc/include/asm/mmu-hash64.h | 128 +- trunk/arch/powerpc/include/asm/reg.h | 3 +- trunk/arch/powerpc/include/asm/systbl.h | 1 - trunk/arch/powerpc/include/asm/unistd.h | 2 +- trunk/arch/powerpc/include/uapi/asm/unistd.h | 1 - trunk/arch/powerpc/kernel/cpu_setup_power.S | 5 +- trunk/arch/powerpc/kernel/cputable.c | 2 +- trunk/arch/powerpc/kernel/entry_64.S | 4 +- trunk/arch/powerpc/kernel/epapr_paravirt.c | 6 - trunk/arch/powerpc/kernel/exceptions-64s.S | 182 +- trunk/arch/powerpc/kernel/process.c | 2 - trunk/arch/powerpc/kernel/prom_init.c | 14 +- trunk/arch/powerpc/kernel/ptrace.c | 1 - trunk/arch/powerpc/kernel/signal_32.c | 2 - trunk/arch/powerpc/kernel/signal_64.c | 2 - trunk/arch/powerpc/kernel/tm.S | 2 - trunk/arch/powerpc/kvm/book3s_64_mmu_host.c | 4 +- trunk/arch/powerpc/kvm/e500.h | 24 +- trunk/arch/powerpc/kvm/e500_mmu_host.c | 84 +- trunk/arch/powerpc/kvm/e500mc.c | 7 +- trunk/arch/powerpc/mm/hash_utils_64.c | 22 +- trunk/arch/powerpc/mm/mmu_context_hash64.c | 11 +- trunk/arch/powerpc/mm/pgtable_64.c | 2 +- trunk/arch/powerpc/mm/slb_low.S | 50 +- trunk/arch/powerpc/mm/tlb_hash64.c | 2 +- trunk/arch/powerpc/perf/power7-pmu.c | 13 - .../arch/powerpc/platforms/85xx/sgy_cts1000.c | 6 +- trunk/arch/powerpc/platforms/Kconfig.cputype | 6 +- .../arch/powerpc/platforms/cell/spufs/inode.c | 1 - .../powerpc/platforms/pseries/hvcserver.c | 5 +- trunk/arch/powerpc/platforms/pseries/lpar.c | 8 +- trunk/arch/s390/Kconfig | 15 +- trunk/arch/s390/Makefile | 10 + trunk/arch/s390/hypfs/hypfs_dbfs.c | 4 +- trunk/arch/s390/hypfs/inode.c | 1 - trunk/arch/s390/include/asm/bitops.h | 117 +- trunk/arch/s390/include/asm/ccwdev.h | 3 +- trunk/arch/s390/include/asm/cio.h | 2 + trunk/arch/s390/include/asm/compat.h | 57 +- trunk/arch/s390/include/asm/cpu_mf.h | 1 - trunk/arch/s390/include/asm/eadm.h | 6 +- trunk/arch/s390/include/asm/elf.h | 23 +- trunk/arch/s390/include/asm/io.h | 4 + trunk/arch/s390/include/asm/pci.h | 1 - trunk/arch/s390/include/asm/pci_debug.h | 9 +- trunk/arch/s390/include/asm/pci_insn.h | 203 +- trunk/arch/s390/include/asm/pci_io.h | 16 +- trunk/arch/s390/include/asm/pgtable.h | 10 +- trunk/arch/s390/include/asm/processor.h | 3 +- trunk/arch/s390/include/asm/ptrace.h | 6 +- trunk/arch/s390/include/asm/syscall.h | 1 - trunk/arch/s390/include/asm/thread_info.h | 6 +- trunk/arch/s390/include/asm/tlbflush.h | 2 + trunk/arch/s390/include/uapi/asm/ptrace.h | 20 + trunk/arch/s390/include/uapi/asm/statfs.h | 63 +- trunk/arch/s390/kernel/Makefile | 17 +- trunk/arch/s390/kernel/asm-offsets.c | 1 - trunk/arch/s390/kernel/compat_signal.c | 2 - trunk/arch/s390/kernel/dis.c | 9 +- trunk/arch/s390/kernel/dumpstack.c | 236 - trunk/arch/s390/kernel/entry.S | 42 +- trunk/arch/s390/kernel/entry.h | 1 - trunk/arch/s390/kernel/entry64.S | 48 +- trunk/arch/s390/kernel/machine_kexec.c | 30 - trunk/arch/s390/kernel/setup.c | 11 +- trunk/arch/s390/kernel/smp.c | 15 +- trunk/arch/s390/kernel/suspend.c | 31 - trunk/arch/s390/kernel/swsusp_asm64.S | 29 +- trunk/arch/s390/kernel/traps.c | 250 +- trunk/arch/s390/kvm/trace.h | 2 +- trunk/arch/s390/lib/uaccess_pt.c | 83 +- trunk/arch/s390/mm/cmm.c | 8 +- trunk/arch/s390/mm/fault.c | 9 +- trunk/arch/s390/mm/init.c | 10 +- trunk/arch/s390/mm/pageattr.c | 24 +- trunk/arch/s390/mm/pgtable.c | 235 +- trunk/arch/s390/net/bpf_jit_comp.c | 3 +- trunk/arch/s390/pci/Makefile | 4 +- trunk/arch/s390/pci/pci.c | 153 +- trunk/arch/s390/pci/pci_clp.c | 13 +- trunk/arch/s390/pci/pci_debug.c | 7 +- trunk/arch/s390/pci/pci_dma.c | 9 +- trunk/arch/s390/pci/pci_insn.c | 202 - trunk/arch/s390/pci/pci_msi.c | 10 +- trunk/arch/score/Kconfig | 2 +- trunk/arch/sparc/Kconfig | 8 +- trunk/arch/sparc/include/asm/Kbuild | 5 - trunk/arch/sparc/include/asm/cputime.h | 6 + .../sparc/include/asm/emergency-restart.h | 6 + trunk/arch/sparc/include/asm/mutex.h | 9 + trunk/arch/sparc/include/asm/pgtable_64.h | 1 - trunk/arch/sparc/include/asm/serial.h | 6 + trunk/arch/sparc/include/asm/smp_32.h | 5 + trunk/arch/sparc/include/asm/spitfire.h | 1 - trunk/arch/sparc/include/asm/switch_to_64.h | 3 +- trunk/arch/sparc/include/asm/tlbflush_64.h | 37 +- trunk/arch/sparc/include/uapi/asm/Kbuild | 1 + trunk/arch/sparc/include/uapi/asm/types.h | 17 + trunk/arch/sparc/kernel/cpu.c | 6 - trunk/arch/sparc/kernel/head_64.S | 25 +- trunk/arch/sparc/kernel/leon_pci_grpci2.c | 41 +- trunk/arch/sparc/kernel/smp_64.c | 41 +- trunk/arch/sparc/lib/bitext.c | 6 +- trunk/arch/sparc/mm/iommu.c | 2 +- trunk/arch/sparc/mm/srmmu.c | 4 +- trunk/arch/sparc/mm/tlb.c | 39 +- trunk/arch/sparc/mm/tsb.c | 57 +- trunk/arch/sparc/mm/ultra.S | 119 +- trunk/arch/tile/Kconfig | 2 +- trunk/arch/tile/configs/tilegx_defconfig | 1 + trunk/arch/tile/configs/tilepro_defconfig | 1 + trunk/arch/tile/include/asm/compat.h | 3 - trunk/arch/tile/include/asm/irqflags.h | 10 +- trunk/arch/tile/kernel/compat.c | 42 +- trunk/arch/tile/kernel/setup.c | 25 +- trunk/arch/um/drivers/chan.h | 2 +- trunk/arch/um/drivers/chan_kern.c | 4 +- trunk/arch/um/drivers/chan_user.c | 12 +- trunk/arch/um/drivers/chan_user.h | 6 +- trunk/arch/um/drivers/line.c | 42 +- trunk/arch/um/drivers/net_kern.c | 2 - trunk/arch/um/drivers/ssl.c | 1 + trunk/arch/um/drivers/stdio_console.c | 1 + trunk/arch/um/os-Linux/signal.c | 2 +- trunk/arch/um/os-Linux/start_up.c | 2 - trunk/arch/unicore32/Kconfig | 2 +- trunk/arch/x86/Kconfig | 3 +- trunk/arch/x86/boot/compressed/Makefile | 5 +- trunk/arch/x86/boot/compressed/eboot.c | 47 - trunk/arch/x86/include/asm/bootparam_utils.h | 20 +- trunk/arch/x86/include/asm/efi.h | 7 - trunk/arch/x86/include/asm/kprobes.h | 1 - trunk/arch/x86/include/asm/kvm_host.h | 4 +- trunk/arch/x86/include/asm/paravirt.h | 5 +- trunk/arch/x86/include/asm/paravirt_types.h | 2 - trunk/arch/x86/include/asm/syscall.h | 4 +- trunk/arch/x86/include/asm/tlb.h | 2 +- trunk/arch/x86/include/asm/xen/hypercall.h | 4 +- trunk/arch/x86/include/uapi/asm/bootparam.h | 1 - trunk/arch/x86/include/uapi/asm/msr-index.h | 1 - trunk/arch/x86/kernel/cpu/mshyperv.c | 18 +- trunk/arch/x86/kernel/cpu/perf_event_intel.c | 24 +- .../arch/x86/kernel/cpu/perf_event_intel_ds.c | 13 +- trunk/arch/x86/kernel/kprobes/core.c | 5 +- trunk/arch/x86/kernel/microcode_core_early.c | 38 +- trunk/arch/x86/kernel/microcode_intel_early.c | 30 +- trunk/arch/x86/kernel/paravirt.c | 25 +- trunk/arch/x86/kernel/setup.c | 55 +- trunk/arch/x86/kernel/smpboot.c | 3 +- trunk/arch/x86/kvm/lapic.c | 2 +- trunk/arch/x86/kvm/x86.c | 69 +- trunk/arch/x86/lguest/boot.c | 1 - trunk/arch/x86/lib/usercopy_64.c | 4 +- trunk/arch/x86/mm/fault.c | 6 +- trunk/arch/x86/mm/init.c | 5 +- trunk/arch/x86/mm/pageattr-test.c | 2 +- trunk/arch/x86/mm/pageattr.c | 12 +- trunk/arch/x86/mm/pat.c | 7 - trunk/arch/x86/mm/pgtable.c | 7 - trunk/arch/x86/pci/common.c | 11 - trunk/arch/x86/pci/xen.c | 6 +- trunk/arch/x86/platform/efi/efi.c | 168 +- trunk/arch/x86/power/cpu.c | 2 - trunk/arch/x86/xen/enlighten.c | 57 +- trunk/arch/x86/xen/mmu.c | 16 +- trunk/arch/x86/xen/smp.c | 21 +- trunk/arch/x86/xen/spinlock.c | 25 - trunk/arch/x86/xen/time.c | 13 +- trunk/arch/xtensa/Kconfig | 2 +- trunk/block/blk-core.c | 1 - trunk/block/blk-flush.c | 2 +- trunk/block/blk-sysfs.c | 2 - trunk/block/genhd.c | 3 +- trunk/crypto/algif_hash.c | 2 - trunk/crypto/algif_skcipher.c | 1 - trunk/crypto/gcm.c | 17 +- trunk/drivers/Kconfig | 2 - trunk/drivers/Makefile | 1 - trunk/drivers/acpi/Kconfig | 2 +- trunk/drivers/acpi/acpi_i2c.c | 2 +- trunk/drivers/acpi/apei/cper.c | 2 +- trunk/drivers/acpi/glue.c | 55 +- trunk/drivers/acpi/pci_root.c | 133 +- trunk/drivers/acpi/pci_slot.c | 170 +- trunk/drivers/acpi/processor_core.c | 3 +- trunk/drivers/acpi/processor_driver.c | 2 +- trunk/drivers/acpi/processor_idle.c | 13 +- trunk/drivers/acpi/processor_perflib.c | 4 +- trunk/drivers/acpi/scan.c | 1 + trunk/drivers/acpi/sleep.c | 24 +- trunk/drivers/amba/tegra-ahb.c | 2 +- trunk/drivers/ata/Kconfig | 13 +- trunk/drivers/ata/ahci.c | 12 +- trunk/drivers/ata/ata_piix.c | 18 +- trunk/drivers/ata/libata-acpi.c | 9 +- trunk/drivers/ata/libata-core.c | 6 +- trunk/drivers/ata/libata-scsi.c | 8 +- trunk/drivers/ata/pata_pcmcia.c | 14 +- trunk/drivers/ata/pata_samsung_cf.c | 13 +- trunk/drivers/ata/sata_fsl.c | 3 +- trunk/drivers/base/bus.c | 8 +- trunk/drivers/base/core.c | 26 +- trunk/drivers/base/cpu.c | 14 - trunk/drivers/base/dd.c | 6 +- trunk/drivers/base/devtmpfs.c | 28 +- trunk/drivers/base/platform.c | 24 +- trunk/drivers/base/power/main.c | 2 + trunk/drivers/base/power/power.h | 8 +- trunk/drivers/base/power/qos.c | 251 +- trunk/drivers/base/power/sysfs.c | 1 - trunk/drivers/base/regmap/regcache-rbtree.c | 2 +- trunk/drivers/base/regmap/regmap-irq.c | 1 - trunk/drivers/base/regmap/regmap.c | 6 +- trunk/drivers/bcma/driver_pci_host.c | 2 - trunk/drivers/block/Kconfig | 4 +- trunk/drivers/block/aoe/aoecmd.c | 3 +- trunk/drivers/block/cciss.c | 2 +- trunk/drivers/block/loop.c | 10 +- trunk/drivers/block/mg_disk.c | 4 +- trunk/drivers/block/mtip32xx/mtip32xx.c | 331 +- trunk/drivers/block/mtip32xx/mtip32xx.h | 18 +- trunk/drivers/block/nvme.c | 33 +- trunk/drivers/block/rbd.c | 50 +- trunk/drivers/block/rsxx/Makefile | 2 +- trunk/drivers/block/rsxx/config.c | 8 +- trunk/drivers/block/rsxx/core.c | 237 +- trunk/drivers/block/rsxx/cregs.c | 112 +- trunk/drivers/block/rsxx/dma.c | 239 +- trunk/drivers/block/rsxx/rsxx.h | 6 +- trunk/drivers/block/rsxx/rsxx_cfg.h | 2 +- trunk/drivers/block/rsxx/rsxx_priv.h | 34 +- trunk/drivers/block/xen-blkback/blkback.c | 68 +- trunk/drivers/block/xen-blkback/common.h | 40 +- trunk/drivers/block/xen-blkback/xenbus.c | 14 +- trunk/drivers/block/xen-blkfront.c | 154 +- trunk/drivers/bluetooth/ath3k.c | 8 - trunk/drivers/bluetooth/bluecard_cs.c | 15 +- trunk/drivers/bluetooth/bt3c_cs.c | 15 +- trunk/drivers/bluetooth/btuart_cs.c | 15 +- trunk/drivers/bluetooth/btusb.c | 4 - trunk/drivers/bluetooth/dtl1_cs.c | 15 +- trunk/drivers/char/applicom.c | 4 +- trunk/drivers/char/hpet.c | 14 +- trunk/drivers/char/hw_random/core.c | 28 +- trunk/drivers/char/hw_random/mxc-rnga.c | 13 +- trunk/drivers/char/hw_random/tx4939-rng.c | 13 +- trunk/drivers/char/hw_random/virtio-rng.c | 13 +- trunk/drivers/char/random.c | 12 +- trunk/drivers/char/tile-srom.c | 2 +- trunk/drivers/char/virtio_console.c | 44 +- trunk/drivers/clk/clk-vt8500.c | 2 +- trunk/drivers/clk/tegra/clk-tegra20.c | 3 +- trunk/drivers/clk/tegra/clk-tegra30.c | 1 + trunk/drivers/connector/cn_proc.c | 8 - trunk/drivers/cpufreq/acpi-cpufreq.c | 2 + trunk/drivers/cpufreq/cpufreq-cpu0.c | 10 +- trunk/drivers/cpufreq/cpufreq_governor.h | 8 +- trunk/drivers/cpufreq/cpufreq_stats.c | 12 +- trunk/drivers/cpufreq/highbank-cpufreq.c | 8 +- trunk/drivers/cpufreq/intel_pstate.c | 67 +- trunk/drivers/crypto/caam/caamalg.c | 27 +- trunk/drivers/crypto/caam/compat.h | 1 + trunk/drivers/crypto/talitos.c | 30 +- trunk/drivers/crypto/ux500/cryp/cryp_core.c | 2 +- trunk/drivers/dma/Kconfig | 1 - trunk/drivers/dma/at_hdmac.c | 9 +- trunk/drivers/dma/dw_dmac.c | 23 +- trunk/drivers/dma/dw_dmac_regs.h | 1 - trunk/drivers/dma/omap-dma.c | 20 +- trunk/drivers/dma/pl330.c | 38 +- trunk/drivers/edac/amd64_edac.c | 15 +- trunk/drivers/edac/edac_mc.c | 6 +- trunk/drivers/edac/edac_mc_sysfs.c | 17 +- trunk/drivers/eisa/eisa-bus.c | 82 +- trunk/drivers/eisa/pci_eisa.c | 72 +- trunk/drivers/extcon/extcon-arizona.c | 498 +- trunk/drivers/extcon/extcon-max77693.c | 111 +- trunk/drivers/extcon/extcon-max8997.c | 68 +- trunk/drivers/firmware/Kconfig | 19 - trunk/drivers/firmware/dmi_scan.c | 5 +- trunk/drivers/firmware/efivars.c | 355 +- trunk/drivers/gpio/gpio-ich.c | 6 +- trunk/drivers/gpio/gpio-mvebu.c | 7 - trunk/drivers/gpio/gpio-pca953x.c | 2 +- trunk/drivers/gpio/gpio-pl061.c | 125 +- trunk/drivers/gpio/gpio-pxa.c | 7 +- trunk/drivers/gpio/gpio-stmpe.c | 15 +- trunk/drivers/gpio/gpiolib-of.c | 20 +- trunk/drivers/gpio/gpiolib.c | 143 +- trunk/drivers/gpu/drm/drm_crtc.c | 2 + trunk/drivers/gpu/drm/drm_edid.c | 3 +- trunk/drivers/gpu/drm/drm_fb_helper.c | 8 +- trunk/drivers/gpu/drm/drm_fops.c | 6 +- trunk/drivers/gpu/drm/drm_modes.c | 20 +- .../drivers/gpu/drm/exynos/exynos_drm_fimd.c | 21 +- trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c | 370 +- trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c | 21 - trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h | 5 - .../drivers/gpu/drm/exynos/exynos_drm_vidi.c | 6 +- trunk/drivers/gpu/drm/exynos/exynos_mixer.c | 2 +- trunk/drivers/gpu/drm/i915/i915_debugfs.c | 2 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 30 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 1 - .../gpu/drm/i915/i915_gem_execbuffer.c | 13 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 26 +- trunk/drivers/gpu/drm/i915/i915_reg.h | 4 +- trunk/drivers/gpu/drm/i915/intel_crt.c | 40 +- trunk/drivers/gpu/drm/i915/intel_ddi.c | 2 +- trunk/drivers/gpu/drm/i915/intel_display.c | 47 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 20 +- trunk/drivers/gpu/drm/i915/intel_i2c.c | 11 +- trunk/drivers/gpu/drm/i915/intel_panel.c | 13 +- trunk/drivers/gpu/drm/i915/intel_pm.c | 5 +- trunk/drivers/gpu/drm/mgag200/mgag200_drv.h | 1 + trunk/drivers/gpu/drm/mgag200/mgag200_i2c.c | 1 - trunk/drivers/gpu/drm/mgag200/mgag200_mode.c | 50 +- .../gpu/drm/nouveau/core/core/object.c | 3 +- .../gpu/drm/nouveau/core/engine/disp/nv50.c | 4 +- .../gpu/drm/nouveau/core/engine/graph/nve0.c | 2 +- .../drm/nouveau/core/include/subdev/therm.h | 2 +- .../gpu/drm/nouveau/core/subdev/bios/base.c | 17 - .../gpu/drm/nouveau/core/subdev/bios/init.c | 2 +- .../gpu/drm/nouveau/core/subdev/i2c/base.c | 1 - .../gpu/drm/nouveau/core/subdev/therm/base.c | 18 +- .../gpu/drm/nouveau/core/subdev/therm/ic.c | 6 +- .../gpu/drm/nouveau/core/subdev/therm/nv40.c | 67 +- .../gpu/drm/nouveau/core/subdev/therm/priv.h | 3 +- .../gpu/drm/nouveau/core/subdev/therm/temp.c | 30 +- trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c | 23 +- trunk/drivers/gpu/drm/nouveau/nouveau_agp.c | 12 - trunk/drivers/gpu/drm/nouveau/nouveau_bo.c | 4 +- trunk/drivers/gpu/drm/nouveau/nouveau_drm.c | 32 +- trunk/drivers/gpu/drm/nouveau/nouveau_drm.h | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_pm.c | 44 +- trunk/drivers/gpu/drm/nouveau/nv50_display.c | 178 +- trunk/drivers/gpu/drm/radeon/evergreen.c | 6 - trunk/drivers/gpu/drm/radeon/evergreen_cs.c | 2 +- trunk/drivers/gpu/drm/radeon/ni.c | 39 +- trunk/drivers/gpu/drm/radeon/r600.c | 6 - .../drivers/gpu/drm/radeon/radeon_benchmark.c | 21 +- trunk/drivers/gpu/drm/radeon/radeon_bios.c | 26 - trunk/drivers/gpu/drm/radeon/radeon_combios.c | 9 - trunk/drivers/gpu/drm/radeon/radeon_drv.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c | 12 - trunk/drivers/gpu/drm/radeon/si.c | 7 - trunk/drivers/gpu/drm/tegra/Kconfig | 1 + trunk/drivers/gpu/drm/tilcdc/Kconfig | 3 +- trunk/drivers/gpu/drm/tilcdc/tilcdc_panel.c | 2 +- trunk/drivers/gpu/drm/udl/udl_connector.c | 4 - trunk/drivers/hid/hid-core.c | 13 +- trunk/drivers/hid/hid-ids.h | 11 +- trunk/drivers/hid/hid-logitech-dj.c | 22 +- trunk/drivers/hid/hid-magicmouse.c | 29 +- trunk/drivers/hid/hid-multitouch.c | 6 +- trunk/drivers/hid/usbhid/hid-quirks.c | 2 - trunk/drivers/hv/Makefile | 2 +- trunk/drivers/hv/channel_mgmt.c | 11 - trunk/drivers/hv/hv.c | 5 +- trunk/drivers/hv/hv_balloon.c | 544 +-- trunk/drivers/hv/hv_snapshot.c | 287 -- trunk/drivers/hv/hv_util.c | 10 - trunk/drivers/hv/ring_buffer.c | 1 - trunk/drivers/hwmon/Kconfig | 48 +- trunk/drivers/hwmon/Makefile | 4 - trunk/drivers/hwmon/abituguru.c | 11 +- trunk/drivers/hwmon/abituguru3.c | 10 +- trunk/drivers/hwmon/ad7314.c | 7 +- trunk/drivers/hwmon/adm1021.c | 11 +- trunk/drivers/hwmon/adm1026.c | 53 +- trunk/drivers/hwmon/adm1029.c | 9 +- trunk/drivers/hwmon/adm9240.c | 9 +- trunk/drivers/hwmon/ads7871.c | 42 +- trunk/drivers/hwmon/adt7310.c | 123 - trunk/drivers/hwmon/adt7410.c | 442 +- trunk/drivers/hwmon/adt7411.c | 10 +- trunk/drivers/hwmon/adt7x10.c | 511 -- trunk/drivers/hwmon/adt7x10.h | 37 - trunk/drivers/hwmon/applesmc.c | 2 +- trunk/drivers/hwmon/asb100.c | 23 +- trunk/drivers/hwmon/asc7621.c | 56 +- trunk/drivers/hwmon/coretemp.c | 3 +- trunk/drivers/hwmon/da9052-hwmon.c | 14 +- trunk/drivers/hwmon/da9055-hwmon.c | 4 +- trunk/drivers/hwmon/dme1737.c | 68 +- trunk/drivers/hwmon/f71805f.c | 3 +- trunk/drivers/hwmon/fam15h_power.c | 4 +- trunk/drivers/hwmon/fschmd.c | 9 +- trunk/drivers/hwmon/gl518sm.c | 5 +- trunk/drivers/hwmon/gpio-fan.c | 106 +- trunk/drivers/hwmon/ibmaem.c | 21 +- trunk/drivers/hwmon/ibmpex.c | 17 +- trunk/drivers/hwmon/ina2xx.c | 16 +- trunk/drivers/hwmon/it87.c | 24 +- trunk/drivers/hwmon/k8temp.c | 4 +- trunk/drivers/hwmon/lineage-pem.c | 2 - trunk/drivers/hwmon/lm75.h | 2 +- trunk/drivers/hwmon/lm78.c | 10 +- trunk/drivers/hwmon/lm80.c | 5 +- trunk/drivers/hwmon/lm85.c | 4 +- trunk/drivers/hwmon/lm93.c | 74 +- trunk/drivers/hwmon/lm95234.c | 769 --- trunk/drivers/hwmon/ltc4151.c | 12 +- trunk/drivers/hwmon/ltc4215.c | 46 +- trunk/drivers/hwmon/ltc4245.c | 116 +- trunk/drivers/hwmon/ltc4261.c | 38 +- trunk/drivers/hwmon/max6697.c | 209 +- trunk/drivers/hwmon/mc13783-adc.c | 13 +- trunk/drivers/hwmon/nct6775.c | 4191 ----------------- trunk/drivers/hwmon/ntc_thermistor.c | 353 +- trunk/drivers/hwmon/pc87360.c | 25 +- trunk/drivers/hwmon/pc87427.c | 13 +- trunk/drivers/hwmon/pmbus/Kconfig | 6 +- trunk/drivers/hwmon/pmbus/lm25066.c | 414 +- trunk/drivers/hwmon/pmbus/ltc2978.c | 200 +- trunk/drivers/hwmon/pmbus/pmbus_core.c | 12 +- trunk/drivers/hwmon/s3c-hwmon.c | 19 +- trunk/drivers/hwmon/sch56xx-common.c | 12 +- trunk/drivers/hwmon/sht15.c | 8 +- trunk/drivers/hwmon/sis5595.c | 5 +- trunk/drivers/hwmon/thmc50.c | 7 +- trunk/drivers/hwmon/tmp102.c | 4 +- trunk/drivers/hwmon/tmp401.c | 728 ++- trunk/drivers/hwmon/tmp421.c | 7 +- trunk/drivers/hwmon/via686a.c | 47 +- trunk/drivers/hwmon/vt1211.c | 23 +- trunk/drivers/hwmon/vt8231.c | 5 +- trunk/drivers/hwmon/w83627ehf.c | 31 +- trunk/drivers/hwmon/w83781d.c | 36 +- trunk/drivers/hwmon/w83791d.c | 4 +- trunk/drivers/hwmon/w83792d.c | 13 +- trunk/drivers/hwmon/w83793.c | 8 +- trunk/drivers/hwmon/w83795.c | 9 +- trunk/drivers/hwspinlock/hwspinlock_core.c | 2 - trunk/drivers/i2c/Kconfig | 2 +- trunk/drivers/i2c/busses/Kconfig | 6 +- .../i2c/busses/i2c-designware-platdrv.c | 1 + trunk/drivers/i2c/busses/i2c-ismt.c | 2 - trunk/drivers/i2c/busses/i2c-tegra.c | 13 +- trunk/drivers/i2c/muxes/i2c-mux-pca9541.c | 2 +- trunk/drivers/idle/intel_idle.c | 1 - .../iio/common/st_sensors/st_sensors_core.c | 9 +- trunk/drivers/iio/dac/ad5064.c | 64 +- trunk/drivers/iio/imu/inv_mpu6050/Kconfig | 1 - trunk/drivers/infiniband/hw/cxgb4/cm.c | 12 - trunk/drivers/infiniband/hw/cxgb4/qp.c | 4 +- trunk/drivers/infiniband/hw/ipath/ipath_fs.c | 1 - .../drivers/infiniband/hw/ipath/ipath_verbs.c | 2 +- trunk/drivers/infiniband/hw/mlx4/cm.c | 1 + trunk/drivers/infiniband/hw/qib/Kconfig | 6 +- trunk/drivers/infiniband/hw/qib/qib_driver.c | 5 +- trunk/drivers/infiniband/hw/qib/qib_fs.c | 1 - trunk/drivers/infiniband/hw/qib/qib_iba6120.c | 3 +- trunk/drivers/infiniband/hw/qib/qib_init.c | 8 +- trunk/drivers/infiniband/hw/qib/qib_sd7220.c | 2 +- trunk/drivers/infiniband/hw/qib/qib_verbs.c | 4 +- trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c | 8 +- trunk/drivers/input/joystick/analog.c | 8 +- trunk/drivers/input/keyboard/tc3589x-keypad.c | 8 +- trunk/drivers/input/mouse/alps.c | 85 +- trunk/drivers/input/mouse/alps.h | 1 - trunk/drivers/input/mouse/cypress_ps2.c | 19 +- trunk/drivers/input/tablet/wacom_wac.c | 12 +- trunk/drivers/input/touchscreen/ads7846.c | 7 +- .../drivers/input/touchscreen/atmel_mxt_ts.c | 68 +- trunk/drivers/input/touchscreen/mms114.c | 34 +- trunk/drivers/iommu/Kconfig | 2 +- trunk/drivers/iommu/amd_iommu.c | 36 +- trunk/drivers/iommu/amd_iommu_init.c | 42 +- trunk/drivers/iommu/amd_iommu_types.h | 11 +- trunk/drivers/iommu/dmar.c | 1 - trunk/drivers/iommu/irq_remapping.c | 1 + trunk/drivers/ipack/carriers/tpci200.c | 14 +- trunk/drivers/ipack/ipack.c | 36 +- trunk/drivers/irqchip/irq-gic.c | 5 +- trunk/drivers/isdn/hardware/avm/avm_cs.c | 14 +- trunk/drivers/isdn/hisax/Kconfig | 6 +- trunk/drivers/isdn/hisax/avma1_cs.c | 14 +- trunk/drivers/isdn/hisax/elsa_cs.c | 14 +- trunk/drivers/isdn/hisax/sedlbauer_cs.c | 14 +- trunk/drivers/isdn/hisax/st5481_usb.c | 12 +- trunk/drivers/isdn/hisax/teles_cs.c | 14 +- trunk/drivers/isdn/i4l/isdn_tty.c | 4 +- trunk/drivers/mailbox/pl320-ipc.c | 3 +- trunk/drivers/md/Kconfig | 11 + trunk/drivers/md/dm-bufio.c | 2 - trunk/drivers/md/dm-cache-metadata.c | 64 +- trunk/drivers/md/dm-cache-metadata.h | 2 +- trunk/drivers/md/dm-cache-policy-cleaner.c | 7 +- trunk/drivers/md/dm-cache-policy-internal.h | 2 - trunk/drivers/md/dm-cache-policy-mq.c | 8 +- trunk/drivers/md/dm-cache-policy.c | 8 - trunk/drivers/md/dm-cache-policy.h | 2 - trunk/drivers/md/dm-cache-target.c | 214 +- trunk/drivers/md/dm-raid.c | 123 +- trunk/drivers/md/dm-thin.c | 11 +- trunk/drivers/md/dm-verity.c | 39 +- trunk/drivers/md/dm.c | 1 - trunk/drivers/md/md.c | 25 +- trunk/drivers/md/md.h | 4 +- .../md/persistent-data/dm-btree-remove.c | 46 +- trunk/drivers/md/raid0.c | 13 +- trunk/drivers/md/raid1.c | 8 +- trunk/drivers/md/raid10.c | 97 +- trunk/drivers/md/raid10.h | 5 - trunk/drivers/md/raid5.c | 165 +- trunk/drivers/md/raid5.h | 5 +- trunk/drivers/media/dvb-frontends/mb86a20s.c | 2 +- trunk/drivers/media/i2c/m5mols/m5mols_core.c | 2 +- trunk/drivers/media/pci/bt8xx/bttv-driver.c | 20 +- .../drivers/media/pci/cx25821/cx25821-video.c | 2 +- trunk/drivers/media/platform/Kconfig | 2 +- .../media/platform/exynos-gsc/gsc-core.c | 8 +- .../media/platform/s5p-fimc/fimc-core.c | 6 +- .../media/platform/s5p-fimc/fimc-lite-reg.c | 8 +- .../media/platform/s5p-fimc/fimc-lite.c | 1 - .../media/platform/s5p-fimc/fimc-mdevice.c | 39 +- .../drivers/media/platform/s5p-mfc/s5p_mfc.c | 2 +- .../media/platform/s5p-mfc/s5p_mfc_enc.c | 1 - trunk/drivers/media/radio/radio-ma901.c | 11 - trunk/drivers/media/rc/Kconfig | 2 +- trunk/drivers/media/v4l2-core/Makefile | 2 +- trunk/drivers/memory/emif.c | 141 +- trunk/drivers/memory/tegra30-mc.c | 2 - trunk/drivers/mfd/Kconfig | 3 +- trunk/drivers/mfd/ab8500-gpadc.c | 17 +- trunk/drivers/mfd/omap-usb-host.c | 6 +- trunk/drivers/mfd/palmas.c | 36 +- trunk/drivers/mfd/pm8921-core.c | 14 +- trunk/drivers/mfd/tps65912-core.c | 1 - trunk/drivers/mfd/twl4030-audio.c | 2 +- trunk/drivers/mfd/twl4030-madc.c | 2 +- trunk/drivers/mfd/wm5102-tables.c | 8 - trunk/drivers/misc/Kconfig | 10 +- trunk/drivers/misc/Makefile | 2 +- trunk/drivers/misc/apds9802als.c | 25 +- trunk/drivers/misc/apds990x.c | 9 +- trunk/drivers/misc/arm-charlcd.c | 13 +- trunk/drivers/misc/atmel_pwm.c | 12 +- trunk/drivers/misc/bh1770glc.c | 7 +- trunk/drivers/misc/bh1780gli.c | 10 +- trunk/drivers/misc/cs5535-mfgpt.c | 41 +- trunk/drivers/misc/dummy-irq.c | 59 - trunk/drivers/misc/eeprom/at25.c | 4 +- trunk/drivers/misc/eeprom/eeprom_93xx46.c | 6 +- trunk/drivers/misc/ep93xx_pwm.c | 13 +- trunk/drivers/misc/fsa9480.c | 19 +- trunk/drivers/misc/ibmasm/ibmasmfs.c | 1 - trunk/drivers/misc/isl29003.c | 19 +- trunk/drivers/misc/lattice-ecp3-config.c | 2 +- trunk/drivers/misc/mei/Kconfig | 5 +- trunk/drivers/misc/mei/Makefile | 9 +- trunk/drivers/misc/mei/amthif.c | 21 +- trunk/drivers/misc/mei/bus.c | 528 --- trunk/drivers/misc/mei/client.c | 116 +- trunk/drivers/misc/mei/client.h | 7 +- trunk/drivers/misc/mei/debugfs.c | 143 - trunk/drivers/misc/mei/hbm.c | 82 +- trunk/drivers/misc/mei/hbm.h | 25 +- trunk/drivers/misc/mei/hw-me.c | 153 +- trunk/drivers/misc/mei/hw-me.h | 6 + trunk/drivers/misc/mei/init.c | 86 +- trunk/drivers/misc/mei/interrupt.c | 242 +- trunk/drivers/misc/mei/main.c | 127 +- trunk/drivers/misc/mei/mei_dev.h | 167 +- trunk/drivers/misc/mei/nfc.c | 554 --- trunk/drivers/misc/mei/pci-me.c | 98 +- trunk/drivers/misc/mei/wd.c | 3 +- trunk/drivers/misc/tsl2550.c | 21 +- trunk/drivers/misc/vmw_vmci/Kconfig | 2 +- trunk/drivers/misc/vmw_vmci/vmci_datagram.c | 4 +- trunk/drivers/mmc/host/sdricoh_cs.c | 20 +- trunk/drivers/mtd/bcm47xxpart.c | 52 +- trunk/drivers/mtd/mtdchar.c | 60 +- trunk/drivers/mtd/nand/nand_base.c | 16 - trunk/drivers/mtd/nand/nand_ids.c | 80 +- trunk/drivers/net/arcnet/com20020_cs.c | 14 +- trunk/drivers/net/bonding/bond_main.c | 115 +- trunk/drivers/net/bonding/bond_sysfs.c | 97 +- trunk/drivers/net/can/mcp251x.c | 10 +- trunk/drivers/net/can/sja1000/Kconfig | 1 - trunk/drivers/net/can/sja1000/ems_pcmcia.c | 13 +- trunk/drivers/net/can/sja1000/peak_pcmcia.c | 13 +- trunk/drivers/net/can/sja1000/plx_pci.c | 4 +- trunk/drivers/net/can/sja1000/sja1000.c | 6 +- trunk/drivers/net/can/sja1000/sja1000.h | 2 +- .../net/can/sja1000/sja1000_of_platform.c | 31 +- trunk/drivers/net/can/softing/softing_cs.c | 16 +- trunk/drivers/net/ethernet/3com/3c574_cs.c | 14 +- trunk/drivers/net/ethernet/3com/3c589_cs.c | 14 +- trunk/drivers/net/ethernet/8390/ax88796.c | 2 +- trunk/drivers/net/ethernet/8390/axnet_cs.c | 14 +- trunk/drivers/net/ethernet/8390/pcnet_cs.c | 14 +- trunk/drivers/net/ethernet/amd/nmclan_cs.c | 14 +- .../net/ethernet/atheros/atl1e/atl1e.h | 3 +- .../net/ethernet/atheros/atl1e/atl1e_main.c | 20 +- trunk/drivers/net/ethernet/broadcom/bgmac.c | 4 - .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 10 +- .../net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | 18 +- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 6 - .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 89 +- .../net/ethernet/broadcom/bnx2x/bnx2x_link.h | 7 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 7 +- .../net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 3 +- trunk/drivers/net/ethernet/broadcom/tg3.c | 29 +- trunk/drivers/net/ethernet/calxeda/xgmac.c | 9 +- .../net/ethernet/chelsio/cxgb4/t4_hw.c | 12 +- trunk/drivers/net/ethernet/davicom/dm9000.c | 214 +- trunk/drivers/net/ethernet/davicom/dm9000.h | 11 +- trunk/drivers/net/ethernet/dec/tulip/Kconfig | 1 - trunk/drivers/net/ethernet/emulex/benet/be.h | 1 - .../net/ethernet/emulex/benet/be_cmds.c | 36 +- .../drivers/net/ethernet/emulex/benet/be_hw.h | 4 +- .../net/ethernet/emulex/benet/be_main.c | 15 +- trunk/drivers/net/ethernet/freescale/fec.c | 195 +- trunk/drivers/net/ethernet/freescale/fec.h | 19 +- .../drivers/net/ethernet/freescale/fec_ptp.c | 3 - .../drivers/net/ethernet/fujitsu/fmvj18x_cs.c | 14 +- trunk/drivers/net/ethernet/intel/e100.c | 36 +- .../net/ethernet/intel/e1000/e1000_ethtool.c | 14 +- .../net/ethernet/intel/e1000e/ethtool.c | 13 - .../net/ethernet/intel/e1000e/ich8lan.c | 71 +- .../net/ethernet/intel/e1000e/ich8lan.h | 2 - .../net/ethernet/intel/e1000e/netdev.c | 89 +- .../drivers/net/ethernet/intel/e1000e/regs.h | 1 - .../net/ethernet/intel/igb/e1000_82575.c | 44 +- trunk/drivers/net/ethernet/intel/igb/igb.h | 10 +- .../net/ethernet/intel/igb/igb_hwmon.c | 14 - .../drivers/net/ethernet/intel/igb/igb_main.c | 190 +- .../drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +- .../net/ethernet/intel/ixgb/ixgb_main.c | 7 +- .../net/ethernet/intel/ixgbe/ixgbe_main.c | 11 +- .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 6 - .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 24 +- trunk/drivers/net/ethernet/lantiq_etop.c | 2 +- trunk/drivers/net/ethernet/marvell/Kconfig | 2 +- .../net/ethernet/marvell/mv643xx_eth.c | 55 +- trunk/drivers/net/ethernet/marvell/mvneta.c | 18 +- trunk/drivers/net/ethernet/marvell/sky2.c | 2 +- trunk/drivers/net/ethernet/marvell/sky2.h | 2 +- trunk/drivers/net/ethernet/mellanox/mlx4/cq.c | 2 +- .../net/ethernet/mellanox/mlx4/en_netdev.c | 112 +- trunk/drivers/net/ethernet/mellanox/mlx4/eq.c | 2 +- trunk/drivers/net/ethernet/mellanox/mlx4/fw.c | 8 - .../drivers/net/ethernet/mellanox/mlx4/main.c | 2 +- .../drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 +- .../net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + trunk/drivers/net/ethernet/mellanox/mlx4/mr.c | 10 +- trunk/drivers/net/ethernet/mellanox/mlx4/pd.c | 2 +- .../drivers/net/ethernet/mellanox/mlx4/port.c | 8 +- trunk/drivers/net/ethernet/mellanox/mlx4/qp.c | 8 +- .../ethernet/mellanox/mlx4/resource_tracker.c | 48 +- .../drivers/net/ethernet/mellanox/mlx4/srq.c | 2 +- trunk/drivers/net/ethernet/micrel/ks8851.c | 2 +- trunk/drivers/net/ethernet/nxp/lpc_eth.c | 3 +- .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 4 +- .../ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 15 +- .../net/ethernet/qlogic/qlcnic/qlcnic_io.c | 3 +- .../net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 4 +- trunk/drivers/net/ethernet/qlogic/qlge/qlge.h | 2 +- .../net/ethernet/qlogic/qlge/qlge_ethtool.c | 2 +- .../net/ethernet/qlogic/qlge/qlge_main.c | 36 +- trunk/drivers/net/ethernet/realtek/r8169.c | 55 +- trunk/drivers/net/ethernet/renesas/sh_eth.c | 38 +- trunk/drivers/net/ethernet/renesas/sh_eth.h | 3 +- trunk/drivers/net/ethernet/sfc/efx.c | 16 +- trunk/drivers/net/ethernet/sfc/efx.h | 4 +- trunk/drivers/net/ethernet/sfc/net_driver.h | 4 +- trunk/drivers/net/ethernet/sfc/nic.c | 3 +- trunk/drivers/net/ethernet/sfc/rx.c | 25 +- trunk/drivers/net/ethernet/smsc/smc91c92_cs.c | 14 +- .../net/ethernet/stmicro/stmmac/mmc_core.c | 1 - trunk/drivers/net/ethernet/ti/cpsw.c | 10 +- trunk/drivers/net/ethernet/ti/davinci_emac.c | 4 +- .../drivers/net/ethernet/xircom/xirc2ps_cs.c | 16 +- trunk/drivers/net/hippi/rrunner.c | 3 - trunk/drivers/net/hyperv/netvsc.c | 17 +- trunk/drivers/net/hyperv/netvsc_drv.c | 2 + trunk/drivers/net/hyperv/rndis_filter.c | 14 +- trunk/drivers/net/macvlan.c | 1 - trunk/drivers/net/netconsole.c | 15 +- trunk/drivers/net/phy/micrel.c | 3 +- trunk/drivers/net/phy/phy_device.c | 10 +- trunk/drivers/net/team/team.c | 2 - trunk/drivers/net/tun.c | 4 +- trunk/drivers/net/usb/Kconfig | 20 +- trunk/drivers/net/usb/Makefile | 1 - trunk/drivers/net/usb/asix_devices.c | 31 - trunk/drivers/net/usb/ax88179_178a.c | 1448 ------ trunk/drivers/net/usb/cdc_mbim.c | 13 +- trunk/drivers/net/usb/cdc_ncm.c | 57 +- trunk/drivers/net/usb/qmi_wwan.c | 153 +- trunk/drivers/net/usb/smsc75xx.c | 12 +- trunk/drivers/net/vmxnet3/vmxnet3_drv.c | 1 - trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c | 6 - trunk/drivers/net/vmxnet3/vmxnet3_int.h | 4 +- trunk/drivers/net/vxlan.c | 10 - trunk/drivers/net/wireless/airo_cs.c | 14 +- .../net/wireless/ath/ath9k/ar9003_calib.c | 4 - .../wireless/ath/ath9k/ar9580_1p0_initvals.h | 2 +- trunk/drivers/net/wireless/ath/ath9k/common.h | 2 +- .../wireless/ath/ath9k/dfs_pattern_detector.c | 4 +- .../net/wireless/ath/ath9k/dfs_pri_detector.c | 4 +- trunk/drivers/net/wireless/ath/ath9k/htc.h | 1 - .../net/wireless/ath/ath9k/htc_drv_init.c | 2 +- .../net/wireless/ath/ath9k/htc_drv_txrx.c | 18 +- trunk/drivers/net/wireless/ath/ath9k/hw.c | 4 +- trunk/drivers/net/wireless/ath/ath9k/link.c | 29 +- trunk/drivers/net/wireless/ath/ath9k/main.c | 4 - trunk/drivers/net/wireless/atmel_cs.c | 14 +- trunk/drivers/net/wireless/b43/dma.c | 65 +- trunk/drivers/net/wireless/b43/pcmcia.c | 4 - trunk/drivers/net/wireless/b43/phy_n.c | 11 +- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 6 +- .../wireless/brcm80211/brcmfmac/wl_cfg80211.c | 53 +- .../wireless/brcm80211/brcmsmac/mac80211_if.c | 264 +- .../wireless/brcm80211/brcmsmac/phy/phy_lcn.c | 369 +- .../brcm80211/brcmsmac/phy/phytbl_lcn.c | 64 +- trunk/drivers/net/wireless/hostap/hostap_cs.c | 15 +- .../drivers/net/wireless/iwlegacy/3945-mac.c | 22 +- trunk/drivers/net/wireless/iwlegacy/4965-rs.c | 3 +- trunk/drivers/net/wireless/iwlwifi/dvm/lib.c | 9 - trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c | 18 +- trunk/drivers/net/wireless/iwlwifi/dvm/sta.c | 2 +- trunk/drivers/net/wireless/iwlwifi/dvm/tx.c | 2 +- .../drivers/net/wireless/iwlwifi/dvm/ucode.c | 4 +- .../net/wireless/iwlwifi/iwl-devtrace.h | 12 +- trunk/drivers/net/wireless/iwlwifi/iwl-drv.c | 3 +- .../net/wireless/iwlwifi/iwl-modparams.h | 2 +- .../drivers/net/wireless/iwlwifi/iwl-phy-db.c | 16 + .../drivers/net/wireless/iwlwifi/iwl-trans.h | 20 +- trunk/drivers/net/wireless/iwlwifi/mvm/d3.c | 104 +- .../drivers/net/wireless/iwlwifi/mvm/fw-api.h | 18 +- trunk/drivers/net/wireless/iwlwifi/mvm/fw.c | 133 +- .../net/wireless/iwlwifi/mvm/mac80211.c | 19 +- trunk/drivers/net/wireless/iwlwifi/mvm/mvm.h | 7 +- trunk/drivers/net/wireless/iwlwifi/mvm/ops.c | 18 +- trunk/drivers/net/wireless/iwlwifi/mvm/rx.c | 37 +- trunk/drivers/net/wireless/iwlwifi/mvm/sta.c | 10 - trunk/drivers/net/wireless/iwlwifi/mvm/tx.c | 6 +- .../net/wireless/iwlwifi/pcie/internal.h | 35 +- trunk/drivers/net/wireless/iwlwifi/pcie/rx.c | 14 +- .../drivers/net/wireless/iwlwifi/pcie/trans.c | 13 - trunk/drivers/net/wireless/iwlwifi/pcie/tx.c | 297 +- trunk/drivers/net/wireless/libertas/if_cs.c | 25 +- trunk/drivers/net/wireless/libertas/if_sdio.c | 6 +- trunk/drivers/net/wireless/mwifiex/cfg80211.c | 3 +- trunk/drivers/net/wireless/mwifiex/cmdevt.c | 22 +- trunk/drivers/net/wireless/mwifiex/init.c | 8 - trunk/drivers/net/wireless/mwifiex/join.c | 7 +- trunk/drivers/net/wireless/mwifiex/main.h | 4 +- trunk/drivers/net/wireless/mwifiex/pcie.c | 3 +- trunk/drivers/net/wireless/mwifiex/scan.c | 17 +- .../drivers/net/wireless/mwifiex/sta_ioctl.c | 10 +- .../drivers/net/wireless/orinoco/orinoco_cs.c | 16 +- .../net/wireless/orinoco/spectrum_cs.c | 16 +- trunk/drivers/net/wireless/rt2x00/Kconfig | 11 +- trunk/drivers/net/wireless/rt2x00/Makefile | 1 - trunk/drivers/net/wireless/rt2x00/rt2400pci.c | 1 - trunk/drivers/net/wireless/rt2x00/rt2500pci.c | 1 - trunk/drivers/net/wireless/rt2x00/rt2800pci.c | 15 +- trunk/drivers/net/wireless/rt2x00/rt2x00dev.c | 8 +- .../drivers/net/wireless/rt2x00/rt2x00mmio.c | 216 - .../drivers/net/wireless/rt2x00/rt2x00mmio.h | 119 - trunk/drivers/net/wireless/rt2x00/rt2x00pci.c | 176 + trunk/drivers/net/wireless/rt2x00/rt2x00pci.h | 88 + trunk/drivers/net/wireless/rt2x00/rt61pci.c | 1 - .../net/wireless/rtlwifi/rtl8192cu/hw.c | 89 +- trunk/drivers/net/wireless/rtlwifi/usb.c | 1 - trunk/drivers/net/wireless/wl3501_cs.c | 14 +- trunk/drivers/nfc/microread/mei.c | 38 +- trunk/drivers/oprofile/oprofilefs.c | 1 - trunk/drivers/parport/parport_amiga.c | 15 +- trunk/drivers/parport/parport_cs.c | 14 +- trunk/drivers/parport/parport_gsc.c | 4 +- trunk/drivers/parport/parport_sunbpp.c | 5 +- trunk/drivers/parport/procfs.c | 6 +- trunk/drivers/pci/bus.c | 14 +- trunk/drivers/pci/hotplug/Kconfig | 7 +- trunk/drivers/pci/hotplug/acpiphp.h | 35 +- trunk/drivers/pci/hotplug/acpiphp_core.c | 30 +- trunk/drivers/pci/hotplug/acpiphp_glue.c | 415 +- trunk/drivers/pci/hotplug/cpci_hotplug.h | 44 +- trunk/drivers/pci/hotplug/cpqphp.h | 70 +- trunk/drivers/pci/hotplug/cpqphp_nvram.h | 12 +- trunk/drivers/pci/hotplug/ibmphp.h | 66 +- trunk/drivers/pci/hotplug/pci_hotplug_core.c | 15 +- trunk/drivers/pci/hotplug/pciehp.h | 22 +- trunk/drivers/pci/hotplug/pciehp_acpi.c | 2 +- trunk/drivers/pci/hotplug/rpadlpar.h | 8 +- trunk/drivers/pci/hotplug/rpaphp.h | 16 +- trunk/drivers/pci/hotplug/s390_pci_hpc.c | 12 +- trunk/drivers/pci/hotplug/shpchp.h | 26 +- trunk/drivers/pci/hotplug/shpchp_sysfs.c | 2 +- trunk/drivers/pci/msi.c | 180 +- trunk/drivers/pci/msi.h | 24 + trunk/drivers/pci/pci-acpi.c | 53 +- trunk/drivers/pci/pci-driver.c | 5 +- trunk/drivers/pci/pci-sysfs.c | 2 +- trunk/drivers/pci/pci.c | 25 +- trunk/drivers/pci/pci.h | 89 +- trunk/drivers/pci/pcie/Kconfig | 2 +- trunk/drivers/pci/pcie/aer/aer_inject.c | 10 +- trunk/drivers/pci/pcie/aer/aerdrv.h | 14 +- trunk/drivers/pci/pcie/aer/aerdrv_core.c | 4 +- trunk/drivers/pci/pcie/pme.c | 2 + trunk/drivers/pci/pcie/portdrv.h | 18 +- trunk/drivers/pci/pcie/portdrv_acpi.c | 1 - trunk/drivers/pci/pcie/portdrv_pci.c | 30 +- trunk/drivers/pci/probe.c | 15 +- trunk/drivers/pci/quirks.c | 148 +- trunk/drivers/pci/remove.c | 4 +- trunk/drivers/pci/rom.c | 28 +- trunk/drivers/pci/setup-bus.c | 4 +- trunk/drivers/pci/setup-res.c | 2 + trunk/drivers/pci/slot.c | 7 +- trunk/drivers/pinctrl/Kconfig | 25 +- trunk/drivers/pinctrl/Makefile | 5 +- trunk/drivers/pinctrl/core.c | 359 +- trunk/drivers/pinctrl/core.h | 8 +- trunk/drivers/pinctrl/devicetree.c | 19 +- trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.c | 41 +- trunk/drivers/pinctrl/pinconf-generic.c | 20 +- trunk/drivers/pinctrl/pinconf.c | 335 +- trunk/drivers/pinctrl/pinconf.h | 10 +- trunk/drivers/pinctrl/pinctrl-ab8500.c | 5 +- trunk/drivers/pinctrl/pinctrl-ab8505.c | 7 +- trunk/drivers/pinctrl/pinctrl-ab8540.c | 5 +- trunk/drivers/pinctrl/pinctrl-ab9540.c | 7 +- trunk/drivers/pinctrl/pinctrl-abx500.c | 20 +- trunk/drivers/pinctrl/pinctrl-at91.c | 88 +- trunk/drivers/pinctrl/pinctrl-bcm2835.c | 6 +- trunk/drivers/pinctrl/pinctrl-coh901.c | 9 +- trunk/drivers/pinctrl/pinctrl-exynos.c | 36 +- trunk/drivers/pinctrl/pinctrl-exynos.h | 16 +- trunk/drivers/pinctrl/pinctrl-exynos5440.c | 159 +- trunk/drivers/pinctrl/pinctrl-falcon.c | 2 +- trunk/drivers/pinctrl/pinctrl-imx.c | 6 +- trunk/drivers/pinctrl/pinctrl-lantiq.c | 4 +- trunk/drivers/pinctrl/pinctrl-mmp2.c | 722 +++ trunk/drivers/pinctrl/pinctrl-mxs.c | 6 +- .../drivers/pinctrl/pinctrl-nomadik-db8500.c | 4 +- .../drivers/pinctrl/pinctrl-nomadik-stn8815.c | 2 +- trunk/drivers/pinctrl/pinctrl-nomadik.c | 16 +- trunk/drivers/pinctrl/pinctrl-pxa168.c | 651 +++ trunk/drivers/pinctrl/pinctrl-pxa3xx.c | 227 + trunk/drivers/pinctrl/pinctrl-pxa3xx.h | 262 ++ trunk/drivers/pinctrl/pinctrl-pxa910.c | 1007 ++++ trunk/drivers/pinctrl/pinctrl-s3c64xx.c | 816 ---- trunk/drivers/pinctrl/pinctrl-samsung.c | 105 +- trunk/drivers/pinctrl/pinctrl-samsung.h | 42 +- trunk/drivers/pinctrl/pinctrl-single.c | 515 +- trunk/drivers/pinctrl/pinctrl-sirf.c | 14 +- trunk/drivers/pinctrl/pinctrl-sunxi.c | 986 +--- trunk/drivers/pinctrl/pinctrl-tegra.c | 6 +- trunk/drivers/pinctrl/pinctrl-u300.c | 6 +- trunk/drivers/pinctrl/pinctrl-xway.c | 2 +- trunk/drivers/pinctrl/pinmux.c | 13 +- trunk/drivers/pinctrl/spear/pinctrl-spear.c | 4 +- trunk/drivers/platform/x86/chromeos_laptop.c | 41 +- trunk/drivers/platform/x86/hp-wmi.c | 4 + trunk/drivers/platform/x86/thinkpad_acpi.c | 10 + trunk/drivers/pnp/pnpacpi/core.c | 8 +- trunk/drivers/regulator/core.c | 12 +- trunk/drivers/regulator/db8500-prcmu.c | 4 +- trunk/drivers/regulator/palmas-regulator.c | 3 +- trunk/drivers/regulator/twl-regulator.c | 9 +- trunk/drivers/remoteproc/Kconfig | 2 +- trunk/drivers/remoteproc/remoteproc_core.c | 6 +- trunk/drivers/remoteproc/ste_modem_rproc.c | 7 +- trunk/drivers/rtc/rtc-da9052.c | 8 +- trunk/drivers/rtc/rtc-mv.c | 28 +- trunk/drivers/s390/block/dasd.c | 172 +- trunk/drivers/s390/block/dasd_devmap.c | 3 +- trunk/drivers/s390/block/dasd_eckd.c | 344 +- trunk/drivers/s390/block/dasd_int.h | 10 +- trunk/drivers/s390/block/dasd_ioctl.c | 31 +- trunk/drivers/s390/block/scm_blk.c | 79 +- trunk/drivers/s390/block/scm_blk.h | 2 - trunk/drivers/s390/block/scm_blk_cluster.c | 6 +- trunk/drivers/s390/block/scm_drv.c | 23 +- trunk/drivers/s390/char/con3215.c | 4 +- trunk/drivers/s390/char/monreader.c | 3 +- trunk/drivers/s390/char/raw3270.c | 6 +- trunk/drivers/s390/char/sclp_cmd.c | 6 +- trunk/drivers/s390/char/tty3270.c | 16 +- trunk/drivers/s390/char/zcore.c | 2 +- trunk/drivers/s390/cio/chp.c | 22 +- trunk/drivers/s390/cio/chp.h | 2 - trunk/drivers/s390/cio/chsc.c | 28 +- trunk/drivers/s390/cio/chsc.h | 2 - trunk/drivers/s390/cio/cio.c | 160 +- trunk/drivers/s390/cio/cio.h | 11 +- trunk/drivers/s390/cio/css.c | 114 +- trunk/drivers/s390/cio/css.h | 4 +- trunk/drivers/s390/cio/device.c | 139 +- trunk/drivers/s390/cio/device.h | 2 + trunk/drivers/s390/cio/device_ops.c | 22 +- trunk/drivers/s390/cio/idset.c | 2 +- trunk/drivers/s390/cio/scm.c | 18 +- trunk/drivers/s390/net/qeth_core.h | 4 - trunk/drivers/s390/net/qeth_core_main.c | 64 +- trunk/drivers/s390/net/qeth_l2_main.c | 2 - trunk/drivers/s390/net/qeth_l3_main.c | 25 +- trunk/drivers/s390/net/qeth_l3_sys.c | 2 - trunk/drivers/sbus/char/bbc_i2c.c | 4 +- trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 6 +- trunk/drivers/scsi/fcoe/fcoe.c | 15 +- trunk/drivers/scsi/fcoe/fcoe_ctlr.c | 60 +- trunk/drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- trunk/drivers/scsi/ipr.c | 13 +- trunk/drivers/scsi/libfc/fc_disc.c | 26 +- trunk/drivers/scsi/libsas/sas_expander.c | 14 +- trunk/drivers/scsi/lpfc/lpfc_sli.c | 3 +- trunk/drivers/scsi/megaraid/megaraid_sas.h | 3 + .../drivers/scsi/megaraid/megaraid_sas_base.c | 4 +- trunk/drivers/scsi/mvsas/mv_init.c | 6 +- trunk/drivers/scsi/mvumi.c | 4 +- trunk/drivers/scsi/mvumi.h | 1 + trunk/drivers/scsi/qla2xxx/qla_attr.c | 5 + trunk/drivers/scsi/qla2xxx/qla_dbg.c | 3 +- trunk/drivers/scsi/qla2xxx/qla_def.h | 1 + trunk/drivers/scsi/qla2xxx/qla_gbl.h | 3 + trunk/drivers/scsi/qla2xxx/qla_init.c | 4 +- trunk/drivers/scsi/qla2xxx/qla_mbx.c | 58 + trunk/drivers/scsi/qla2xxx/qla_version.h | 2 +- trunk/drivers/scsi/scsi_lib.c | 7 +- trunk/drivers/scsi/st.c | 8 +- trunk/drivers/spi/Kconfig | 3 +- trunk/drivers/spi/spi-bcm63xx.c | 3 +- trunk/drivers/spi/spi-mpc512x-psc.c | 2 +- trunk/drivers/spi/spi-pxa2xx.c | 1 + trunk/drivers/spi/spi-s3c64xx.c | 41 +- trunk/drivers/spi/spi-tegra20-slink.c | 25 +- trunk/drivers/spi/spi.c | 17 +- trunk/drivers/ssb/driver_chipcommon_pmu.c | 29 - trunk/drivers/ssbi/Kconfig | 16 - trunk/drivers/ssbi/Makefile | 1 - trunk/drivers/ssbi/ssbi.c | 379 -- trunk/drivers/staging/android/Kconfig | 9 + trunk/drivers/staging/android/Makefile | 1 + trunk/drivers/staging/android/sync.c | 525 +++ trunk/drivers/staging/android/sync.h | 314 ++ trunk/drivers/staging/ccg/f_fs.c | 1 - trunk/drivers/staging/comedi/drivers/dt9812.c | 16 +- trunk/drivers/staging/comedi/drivers/s626.c | 2 +- trunk/drivers/staging/comedi/drivers/usbdux.c | 31 +- .../staging/comedi/drivers/usbduxfast.c | 30 +- .../staging/comedi/drivers/usbduxsigma.c | 27 +- trunk/drivers/staging/imx-drm/ipuv3-crtc.c | 23 +- trunk/drivers/staging/tidspbridge/rmgr/drv.c | 70 +- trunk/drivers/staging/vt6656/card.c | 2 +- trunk/drivers/staging/vt6656/main_usb.c | 4 + trunk/drivers/staging/zcache/Kconfig | 2 +- trunk/drivers/staging/zcache/ramster/tcp.c | 25 +- .../drivers/target/iscsi/iscsi_target_auth.c | 5 +- trunk/drivers/target/target_core_alua.c | 3 - trunk/drivers/target/target_core_file.h | 2 +- trunk/drivers/target/target_core_pscsi.c | 11 +- trunk/drivers/target/target_core_sbc.c | 7 +- trunk/drivers/target/target_core_tpg.c | 3 +- trunk/drivers/target/target_core_transport.c | 4 +- trunk/drivers/thermal/dove_thermal.c | 16 +- trunk/drivers/thermal/exynos_thermal.c | 2 +- trunk/drivers/thermal/kirkwood_thermal.c | 8 +- trunk/drivers/thermal/rcar_thermal.c | 29 +- trunk/drivers/tty/hvc/hvcs.c | 9 +- trunk/drivers/tty/mxser.c | 8 +- .../tty/serial/8250/{8250_core.c => 8250.c} | 54 +- trunk/drivers/tty/serial/8250/8250_pci.c | 34 +- trunk/drivers/tty/serial/8250/Kconfig | 17 - trunk/drivers/tty/serial/8250/Makefile | 8 +- trunk/drivers/tty/serial/8250/serial_cs.c | 14 +- trunk/drivers/tty/serial/Kconfig | 4 +- trunk/drivers/tty/serial/atmel_serial.c | 11 +- trunk/drivers/tty/serial/bcm63xx_uart.c | 8 +- trunk/drivers/tty/serial/mpc52xx_uart.c | 2 +- trunk/drivers/tty/serial/of_serial.c | 6 - trunk/drivers/tty/serial/omap-serial.c | 11 - trunk/drivers/tty/serial/sunsu.c | 21 +- trunk/drivers/tty/serial/vt8500_serial.c | 9 +- trunk/drivers/tty/serial/xilinx_uartps.c | 2 - trunk/drivers/tty/tty_buffer.c | 2 +- trunk/drivers/tty/tty_io.c | 18 +- trunk/drivers/tty/vt/vc_screen.c | 6 +- trunk/drivers/uio/uio.c | 1 - trunk/drivers/usb/Makefile | 2 +- trunk/drivers/usb/c67x00/c67x00-sched.c | 4 +- trunk/drivers/usb/chipidea/udc.c | 6 +- trunk/drivers/usb/class/cdc-acm.c | 22 +- trunk/drivers/usb/class/cdc-wdm.c | 23 +- trunk/drivers/usb/core/hcd-pci.c | 23 +- trunk/drivers/usb/core/hcd.c | 8 - trunk/drivers/usb/core/port.c | 1 + trunk/drivers/usb/core/usb-acpi.c | 17 +- trunk/drivers/usb/core/usb.c | 3 +- trunk/drivers/usb/dwc3/core.c | 1 - trunk/drivers/usb/dwc3/dwc3-exynos.c | 2 + trunk/drivers/usb/dwc3/dwc3-omap.c | 8 +- trunk/drivers/usb/dwc3/dwc3-pci.c | 2 + trunk/drivers/usb/dwc3/ep0.c | 7 +- trunk/drivers/usb/dwc3/gadget.c | 3 + trunk/drivers/usb/gadget/Kconfig | 1 - trunk/drivers/usb/gadget/Makefile | 12 +- trunk/drivers/usb/gadget/composite.c | 5 +- trunk/drivers/usb/gadget/f_fs.c | 1 - trunk/drivers/usb/gadget/f_rndis.c | 3 +- trunk/drivers/usb/gadget/f_uac1.c | 1 - trunk/drivers/usb/gadget/g_ffs.c | 4 +- trunk/drivers/usb/gadget/imx_udc.c | 20 +- trunk/drivers/usb/gadget/inode.c | 1 - trunk/drivers/usb/gadget/net2272.c | 9 +- trunk/drivers/usb/gadget/net2280.c | 8 +- trunk/drivers/usb/gadget/omap_udc.c | 3 +- trunk/drivers/usb/gadget/pxa25x_udc.c | 24 +- trunk/drivers/usb/gadget/pxa27x_udc.c | 18 +- trunk/drivers/usb/gadget/s3c2410_udc.c | 28 +- trunk/drivers/usb/gadget/u_serial.c | 2 +- trunk/drivers/usb/gadget/u_uac1.c | 3 - trunk/drivers/usb/gadget/udc-core.c | 2 +- trunk/drivers/usb/host/ehci-hcd.c | 7 +- trunk/drivers/usb/host/ehci-hub.c | 2 +- trunk/drivers/usb/host/ehci-q.c | 49 +- trunk/drivers/usb/host/ehci-sched.c | 2 - trunk/drivers/usb/host/ehci-timer.c | 2 +- trunk/drivers/usb/host/sl811_cs.c | 15 +- trunk/drivers/usb/host/xhci-mem.c | 36 +- trunk/drivers/usb/host/xhci-pci.c | 1 - trunk/drivers/usb/host/xhci-ring.c | 61 +- trunk/drivers/usb/host/xhci.c | 25 +- trunk/drivers/usb/host/xhci.h | 9 +- trunk/drivers/usb/musb/Kconfig | 5 + trunk/drivers/usb/musb/da8xx.c | 2 +- trunk/drivers/usb/musb/musb_core.c | 6 + trunk/drivers/usb/musb/musb_gadget.c | 9 +- trunk/drivers/usb/musb/omap2430.c | 12 +- trunk/drivers/usb/otg/otg.c | 10 +- trunk/drivers/usb/phy/Kconfig | 1 - trunk/drivers/usb/phy/omap-control-usb.c | 24 +- trunk/drivers/usb/phy/omap-usb3.c | 8 +- trunk/drivers/usb/phy/samsung-usbphy.c | 8 +- trunk/drivers/usb/serial/ark3116.c | 10 +- trunk/drivers/usb/serial/ch341.c | 11 +- trunk/drivers/usb/serial/cp210x.c | 20 - trunk/drivers/usb/serial/cypress_m8.c | 14 +- trunk/drivers/usb/serial/f81232.c | 9 +- trunk/drivers/usb/serial/ftdi_sio.c | 20 +- trunk/drivers/usb/serial/ftdi_sio_ids.h | 7 - trunk/drivers/usb/serial/garmin_gps.c | 7 +- trunk/drivers/usb/serial/io_edgeport.c | 12 +- trunk/drivers/usb/serial/io_ti.c | 13 +- trunk/drivers/usb/serial/mct_u232.c | 13 +- trunk/drivers/usb/serial/mos7840.c | 16 +- trunk/drivers/usb/serial/option.c | 5 - trunk/drivers/usb/serial/oti6858.c | 10 +- trunk/drivers/usb/serial/pl2303.c | 11 +- trunk/drivers/usb/serial/qcaux.c | 1 - trunk/drivers/usb/serial/qcserial.c | 7 +- trunk/drivers/usb/serial/quatech2.c | 19 +- trunk/drivers/usb/serial/spcp8x5.c | 9 +- trunk/drivers/usb/serial/ssu100.c | 12 +- trunk/drivers/usb/serial/ti_usb_3410_5052.c | 10 +- trunk/drivers/usb/serial/usb-serial.c | 4 +- trunk/drivers/usb/storage/initializers.c | 76 +- trunk/drivers/usb/storage/initializers.h | 4 +- trunk/drivers/usb/storage/unusual_devs.h | 344 +- trunk/drivers/vfio/pci/vfio_pci.c | 13 +- trunk/drivers/vfio/pci/vfio_pci_config.c | 1 - trunk/drivers/vfio/pci/vfio_pci_intrs.c | 1 - trunk/drivers/vhost/net.c | 3 +- trunk/drivers/vhost/tcm_vhost.c | 220 +- trunk/drivers/video/Kconfig | 59 +- trunk/drivers/video/Makefile | 8 +- trunk/drivers/video/amifb.c | 14 +- trunk/drivers/video/atmel_lcdfb.c | 35 +- trunk/drivers/video/auo_k1900fb.c | 11 +- trunk/drivers/video/auo_k1901fb.c | 11 +- trunk/drivers/video/auo_k190x.c | 235 +- trunk/drivers/video/controlfb.c | 50 +- trunk/drivers/video/ep93xx-fb.c | 1 - trunk/drivers/video/exynos/exynos_mipi_dsi.c | 2 + .../video/exynos/exynos_mipi_dsi_common.c | 2 + .../video/exynos/exynos_mipi_dsi_lowlevel.c | 2 + trunk/drivers/video/fb-puv3.c | 14 +- trunk/drivers/video/fbmem.c | 36 +- trunk/drivers/video/fbmon.c | 16 +- trunk/drivers/video/fsl-diu-fb.c | 157 +- trunk/drivers/video/gbefb.c | 4 +- trunk/drivers/video/mmp/core.c | 2 + trunk/drivers/video/mxsfb.c | 7 +- trunk/drivers/video/of_display_timing.c | 19 +- trunk/drivers/video/of_videomode.c | 2 +- trunk/drivers/video/omap/Kconfig | 11 + trunk/drivers/video/omap/lcd_ams_delta.c | 1 - trunk/drivers/video/omap/lcd_osk.c | 3 - trunk/drivers/video/omap/omapfb_main.c | 2 - .../omap2/displays/panel-tpo-td043mtea1.c | 13 +- trunk/drivers/video/omap2/dss/dss_features.c | 6 +- .../drivers/video/omap2/omapfb/omapfb-main.c | 30 +- trunk/drivers/video/omap2/vrfb.c | 13 +- trunk/drivers/video/ps3fb.c | 18 +- trunk/drivers/video/s3c-fb.c | 3 +- trunk/drivers/video/sa1100fb.c | 16 +- trunk/drivers/video/sgivwfb.c | 20 +- trunk/drivers/video/sh_mipi_dsi.c | 12 +- trunk/drivers/video/sh_mobile_hdmi.c | 12 +- trunk/drivers/video/sh_mobile_lcdcfb.c | 1 - trunk/drivers/video/smscufx.c | 6 +- trunk/drivers/video/udlfb.c | 6 +- trunk/drivers/video/uvesafb.c | 3 +- trunk/drivers/video/vermilion/vermilion.c | 14 +- trunk/drivers/video/vfb.c | 7 +- trunk/drivers/video/videomode.c | 36 +- trunk/drivers/video/vt8500lcdfb.c | 55 +- trunk/drivers/video/wm8505fb.c | 145 +- trunk/drivers/video/wmt_ge_rops.h | 23 - trunk/drivers/w1/masters/mxc_w1.c | 6 +- trunk/drivers/w1/masters/w1-gpio.c | 6 +- trunk/drivers/w1/slaves/Kconfig | 10 - trunk/drivers/w1/slaves/w1_ds2408.c | 25 +- trunk/drivers/w1/w1.c | 3 +- trunk/drivers/watchdog/Kconfig | 2 +- trunk/drivers/watchdog/sp5100_tco.c | 126 +- trunk/drivers/watchdog/sp5100_tco.h | 2 +- trunk/drivers/xen/Kconfig | 2 +- trunk/drivers/xen/events.c | 72 +- trunk/drivers/xen/fallback.c | 3 +- trunk/drivers/xen/xen-acpi-processor.c | 93 +- trunk/drivers/xen/xen-pciback/pci_stub.c | 59 +- trunk/drivers/xen/xen-pciback/pciback_ops.c | 3 +- trunk/drivers/xen/xen-stub.c | 1 + trunk/drivers/xen/xenfs/super.c | 1 - trunk/fs/9p/vfs_super.c | 1 - trunk/fs/adfs/super.c | 1 - trunk/fs/affs/super.c | 1 - trunk/fs/afs/super.c | 1 - trunk/fs/aio.c | 2 +- trunk/fs/autofs4/init.c | 1 - trunk/fs/befs/linuxvfs.c | 1 - trunk/fs/bfs/inode.c | 1 - trunk/fs/binfmt_elf.c | 1 - trunk/fs/binfmt_misc.c | 1 - trunk/fs/bio.c | 2 + trunk/fs/block_dev.c | 1 - trunk/fs/btrfs/ctree.c | 30 +- trunk/fs/btrfs/delayed-inode.c | 151 +- trunk/fs/btrfs/delayed-inode.h | 2 - trunk/fs/btrfs/disk-io.c | 30 +- trunk/fs/btrfs/extent-tree.c | 89 +- trunk/fs/btrfs/extent_io.c | 33 - trunk/fs/btrfs/extent_io.h | 2 - trunk/fs/btrfs/file-item.c | 6 +- trunk/fs/btrfs/file.c | 10 - trunk/fs/btrfs/inode.c | 31 +- trunk/fs/btrfs/ioctl.c | 18 +- trunk/fs/btrfs/locking.h | 1 + trunk/fs/btrfs/ordered-data.c | 2 - trunk/fs/btrfs/qgroup.c | 13 +- trunk/fs/btrfs/relocation.c | 74 +- trunk/fs/btrfs/scrub.c | 3 +- trunk/fs/btrfs/send.c | 10 +- trunk/fs/btrfs/super.c | 1 - trunk/fs/btrfs/transaction.c | 76 +- trunk/fs/btrfs/tree-log.c | 53 +- trunk/fs/btrfs/volumes.c | 33 +- trunk/fs/ceph/super.c | 1 - trunk/fs/cifs/asn1.c | 53 +- trunk/fs/cifs/cifsfs.c | 25 - trunk/fs/cifs/cifsfs.h | 4 - trunk/fs/cifs/cifssmb.c | 2 +- trunk/fs/cifs/connect.c | 32 +- trunk/fs/cifs/file.c | 6 +- trunk/fs/cifs/inode.c | 21 +- trunk/fs/cifs/netmisc.c | 2 +- trunk/fs/cifs/smb2ops.c | 1 - trunk/fs/coda/inode.c | 1 - trunk/fs/compat.c | 15 +- trunk/fs/configfs/mount.c | 1 - trunk/fs/cramfs/inode.c | 1 - trunk/fs/dcache.c | 16 +- trunk/fs/debugfs/inode.c | 1 - trunk/fs/ecryptfs/Kconfig | 8 - trunk/fs/ecryptfs/Makefile | 7 +- trunk/fs/ecryptfs/crypto.c | 9 +- trunk/fs/ecryptfs/dentry.c | 2 + trunk/fs/ecryptfs/ecryptfs_kernel.h | 40 +- trunk/fs/ecryptfs/file.c | 2 + trunk/fs/ecryptfs/inode.c | 8 +- trunk/fs/ecryptfs/keystore.c | 9 +- trunk/fs/ecryptfs/main.c | 1 - trunk/fs/ecryptfs/messaging.c | 5 +- trunk/fs/ecryptfs/miscdev.c | 14 +- trunk/fs/efs/super.c | 1 - trunk/fs/exofs/super.c | 1 - trunk/fs/ext2/ialloc.c | 1 + trunk/fs/ext2/inode.c | 2 - trunk/fs/ext2/super.c | 1 - trunk/fs/ext3/super.c | 5 +- trunk/fs/ext4/ext4.h | 8 +- trunk/fs/ext4/extents.c | 108 +- trunk/fs/ext4/extents_status.c | 212 +- trunk/fs/ext4/extents_status.h | 9 - trunk/fs/ext4/ialloc.c | 4 +- trunk/fs/ext4/indirect.c | 4 +- trunk/fs/ext4/inode.c | 182 +- trunk/fs/ext4/mballoc.c | 23 +- trunk/fs/ext4/move_extent.c | 43 +- trunk/fs/ext4/page-io.c | 12 +- trunk/fs/ext4/resize.c | 4 +- trunk/fs/ext4/super.c | 11 +- trunk/fs/f2fs/super.c | 1 - trunk/fs/fat/namei_msdos.c | 1 - trunk/fs/fat/namei_vfat.c | 1 - trunk/fs/filesystems.c | 2 +- trunk/fs/freevxfs/vxfs_super.c | 3 +- trunk/fs/fuse/control.c | 1 - trunk/fs/fuse/inode.c | 2 - trunk/fs/gfs2/file.c | 5 +- trunk/fs/gfs2/incore.h | 1 - trunk/fs/gfs2/lock_dlm.c | 39 +- trunk/fs/gfs2/ops_fstype.c | 4 +- trunk/fs/gfs2/rgrp.c | 32 +- trunk/fs/hfs/super.c | 1 - trunk/fs/hfsplus/extents.c | 2 +- trunk/fs/hfsplus/super.c | 1 - trunk/fs/hostfs/hostfs_kern.c | 10 +- trunk/fs/hpfs/super.c | 1 - trunk/fs/hppfs/hppfs.c | 1 - trunk/fs/hugetlbfs/inode.c | 3 +- trunk/fs/inode.c | 2 +- trunk/fs/internal.h | 5 - trunk/fs/isofs/inode.c | 4 +- trunk/fs/jbd2/transaction.c | 15 +- trunk/fs/jffs2/super.c | 1 - trunk/fs/jfs/super.c | 1 - trunk/fs/logfs/super.c | 1 - trunk/fs/minix/inode.c | 1 - trunk/fs/namei.c | 2 + trunk/fs/namespace.c | 56 +- trunk/fs/ncpfs/inode.c | 1 - trunk/fs/nfs/blocklayout/blocklayoutdm.c | 4 +- trunk/fs/nfs/idmap.c | 13 +- trunk/fs/nfs/nfs4client.c | 45 +- trunk/fs/nfs/nfs4filelayout.c | 1 + trunk/fs/nfs/nfs4proc.c | 17 +- trunk/fs/nfs/nfs4state.c | 8 +- trunk/fs/nfs/pnfs.c | 81 +- trunk/fs/nfs/pnfs.h | 6 - trunk/fs/nfs/super.c | 4 +- trunk/fs/nfsd/nfs4state.c | 36 +- trunk/fs/nfsd/nfs4xdr.c | 2 +- trunk/fs/nfsd/nfscache.c | 11 +- trunk/fs/nfsd/nfsctl.c | 1 - trunk/fs/nfsd/vfs.c | 3 +- trunk/fs/nilfs2/super.c | 1 - trunk/fs/ntfs/super.c | 1 - trunk/fs/ocfs2/dlmfs/dlmfs.c | 1 - trunk/fs/ocfs2/super.c | 1 - trunk/fs/omfs/inode.c | 1 - trunk/fs/openpromfs/inode.c | 1 - trunk/fs/pipe.c | 3 - trunk/fs/pnode.c | 6 - trunk/fs/pnode.h | 1 - trunk/fs/proc/array.c | 1 - trunk/fs/proc/generic.c | 119 +- trunk/fs/proc/inode.c | 6 +- trunk/fs/proc/namespaces.c | 12 +- trunk/fs/proc/root.c | 4 - trunk/fs/qnx4/inode.c | 1 - trunk/fs/qnx6/inode.c | 1 - trunk/fs/quota/dquot.c | 5 +- trunk/fs/read_write.c | 28 - trunk/fs/reiserfs/super.c | 5 +- trunk/fs/reiserfs/xattr.c | 4 +- trunk/fs/romfs/super.c | 1 - trunk/fs/splice.c | 4 +- trunk/fs/squashfs/super.c | 1 - trunk/fs/sysfs/dir.c | 58 +- trunk/fs/sysfs/mount.c | 4 - trunk/fs/sysv/super.c | 4 +- trunk/fs/ubifs/super.c | 13 +- trunk/fs/udf/super.c | 1 - trunk/fs/ufs/super.c | 1 - trunk/fs/xfs/xfs_buf.c | 6 - trunk/fs/xfs/xfs_iomap.c | 4 +- trunk/fs/xfs/xfs_super.c | 1 - trunk/include/acpi/acpi_bus.h | 6 +- trunk/include/acpi/processor.h | 3 - trunk/include/asm-generic/atomic.h | 6 + trunk/include/asm-generic/cmpxchg.h | 10 - trunk/include/asm-generic/tlb.h | 7 +- trunk/include/drm/drm_crtc.h | 6 +- trunk/include/drm/drm_pciids.h | 13 +- trunk/include/linux/acpi.h | 9 + trunk/include/linux/ata.h | 2 +- trunk/include/linux/blktrace_api.h | 1 + trunk/include/linux/capability.h | 2 - trunk/include/linux/compat.h | 4 +- trunk/include/linux/debug_locks.h | 4 +- trunk/include/linux/devfreq.h | 16 +- trunk/include/linux/device.h | 19 +- trunk/include/linux/ecryptfs.h | 12 +- trunk/include/linux/edac.h | 7 +- trunk/include/linux/efi.h | 9 +- trunk/include/linux/freezer.h | 3 + trunk/include/linux/fs.h | 2 - trunk/include/linux/fs_struct.h | 2 - trunk/include/linux/ftrace.h | 5 +- trunk/include/linux/hardirq.h | 2 + trunk/include/linux/hash.h | 3 +- trunk/include/linux/hyperv.h | 69 - trunk/include/linux/i2c/atmel_mxt_ts.h | 5 - trunk/include/linux/idr.h | 68 +- trunk/include/linux/iio/common/st_sensors.h | 9 +- trunk/include/linux/ipack.h | 42 +- trunk/include/linux/irq_work.h | 2 +- trunk/include/linux/kernel.h | 1 + trunk/include/linux/kexec.h | 2 - trunk/include/linux/kvm_host.h | 2 +- trunk/include/linux/kvm_types.h | 1 - trunk/include/linux/libata.h | 1 - trunk/include/linux/list.h | 4 +- trunk/include/linux/mei_cl_bus.h | 44 - trunk/include/linux/mfd/arizona/core.h | 3 - trunk/include/linux/mfd/arizona/pdata.h | 21 - trunk/include/linux/mfd/arizona/registers.h | 4 - trunk/include/linux/mfd/max77693-private.h | 23 - trunk/include/linux/mfd/palmas.h | 1 - trunk/include/linux/mfd/tps65912.h | 1 - trunk/include/linux/mfd/wm831x/auxadc.h | 2 - trunk/include/linux/mfd/wm831x/core.h | 2 +- trunk/include/linux/mm.h | 3 +- trunk/include/linux/mman.h | 4 +- trunk/include/linux/mmzone.h | 2 +- trunk/include/linux/mod_devicetable.h | 9 - trunk/include/linux/mount.h | 2 - trunk/include/linux/msi.h | 23 +- trunk/include/linux/mtd/nand.h | 7 - trunk/include/linux/mutex.h | 3 - trunk/include/linux/mxsfb.h | 7 +- trunk/include/linux/netdevice.h | 4 +- .../linux/netfilter/ipset/ip_set_ahash.h | 32 +- trunk/include/linux/nvme.h | 28 - trunk/include/linux/pci-acpi.h | 29 - trunk/include/linux/pci-aspm.h | 20 +- trunk/include/linux/pci-ats.h | 26 +- trunk/include/linux/pci.h | 118 +- trunk/include/linux/pci_hotplug.h | 12 +- trunk/include/linux/pci_ids.h | 1 - trunk/include/linux/pcieport_if.h | 4 +- trunk/include/linux/perf_event.h | 6 - trunk/include/linux/pinctrl/pinconf.h | 6 - trunk/include/linux/pinctrl/pinctrl.h | 6 +- trunk/include/linux/platform_data/emif_plat.h | 1 - .../linux/platform_data/ntc_thermistor.h | 10 +- .../linux/platform_data/video-vt8500lcdfb.h | 31 + trunk/include/linux/platform_data/video_s3c.h | 54 - trunk/include/linux/platform_device.h | 25 +- trunk/include/linux/preempt.h | 22 +- trunk/include/linux/printk.h | 6 - trunk/include/linux/proc_fs.h | 2 - trunk/include/linux/regulator/driver.h | 2 - trunk/include/linux/res_counter.h | 1 - trunk/include/linux/sched.h | 6 +- trunk/include/linux/security.h | 12 - trunk/include/linux/signal.h | 4 +- trunk/include/linux/skbuff.h | 20 +- trunk/include/linux/smpboot.h | 4 - trunk/include/linux/spinlock_up.h | 29 +- .../include/linux/ssb/ssb_driver_chipcommon.h | 2 - trunk/include/linux/ssbi.h | 38 - trunk/include/linux/swiotlb.h | 1 - trunk/include/linux/thermal.h | 2 +- trunk/include/linux/ucs2_string.h | 14 - trunk/include/linux/udp.h | 1 - trunk/include/linux/usb/cdc_ncm.h | 1 - trunk/include/linux/usb/composite.h | 3 +- trunk/include/linux/usb/hcd.h | 2 - trunk/include/linux/usb/serial.h | 2 - trunk/include/linux/usb/ulpi.h | 8 - trunk/include/linux/user_namespace.h | 4 - trunk/include/net/addrconf.h | 1 - trunk/include/net/dst.h | 6 +- trunk/include/net/flow_keys.h | 1 - trunk/include/net/inet_frag.h | 9 - trunk/include/net/ip_fib.h | 12 +- trunk/include/net/ip_vs.h | 12 - trunk/include/net/ipip.h | 16 +- trunk/include/net/irda/irlmp.h | 3 +- trunk/include/net/iucv/af_iucv.h | 8 - trunk/include/net/scm.h | 4 +- trunk/include/net/tcp.h | 4 - trunk/include/pcmcia/ds.h | 12 - trunk/include/scsi/libfc.h | 3 +- trunk/include/sound/max98090.h | 0 trunk/include/sound/soc-dapm.h | 1 - trunk/include/trace/events/block.h | 8 +- trunk/include/trace/events/sched.h | 2 +- trunk/include/uapi/linux/acct.h | 6 +- trunk/include/uapi/linux/aio_abi.h | 4 +- trunk/include/uapi/linux/connector.h | 5 +- trunk/include/uapi/linux/fuse.h | 436 +- trunk/include/uapi/linux/packet_diag.h | 4 +- trunk/include/uapi/linux/pci_regs.h | 30 +- trunk/include/uapi/linux/raid/md_p.h | 6 +- trunk/include/uapi/linux/serial_core.h | 5 +- trunk/include/uapi/linux/unix_diag.h | 4 +- trunk/include/video/atmel_lcdc.h | 2 +- trunk/include/video/auo_k190xfb.h | 3 +- trunk/include/video/display_timing.h | 57 +- trunk/include/video/videomode.h | 18 +- trunk/include/xen/events.h | 3 +- trunk/include/xen/interface/io/blkif.h | 10 - trunk/include/xen/interface/physdev.h | 6 - trunk/init/Kconfig | 4 + trunk/ipc/mqueue.c | 15 +- trunk/ipc/msg.c | 7 +- trunk/ipc/msgutil.c | 3 + trunk/kernel/.gitignore | 1 - trunk/kernel/capability.c | 24 - trunk/kernel/events/core.c | 16 +- trunk/kernel/events/internal.h | 2 +- trunk/kernel/events/ring_buffer.c | 22 +- trunk/kernel/exit.c | 2 +- trunk/kernel/fork.c | 5 +- trunk/kernel/futex.c | 46 +- trunk/kernel/hrtimer.c | 3 +- trunk/kernel/kexec.c | 118 +- trunk/kernel/kprobes.c | 19 +- trunk/kernel/kthread.c | 52 +- trunk/kernel/lockdep.c | 46 +- trunk/kernel/mutex.c | 151 +- trunk/kernel/pid_namespace.c | 3 +- trunk/kernel/printk.c | 80 +- trunk/kernel/rtmutex-tester.c | 5 +- trunk/kernel/sched/clock.c | 26 - trunk/kernel/sched/core.c | 53 +- trunk/kernel/sched/cputime.c | 2 +- trunk/kernel/sched/features.h | 7 + trunk/kernel/signal.c | 7 +- trunk/kernel/smpboot.c | 18 +- trunk/kernel/softirq.c | 21 +- trunk/kernel/stop_machine.c | 2 +- trunk/kernel/sys.c | 60 +- trunk/kernel/time/tick-broadcast.c | 3 +- trunk/kernel/trace/Kconfig | 24 +- trunk/kernel/trace/blktrace.c | 26 +- trunk/kernel/trace/ftrace.c | 58 +- trunk/kernel/trace/trace.c | 95 +- trunk/kernel/trace/trace.h | 6 - trunk/kernel/trace/trace_irqsoff.c | 19 +- trunk/kernel/trace/trace_sched_wakeup.c | 18 +- trunk/kernel/trace/trace_stack.c | 2 +- trunk/kernel/user.c | 2 - trunk/kernel/user_namespace.c | 37 +- trunk/kernel/workqueue.c | 51 +- trunk/lib/Kconfig | 3 - trunk/lib/Makefile | 2 - trunk/lib/bust_spinlocks.c | 3 +- trunk/lib/dma-debug.c | 45 +- trunk/lib/idr.c | 96 +- trunk/lib/kobject.c | 9 +- trunk/lib/swiotlb.c | 19 +- trunk/lib/ucs2_string.c | 51 - trunk/lib/xz/Kconfig | 2 +- trunk/mm/Kconfig | 8 +- trunk/mm/fremap.c | 17 +- trunk/mm/hugetlb.c | 20 +- trunk/mm/ksm.c | 2 +- trunk/mm/memcontrol.c | 8 +- trunk/mm/memory.c | 48 - trunk/mm/memory_hotplug.c | 8 +- trunk/mm/mempolicy.c | 4 +- trunk/mm/mlock.c | 11 +- trunk/mm/mmap.c | 6 +- trunk/mm/nommu.c | 12 +- trunk/mm/page_alloc.c | 1 - trunk/mm/process_vm_access.c | 8 + trunk/mm/vmscan.c | 2 +- trunk/net/802/mrp.c | 4 - trunk/net/8021q/vlan.c | 14 +- trunk/net/9p/trans_virtio.c | 2 +- trunk/net/atm/common.c | 2 - trunk/net/ax25/af_ax25.c | 1 - trunk/net/batman-adv/bat_iv_ogm.c | 6 +- trunk/net/batman-adv/main.c | 5 +- trunk/net/batman-adv/main.h | 2 +- trunk/net/batman-adv/routing.c | 38 +- trunk/net/batman-adv/translation-table.c | 2 +- trunk/net/batman-adv/vis.c | 4 +- trunk/net/bluetooth/af_bluetooth.c | 4 +- trunk/net/bluetooth/rfcomm/sock.c | 1 - trunk/net/bluetooth/sco.c | 2 - trunk/net/bridge/br_device.c | 2 +- trunk/net/bridge/br_fdb.c | 2 +- trunk/net/bridge/br_if.c | 3 +- trunk/net/bridge/br_input.c | 2 +- trunk/net/bridge/br_mdb.c | 4 - trunk/net/bridge/br_multicast.c | 3 +- trunk/net/bridge/br_netlink.c | 2 - trunk/net/bridge/br_private.h | 5 +- trunk/net/bridge/br_stp_if.c | 1 - trunk/net/caif/caif_dev.c | 2 +- trunk/net/caif/caif_socket.c | 2 - trunk/net/caif/caif_usb.c | 4 +- trunk/net/can/gw.c | 6 +- trunk/net/ceph/osdmap.c | 42 +- trunk/net/core/dev.c | 19 +- trunk/net/core/dev_addr_lists.c | 6 +- trunk/net/core/flow.c | 2 +- trunk/net/core/flow_dissector.c | 2 - trunk/net/core/rtnetlink.c | 11 +- trunk/net/core/scm.c | 4 +- trunk/net/dcb/dcbnl.c | 8 - trunk/net/ieee802154/6lowpan.h | 2 +- trunk/net/ipv4/af_inet.c | 3 +- trunk/net/ipv4/devinet.c | 66 +- trunk/net/ipv4/esp4.c | 6 +- trunk/net/ipv4/inet_connection_sock.c | 1 - trunk/net/ipv4/inet_fragment.c | 20 +- trunk/net/ipv4/ip_fragment.c | 25 +- trunk/net/ipv4/ip_gre.c | 5 +- trunk/net/ipv4/ip_input.c | 6 +- trunk/net/ipv4/ip_options.c | 7 +- trunk/net/ipv4/ipconfig.c | 3 +- trunk/net/ipv4/netfilter/Kconfig | 13 + trunk/net/ipv4/netfilter/ipt_rpfilter.c | 8 +- trunk/net/ipv4/syncookies.c | 4 +- trunk/net/ipv4/tcp.c | 2 +- trunk/net/ipv4/tcp_input.c | 77 +- trunk/net/ipv4/tcp_ipv4.c | 14 +- trunk/net/ipv4/tcp_output.c | 17 +- trunk/net/ipv4/udp.c | 7 - trunk/net/ipv6/addrconf.c | 77 +- trunk/net/ipv6/addrconf_core.c | 19 - trunk/net/ipv6/ip6_input.c | 21 +- trunk/net/ipv6/netfilter/ip6t_NPT.c | 4 +- trunk/net/ipv6/netfilter/ip6t_rpfilter.c | 8 +- trunk/net/ipv6/netfilter/nf_conntrack_reasm.c | 12 +- trunk/net/ipv6/reassembly.c | 20 +- trunk/net/ipv6/route.c | 3 +- trunk/net/ipv6/tcp_ipv6.c | 8 - trunk/net/ipv6/udp.c | 8 - trunk/net/irda/af_irda.c | 8 +- trunk/net/irda/ircomm/ircomm_tty.c | 29 +- trunk/net/irda/iriap.c | 10 +- trunk/net/irda/irlmp.c | 10 +- trunk/net/iucv/af_iucv.c | 36 +- trunk/net/key/af_key.c | 9 +- trunk/net/l2tp/l2tp_core.c | 206 +- trunk/net/l2tp/l2tp_core.h | 22 +- trunk/net/l2tp/l2tp_debugfs.c | 28 +- trunk/net/l2tp/l2tp_ip.c | 6 - trunk/net/l2tp/l2tp_ip6.c | 8 - trunk/net/l2tp/l2tp_netlink.c | 72 +- trunk/net/l2tp/l2tp_ppp.c | 112 +- trunk/net/llc/af_llc.c | 2 - trunk/net/mac80211/cfg.c | 17 +- trunk/net/mac80211/chan.c | 17 +- trunk/net/mac80211/ieee80211_i.h | 4 +- trunk/net/mac80211/iface.c | 68 +- trunk/net/mac80211/mesh.c | 3 +- trunk/net/mac80211/mlme.c | 58 +- trunk/net/mac80211/offchannel.c | 23 +- trunk/net/mac80211/rx.c | 14 +- trunk/net/mac80211/sta_info.c | 12 +- trunk/net/mac80211/tx.c | 80 +- .../net/netfilter/ipset/ip_set_bitmap_ipmac.c | 6 +- trunk/net/netfilter/ipset/ip_set_core.c | 3 +- .../netfilter/ipset/ip_set_hash_ipportnet.c | 18 - trunk/net/netfilter/ipset/ip_set_hash_net.c | 22 +- .../netfilter/ipset/ip_set_hash_netiface.c | 22 +- .../net/netfilter/ipset/ip_set_hash_netport.c | 18 - trunk/net/netfilter/ipset/ip_set_list_set.c | 10 +- trunk/net/netfilter/ipvs/ip_vs_core.c | 14 +- trunk/net/netfilter/ipvs/ip_vs_ctl.c | 7 - trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c | 16 +- trunk/net/netfilter/nf_conntrack_helper.c | 11 +- trunk/net/netfilter/nf_conntrack_proto_dccp.c | 12 +- trunk/net/netfilter/nf_conntrack_proto_gre.c | 12 +- trunk/net/netfilter/nf_conntrack_proto_sctp.c | 12 +- .../netfilter/nf_conntrack_proto_udplite.c | 12 +- trunk/net/netfilter/nf_conntrack_sip.c | 6 +- trunk/net/netfilter/nf_conntrack_standalone.c | 1 - trunk/net/netfilter/nf_nat_core.c | 40 +- trunk/net/netfilter/nfnetlink.c | 7 +- trunk/net/netfilter/nfnetlink_acct.c | 2 - trunk/net/netfilter/nfnetlink_queue_core.c | 6 +- trunk/net/netfilter/xt_AUDIT.c | 3 - trunk/net/netlabel/netlabel_unlabeled.c | 27 +- trunk/net/netlink/genetlink.c | 1 - trunk/net/netrom/af_netrom.c | 1 - trunk/net/nfc/llcp/llcp.c | 66 +- trunk/net/nfc/llcp/sock.c | 11 +- trunk/net/openvswitch/actions.c | 4 +- trunk/net/openvswitch/datapath.c | 33 +- trunk/net/openvswitch/flow.c | 8 +- trunk/net/openvswitch/vport-netdev.c | 3 +- trunk/net/openvswitch/vport.c | 3 +- trunk/net/rds/message.c | 8 +- trunk/net/rds/stats.c | 1 - trunk/net/rose/af_rose.c | 1 - trunk/net/sched/cls_fw.c | 2 +- trunk/net/sched/sch_cbq.c | 5 +- trunk/net/sched/sch_fq_codel.c | 2 +- trunk/net/sched/sch_generic.c | 2 +- trunk/net/sched/sch_qfq.c | 66 +- trunk/net/sctp/associola.c | 2 +- trunk/net/sctp/endpointola.c | 2 +- trunk/net/sctp/sm_statefuns.c | 2 +- trunk/net/sctp/socket.c | 6 +- trunk/net/sctp/ssnmap.c | 8 +- trunk/net/sctp/tsnmap.c | 13 +- trunk/net/sctp/ulpqueue.c | 87 +- trunk/net/sunrpc/auth_gss/svcauth_gss.c | 12 +- trunk/net/sunrpc/clnt.c | 11 +- trunk/net/sunrpc/rpc_pipe.c | 5 +- trunk/net/sunrpc/sched.c | 9 +- trunk/net/sunrpc/xprtsock.c | 15 +- trunk/net/tipc/socket.c | 7 - trunk/net/unix/af_unix.c | 9 +- trunk/net/vmw_vsock/af_vsock.c | 8 +- trunk/net/vmw_vsock/vmci_transport.c | 34 +- trunk/net/vmw_vsock/vsock_addr.c | 10 + trunk/net/vmw_vsock/vsock_addr.h | 2 + trunk/net/wireless/core.c | 67 +- trunk/net/wireless/core.h | 3 - trunk/net/wireless/nl80211.c | 162 +- trunk/net/wireless/scan.c | 24 +- trunk/net/wireless/sme.c | 8 +- trunk/net/wireless/trace.h | 5 +- trunk/net/wireless/wext-sme.c | 6 - trunk/net/xfrm/xfrm_replay.c | 66 +- trunk/scripts/Makefile.headersinst | 11 +- trunk/scripts/checkpatch.pl | 1 - trunk/scripts/mod/devicetable-offsets.c | 3 - trunk/scripts/mod/file2alias.c | 12 - trunk/security/capability.c | 6 - trunk/security/keys/compat.c | 4 +- trunk/security/keys/process_keys.c | 4 +- trunk/security/security.c | 5 - trunk/security/selinux/hooks.c | 7 - trunk/security/selinux/xfrm.c | 2 +- trunk/security/yama/yama_lsm.c | 4 +- trunk/sound/core/pcm_native.c | 12 +- trunk/sound/core/seq/oss/seq_oss_event.c | 14 +- trunk/sound/core/seq/seq_timer.c | 8 +- trunk/sound/core/vmaster.c | 5 +- trunk/sound/oss/sequencer.c | 6 - trunk/sound/pci/asihpi/asihpi.c | 3 +- trunk/sound/pci/hda/hda_codec.c | 39 +- trunk/sound/pci/hda/hda_eld.c | 2 +- trunk/sound/pci/hda/hda_generic.c | 48 +- trunk/sound/pci/hda/hda_intel.c | 138 +- trunk/sound/pci/hda/patch_ca0132.c | 36 +- trunk/sound/pci/hda/patch_cirrus.c | 8 +- trunk/sound/pci/hda/patch_conexant.c | 16 +- trunk/sound/pci/hda/patch_hdmi.c | 2 +- trunk/sound/pci/hda/patch_realtek.c | 6 +- trunk/sound/pci/hda/patch_sigmatel.c | 29 - trunk/sound/pci/ice1712/ice1712.c | 2 - trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c | 15 +- trunk/sound/pcmcia/vx/vxpocket.c | 14 +- trunk/sound/soc/codecs/arizona.c | 33 - trunk/sound/soc/codecs/arizona.h | 3 - trunk/sound/soc/codecs/max98090.c | 0 trunk/sound/soc/codecs/max98090.h | 0 trunk/sound/soc/codecs/si476x.c | 1 - trunk/sound/soc/codecs/wm5102.c | 25 +- trunk/sound/soc/codecs/wm5110.c | 24 +- trunk/sound/soc/codecs/wm8350.c | 4 +- trunk/sound/soc/codecs/wm8903.c | 2 - trunk/sound/soc/codecs/wm8960.c | 8 +- trunk/sound/soc/codecs/wm_adsp.c | 5 +- trunk/sound/soc/fsl/imx-ssi.c | 5 - trunk/sound/soc/fsl/pcm030-audio-fabric.c | 2 +- trunk/sound/soc/samsung/i2s.c | 17 +- trunk/sound/soc/sh/dma-sh7760.c | 4 +- trunk/sound/soc/soc-compress.c | 14 +- trunk/sound/soc/soc-core.c | 10 +- trunk/sound/soc/soc-dapm.c | 14 - trunk/sound/soc/spear/spear_pcm.c | 12 +- trunk/sound/soc/tegra/tegra20_i2s.h | 2 +- trunk/sound/soc/tegra/tegra30_i2s.h | 2 +- trunk/sound/soc/tegra/tegra_pcm.c | 24 +- trunk/sound/usb/card.c | 15 - trunk/sound/usb/clock.c | 45 +- trunk/sound/usb/mixer.c | 21 +- trunk/sound/usb/mixer_quirks.c | 4 +- trunk/sound/usb/quirks.c | 2 +- trunk/tools/hv/hv_kvp_daemon.c | 16 +- trunk/tools/hv/hv_vss_daemon.c | 249 - trunk/tools/lib/traceevent/Makefile | 2 +- trunk/tools/perf/Makefile | 8 +- trunk/tools/perf/bench/bench.h | 24 - trunk/tools/perf/builtin-record.c | 6 +- trunk/tools/perf/util/hist.h | 5 +- trunk/tools/perf/util/strlist.c | 2 +- trunk/tools/power/x86/turbostat/turbostat.c | 5 +- .../testing/selftests/efivarfs/efivarfs.sh | 59 - trunk/tools/usb/ffs-test.c | 2 +- trunk/virt/kvm/ioapic.c | 7 +- trunk/virt/kvm/kvm_main.c | 47 +- 2033 files changed, 21109 insertions(+), 38673 deletions(-) delete mode 100644 trunk/Documentation/ABI/testing/sysfs-bus-mei delete mode 100644 trunk/Documentation/devicetree/bindings/arm/msm/ssbi.txt delete mode 100644 trunk/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt delete mode 100644 trunk/Documentation/hwmon/lm95234 delete mode 100644 trunk/Documentation/hwmon/nct6775 delete mode 100644 trunk/Documentation/misc-devices/mei/mei-client-bus.txt rename trunk/arch/arm/{mm => kernel}/tcm.h (100%) create mode 100644 trunk/arch/arm/mm/cache-v3.S delete mode 100644 trunk/arch/parisc/lib/ucmpdi2.c delete mode 100644 trunk/arch/s390/kernel/dumpstack.c delete mode 100644 trunk/arch/s390/pci/pci_insn.c create mode 100644 trunk/arch/sparc/include/asm/cputime.h create mode 100644 trunk/arch/sparc/include/asm/emergency-restart.h create mode 100644 trunk/arch/sparc/include/asm/mutex.h create mode 100644 trunk/arch/sparc/include/asm/serial.h create mode 100644 trunk/arch/sparc/include/uapi/asm/types.h delete mode 100644 trunk/drivers/hv/hv_snapshot.c delete mode 100644 trunk/drivers/hwmon/adt7310.c delete mode 100644 trunk/drivers/hwmon/adt7x10.c delete mode 100644 trunk/drivers/hwmon/adt7x10.h delete mode 100644 trunk/drivers/hwmon/lm95234.c delete mode 100644 trunk/drivers/hwmon/nct6775.c delete mode 100644 trunk/drivers/misc/dummy-irq.c delete mode 100644 trunk/drivers/misc/mei/bus.c delete mode 100644 trunk/drivers/misc/mei/debugfs.c delete mode 100644 trunk/drivers/misc/mei/nfc.c delete mode 100644 trunk/drivers/net/usb/ax88179_178a.c delete mode 100644 trunk/drivers/net/wireless/rt2x00/rt2x00mmio.c delete mode 100644 trunk/drivers/net/wireless/rt2x00/rt2x00mmio.h create mode 100644 trunk/drivers/pci/msi.h create mode 100644 trunk/drivers/pinctrl/pinctrl-mmp2.c create mode 100644 trunk/drivers/pinctrl/pinctrl-pxa168.c create mode 100644 trunk/drivers/pinctrl/pinctrl-pxa3xx.c create mode 100644 trunk/drivers/pinctrl/pinctrl-pxa3xx.h create mode 100644 trunk/drivers/pinctrl/pinctrl-pxa910.c delete mode 100644 trunk/drivers/pinctrl/pinctrl-s3c64xx.c delete mode 100644 trunk/drivers/ssbi/Kconfig delete mode 100644 trunk/drivers/ssbi/Makefile delete mode 100644 trunk/drivers/ssbi/ssbi.c create mode 100644 trunk/drivers/staging/android/sync.c create mode 100644 trunk/drivers/staging/android/sync.h rename trunk/drivers/tty/serial/8250/{8250_core.c => 8250.c} (98%) delete mode 100644 trunk/include/linux/mei_cl_bus.h create mode 100644 trunk/include/linux/platform_data/video-vt8500lcdfb.h delete mode 100644 trunk/include/linux/platform_data/video_s3c.h delete mode 100644 trunk/include/linux/ssbi.h delete mode 100644 trunk/include/linux/ucs2_string.h mode change 100644 => 100755 trunk/include/sound/max98090.h delete mode 100644 trunk/lib/ucs2_string.c mode change 100644 => 100755 trunk/sound/soc/codecs/max98090.c mode change 100644 => 100755 trunk/sound/soc/codecs/max98090.h delete mode 100644 trunk/tools/hv/hv_vss_daemon.c diff --git a/[refs] b/[refs] index c5d14cd7f4af..41cafa97c667 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2794b5d408c625e104de813d3de7ac0ec34d46d9 +refs/heads/master: 7ad530bf2499c702a6dcbb279cf78b76845ed584 diff --git a/trunk/CREDITS b/trunk/CREDITS index afaa7cec6ea5..948e0fb9a70e 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -953,11 +953,11 @@ S: Blacksburg, Virginia 24061 S: USA N: Randy Dunlap -E: rdunlap@infradead.org -W: http://www.infradead.org/~rdunlap/ +E: rdunlap@xenotime.net +W: http://www.xenotime.net/linux/linux.html +W: http://www.linux-usb.org D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers D: x86 SMP, ACPI, bootflag hacking -D: documentation, builds S: (ask for current address) S: USA @@ -1510,14 +1510,6 @@ D: Natsemi ethernet D: Cobalt Networks (x86) support D: This-and-That -N: Mark M. Hoffman -E: mhoffman@lightlink.com -D: asb100, lm93 and smsc47b397 hardware monitoring drivers -D: hwmon subsystem core -D: hwmon subsystem maintainer -D: i2c-sis96x and i2c-stub SMBus drivers -S: USA - N: Dirk Hohndel E: hohndel@suse.de D: The XFree86[tm] Project diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-mei b/trunk/Documentation/ABI/testing/sysfs-bus-mei deleted file mode 100644 index 2066f0bbd453..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-bus-mei +++ /dev/null @@ -1,7 +0,0 @@ -What: /sys/bus/mei/devices/.../modalias -Date: March 2013 -KernelVersion: 3.10 -Contact: Samuel Ortiz - linux-mei@linux.intel.com -Description: Stores the same MODALIAS value emitted by uevent - Format: mei: diff --git a/trunk/Documentation/ABI/testing/sysfs-devices-system-cpu b/trunk/Documentation/ABI/testing/sysfs-devices-system-cpu index 2447698aed41..9c978dcae07d 100644 --- a/trunk/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/trunk/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -173,15 +173,3 @@ Description: Processor frequency boosting control Boosting allows the CPU and the firmware to run at a frequency beyound it's nominal limit. More details can be found in Documentation/cpu-freq/boost.txt - - -What: /sys/devices/system/cpu/cpu#/crash_notes - /sys/devices/system/cpu/cpu#/crash_notes_size -Date: April 2013 -Contact: kexec@lists.infradead.org -Description: address and size of the percpu note. - - crash_notes: the physical address of the memory that holds the - note of cpu#. - - crash_notes_size: size of the note of cpu#. diff --git a/trunk/Documentation/DocBook/device-drivers.tmpl b/trunk/Documentation/DocBook/device-drivers.tmpl index c36892c072da..7514dbf0a679 100644 --- a/trunk/Documentation/DocBook/device-drivers.tmpl +++ b/trunk/Documentation/DocBook/device-drivers.tmpl @@ -227,7 +227,7 @@ X!Isound/sound_firmware.c 16x50 UART Driver !Edrivers/tty/serial/serial_core.c -!Edrivers/tty/serial/8250/8250_core.c +!Edrivers/tty/serial/8250/8250.c diff --git a/trunk/Documentation/SubmittingPatches b/trunk/Documentation/SubmittingPatches index aa0c1e63f050..c379a2a6949f 100644 --- a/trunk/Documentation/SubmittingPatches +++ b/trunk/Documentation/SubmittingPatches @@ -60,7 +60,8 @@ own source tree. For example: "dontdiff" is a list of files which are generated by the kernel during the build process, and should be ignored in any diff(1)-generated patch. The "dontdiff" file is included in the kernel tree in -2.6.12 and later. +2.6.12 and later. For earlier kernel versions, you can get it +from . Make sure your patch does not include any extra files which do not belong in a patch submission. Make sure to review your patch -after- diff --git a/trunk/Documentation/device-mapper/dm-raid.txt b/trunk/Documentation/device-mapper/dm-raid.txt index b428556197c9..56fb62b09fc5 100644 --- a/trunk/Documentation/device-mapper/dm-raid.txt +++ b/trunk/Documentation/device-mapper/dm-raid.txt @@ -30,7 +30,6 @@ The target is named "raid" and it accepts the following parameters: raid10 Various RAID10 inspired algorithms chosen by additional params - RAID10: Striped Mirrors (aka 'Striping on top of mirrors') - RAID1E: Integrated Adjacent Stripe Mirroring - - RAID1E: Integrated Offset Stripe Mirroring - and other similar RAID10 variants Reference: Chapter 4 of @@ -65,15 +64,15 @@ The target is named "raid" and it accepts the following parameters: synchronisation state for each region. [raid10_copies <# copies>] - [raid10_format ] + [raid10_format near] These two options are used to alter the default layout of a RAID10 configuration. The number of copies is can be - specified, but the default is 2. There are also three - variations to how the copies are laid down - the default - is "near". Near copies are what most people think of with - respect to mirroring. If these options are left unspecified, - or 'raid10_copies 2' and/or 'raid10_format near' are given, - then the layouts for 2, 3 and 4 devices are: + specified, but the default is 2. There are other variations + to how the copies are laid down - the default and only current + option is "near". Near copies are what most people think of + with respect to mirroring. If these options are left + unspecified, or 'raid10_copies 2' and/or 'raid10_format near' + are given, then the layouts for 2, 3 and 4 devices are: 2 drives 3 drives 4 drives -------- ---------- -------------- A1 A1 A1 A1 A2 A1 A1 A2 A2 @@ -86,33 +85,6 @@ The target is named "raid" and it accepts the following parameters: 3-device layout is what might be called a 'RAID1E - Integrated Adjacent Stripe Mirroring'. - If 'raid10_copies 2' and 'raid10_format far', then the layouts - for 2, 3 and 4 devices are: - 2 drives 3 drives 4 drives - -------- -------------- -------------------- - A1 A2 A1 A2 A3 A1 A2 A3 A4 - A3 A4 A4 A5 A6 A5 A6 A7 A8 - A5 A6 A7 A8 A9 A9 A10 A11 A12 - .. .. .. .. .. .. .. .. .. - A2 A1 A3 A1 A2 A2 A1 A4 A3 - A4 A3 A6 A4 A5 A6 A5 A8 A7 - A6 A5 A9 A7 A8 A10 A9 A12 A11 - .. .. .. .. .. .. .. .. .. - - If 'raid10_copies 2' and 'raid10_format offset', then the - layouts for 2, 3 and 4 devices are: - 2 drives 3 drives 4 drives - -------- ------------ ----------------- - A1 A2 A1 A2 A3 A1 A2 A3 A4 - A2 A1 A3 A1 A2 A2 A1 A4 A3 - A3 A4 A4 A5 A6 A5 A6 A7 A8 - A4 A3 A6 A4 A5 A6 A5 A8 A7 - A5 A6 A7 A8 A9 A9 A10 A11 A12 - A6 A5 A9 A7 A8 A10 A9 A12 A11 - .. .. .. .. .. .. .. .. .. - Here we see layouts closely akin to 'RAID1E - Integrated - Offset Stripe Mirroring'. - <#raid_devs>: The number of devices composing the array. Each device consists of two entries. The first is the device containing the metadata (if any); the second is the one containing the @@ -170,5 +142,3 @@ Version History 1.3.0 Added support for RAID 10 1.3.1 Allow device replacement/rebuild for RAID 10 1.3.2 Fix/improve redundancy checking for RAID10 -1.4.0 Non-functional change. Removes arg from mapping function. -1.4.1 Add RAID10 "far" and "offset" algorithm support. diff --git a/trunk/Documentation/devicetree/bindings/arm/msm/ssbi.txt b/trunk/Documentation/devicetree/bindings/arm/msm/ssbi.txt deleted file mode 100644 index 54fd5ced3401..000000000000 --- a/trunk/Documentation/devicetree/bindings/arm/msm/ssbi.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Qualcomm SSBI - -Some Qualcomm MSM devices contain a point-to-point serial bus used to -communicate with a limited range of devices (mostly power management -chips). - -These require the following properties: - -- compatible: "qcom,ssbi" - -- qcom,controller-type - indicates the SSBI bus variant the controller should use to talk - with the slave device. This should be one of "ssbi", "ssbi2", or - "pmic-arbiter". The type chosen is determined by the attached - slave. - -The slave device should be the single child node of the ssbi device -with a compatible field. diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio.txt index d933af370697..a33628759d36 100644 --- a/trunk/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio.txt @@ -98,7 +98,7 @@ announce the pinrange to the pin ctrl subsystem. For example, compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; reg = <0x1460 0x18>; gpio-controller; - gpio-ranges = <&pinctrl1 0 20 10>, <&pinctrl2 10 50 20>; + gpio-ranges = <&pinctrl1 20 10>, <&pinctrl2 50 20>; } @@ -107,8 +107,8 @@ where, Next values specify the base pin and number of pins for the range handled by 'qe_pio_e' gpio. In the given example from base pin 20 to - pin 29 under pinctrl1 with gpio offset 0 and pin 50 to pin 69 under - pinctrl2 with gpio offset 10 is handled by this gpio controller. + pin 29 under pinctrl1 and pin 50 to pin 69 under pinctrl2 is handled + by this gpio controller. The pinctrl node must have "#gpio-range-cells" property to show number of arguments to pass with phandle from gpio controllers node. diff --git a/trunk/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt b/trunk/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt deleted file mode 100644 index c6f66674f19c..000000000000 --- a/trunk/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt +++ /dev/null @@ -1,29 +0,0 @@ -NTC Thermistor hwmon sensors -------------------------------- - -Requires node properties: -- "compatible" value : one of - "ntc,ncp15wb473" - "ntc,ncp18wb473" - "ntc,ncp21wb473" - "ntc,ncp03wb473" - "ntc,ncp15wl333" -- "pullup-uv" Pull up voltage in micro volts -- "pullup-ohm" Pull up resistor value in ohms -- "pulldown-ohm" Pull down resistor value in ohms -- "connected-positive" Always ON, If not specified. - Status change is possible. -- "io-channels" Channel node of ADC to be used for - conversion. - -Read more about iio bindings at - Documentation/devicetree/bindings/iio/iio-bindings.txt - -Example: - ncp15wb473@0 { - compatible = "ntc,ncp15wb473"; - pullup-uv = <1800000>; - pullup-ohm = <47000>; - pulldown-ohm = <0>; - io-channels = <&adc 3>; - }; diff --git a/trunk/Documentation/devicetree/bindings/mfd/ab8500.txt b/trunk/Documentation/devicetree/bindings/mfd/ab8500.txt index c3a14e0ad0ad..13b707b7355c 100644 --- a/trunk/Documentation/devicetree/bindings/mfd/ab8500.txt +++ b/trunk/Documentation/devicetree/bindings/mfd/ab8500.txt @@ -13,6 +13,9 @@ Required parent device properties: 4 = active high level-sensitive 8 = active low level-sensitive +Optional parent device properties: +- reg : contains the PRCMU mailbox address for the AB8500 i2c port + The AB8500 consists of a large and varied group of sub-devices: Device IRQ Names Supply Names Description @@ -83,8 +86,9 @@ Non-standard child device properties: - stericsson,amic2-bias-vamic1 : Analoge Mic wishes to use a non-standard Vamic - stericsson,earpeice-cmv : Earpeice voltage (only: 950 | 1100 | 1270 | 1580) -ab8500 { +ab8500@5 { compatible = "stericsson,ab8500"; + reg = <5>; /* mailbox 5 is i2c */ interrupts = <0 40 0x4>; interrupt-controller; #interrupt-cells = <2>; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt index 08f0c3d01575..2c81e45f1374 100644 --- a/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +++ b/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt @@ -1,9 +1,7 @@ One-register-per-pin type device tree based pinctrl driver Required properties: -- compatible : "pinctrl-single" or "pinconf-single". - "pinctrl-single" means that pinconf isn't supported. - "pinconf-single" means that generic pinconf is supported. +- compatible : "pinctrl-single" - reg : offset and length of the register set for the mux registers @@ -16,61 +14,9 @@ Optional properties: - pinctrl-single,function-off : function off mode for disabled state if available and same for all registers; if not specified, disabling of pin functions is ignored - - pinctrl-single,bit-per-mux : boolean to indicate that one register controls more than one pin -- pinctrl-single,drive-strength : array of value that are used to configure - drive strength in the pinmux register. They're value of drive strength - current and drive strength mask. - - /* drive strength current, mask */ - pinctrl-single,power-source = <0x30 0xf0>; - -- pinctrl-single,bias-pullup : array of value that are used to configure the - input bias pullup in the pinmux register. - - /* input, enabled pullup bits, disabled pullup bits, mask */ - pinctrl-single,bias-pullup = <0 1 0 1>; - -- pinctrl-single,bias-pulldown : array of value that are used to configure the - input bias pulldown in the pinmux register. - - /* input, enabled pulldown bits, disabled pulldown bits, mask */ - pinctrl-single,bias-pulldown = <2 2 0 2>; - - * Two bits to control input bias pullup and pulldown: User should use - pinctrl-single,bias-pullup & pinctrl-single,bias-pulldown. One bit means - pullup, and the other one bit means pulldown. - * Three bits to control input bias enable, pullup and pulldown. User should - use pinctrl-single,bias-pullup & pinctrl-single,bias-pulldown. Input bias - enable bit should be included in pullup or pulldown bits. - * Although driver could set PIN_CONFIG_BIAS_DISABLE, there's no property as - pinctrl-single,bias-disable. Because pinctrl single driver could implement - it by calling pulldown, pullup disabled. - -- pinctrl-single,input-schmitt : array of value that are used to configure - input schmitt in the pinmux register. In some silicons, there're two input - schmitt value (rising-edge & falling-edge) in the pinmux register. - - /* input schmitt value, mask */ - pinctrl-single,input-schmitt = <0x30 0x70>; - -- pinctrl-single,input-schmitt-enable : array of value that are used to - configure input schmitt enable or disable in the pinmux register. - - /* input, enable bits, disable bits, mask */ - pinctrl-single,input-schmitt-enable = <0x30 0x40 0 0x70>; - -- pinctrl-single,gpio-range : list of value that are used to configure a GPIO - range. They're value of subnode phandle, pin base in pinctrl device, pin - number in this range, GPIO function value of this GPIO range. - The number of parameters is depend on #pinctrl-single,gpio-range-cells - property. - - /* pin base, nr pins & gpio function */ - pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1>; - This driver assumes that there is only one register for each pin (unless the pinctrl-single,bit-per-mux is set), and uses the common pinctrl bindings as specified in the pinctrl-bindings.txt document in this directory. @@ -96,20 +42,6 @@ Where 0xdc is the offset from the pinctrl register base address for the device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to be used when applying this change to the register. - -Optional sub-node: In case some pins could be configured as GPIO in the pinmux -register, those pins could be defined as a GPIO range. This sub-node is required -by pinctrl-single,gpio-range property. - -Required properties in sub-node: -- #pinctrl-single,gpio-range-cells : the number of parameters after phandle in - pinctrl-single,gpio-range property. - - range: gpio-range { - #pinctrl-single,gpio-range-cells = <3>; - }; - - Example: /* SoC common file */ @@ -126,7 +58,7 @@ pmx_core: pinmux@4a100040 { /* second controller instance for pins in wkup domain */ pmx_wkup: pinmux@4a31e040 { - compatible = "pinctrl-single"; + compatible = "pinctrl-single; reg = <0x4a31e040 0x0038>; #address-cells = <1>; #size-cells = <0>; @@ -144,29 +76,6 @@ control_devconf0: pinmux@48002274 { pinctrl-single,function-mask = <0x5F>; }; -/* third controller instance for pins in gpio domain */ -pmx_gpio: pinmux@d401e000 { - compatible = "pinconf-single"; - reg = <0xd401e000 0x0330>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - pinctrl-single,register-width = <32>; - pinctrl-single,function-mask = <7>; - - /* sparse GPIO range could be supported */ - pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1 - &range 12 1 0 &range 13 29 1 - &range 43 1 0 &range 44 49 1 - &range 94 1 1 &range 96 2 1>; - - range: gpio-range { - #pinctrl-single,gpio-range-cells = <3>; - }; -}; - - /* board specific .dts file */ &pmx_core { @@ -187,15 +96,6 @@ pmx_gpio: pinmux@d401e000 { >; }; - uart0_pins: pinmux_uart0_pins { - pinctrl-single,pins = < - 0x208 0 /* UART0_RXD (IOCFG138) */ - 0x20c 0 /* UART0_TXD (IOCFG139) */ - >; - pinctrl-single,bias-pulldown = <0 2 2>; - pinctrl-single,bias-pullup = <0 1 1>; - }; - /* map uart2 pins */ uart2_pins: pinmux_uart2_pins { pinctrl-single,pins = < @@ -222,11 +122,6 @@ pmx_gpio: pinmux@d401e000 { }; -&uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins>; -}; - &uart2 { pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt index c70fca146e91..4598a47aa0cd 100644 --- a/trunk/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt +++ b/trunk/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt @@ -7,7 +7,6 @@ on-chip controllers onto these pads. Required Properties: - compatible: should be one of the following. - - "samsung,s3c64xx-pinctrl": for S3C64xx-compatible pin-controller, - "samsung,exynos4210-pinctrl": for Exynos4210 compatible pin-controller. - "samsung,exynos4x12-pinctrl": for Exynos4x12 compatible pin-controller. - "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller. @@ -106,8 +105,6 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a - compatible: identifies the type of the external wakeup interrupt controller The possible values are: - - samsung,s3c64xx-wakeup-eint: represents wakeup interrupt controller - found on Samsung S3C64xx SoCs, - samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller found on Samsung Exynos4210 SoC. - interrupt-parent: phandle of the interrupt parent to which the external diff --git a/trunk/Documentation/devicetree/bindings/tty/serial/of-serial.txt b/trunk/Documentation/devicetree/bindings/tty/serial/of-serial.txt index 8f01cb190f25..1e1145ca4f3c 100644 --- a/trunk/Documentation/devicetree/bindings/tty/serial/of-serial.txt +++ b/trunk/Documentation/devicetree/bindings/tty/serial/of-serial.txt @@ -11,9 +11,6 @@ Required properties: - "nvidia,tegra20-uart" - "nxp,lpc3220-uart" - "ibm,qpace-nwp-serial" - - "altr,16550-FIFO32" - - "altr,16550-FIFO64" - - "altr,16550-FIFO128" - "serial" if the port type is unknown. - reg : offset and length of the register set for the device. - interrupts : should contain uart interrupt. diff --git a/trunk/Documentation/devicetree/bindings/video/via,vt8500-fb.txt b/trunk/Documentation/devicetree/bindings/video/via,vt8500-fb.txt index 2871e218a0fb..c870b6478ec8 100644 --- a/trunk/Documentation/devicetree/bindings/video/via,vt8500-fb.txt +++ b/trunk/Documentation/devicetree/bindings/video/via,vt8500-fb.txt @@ -5,32 +5,58 @@ Required properties: - compatible : "via,vt8500-fb" - reg : Should contain 1 register ranges(address and length) - interrupts : framebuffer controller interrupt -- bits-per-pixel : bit depth of framebuffer (16 or 32) +- display: a phandle pointing to the display node -Required subnodes: -- display-timings: see display-timing.txt for information +Required nodes: +- display: a display node is required to initialize the lcd panel + This should be in the board dts. +- default-mode: a videomode within the display with timing parameters + as specified below. Example: - fb@d8050800 { + fb@d800e400 { compatible = "via,vt8500-fb"; reg = <0xd800e400 0x400>; interrupts = <12>; - bits-per-pixel = <16>; + display = <&display>; + default-mode = <&mode0>; + }; + +VIA VT8500 Display +----------------------------------------------------- +Required properties (as per of_videomode_helper): + + - hactive, vactive: Display resolution + - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters + in pixels + vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in + lines + - clock: displayclock in Hz + - bpp: lcd panel bit-depth. + <16> for RGB565, <32> for RGB888 + +Optional properties (as per of_videomode_helper): + - width-mm, height-mm: Display dimensions in mm + - hsync-active-high (bool): Hsync pulse is active high + - vsync-active-high (bool): Vsync pulse is active high + - interlaced (bool): This is an interlaced mode + - doublescan (bool): This is a doublescan mode - display-timings { - native-mode = <&timing0>; - timing0: 800x480 { - clock-frequency = <0>; /* unused but required */ +Example: + display: display@0 { + modes { + mode0: mode@0 { hactive = <800>; vactive = <480>; - hfront-porch = <40>; hback-porch = <88>; + hfront-porch = <40>; hsync-len = <0>; vback-porch = <32>; vfront-porch = <11>; vsync-len = <1>; + clock = <0>; /* unused but required */ + bpp = <16>; /* non-standard but required */ }; }; }; - diff --git a/trunk/Documentation/devicetree/bindings/video/wm,wm8505-fb.txt b/trunk/Documentation/devicetree/bindings/video/wm,wm8505-fb.txt index 0bcadb2840a5..3d325e1d11ee 100644 --- a/trunk/Documentation/devicetree/bindings/video/wm,wm8505-fb.txt +++ b/trunk/Documentation/devicetree/bindings/video/wm,wm8505-fb.txt @@ -4,30 +4,20 @@ Wondermedia WM8505 Framebuffer Required properties: - compatible : "wm,wm8505-fb" - reg : Should contain 1 register ranges(address and length) -- bits-per-pixel : bit depth of framebuffer (16 or 32) +- via,display: a phandle pointing to the display node -Required subnodes: -- display-timings: see display-timing.txt for information +Required nodes: +- display: a display node is required to initialize the lcd panel + This should be in the board dts. See definition in + Documentation/devicetree/bindings/video/via,vt8500-fb.txt +- default-mode: a videomode node as specified in + Documentation/devicetree/bindings/video/via,vt8500-fb.txt Example: - fb@d8051700 { + fb@d8050800 { compatible = "wm,wm8505-fb"; - reg = <0xd8051700 0x200>; - bits-per-pixel = <16>; - - display-timings { - native-mode = <&timing0>; - timing0: 800x480 { - clock-frequency = <0>; /* unused but required */ - hactive = <800>; - vactive = <480>; - hfront-porch = <40>; - hback-porch = <88>; - hsync-len = <0>; - vback-porch = <32>; - vfront-porch = <11>; - vsync-len = <1>; - }; - }; + reg = <0xd8050800 0x200>; + display = <&display>; + default-mode = <&mode0>; }; diff --git a/trunk/Documentation/hwmon/adm1275 b/trunk/Documentation/hwmon/adm1275 index 15b4a20d5062..2cfa25667123 100644 --- a/trunk/Documentation/hwmon/adm1275 +++ b/trunk/Documentation/hwmon/adm1275 @@ -15,7 +15,7 @@ Supported chips: Addresses scanned: - Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1276.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/adt7410 b/trunk/Documentation/hwmon/adt7410 index 9817941e5f19..96004000dc2a 100644 --- a/trunk/Documentation/hwmon/adt7410 +++ b/trunk/Documentation/hwmon/adt7410 @@ -4,50 +4,28 @@ Kernel driver adt7410 Supported chips: * Analog Devices ADT7410 Prefix: 'adt7410' - Addresses scanned: None + Addresses scanned: I2C 0x48 - 0x4B Datasheet: Publicly available at the Analog Devices website http://www.analog.com/static/imported-files/data_sheets/ADT7410.pdf - * Analog Devices ADT7420 - Prefix: 'adt7420' - Addresses scanned: None - Datasheet: Publicly available at the Analog Devices website - http://www.analog.com/static/imported-files/data_sheets/ADT7420.pdf - * Analog Devices ADT7310 - Prefix: 'adt7310' - Addresses scanned: None - Datasheet: Publicly available at the Analog Devices website - http://www.analog.com/static/imported-files/data_sheets/ADT7310.pdf - * Analog Devices ADT7320 - Prefix: 'adt7320' - Addresses scanned: None - Datasheet: Publicly available at the Analog Devices website - http://www.analog.com/static/imported-files/data_sheets/ADT7320.pdf Author: Hartmut Knaack Description ----------- -The ADT7310/ADT7410 is a temperature sensor with rated temperature range of --55°C to +150°C. It has a high accuracy of +/-0.5°C and can be operated at a -resolution of 13 bits (0.0625°C) or 16 bits (0.0078°C). The sensor provides an -INT pin to indicate that a minimum or maximum temperature set point has been -exceeded, as well as a critical temperature (CT) pin to indicate that the -critical temperature set point has been exceeded. Both pins can be set up with a -common hysteresis of 0°C - 15°C and a fault queue, ranging from 1 to 4 events. -Both pins can individually set to be active-low or active-high, while the whole -device can either run in comparator mode or interrupt mode. The ADT7410 supports -continuous temperature sampling, as well as sampling one temperature value per -second or even just get one sample on demand for power saving. Besides, it can -completely power down its ADC, if power management is required. - -The ADT7320/ADT7420 is register compatible, the only differences being the -package, a slightly narrower operating temperature range (-40°C to +150°C), and -a better accuracy (0.25°C instead of 0.50°C.) - -The difference between the ADT7310/ADT7320 and ADT7410/ADT7420 is the control -interface, the ADT7310 and ADT7320 use SPI while the ADT7410 and ADT7420 use -I2C. +The ADT7410 is a temperature sensor with rated temperature range of -55°C to ++150°C. It has a high accuracy of +/-0.5°C and can be operated at a resolution +of 13 bits (0.0625°C) or 16 bits (0.0078°C). The sensor provides an INT pin to +indicate that a minimum or maximum temperature set point has been exceeded, as +well as a critical temperature (CT) pin to indicate that the critical +temperature set point has been exceeded. Both pins can be set up with a common +hysteresis of 0°C - 15°C and a fault queue, ranging from 1 to 4 events. Both +pins can individually set to be active-low or active-high, while the whole +device can either run in comparator mode or interrupt mode. The ADT7410 +supports continous temperature sampling, as well as sampling one temperature +value per second or even justget one sample on demand for power saving. +Besides, it can completely power down its ADC, if power management is +required. Configuration Notes ------------------- diff --git a/trunk/Documentation/hwmon/jc42 b/trunk/Documentation/hwmon/jc42 index 868d74d6b773..165077121238 100644 --- a/trunk/Documentation/hwmon/jc42 +++ b/trunk/Documentation/hwmon/jc42 @@ -49,7 +49,7 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1f Author: - Guenter Roeck + Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/lineage-pem b/trunk/Documentation/hwmon/lineage-pem index 83b2ddc160c8..2ba5ed126858 100644 --- a/trunk/Documentation/hwmon/lineage-pem +++ b/trunk/Documentation/hwmon/lineage-pem @@ -8,7 +8,7 @@ Supported devices: Documentation: http://www.lineagepower.com/oem/pdf/CPLI2C.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/lm25066 b/trunk/Documentation/hwmon/lm25066 index c1b57d72efc3..a21db81c4591 100644 --- a/trunk/Documentation/hwmon/lm25066 +++ b/trunk/Documentation/hwmon/lm25066 @@ -1,13 +1,7 @@ -Kernel driver lm25066 +Kernel driver max8688 ===================== Supported chips: - * TI LM25056 - Prefix: 'lm25056' - Addresses scanned: - - Datasheets: - http://www.ti.com/lit/gpn/lm25056 - http://www.ti.com/lit/gpn/lm25056a * National Semiconductor LM25066 Prefix: 'lm25066' Addresses scanned: - @@ -25,15 +19,14 @@ Supported chips: Datasheet: http://www.national.com/pf/LM/LM5066.html -Author: Guenter Roeck +Author: Guenter Roeck Description ----------- -This driver supports hardware montoring for National Semiconductor / TI LM25056, -LM25066, LM5064, and LM5064 Power Management, Monitoring, Control, and -Protection ICs. +This driver supports hardware montoring for National Semiconductor LM25066, +LM5064, and LM5064 Power Management, Monitoring, Control, and Protection ICs. The driver is a client driver to the core PMBus driver. Please see Documentation/hwmon/pmbus for details on PMBus client drivers. @@ -67,19 +60,14 @@ in1_max Maximum input voltage. in1_min_alarm Input voltage low alarm. in1_max_alarm Input voltage high alarm. -in2_label "vmon" -in2_input Measured voltage on VAUX pin -in2_min Minimum VAUX voltage (LM25056 only). -in2_max Maximum VAUX voltage (LM25056 only). -in2_min_alarm VAUX voltage low alarm (LM25056 only). -in2_max_alarm VAUX voltage high alarm (LM25056 only). - -in3_label "vout1" - Not supported on LM25056. -in3_input Measured output voltage. -in3_average Average measured output voltage. -in3_min Minimum output voltage. -in3_min_alarm Output voltage low alarm. +in2_label "vout1" +in2_input Measured output voltage. +in2_average Average measured output voltage. +in2_min Minimum output voltage. +in2_min_alarm Output voltage low alarm. + +in3_label "vout2" +in3_input Measured voltage on vaux pin curr1_label "iin" curr1_input Measured input current. diff --git a/trunk/Documentation/hwmon/lm75 b/trunk/Documentation/hwmon/lm75 index 69af1c7db6b7..c91a1d15fa28 100644 --- a/trunk/Documentation/hwmon/lm75 +++ b/trunk/Documentation/hwmon/lm75 @@ -23,7 +23,7 @@ Supported chips: Datasheet: Publicly available at the Maxim website http://www.maxim-ic.com/ * Microchip (TelCom) TCN75 - Prefix: 'tcn75' + Prefix: 'lm75' Addresses scanned: none Datasheet: Publicly available at the Microchip website http://www.microchip.com/ diff --git a/trunk/Documentation/hwmon/lm95234 b/trunk/Documentation/hwmon/lm95234 deleted file mode 100644 index a0e95ddfd372..000000000000 --- a/trunk/Documentation/hwmon/lm95234 +++ /dev/null @@ -1,36 +0,0 @@ -Kernel driver lm95234 -===================== - -Supported chips: - * National Semiconductor / Texas Instruments LM95234 - Addresses scanned: I2C 0x18, 0x4d, 0x4e - Datasheet: Publicly available at the Texas Instruments website - http://www.ti.com/product/lm95234 - - -Author: Guenter Roeck - -Description ------------ - -LM95234 is an 11-bit digital temperature sensor with a 2-wire System Management -Bus (SMBus) interface and TrueTherm technology that can very accurately monitor -the temperature of four remote diodes as well as its own temperature. -The four remote diodes can be external devices such as microprocessors, -graphics processors or diode-connected 2N3904s. The LM95234's TruTherm -beta compensation technology allows sensing of 90 nm or 65 nm process -thermal diodes accurately. - -All temperature values are given in millidegrees Celsius. Temperature -is provided within a range of -127 to +255 degrees (+127.875 degrees for -the internal sensor). Resolution depends on temperature input and range. - -Each sensor has its own maximum limit, but the hysteresis is common to all -channels. The hysteresis is configurable with the tem1_max_hyst attribute and -affects the hysteresis on all channels. The first two external sensors also -have a critical limit. - -The lm95234 driver can change its update interval to a fixed set of values. -It will round up to the next selectable interval. See the datasheet for exact -values. Reading sensor values more often will do no harm, but will return -'old' values. diff --git a/trunk/Documentation/hwmon/ltc2978 b/trunk/Documentation/hwmon/ltc2978 index dc0d08c61305..c365f9beb5dd 100644 --- a/trunk/Documentation/hwmon/ltc2978 +++ b/trunk/Documentation/hwmon/ltc2978 @@ -2,32 +2,24 @@ Kernel driver ltc2978 ===================== Supported chips: - * Linear Technology LTC2974 - Prefix: 'ltc2974' - Addresses scanned: - - Datasheet: http://www.linear.com/product/ltc2974 * Linear Technology LTC2978 Prefix: 'ltc2978' Addresses scanned: - - Datasheet: http://www.linear.com/product/ltc2978 + Datasheet: http://cds.linear.com/docs/Datasheet/2978fa.pdf * Linear Technology LTC3880 Prefix: 'ltc3880' Addresses scanned: - - Datasheet: http://www.linear.com/product/ltc3880 - * Linear Technology LTC3883 - Prefix: 'ltc3883' - Addresses scanned: - - Datasheet: http://www.linear.com/product/ltc3883 + Datasheet: http://cds.linear.com/docs/Datasheet/3880f.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description ----------- -LTC2974 is a quad digital power supply manager. LTC2978 is an octal power supply -monitor. LTC3880 is a dual output poly-phase step-down DC/DC controller. LTC3883 -is a single phase step-down DC/DC controller. +The LTC2978 is an octal power supply monitor, supervisor, sequencer and +margin controller. The LTC3880 is a dual, PolyPhase DC/DC synchronous +step-down switching regulator controller. Usage Notes @@ -49,90 +41,63 @@ Sysfs attributes in1_label "vin" in1_input Measured input voltage. in1_min Minimum input voltage. -in1_max Maximum input voltage. LTC2974 and LTC2978 only. -in1_lcrit Critical minimum input voltage. LTC2974 and LTC2978 - only. +in1_max Maximum input voltage. +in1_lcrit Critical minimum input voltage. in1_crit Critical maximum input voltage. in1_min_alarm Input voltage low alarm. -in1_max_alarm Input voltage high alarm. LTC2974 and LTC2978 only. -in1_lcrit_alarm Input voltage critical low alarm. LTC2974 and LTC2978 - only. +in1_max_alarm Input voltage high alarm. +in1_lcrit_alarm Input voltage critical low alarm. in1_crit_alarm Input voltage critical high alarm. -in1_lowest Lowest input voltage. LTC2974 and LTC2978 only. +in1_lowest Lowest input voltage. LTC2978 only. in1_highest Highest input voltage. -in1_reset_history Reset input voltage history. - -in[N]_label "vout[1-8]". - LTC2974: N=2-5 - LTC2978: N=2-9 - LTC3880: N=2-3 - LTC3883: N=2 -in[N]_input Measured output voltage. -in[N]_min Minimum output voltage. -in[N]_max Maximum output voltage. -in[N]_lcrit Critical minimum output voltage. -in[N]_crit Critical maximum output voltage. -in[N]_min_alarm Output voltage low alarm. -in[N]_max_alarm Output voltage high alarm. -in[N]_lcrit_alarm Output voltage critical low alarm. -in[N]_crit_alarm Output voltage critical high alarm. -in[N]_lowest Lowest output voltage. LTC2974 and LTC2978 only. -in[N]_highest Highest output voltage. -in[N]_reset_history Reset output voltage history. - -temp[N]_input Measured temperature. - On LTC2974, temp[1-4] report external temperatures, - and temp5 reports the chip temperature. +in1_reset_history Reset history. Writing into this attribute will reset + history for all attributes. + +in[2-9]_label "vout[1-8]". Channels 3 to 9 on LTC2978 only. +in[2-9]_input Measured output voltage. +in[2-9]_min Minimum output voltage. +in[2-9]_max Maximum output voltage. +in[2-9]_lcrit Critical minimum output voltage. +in[2-9]_crit Critical maximum output voltage. +in[2-9]_min_alarm Output voltage low alarm. +in[2-9]_max_alarm Output voltage high alarm. +in[2-9]_lcrit_alarm Output voltage critical low alarm. +in[2-9]_crit_alarm Output voltage critical high alarm. +in[2-9]_lowest Lowest output voltage. LTC2978 only. +in[2-9]_highest Lowest output voltage. +in[2-9]_reset_history Reset history. Writing into this attribute will reset + history for all attributes. + +temp[1-3]_input Measured temperature. On LTC2978, only one temperature measurement is - supported and reports the chip temperature. + supported and reflects the internal temperature. On LTC3880, temp1 and temp2 report external - temperatures, and temp3 reports the chip temperature. - On LTC3883, temp1 reports an external temperature, - and temp2 reports the chip temperature. -temp[N]_min Mimimum temperature. LTC2974 and LTC2978 only. -temp[N]_max Maximum temperature. -temp[N]_lcrit Critical low temperature. -temp[N]_crit Critical high temperature. -temp[N]_min_alarm Temperature low alarm. LTC2974 and LTC2978 only. -temp[N]_max_alarm Temperature high alarm. -temp[N]_lcrit_alarm Temperature critical low alarm. -temp[N]_crit_alarm Temperature critical high alarm. -temp[N]_lowest Lowest measured temperature. LTC2974 and LTC2978 only. - Not supported for chip temperature sensor on LTC2974. -temp[N]_highest Highest measured temperature. Not supported for chip - temperature sensor on LTC2974. -temp[N]_reset_history Reset temperature history. Not supported for chip - temperature sensor on LTC2974. - -power1_label "pin". LTC3883 only. -power1_input Measured input power. - -power[N]_label "pout[1-4]". - LTC2974: N=1-4 - LTC2978: Not supported - LTC3880: N=1-2 - LTC3883: N=2 -power[N]_input Measured output power. - -curr1_label "iin". LTC3880 and LTC3883 only. + temperatures, and temp3 reports the internal + temperature. +temp[1-3]_min Mimimum temperature. +temp[1-3]_max Maximum temperature. +temp[1-3]_lcrit Critical low temperature. +temp[1-3]_crit Critical high temperature. +temp[1-3]_min_alarm Chip temperature low alarm. +temp[1-3]_max_alarm Chip temperature high alarm. +temp[1-3]_lcrit_alarm Chip temperature critical low alarm. +temp[1-3]_crit_alarm Chip temperature critical high alarm. +temp[1-3]_lowest Lowest measured temperature. LTC2978 only. +temp[1-3]_highest Highest measured temperature. +temp[1-3]_reset_history Reset history. Writing into this attribute will reset + history for all attributes. + +power[1-2]_label "pout[1-2]". LTC3880 only. +power[1-2]_input Measured power. + +curr1_label "iin". LTC3880 only. curr1_input Measured input current. curr1_max Maximum input current. curr1_max_alarm Input current high alarm. -curr1_highest Highest input current. LTC3883 only. -curr1_reset_history Reset input current history. LTC3883 only. - -curr[N]_label "iout[1-4]". - LTC2974: N=1-4 - LTC2978: not supported - LTC3880: N=2-3 - LTC3883: N=2 -curr[N]_input Measured output current. -curr[N]_max Maximum output current. -curr[N]_crit Critical high output current. -curr[N]_lcrit Critical low output current. LTC2974 only. -curr[N]_max_alarm Output current high alarm. -curr[N]_crit_alarm Output current critical high alarm. -curr[N]_lcrit_alarm Output current critical low alarm. LTC2974 only. -curr[N]_lowest Lowest output current. LTC2974 only. -curr[N]_highest Highest output current. -curr[N]_reset_history Reset output current history. + +curr[2-3]_label "iout[1-2]". LTC3880 only. +curr[2-3]_input Measured input current. +curr[2-3]_max Maximum input current. +curr[2-3]_crit Critical input current. +curr[2-3]_max_alarm Input current high alarm. +curr[2-3]_crit_alarm Input current critical high alarm. diff --git a/trunk/Documentation/hwmon/ltc4261 b/trunk/Documentation/hwmon/ltc4261 index 9378a75c6134..eba2e2c4b94d 100644 --- a/trunk/Documentation/hwmon/ltc4261 +++ b/trunk/Documentation/hwmon/ltc4261 @@ -8,7 +8,7 @@ Supported chips: Datasheet: http://cds.linear.com/docs/Datasheet/42612fb.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/max16064 b/trunk/Documentation/hwmon/max16064 index d59cc7829bec..f8b478076f6d 100644 --- a/trunk/Documentation/hwmon/max16064 +++ b/trunk/Documentation/hwmon/max16064 @@ -7,7 +7,7 @@ Supported chips: Addresses scanned: - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX16064.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/max16065 b/trunk/Documentation/hwmon/max16065 index 208a29e43010..c11f64a1f2ad 100644 --- a/trunk/Documentation/hwmon/max16065 +++ b/trunk/Documentation/hwmon/max16065 @@ -24,7 +24,7 @@ Supported chips: http://datasheets.maxim-ic.com/en/ds/MAX16070-MAX16071.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/max34440 b/trunk/Documentation/hwmon/max34440 index 37cbf472a19d..47651ff341ae 100644 --- a/trunk/Documentation/hwmon/max34440 +++ b/trunk/Documentation/hwmon/max34440 @@ -27,7 +27,7 @@ Supported chips: Addresses scanned: - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX34461.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/max8688 b/trunk/Documentation/hwmon/max8688 index e78078638b91..fe849871df32 100644 --- a/trunk/Documentation/hwmon/max8688 +++ b/trunk/Documentation/hwmon/max8688 @@ -7,7 +7,7 @@ Supported chips: Addresses scanned: - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8688.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/nct6775 b/trunk/Documentation/hwmon/nct6775 deleted file mode 100644 index 4e9ef60e8c6c..000000000000 --- a/trunk/Documentation/hwmon/nct6775 +++ /dev/null @@ -1,188 +0,0 @@ -Note -==== - -This driver supersedes the NCT6775F and NCT6776F support in the W83627EHF -driver. - -Kernel driver NCT6775 -===================== - -Supported chips: - * Nuvoton NCT5572D/NCT6771F/NCT6772F/NCT6775F/W83677HG-I - Prefix: 'nct6775' - Addresses scanned: ISA address retrieved from Super I/O registers - Datasheet: Available from Nuvoton upon request - * Nuvoton NCT5577D/NCT6776D/NCT6776F - Prefix: 'nct6776' - Addresses scanned: ISA address retrieved from Super I/O registers - Datasheet: Available from Nuvoton upon request - * Nuvoton NCT5532D/NCT6779D - Prefix: 'nct6779' - Addresses scanned: ISA address retrieved from Super I/O registers - Datasheet: Available from Nuvoton upon request - -Authors: - Guenter Roeck - -Description ------------ - -This driver implements support for the Nuvoton NCT6775F, NCT6776F, and NCT6779D -and compatible super I/O chips. - -The chips support up to 25 temperature monitoring sources. Up to 6 of those are -direct temperature sensor inputs, the others are special sources such as PECI, -PCH, and SMBUS. Depending on the chip type, 2 to 6 of the temperature sources -can be monitored and compared against minimum, maximum, and critical -temperatures. The driver reports up to 10 of the temperatures to the user. -There are 4 to 5 fan rotation speed sensors, 8 to 15 analog voltage sensors, -one VID, alarms with beep warnings (control unimplemented), and some automatic -fan regulation strategies (plus manual fan control mode). - -The temperature sensor sources on all chips are configurable. The configured -source for each of the temperature sensors is provided in tempX_label. - -Temperatures are measured in degrees Celsius and measurement resolution is -either 1 degC or 0.5 degC, depending on the temperature source and -configuration. An alarm is triggered when the temperature gets higher than -the high limit; it stays on until the temperature falls below the hysteresis -value. Alarms are only supported for temp1 to temp6, depending on the chip type. - -Fan rotation speeds are reported in RPM (rotations per minute). An alarm is -triggered if the rotation speed has dropped below a programmable limit. On -NCT6775F, fan readings can be divided by a programmable divider (1, 2, 4, 8, -16, 32, 64 or 128) to give the readings more range or accuracy; the other chips -do not have a fan speed divider. The driver sets the most suitable fan divisor -itself; specifically, it increases the divider value each time a fan speed -reading returns an invalid value, and it reduces it if the fan speed reading -is lower than optimal. Some fans might not be present because they share pins -with other functions. - -Voltage sensors (also known as IN sensors) report their values in millivolts. -An alarm is triggered if the voltage has crossed a programmable minimum -or maximum limit. - -The driver supports automatic fan control mode known as Thermal Cruise. -In this mode, the chip attempts to keep the measured temperature in a -predefined temperature range. If the temperature goes out of range, fan -is driven slower/faster to reach the predefined range again. - -The mode works for fan1-fan5. - -sysfs attributes ----------------- - -pwm[1-5] - this file stores PWM duty cycle or DC value (fan speed) in range: - 0 (lowest speed) to 255 (full) - -pwm[1-5]_enable - this file controls mode of fan/temperature control: - * 0 Fan control disabled (fans set to maximum speed) - * 1 Manual mode, write to pwm[0-5] any value 0-255 - * 2 "Thermal Cruise" mode - * 3 "Fan Speed Cruise" mode - * 4 "Smart Fan III" mode (NCT6775F only) - * 5 "Smart Fan IV" mode - -pwm[1-5]_mode - controls if output is PWM or DC level - * 0 DC output - * 1 PWM output - -Common fan control attributes ------------------------------ - -pwm[1-5]_temp_sel Temperature source. Value is temperature sensor index. - For example, select '1' for temp1_input. -pwm[1-5]_weight_temp_sel - Secondary temperature source. Value is temperature - sensor index. For example, select '1' for temp1_input. - Set to 0 to disable secondary temperature control. - -If secondary temperature functionality is enabled, it is controlled with the -following attributes. - -pwm[1-5]_weight_duty_step - Duty step size. -pwm[1-5]_weight_temp_step - Temperature step size. With each step over - temp_step_base, the value of weight_duty_step is added - to the current pwm value. -pwm[1-5]_weight_temp_step_base - Temperature at which secondary temperature control kicks - in. -pwm[1-5]_weight_temp_step_tol - Temperature step tolerance. - -Thermal Cruise mode (2) ------------------------ - -If the temperature is in the range defined by: - -pwm[1-5]_target_temp Target temperature, unit millidegree Celsius - (range 0 - 127000) -pwm[1-5]_temp_tolerance - Target temperature tolerance, unit millidegree Celsius - -there are no changes to fan speed. Once the temperature leaves the interval, fan -speed increases (if temperature is higher that desired) or decreases (if -temperature is lower than desired), using the following limits and time -intervals. - -pwm[1-5]_start fan pwm start value (range 1 - 255), to start fan - when the temperature is above defined range. -pwm[1-5]_floor lowest fan pwm (range 0 - 255) if temperature is below - the defined range. If set to 0, the fan is expected to - stop if the temperature is below the defined range. -pwm[1-5]_step_up_time milliseconds before fan speed is increased -pwm[1-5]_step_down_time milliseconds before fan speed is decreased -pwm[1-5]_stop_time how many milliseconds must elapse to switch - corresponding fan off (when the temperature was below - defined range). - -Speed Cruise mode (3) ---------------------- - -This modes tries to keep the fan speed constant. - -fan[1-5]_target Target fan speed -fan[1-5]_tolerance - Target speed tolerance - - -Untested; use at your own risk. - -Smart Fan IV mode (5) ---------------------- - -This mode offers multiple slopes to control the fan speed. The slopes can be -controlled by setting the pwm and temperature attributes. When the temperature -rises, the chip will calculate the DC/PWM output based on the current slope. -There are up to seven data points depending on the chip type. Subsequent data -points should be set to higher temperatures and higher pwm values to achieve -higher fan speeds with increasing temperature. The last data point reflects -critical temperature mode, in which the fans should run at full speed. - -pwm[1-5]_auto_point[1-7]_pwm - pwm value to be set if temperature reaches matching - temperature range. -pwm[1-5]_auto_point[1-7]_temp - Temperature over which the matching pwm is enabled. -pwm[1-5]_temp_tolerance - Temperature tolerance, unit millidegree Celsius -pwm[1-5]_crit_temp_tolerance - Temperature tolerance for critical temperature, - unit millidegree Celsius - -pwm[1-5]_step_up_time milliseconds before fan speed is increased -pwm[1-5]_step_down_time milliseconds before fan speed is decreased - -Usage Notes ------------ - -On various ASUS boards with NCT6776F, it appears that CPUTIN is not really -connected to anything and floats, or that it is connected to some non-standard -temperature measurement device. As a result, the temperature reported on CPUTIN -will not reflect a usable value. It often reports unreasonably high -temperatures, and in some cases the reported temperature declines if the actual -temperature increases (similar to the raw PECI temperature value - see PECI -specification for details). CPUTIN should therefore be be ignored on ASUS -boards. The CPU temperature on ASUS boards is reported from PECI 0. diff --git a/trunk/Documentation/hwmon/pmbus b/trunk/Documentation/hwmon/pmbus index cf756ed48ff9..3d3a0f97f966 100644 --- a/trunk/Documentation/hwmon/pmbus +++ b/trunk/Documentation/hwmon/pmbus @@ -34,7 +34,7 @@ Supported chips: Addresses scanned: - Datasheet: n.a. -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/sht15 b/trunk/Documentation/hwmon/sht15 index 778987d1856f..02850bdfac18 100644 --- a/trunk/Documentation/hwmon/sht15 +++ b/trunk/Documentation/hwmon/sht15 @@ -40,7 +40,7 @@ bits for humidity, or 12 bits for temperature and 8 bits for humidity. The humidity calibration coefficients are programmed into an OTP memory on the chip. These coefficients are used to internally calibrate the signals from the sensors. Disabling the reload of those coefficients allows saving 10ms for each -measurement and decrease power consumption, while losing on precision. +measurement and decrease power consumption, while loosing on precision. Some options may be set directly in the sht15_platform_data structure or via sysfs attributes. diff --git a/trunk/Documentation/hwmon/smm665 b/trunk/Documentation/hwmon/smm665 index a341eeedab75..59e316140542 100644 --- a/trunk/Documentation/hwmon/smm665 +++ b/trunk/Documentation/hwmon/smm665 @@ -29,7 +29,7 @@ Supported chips: http://www.summitmicro.com/prod_select/summary/SMM766/SMM766_2086.pdf http://www.summitmicro.com/prod_select/summary/SMM766B/SMM766B_2122.pdf -Author: Guenter Roeck +Author: Guenter Roeck Module Parameters diff --git a/trunk/Documentation/hwmon/tmp401 b/trunk/Documentation/hwmon/tmp401 index f91e3fa7e5ec..9fc447249212 100644 --- a/trunk/Documentation/hwmon/tmp401 +++ b/trunk/Documentation/hwmon/tmp401 @@ -8,16 +8,8 @@ Supported chips: Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp401.html * Texas Instruments TMP411 Prefix: 'tmp411' - Addresses scanned: I2C 0x4c, 0x4d, 0x4e + Addresses scanned: I2C 0x4c Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp411.html - * Texas Instruments TMP431 - Prefix: 'tmp431' - Addresses scanned: I2C 0x4c, 0x4d - Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp431.html - * Texas Instruments TMP432 - Prefix: 'tmp432' - Addresses scanned: I2C 0x4c, 0x4d - Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp432.html Authors: Hans de Goede @@ -26,19 +18,19 @@ Authors: Description ----------- -This driver implements support for Texas Instruments TMP401, TMP411, -TMP431, and TMP432 chips. These chips implement one or two remote and -one local temperature sensors. Temperature is measured in degrees +This driver implements support for Texas Instruments TMP401 and +TMP411 chips. These chips implements one remote and one local +temperature sensor. Temperature is measured in degrees Celsius. Resolution of the remote sensor is 0.0625 degree. Local sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not supported by the driver so far, so using the default resolution of 0.5 degree). The driver provides the common sysfs-interface for temperatures (see -Documentation/hwmon/sysfs-interface under Temperatures). +/Documentation/hwmon/sysfs-interface under Temperatures). -The TMP411 and TMP431 chips are compatible with TMP401. TMP411 provides -some additional features. +The TMP411 chip is compatible with TMP401. It provides some additional +features. * Minimum and Maximum temperature measured since power-on, chip-reset @@ -48,6 +40,3 @@ some additional features. Exported via sysfs attribute temp_reset_history. Writing 1 to this file triggers a reset. - -TMP432 is compatible with TMP401 and TMP431. It supports two external -temperature sensors. diff --git a/trunk/Documentation/hwmon/ucd9000 b/trunk/Documentation/hwmon/ucd9000 index 805e33edb978..0df5f276505b 100644 --- a/trunk/Documentation/hwmon/ucd9000 +++ b/trunk/Documentation/hwmon/ucd9000 @@ -11,7 +11,7 @@ Supported chips: http://focus.ti.com/lit/ds/symlink/ucd9090.pdf http://focus.ti.com/lit/ds/symlink/ucd90910.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/ucd9200 b/trunk/Documentation/hwmon/ucd9200 index 1e8060e631bd..fd7d07b1908a 100644 --- a/trunk/Documentation/hwmon/ucd9200 +++ b/trunk/Documentation/hwmon/ucd9200 @@ -15,7 +15,7 @@ Supported chips: http://focus.ti.com/lit/ds/symlink/ucd9246.pdf http://focus.ti.com/lit/ds/symlink/ucd9248.pdf -Author: Guenter Roeck +Author: Guenter Roeck Description diff --git a/trunk/Documentation/hwmon/zl6100 b/trunk/Documentation/hwmon/zl6100 index 33908a4d68ff..3d924b6b59e9 100644 --- a/trunk/Documentation/hwmon/zl6100 +++ b/trunk/Documentation/hwmon/zl6100 @@ -54,7 +54,7 @@ http://archive.ericsson.net/service/internet/picov/get?DocNo=28701-EN/LZT146401 http://archive.ericsson.net/service/internet/picov/get?DocNo=28701-EN/LZT146256 -Author: Guenter Roeck +Author: Guenter Roeck Description @@ -125,7 +125,7 @@ in2_label "vmon" in2_input Measured voltage on VMON (ZL2004) or VDRV (ZL9101M, ZL9117M) pin. Reported voltage is 16x the voltage on the pin (adjusted internally by the chip). -in2_lcrit Critical minimum VMON/VDRV Voltage. +in2_lcrit Critical minumum VMON/VDRV Voltage. in2_crit Critical maximum VMON/VDRV voltage. in2_lcrit_alarm VMON/VDRV voltage critical low alarm. in2_crit_alarm VMON/VDRV voltage critical high alarm. diff --git a/trunk/Documentation/i2c/busses/i2c-diolan-u2c b/trunk/Documentation/i2c/busses/i2c-diolan-u2c index 0d6018c316c7..30fe4bb9a069 100644 --- a/trunk/Documentation/i2c/busses/i2c-diolan-u2c +++ b/trunk/Documentation/i2c/busses/i2c-diolan-u2c @@ -5,7 +5,7 @@ Supported adapters: Documentation: http://www.diolan.com/i2c/u2c12.html -Author: Guenter Roeck +Author: Guenter Roeck Description ----------- diff --git a/trunk/Documentation/ia64/err_inject.txt b/trunk/Documentation/ia64/err_inject.txt index 9f651c181429..223e4f0582d0 100644 --- a/trunk/Documentation/ia64/err_inject.txt +++ b/trunk/Documentation/ia64/err_inject.txt @@ -882,7 +882,7 @@ int err_inj() cpu=parameters[i].cpu; k = cpu%64; j = cpu/64; - mask[j] = 1UL << k; + mask[j]=1< @@ -805,12 +788,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. edd= [EDD] Format: {"off" | "on" | "skip[mbr]"} - efi_no_storage_paranoia [EFI; X86] - Using this parameter you can use more than 50% of - your efi variable storage. Use this parameter only if - you are really sure that your UEFI does sane gc and - fulfills the spec otherwise your board may brick. - eisa_irq_edge= [PARISC,HW] See header of drivers/parisc/eisa.c. diff --git a/trunk/Documentation/misc-devices/mei/mei-client-bus.txt b/trunk/Documentation/misc-devices/mei/mei-client-bus.txt deleted file mode 100644 index f83910a8ce76..000000000000 --- a/trunk/Documentation/misc-devices/mei/mei-client-bus.txt +++ /dev/null @@ -1,138 +0,0 @@ -Intel(R) Management Engine (ME) Client bus API -=============================================== - - -Rationale -========= -MEI misc character device is useful for dedicated applications to send and receive -data to the many FW appliance found in Intel's ME from the user space. -However for some of the ME functionalities it make sense to leverage existing software -stack and expose them through existing kernel subsystems. - -In order to plug seamlessly into the kernel device driver model we add kernel virtual -bus abstraction on top of the MEI driver. This allows implementing linux kernel drivers -for the various MEI features as a stand alone entities found in their respective subsystem. -Existing device drivers can even potentially be re-used by adding an MEI CL bus layer to -the existing code. - - -MEI CL bus API -=========== -A driver implementation for an MEI Client is very similar to existing bus -based device drivers. The driver registers itself as an MEI CL bus driver through -the mei_cl_driver structure: - -struct mei_cl_driver { - struct device_driver driver; - const char *name; - - const struct mei_cl_device_id *id_table; - - int (*probe)(struct mei_cl_device *dev, const struct mei_cl_id *id); - int (*remove)(struct mei_cl_device *dev); -}; - -struct mei_cl_id { - char name[MEI_NAME_SIZE]; - kernel_ulong_t driver_info; -}; - -The mei_cl_id structure allows the driver to bind itself against a device name. - -To actually register a driver on the ME Client bus one must call the mei_cl_add_driver() -API. This is typically called at module init time. - -Once registered on the ME Client bus, a driver will typically try to do some I/O on -this bus and this should be done through the mei_cl_send() and mei_cl_recv() -routines. The latter is synchronous (blocks and sleeps until data shows up). -In order for drivers to be notified of pending events waiting for them (e.g. -an Rx event) they can register an event handler through the -mei_cl_register_event_cb() routine. Currently only the MEI_EVENT_RX event -will trigger an event handler call and the driver implementation is supposed -to call mei_recv() from the event handler in order to fetch the pending -received buffers. - - -Example -======= -As a theoretical example let's pretend the ME comes with a "contact" NFC IP. -The driver init and exit routines for this device would look like: - -#define CONTACT_DRIVER_NAME "contact" - -static struct mei_cl_device_id contact_mei_cl_tbl[] = { - { CONTACT_DRIVER_NAME, }, - - /* required last entry */ - { } -}; -MODULE_DEVICE_TABLE(mei_cl, contact_mei_cl_tbl); - -static struct mei_cl_driver contact_driver = { - .id_table = contact_mei_tbl, - .name = CONTACT_DRIVER_NAME, - - .probe = contact_probe, - .remove = contact_remove, -}; - -static int contact_init(void) -{ - int r; - - r = mei_cl_driver_register(&contact_driver); - if (r) { - pr_err(CONTACT_DRIVER_NAME ": driver registration failed\n"); - return r; - } - - return 0; -} - -static void __exit contact_exit(void) -{ - mei_cl_driver_unregister(&contact_driver); -} - -module_init(contact_init); -module_exit(contact_exit); - -And the driver's simplified probe routine would look like that: - -int contact_probe(struct mei_cl_device *dev, struct mei_cl_device_id *id) -{ - struct contact_driver *contact; - - [...] - mei_cl_enable_device(dev); - - mei_cl_register_event_cb(dev, contact_event_cb, contact); - - return 0; - } - -In the probe routine the driver first enable the MEI device and then registers -an ME bus event handler which is as close as it can get to registering a -threaded IRQ handler. -The handler implementation will typically call some I/O routine depending on -the pending events: - -#define MAX_NFC_PAYLOAD 128 - -static void contact_event_cb(struct mei_cl_device *dev, u32 events, - void *context) -{ - struct contact_driver *contact = context; - - if (events & BIT(MEI_EVENT_RX)) { - u8 payload[MAX_NFC_PAYLOAD]; - int payload_size; - - payload_size = mei_recv(dev, payload, MAX_NFC_PAYLOAD); - if (payload_size <= 0) - return; - - /* Hook to the NFC subsystem */ - nfc_hci_recv_frame(contact->hdev, payload, payload_size); - } -} diff --git a/trunk/Documentation/networking/ipvs-sysctl.txt b/trunk/Documentation/networking/ipvs-sysctl.txt index 9573d0c48c6e..f2a2488f1bf3 100644 --- a/trunk/Documentation/networking/ipvs-sysctl.txt +++ b/trunk/Documentation/networking/ipvs-sysctl.txt @@ -15,13 +15,6 @@ amemthresh - INTEGER enabled and the variable is automatically set to 2, otherwise the strategy is disabled and the variable is set to 1. -backup_only - BOOLEAN - 0 - disabled (default) - not 0 - enabled - - If set, disable the director function while the server is - in backup mode to avoid packet loops for DR/TUN methods. - conntrack - BOOLEAN 0 - disabled (default) not 0 - enabled diff --git a/trunk/Documentation/networking/tuntap.txt b/trunk/Documentation/networking/tuntap.txt index 949d5dcdd9a3..c0aab985bad9 100644 --- a/trunk/Documentation/networking/tuntap.txt +++ b/trunk/Documentation/networking/tuntap.txt @@ -105,83 +105,6 @@ Copyright (C) 1999-2000 Maxim Krasnyansky Proto [2 bytes] Raw protocol(IP, IPv6, etc) frame. - 3.3 Multiqueue tuntap interface: - - From version 3.8, Linux supports multiqueue tuntap which can uses multiple - file descriptors (queues) to parallelize packets sending or receiving. The - device allocation is the same as before, and if user wants to create multiple - queues, TUNSETIFF with the same device name must be called many times with - IFF_MULTI_QUEUE flag. - - char *dev should be the name of the device, queues is the number of queues to - be created, fds is used to store and return the file descriptors (queues) - created to the caller. Each file descriptor were served as the interface of a - queue which could be accessed by userspace. - - #include - #include - - int tun_alloc_mq(char *dev, int queues, int *fds) - { - struct ifreq ifr; - int fd, err, i; - - if (!dev) - return -1; - - memset(&ifr, 0, sizeof(ifr)); - /* Flags: IFF_TUN - TUN device (no Ethernet headers) - * IFF_TAP - TAP device - * - * IFF_NO_PI - Do not provide packet information - * IFF_MULTI_QUEUE - Create a queue of multiqueue device - */ - ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE; - strcpy(ifr.ifr_name, dev); - - for (i = 0; i < queues; i++) { - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) - goto err; - err = ioctl(fd, TUNSETIFF, (void *)&ifr); - if (err) { - close(fd); - goto err; - } - fds[i] = fd; - } - - return 0; - err: - for (--i; i >= 0; i--) - close(fds[i]); - return err; - } - - A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When - calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when - calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were - enabled by default after it was created through TUNSETIFF. - - fd is the file descriptor (queue) that we want to enable or disable, when - enable is true we enable it, otherwise we disable it - - #include - #include - - int tun_set_queue(int fd, int enable) - { - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - - if (enable) - ifr.ifr_flags = IFF_ATTACH_QUEUE; - else - ifr.ifr_flags = IFF_DETACH_QUEUE; - - return ioctl(fd, TUNSETQUEUE, (void *)&ifr); - } - Universal TUN/TAP device driver Frequently Asked Question. 1. What platforms are supported by TUN/TAP driver ? diff --git a/trunk/Documentation/pinctrl.txt b/trunk/Documentation/pinctrl.txt index 447fd4cd54ec..a2b57e0a1db0 100644 --- a/trunk/Documentation/pinctrl.txt +++ b/trunk/Documentation/pinctrl.txt @@ -736,13 +736,6 @@ All the above functions are mandatory to implement for a pinmux driver. Pin control interaction with the GPIO subsystem =============================================== -Note that the following implies that the use case is to use a certain pin -from the Linux kernel using the API in with gpio_request() -and similar functions. There are cases where you may be using something -that your datasheet calls "GPIO mode" but actually is just an electrical -configuration for a certain device. See the section below named -"GPIO mode pitfalls" for more details on this scenario. - The public pinmux API contains two functions named pinctrl_request_gpio() and pinctrl_free_gpio(). These two functions shall *ONLY* be called from gpiolib-based drivers as part of their gpio_request() and @@ -781,111 +774,6 @@ obtain the function "gpioN" where "N" is the global GPIO pin number if no special GPIO-handler is registered. -GPIO mode pitfalls -================== - -Sometime the developer may be confused by a datasheet talking about a pin -being possible to set into "GPIO mode". It appears that what hardware -engineers mean with "GPIO mode" is not necessarily the use case that is -implied in the kernel interface : a pin that you grab from -kernel code and then either listen for input or drive high/low to -assert/deassert some external line. - -Rather hardware engineers think that "GPIO mode" means that you can -software-control a few electrical properties of the pin that you would -not be able to control if the pin was in some other mode, such as muxed in -for a device. - -Example: a pin is usually muxed in to be used as a UART TX line. But during -system sleep, we need to put this pin into "GPIO mode" and ground it. - -If you make a 1-to-1 map to the GPIO subsystem for this pin, you may start -to think that you need to come up with something real complex, that the -pin shall be used for UART TX and GPIO at the same time, that you will grab -a pin control handle and set it to a certain state to enable UART TX to be -muxed in, then twist it over to GPIO mode and use gpio_direction_output() -to drive it low during sleep, then mux it over to UART TX again when you -wake up and maybe even gpio_request/gpio_free as part of this cycle. This -all gets very complicated. - -The solution is to not think that what the datasheet calls "GPIO mode" -has to be handled by the interface. Instead view this as -a certain pin config setting. Look in e.g. -and you find this in the documentation: - - PIN_CONFIG_OUTPUT: this will configure the pin in output, use argument - 1 to indicate high level, argument 0 to indicate low level. - -So it is perfectly possible to push a pin into "GPIO mode" and drive the -line low as part of the usual pin control map. So for example your UART -driver may look like this: - -#include - -struct pinctrl *pinctrl; -struct pinctrl_state *pins_default; -struct pinctrl_state *pins_sleep; - -pins_default = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_DEFAULT); -pins_sleep = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_SLEEP); - -/* Normal mode */ -retval = pinctrl_select_state(pinctrl, pins_default); -/* Sleep mode */ -retval = pinctrl_select_state(pinctrl, pins_sleep); - -And your machine configuration may look like this: --------------------------------------------------- - -static unsigned long uart_default_mode[] = { - PIN_CONF_PACKED(PIN_CONFIG_DRIVE_PUSH_PULL, 0), -}; - -static unsigned long uart_sleep_mode[] = { - PIN_CONF_PACKED(PIN_CONFIG_OUTPUT, 0), -}; - -static struct pinctrl_map __initdata pinmap[] = { - PIN_MAP_MUX_GROUP("uart", PINCTRL_STATE_DEFAULT, "pinctrl-foo", - "u0_group", "u0"), - PIN_MAP_CONFIGS_PIN("uart", PINCTRL_STATE_DEFAULT, "pinctrl-foo", - "UART_TX_PIN", uart_default_mode), - PIN_MAP_MUX_GROUP("uart", PINCTRL_STATE_SLEEP, "pinctrl-foo", - "u0_group", "gpio-mode"), - PIN_MAP_CONFIGS_PIN("uart", PINCTRL_STATE_SLEEP, "pinctrl-foo", - "UART_TX_PIN", uart_sleep_mode), -}; - -foo_init(void) { - pinctrl_register_mappings(pinmap, ARRAY_SIZE(pinmap)); -} - -Here the pins we want to control are in the "u0_group" and there is some -function called "u0" that can be enabled on this group of pins, and then -everything is UART business as usual. But there is also some function -named "gpio-mode" that can be mapped onto the same pins to move them into -GPIO mode. - -This will give the desired effect without any bogus interaction with the -GPIO subsystem. It is just an electrical configuration used by that device -when going to sleep, it might imply that the pin is set into something the -datasheet calls "GPIO mode" but that is not the point: it is still used -by that UART device to control the pins that pertain to that very UART -driver, putting them into modes needed by the UART. GPIO in the Linux -kernel sense are just some 1-bit line, and is a different use case. - -How the registers are poked to attain the push/pull and output low -configuration and the muxing of the "u0" or "gpio-mode" group onto these -pins is a question for the driver. - -Some datasheets will be more helpful and refer to the "GPIO mode" as -"low power mode" rather than anything to do with GPIO. This often means -the same thing electrically speaking, but in this latter case the -software engineers will usually quickly identify that this is some -specific muxing/configuration rather than anything related to the GPIO -API. - - Board/machine configuration ================================== diff --git a/trunk/Documentation/power/opp.txt b/trunk/Documentation/power/opp.txt index 425c51d56aef..3035d00757ad 100644 --- a/trunk/Documentation/power/opp.txt +++ b/trunk/Documentation/power/opp.txt @@ -1,5 +1,6 @@ -Operating Performance Points (OPP) Library -========================================== +*=============* +* OPP Library * +*=============* (C) 2009-2010 Nishanth Menon , Texas Instruments Incorporated @@ -15,31 +16,15 @@ Contents 1. Introduction =============== -1.1 What is an Operating Performance Point (OPP)? - Complex SoCs of today consists of a multiple sub-modules working in conjunction. In an operational system executing varied use cases, not all modules in the SoC need to function at their highest performing frequency all the time. To facilitate this, sub-modules in a SoC are grouped into domains, allowing some -domains to run at lower voltage and frequency while other domains run at -voltage/frequency pairs that are higher. - -The set of discrete tuples consisting of frequency and voltage pairs that +domains to run at lower voltage and frequency while other domains are loaded +more. The set of discrete tuples consisting of frequency and voltage pairs that the device will support per domain are called Operating Performance Points or OPPs. -As an example: -Let us consider an MPU device which supports the following: -{300MHz at minimum voltage of 1V}, {800MHz at minimum voltage of 1.2V}, -{1GHz at minimum voltage of 1.3V} - -We can represent these as three OPPs as the following {Hz, uV} tuples: -{300000000, 1000000} -{800000000, 1200000} -{1000000000, 1300000} - -1.2 Operating Performance Points Library - OPP library provides a set of helper functions to organize and query the OPP information. The library is located in drivers/base/power/opp.c and the header is located in include/linux/opp.h. OPP library can be enabled by enabling diff --git a/trunk/Documentation/printk-formats.txt b/trunk/Documentation/printk-formats.txt index 6e953564de03..e8a6aa473bab 100644 --- a/trunk/Documentation/printk-formats.txt +++ b/trunk/Documentation/printk-formats.txt @@ -170,5 +170,5 @@ Reminder: sizeof() result is of type size_t. Thank you for your cooperation and attention. -By Randy Dunlap and +By Randy Dunlap and Andrew Murray diff --git a/trunk/Documentation/s390/s390dbf.txt b/trunk/Documentation/s390/s390dbf.txt index fcaf0b4efba2..ae66f9b90a25 100644 --- a/trunk/Documentation/s390/s390dbf.txt +++ b/trunk/Documentation/s390/s390dbf.txt @@ -143,8 +143,7 @@ Parameter: id: handle for debug log Return Value: none -Description: frees memory for a debug log and removes all registered debug - views. +Description: frees memory for a debug log Must not be called within an interrupt handler --------------------------------------------------------------------------- diff --git a/trunk/Documentation/scsi/LICENSE.qla2xxx b/trunk/Documentation/scsi/LICENSE.qla2xxx index 5020b7b5a244..27a91cf43d6d 100644 --- a/trunk/Documentation/scsi/LICENSE.qla2xxx +++ b/trunk/Documentation/scsi/LICENSE.qla2xxx @@ -1,4 +1,4 @@ -Copyright (c) 2003-2013 QLogic Corporation +Copyright (c) 2003-2012 QLogic Corporation QLogic Linux FC-FCoE Driver This program includes a device driver for Linux 3.x. diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 95731a08f257..ce6581c8ca26 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -890,8 +890,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) power_save - Automatic power-saving timeout (in second, 0 = disable) - power_save_controller - Reset HD-audio controller in power-saving mode - (default = on) + power_save_controller - Support runtime D3 of HD-audio controller + (-1 = on for supported chip (default), false = off, + true = force to on even for unsupported hardware) align_buffer_size - Force rounding of buffer/period sizes to multiples of 128 bytes. This is more efficient in terms of memory access but isn't required by the HDA spec and prevents @@ -911,7 +912,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. models depending on the codec chip. The list of available models is found in HD-Audio-Models.txt - The model name "generic" is treated as a special case. When this + The model name "genric" is treated as a special case. When this model is given, the driver uses the generic codec parser without "codec-patch". It's sometimes good for testing and debugging. diff --git a/trunk/Documentation/sound/alsa/seq_oss.html b/trunk/Documentation/sound/alsa/seq_oss.html index 9663b45f6fde..d9776cf60c07 100644 --- a/trunk/Documentation/sound/alsa/seq_oss.html +++ b/trunk/Documentation/sound/alsa/seq_oss.html @@ -285,7 +285,7 @@

7.2.4 Close Callback

The close callback is called when this device is closed by the -application. If any private data was allocated in open callback, it must +applicaion. If any private data was allocated in open callback, it must be released in the close callback. The deletion of ALSA port should be done here, too. This callback must not be NULL.

diff --git a/trunk/Documentation/trace/ftrace.txt b/trunk/Documentation/trace/ftrace.txt index a372304aef10..53d6a3c51d87 100644 --- a/trunk/Documentation/trace/ftrace.txt +++ b/trunk/Documentation/trace/ftrace.txt @@ -1873,7 +1873,7 @@ feature: status\input | 0 | 1 | else | --------------+------------+------------+------------+ - not allocated |(do nothing)| alloc+swap |(do nothing)| + not allocated |(do nothing)| alloc+swap | EINVAL | --------------+------------+------------+------------+ allocated | free | swap | clear | --------------+------------+------------+------------+ diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 8ba3b484d826..e95b1e944eb7 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -114,6 +114,12 @@ Maintainers List (try to look for most precise areas first) ----------------------------------- +3C505 NETWORK DRIVER +M: Philip Blundell +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/ethernet/i825xx/3c505* + 3C59X NETWORK DRIVER M: Steffen Klassert L: netdev@vger.kernel.org @@ -1031,7 +1037,6 @@ F: drivers/mmc/host/msm_sdcc.h F: drivers/tty/serial/msm_serial.h F: drivers/tty/serial/msm_serial.c F: drivers/*/pm8???-* -F: drivers/ssbi/ F: include/linux/mfd/pm8xxx/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/davidb/linux-msm.git S: Maintained @@ -1339,6 +1344,12 @@ S: Maintained F: drivers/platform/x86/asus*.c F: drivers/platform/x86/eeepc*.c +ASUS ASB100 HARDWARE MONITOR DRIVER +M: "Mark M. Hoffman" +L: lm-sensors@lm-sensors.org +S: Maintained +F: drivers/hwmon/asb100.c + ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API M: Dan Williams W: http://sourceforge.net/projects/xscaleiop @@ -1462,12 +1473,6 @@ F: drivers/dma/at_hdmac.c F: drivers/dma/at_hdmac_regs.h F: include/linux/platform_data/dma-atmel.h -ATMEL I2C DRIVER -M: Ludovic Desroches -L: linux-i2c@vger.kernel.org -S: Supported -F: drivers/i2c/busses/i2c-at91.c - ATMEL ISI DRIVER M: Josh Wu L: linux-media@vger.kernel.org @@ -2356,6 +2361,12 @@ W: http://www.arm.linux.org.uk/ S: Maintained F: drivers/video/cyber2000fb.* +CYCLADES 2X SYNC CARD DRIVER +M: Arnaldo Carvalho de Melo +W: http://oops.ghostprotocols.net:81/blog +S: Maintained +F: drivers/net/wan/cycx* + CYCLADES ASYNC MUX DRIVER W: http://www.cyclades.com/ S: Orphan @@ -2630,7 +2641,7 @@ F: include/uapi/drm/ INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) M: Daniel Vetter -L: intel-gfx@lists.freedesktop.org +L: intel-gfx@lists.freedesktop.org (subscribers-only) L: dri-devel@lists.freedesktop.org T: git git://people.freedesktop.org/~danvet/drm-intel S: Supported @@ -3056,6 +3067,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git F: drivers/video/s1d13xxxfb.c F: include/video/s1d13xxxfb.h +ETHEREXPRESS-16 NETWORK DRIVER +M: Philip Blundell +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/ethernet/i825xx/eexpress.* + ETHERNET BRIDGE M: Stephen Hemminger L: bridge@lists.linux-foundation.org @@ -3243,12 +3260,6 @@ F: Documentation/firmware_class/ F: drivers/base/firmware*.c F: include/linux/firmware.h -FLASHSYSTEM DRIVER (IBM FlashSystem 70/80 PCI SSD Flash Card) -M: Joshua Morris -M: Philip Kelleher -S: Maintained -F: drivers/block/rsxx/ - FLOPPY DRIVER M: Jiri Kosina T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git @@ -3858,7 +3869,7 @@ F: drivers/i2c/busses/i2c-ismt.c F: Documentation/i2c/busses/i2c-ismt I2C/SMBUS STUB DRIVER -M: Jean Delvare +M: "Mark M. Hoffman" L: linux-i2c@vger.kernel.org S: Maintained F: drivers/i2c/i2c-stub.c @@ -4012,22 +4023,6 @@ M: Stanislaw Gruszka S: Maintained F: drivers/usb/atm/ueagle-atm.c -INA209 HARDWARE MONITOR DRIVER -M: Guenter Roeck -L: lm-sensors@lm-sensors.org -S: Maintained -F: Documentation/hwmon/ina209 -F: Documentation/devicetree/bindings/i2c/ina209.txt -F: drivers/hwmon/ina209.c - -INA2XX HARDWARE MONITOR DRIVER -M: Guenter Roeck -L: lm-sensors@lm-sensors.org -S: Maintained -F: Documentation/hwmon/ina2xx -F: drivers/hwmon/ina2xx.c -F: include/linux/platform_data/ina2xx.h - INDUSTRY PACK SUBSYSTEM (IPACK) M: Samuel Iglesias Gonsalvez M: Jens Taprogge @@ -4942,12 +4937,6 @@ W: logfs.org S: Maintained F: fs/logfs/ -LPC32XX MACHINE SUPPORT -M: Roland Stigge -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained -F: arch/arm/mach-lpc32xx/ - LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) M: Nagalakshmi Nandigama M: Sreekanth Reddy @@ -5072,8 +5061,9 @@ S: Maintained F: drivers/net/ethernet/marvell/sk* MARVELL LIBERTAS WIRELESS DRIVER +M: Dan Williams L: libertas-dev@lists.infradead.org -S: Orphan +S: Maintained F: drivers/net/wireless/libertas/ MARVELL MV643XX ETHERNET DRIVER @@ -5126,15 +5116,6 @@ S: Maintained F: Documentation/hwmon/max6650 F: drivers/hwmon/max6650.c -MAX6697 HARDWARE MONITOR DRIVER -M: Guenter Roeck -L: lm-sensors@lm-sensors.org -S: Maintained -F: Documentation/hwmon/max6697 -F: Documentation/devicetree/bindings/i2c/max6697.txt -F: drivers/hwmon/max6697.c -F: include/linux/platform_data/max6697.h - MAXIRADIO FM RADIO RECEIVER DRIVER M: Hans Verkuil L: linux-media@vger.kernel.org @@ -5413,13 +5394,6 @@ L: linux-scsi@vger.kernel.org S: Maintained F: drivers/scsi/NCR_D700.* -NCT6775 HARDWARE MONITOR DRIVER -M: Guenter Roeck -L: lm-sensors@lm-sensors.org -S: Maintained -F: Documentation/hwmon/nct6775 -F: drivers/hwmon/nct6775.c - NETEFFECT IWARP RNIC DRIVER (IW_NES) M: Faisal Latif L: linux-rdma@vger.kernel.org @@ -5582,7 +5556,6 @@ F: include/uapi/linux/if_* F: include/uapi/linux/netdevice.h NETXEN (1/10) GbE SUPPORT -M: Manish Chopra M: Sony Chacko M: Rajesh Borundia L: netdev@vger.kernel.org @@ -5667,14 +5640,6 @@ S: Maintained F: drivers/video/riva/ F: drivers/video/nvidia/ -NVM EXPRESS DRIVER -M: Matthew Wilcox -L: linux-nvme@lists.infradead.org -T: git git://git.infradead.org/users/willy/linux-nvme.git -S: Supported -F: drivers/block/nvme.c -F: include/linux/nvme.h - OMAP SUPPORT M: Tony Lindgren L: linux-omap@vger.kernel.org @@ -5703,7 +5668,7 @@ S: Maintained F: arch/arm/*omap*/*clock* OMAP POWER MANAGEMENT SUPPORT -M: Kevin Hilman +M: Kevin Hilman L: linux-omap@vger.kernel.org S: Maintained F: arch/arm/*omap*/*pm* @@ -5797,7 +5762,7 @@ F: arch/arm/*omap*/usb* OMAP GPIO DRIVER M: Santosh Shilimkar -M: Kevin Hilman +M: Kevin Hilman L: linux-omap@vger.kernel.org S: Maintained F: drivers/gpio/gpio-omap.c @@ -6229,7 +6194,7 @@ F: include/linux/power_supply.h F: drivers/power/ PNP SUPPORT -M: Rafael J. Wysocki +M: Adam Belay M: Bjorn Helgaas S: Maintained F: drivers/pnp/ @@ -6465,8 +6430,6 @@ F: Documentation/networking/LICENSE.qla3xxx F: drivers/net/ethernet/qlogic/qla3xxx.* QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER -M: Rajesh Borundia -M: Shahed Shaikh M: Jitendra Kalsaria M: Sony Chacko M: linux-driver@qlogic.com @@ -6571,6 +6534,12 @@ S: Maintained F: Documentation/blockdev/ramdisk.txt F: drivers/block/brd.c +RAMSAM DRIVER (IBM RamSan 70/80 PCI SSD Flash Card) +M: Joshua Morris +M: Philip Kelleher +S: Maintained +F: drivers/block/rsxx/ + RANDOM NUMBER DRIVER M: Theodore Ts'o" S: Maintained @@ -6639,7 +6608,7 @@ S: Supported F: fs/reiserfs/ REGISTER MAP ABSTRACTION -M: Mark Brown +M: Mark Brown T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git S: Supported F: drivers/base/regmap/ @@ -6965,6 +6934,7 @@ F: drivers/scsi/st* SCTP PROTOCOL M: Vlad Yasevich +M: Sridhar Samudrala M: Neil Horman L: linux-sctp@vger.kernel.org W: http://lksctp.sourceforge.net @@ -7186,7 +7156,7 @@ F: arch/arm/mach-s3c2410/bast-irq.c TI DAVINCI MACHINE SUPPORT M: Sekhar Nori -M: Kevin Hilman +M: Kevin Hilman L: davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers) T: git git://gitorious.org/linux-davinci/linux-davinci.git Q: http://patchwork.kernel.org/project/linux-davinci/list/ @@ -7219,6 +7189,13 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/sis/sis900.* +SIS 96X I2C/SMBUS DRIVER +M: "Mark M. Hoffman" +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/busses/i2c-sis96x +F: drivers/i2c/busses/i2c-sis96x.c + SIS FRAMEBUFFER DRIVER M: Thomas Winischhofer W: http://www.winischhofer.net/linuxsisvga.shtml @@ -7296,7 +7273,7 @@ F: Documentation/hwmon/sch5627 F: drivers/hwmon/sch5627.c SMSC47B397 HARDWARE MONITOR DRIVER -M: Jean Delvare +M: "Mark M. Hoffman" L: lm-sensors@lm-sensors.org S: Maintained F: Documentation/hwmon/smsc47b397 @@ -7387,7 +7364,7 @@ F: sound/ SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) M: Liam Girdwood -M: Mark Brown +M: Mark Brown T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git L: alsa-devel@alsa-project.org (moderated for non-subscribers) W: http://alsa-project.org/main/index.php/ASoC @@ -7476,7 +7453,7 @@ F: drivers/clk/spear/ SPI SUBSYSTEM M: Grant Likely -M: Mark Brown +M: Mark Brown L: spi-devel-general@lists.sourceforge.net Q: http://patchwork.kernel.org/project/spi-devel-general/list/ T: git git://git.secretlab.ca/git/linux-2.6.git @@ -7719,10 +7696,9 @@ F: include/linux/swiotlb.h SYNOPSYS ARC ARCHITECTURE M: Vineet Gupta +L: linux-snps-arc@vger.kernel.org S: Supported F: arch/arc/ -F: Documentation/devicetree/bindings/arc/ -F: drivers/tty/serial/arc-uart.c SYSV FILESYSTEM M: Christoph Hellwig @@ -8721,7 +8697,7 @@ F: drivers/scsi/vmw_pvscsi.h VOLTAGE AND CURRENT REGULATOR FRAMEWORK M: Liam Girdwood -M: Mark Brown +M: Mark Brown W: http://opensource.wolfsonmicro.com/node/15 W: http://www.slimlogic.co.uk/?p=48 T: git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/regulator.git diff --git a/trunk/Makefile b/trunk/Makefile index 8fe69916e726..5bd9f7700eb9 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 9 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = Unicycling Gorilla # *DOCUMENTATION* @@ -513,8 +513,7 @@ ifeq ($(KBUILD_EXTMOD),) # Carefully list dependencies so we do not try to build scripts twice # in parallel PHONY += scripts -scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \ - asm-generic +scripts: scripts_basic include/config/auto.conf include/config/tristate.conf $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 1455579791ec..5a1779c93940 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -319,6 +319,13 @@ config ARCH_WANT_OLD_COMPAT_IPC select ARCH_WANT_COMPAT_IPC_PARSE_VERSION bool +config HAVE_VIRT_TO_BUS + bool + help + An architecture should select this if it implements the + deprecated interface virt_to_bus(). All new architectures + should probably not select this. + config HAVE_ARCH_SECCOMP_FILTER bool help diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 8a33ba01301f..5833aa441481 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -9,7 +9,7 @@ config ALPHA select HAVE_PERF_EVENTS select HAVE_DMA_ATTRS select HAVE_GENERIC_HARDIRQS - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select GENERIC_IRQ_PROBE select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW diff --git a/trunk/arch/alpha/Makefile b/trunk/arch/alpha/Makefile index 2cc3cc519c54..4759fe751aa1 100644 --- a/trunk/arch/alpha/Makefile +++ b/trunk/arch/alpha/Makefile @@ -12,7 +12,7 @@ NM := $(NM) -B LDFLAGS_vmlinux := -static -N #-relax CHECKFLAGS += -D__alpha__ -m64 -cflags-y := -pipe -mno-fp-regs -ffixed-8 +cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data cflags-y += $(call cc-option, -fno-jump-tables) cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4 diff --git a/trunk/arch/alpha/boot/head.S b/trunk/arch/alpha/boot/head.S index 8efb26686d47..b06812bcac83 100644 --- a/trunk/arch/alpha/boot/head.S +++ b/trunk/arch/alpha/boot/head.S @@ -4,7 +4,6 @@ * initial bootloader stuff.. */ -#include .set noreorder .globl __start diff --git a/trunk/arch/alpha/include/asm/floppy.h b/trunk/arch/alpha/include/asm/floppy.h index bae97eb19d26..46cefbd50e73 100644 --- a/trunk/arch/alpha/include/asm/floppy.h +++ b/trunk/arch/alpha/include/asm/floppy.h @@ -26,7 +26,7 @@ #define fd_disable_irq() disable_irq(FLOPPY_IRQ) #define fd_cacheflush(addr,size) /* nothing */ #define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt,\ - 0, "floppy", NULL) + IRQF_DISABLED, "floppy", NULL) #define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) #ifdef CONFIG_PCI diff --git a/trunk/arch/alpha/kernel/irq.c b/trunk/arch/alpha/kernel/irq.c index 7b2be251c30f..2872accd2215 100644 --- a/trunk/arch/alpha/kernel/irq.c +++ b/trunk/arch/alpha/kernel/irq.c @@ -117,6 +117,13 @@ handle_irq(int irq) return; } + /* + * From here we must proceed with IPL_MAX. Note that we do not + * explicitly enable interrupts afterwards - some MILO PALcode + * (namely LX164 one) seems to have severe problems with RTI + * at IPL 0. + */ + local_irq_disable(); irq_enter(); generic_handle_irq_desc(irq, desc); irq_exit(); diff --git a/trunk/arch/alpha/kernel/irq_alpha.c b/trunk/arch/alpha/kernel/irq_alpha.c index f433fc11877a..772ddfdb71a8 100644 --- a/trunk/arch/alpha/kernel/irq_alpha.c +++ b/trunk/arch/alpha/kernel/irq_alpha.c @@ -45,14 +45,6 @@ do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, struct pt_regs *regs) { struct pt_regs *old_regs; - - /* - * Disable interrupts during IRQ handling. - * Note that there is no matching local_irq_enable() due to - * severe problems with RTI at IPL0 and some MILO PALcode - * (namely LX164). - */ - local_irq_disable(); switch (type) { case 0: #ifdef CONFIG_SMP @@ -70,6 +62,7 @@ do_entInt(unsigned long type, unsigned long vector, { long cpu; + local_irq_disable(); smp_percpu_timer_interrupt(regs); cpu = smp_processor_id(); if (cpu != boot_cpuid) { @@ -229,6 +222,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr, struct irqaction timer_irqaction = { .handler = timer_interrupt, + .flags = IRQF_DISABLED, .name = "timer", }; diff --git a/trunk/arch/alpha/kernel/sys_nautilus.c b/trunk/arch/alpha/kernel/sys_nautilus.c index 1383f8601a93..4d4c046f708d 100644 --- a/trunk/arch/alpha/kernel/sys_nautilus.c +++ b/trunk/arch/alpha/kernel/sys_nautilus.c @@ -188,10 +188,6 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr) extern void free_reserved_mem(void *, void *); extern void pcibios_claim_one_bus(struct pci_bus *); -static struct resource irongate_io = { - .name = "Irongate PCI IO", - .flags = IORESOURCE_IO, -}; static struct resource irongate_mem = { .name = "Irongate PCI MEM", .flags = IORESOURCE_MEM, @@ -213,7 +209,6 @@ nautilus_init_pci(void) irongate = pci_get_bus_and_slot(0, 0); bus->self = irongate; - bus->resource[0] = &irongate_io; bus->resource[1] = &irongate_mem; pci_bus_size_bridges(bus); diff --git a/trunk/arch/alpha/kernel/sys_titan.c b/trunk/arch/alpha/kernel/sys_titan.c index a53cf03f49d5..5cf4a481b8c5 100644 --- a/trunk/arch/alpha/kernel/sys_titan.c +++ b/trunk/arch/alpha/kernel/sys_titan.c @@ -280,15 +280,15 @@ titan_late_init(void) * all reported to the kernel as machine checks, so the handler * is a nop so it can be called to count the individual events. */ - titan_request_irq(63+16, titan_intr_nop, 0, + titan_request_irq(63+16, titan_intr_nop, IRQF_DISABLED, "CChip Error", NULL); - titan_request_irq(62+16, titan_intr_nop, 0, + titan_request_irq(62+16, titan_intr_nop, IRQF_DISABLED, "PChip 0 H_Error", NULL); - titan_request_irq(61+16, titan_intr_nop, 0, + titan_request_irq(61+16, titan_intr_nop, IRQF_DISABLED, "PChip 1 H_Error", NULL); - titan_request_irq(60+16, titan_intr_nop, 0, + titan_request_irq(60+16, titan_intr_nop, IRQF_DISABLED, "PChip 0 C_Error", NULL); - titan_request_irq(59+16, titan_intr_nop, 0, + titan_request_irq(59+16, titan_intr_nop, IRQF_DISABLED, "PChip 1 C_Error", NULL); /* @@ -348,9 +348,9 @@ privateer_init_pci(void) * Hook a couple of extra err interrupts that the * common titan code won't. */ - titan_request_irq(53+16, titan_intr_nop, 0, + titan_request_irq(53+16, titan_intr_nop, IRQF_DISABLED, "NMI", NULL); - titan_request_irq(50+16, titan_intr_nop, 0, + titan_request_irq(50+16, titan_intr_nop, IRQF_DISABLED, "Temperature Warning", NULL); /* diff --git a/trunk/arch/arc/include/asm/dma-mapping.h b/trunk/arch/arc/include/asm/dma-mapping.h index 45b8e0cea176..31f77aec0823 100644 --- a/trunk/arch/arc/include/asm/dma-mapping.h +++ b/trunk/arch/arc/include/asm/dma-mapping.h @@ -126,7 +126,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int i; for_each_sg(sg, s, nents, i) - s->dma_address = dma_map_page(dev, sg_page(s), s->offset, + sg->dma_address = dma_map_page(dev, sg_page(s), s->offset, s->length, dir); return nents; diff --git a/trunk/arch/arc/include/asm/elf.h b/trunk/arch/arc/include/asm/elf.h index a26282857683..f4c8d36ebecb 100644 --- a/trunk/arch/arc/include/asm/elf.h +++ b/trunk/arch/arc/include/asm/elf.h @@ -72,4 +72,7 @@ extern int elf_check_arch(const struct elf32_hdr *); */ #define ELF_PLATFORM (NULL) +#define SET_PERSONALITY(ex) \ + set_personality(PER_LINUX | (current->personality & (~PER_MASK))) + #endif diff --git a/trunk/arch/arc/include/asm/entry.h b/trunk/arch/arc/include/asm/entry.h index eb2ae53187d9..23daa326fc9b 100644 --- a/trunk/arch/arc/include/asm/entry.h +++ b/trunk/arch/arc/include/asm/entry.h @@ -415,7 +415,7 @@ *-------------------------------------------------------------*/ .macro SAVE_ALL_EXCEPTION marker - st \marker, [sp, 8] /* orig_r8 */ + st \marker, [sp, 8] st r0, [sp, 4] /* orig_r0, needed only for sys calls */ /* Restore r9 used to code the early prologue */ diff --git a/trunk/arch/arc/include/asm/irqflags.h b/trunk/arch/arc/include/asm/irqflags.h index eac071668201..ccd84806b62f 100644 --- a/trunk/arch/arc/include/asm/irqflags.h +++ b/trunk/arch/arc/include/asm/irqflags.h @@ -39,7 +39,7 @@ static inline long arch_local_irq_save(void) " flag.nz %0 \n" : "=r"(temp), "=r"(flags) : "n"((STATUS_E1_MASK | STATUS_E2_MASK)) - : "memory", "cc"); + : "cc"); return flags; } @@ -53,8 +53,7 @@ static inline void arch_local_irq_restore(unsigned long flags) __asm__ __volatile__( " flag %0 \n" : - : "r"(flags) - : "memory"); + : "r"(flags)); } /* @@ -74,8 +73,7 @@ static inline void arch_local_irq_disable(void) " and %0, %0, %1 \n" " flag %0 \n" : "=&r"(temp) - : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK)) - : "memory"); + : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK))); } /* @@ -87,9 +85,7 @@ static inline long arch_local_save_flags(void) __asm__ __volatile__( " lr %0, [status32] \n" - : "=&r"(temp) - : - : "memory"); + : "=&r"(temp)); return temp; } diff --git a/trunk/arch/arc/include/asm/kgdb.h b/trunk/arch/arc/include/asm/kgdb.h index 4930957ca3d3..f3c4934f0ca9 100644 --- a/trunk/arch/arc/include/asm/kgdb.h +++ b/trunk/arch/arc/include/asm/kgdb.h @@ -13,7 +13,7 @@ #ifdef CONFIG_KGDB -#include +#include /* to ensure compatibility with Linux 2.6.35, we don't implement the get/set * register API yet */ @@ -53,7 +53,9 @@ enum arc700_linux_regnums { }; #else -#define kgdb_trap(regs, param) +static inline void kgdb_trap(struct pt_regs *regs, int param) +{ +} #endif #endif /* __ARC_KGDB_H__ */ diff --git a/trunk/arch/arc/include/asm/ptrace.h b/trunk/arch/arc/include/asm/ptrace.h index 6179de7e07c2..8ae783d20a81 100644 --- a/trunk/arch/arc/include/asm/ptrace.h +++ b/trunk/arch/arc/include/asm/ptrace.h @@ -123,7 +123,7 @@ static inline long regs_return_value(struct pt_regs *regs) #define orig_r8_IS_SCALL 0x0001 #define orig_r8_IS_SCALL_RESTARTED 0x0002 #define orig_r8_IS_BRKPT 0x0004 -#define orig_r8_IS_EXCPN 0x0008 +#define orig_r8_IS_EXCPN 0x0004 #define orig_r8_IS_IRQ1 0x0010 #define orig_r8_IS_IRQ2 0x0020 diff --git a/trunk/arch/arc/include/asm/syscalls.h b/trunk/arch/arc/include/asm/syscalls.h index dd785befe7fd..e53a5340ba4f 100644 --- a/trunk/arch/arc/include/asm/syscalls.h +++ b/trunk/arch/arc/include/asm/syscalls.h @@ -16,6 +16,8 @@ #include int sys_clone_wrapper(int, int, int, int, int); +int sys_fork_wrapper(void); +int sys_vfork_wrapper(void); int sys_cacheflush(uint32_t, uint32_t uint32_t); int sys_arc_settls(void *); int sys_arc_gettls(void); diff --git a/trunk/arch/arc/include/uapi/asm/ptrace.h b/trunk/arch/arc/include/uapi/asm/ptrace.h index 30333cec0fef..6afa4f702075 100644 --- a/trunk/arch/arc/include/uapi/asm/ptrace.h +++ b/trunk/arch/arc/include/uapi/asm/ptrace.h @@ -28,14 +28,14 @@ */ struct user_regs_struct { - struct { + struct scratch { long pad; long bta, lp_start, lp_end, lp_count; long status32, ret, blink, fp, gp; long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0; long sp; } scratch; - struct { + struct callee { long pad; long r25, r24, r23, r22, r21, r20; long r19, r18, r17, r16, r15, r14, r13; diff --git a/trunk/arch/arc/kernel/entry.S b/trunk/arch/arc/kernel/entry.S index 91eeab81f52d..ef6800ba2f03 100644 --- a/trunk/arch/arc/kernel/entry.S +++ b/trunk/arch/arc/kernel/entry.S @@ -452,7 +452,7 @@ tracesys: ; using ERET won't work since next-PC has already committed lr r12, [efa] GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11 - st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address + st r12, [r11, THREAD_FAULT_ADDR] ; PRE Sys Call Ptrace hook mov r0, sp ; pt_regs needed @@ -792,6 +792,31 @@ ARC_EXIT ret_from_fork ;################### Special Sys Call Wrappers ########################## +; TBD: call do_fork directly from here +ARC_ENTRY sys_fork_wrapper + SAVE_CALLEE_SAVED_USER + bl @sys_fork + DISCARD_CALLEE_SAVED_USER + + GET_CURR_THR_INFO_FLAGS r10 + btst r10, TIF_SYSCALL_TRACE + bnz tracesys_exit + + b ret_from_system_call +ARC_EXIT sys_fork_wrapper + +ARC_ENTRY sys_vfork_wrapper + SAVE_CALLEE_SAVED_USER + bl @sys_vfork + DISCARD_CALLEE_SAVED_USER + + GET_CURR_THR_INFO_FLAGS r10 + btst r10, TIF_SYSCALL_TRACE + bnz tracesys_exit + + b ret_from_system_call +ARC_EXIT sys_vfork_wrapper + ARC_ENTRY sys_clone_wrapper SAVE_CALLEE_SAVED_USER bl @sys_clone diff --git a/trunk/arch/arc/kernel/kgdb.c b/trunk/arch/arc/kernel/kgdb.c index 52bdc83c1495..2888ba5be47e 100644 --- a/trunk/arch/arc/kernel/kgdb.c +++ b/trunk/arch/arc/kernel/kgdb.c @@ -9,7 +9,6 @@ */ #include -#include #include #include diff --git a/trunk/arch/arc/kernel/setup.c b/trunk/arch/arc/kernel/setup.c index 2d95ac07df7b..dc0f968dae0a 100644 --- a/trunk/arch/arc/kernel/setup.c +++ b/trunk/arch/arc/kernel/setup.c @@ -232,8 +232,10 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) n += scnprintf(buf + n, len - n, "\n"); +#ifdef _ASM_GENERIC_UNISTD_H n += scnprintf(buf + n, len - n, - "OS ABI [v3]\t: no-legacy-syscalls\n"); + "OS ABI [v2]\t: asm-generic/{unistd,stat,fcntl}\n"); +#endif return buf; } diff --git a/trunk/arch/arc/kernel/sys.c b/trunk/arch/arc/kernel/sys.c index 9d6c1ca26af6..f6bdd07583f3 100644 --- a/trunk/arch/arc/kernel/sys.c +++ b/trunk/arch/arc/kernel/sys.c @@ -6,6 +6,8 @@ #include #define sys_clone sys_clone_wrapper +#define sys_fork sys_fork_wrapper +#define sys_vfork sys_vfork_wrapper #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 1cacda426a0e..5b714695b01b 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -49,6 +49,7 @@ config ARM select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 + select HAVE_VIRT_TO_BUS select KTIME_SCALAR select PERF_USE_VMALLOC select RTC_LIB @@ -555,6 +556,7 @@ config ARCH_IXP4XX config ARCH_DOVE bool "Marvell Dove" select ARCH_REQUIRE_GPIOLIB + select COMMON_CLK_DOVE select CPU_V7 select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI @@ -742,7 +744,6 @@ config ARCH_RPC select NEED_MACH_IO_H select NEED_MACH_MEMORY_H select NO_IOPORT - select VIRT_TO_BUS help On the Acorn Risc-PC, Linux can support the internal IDE disk and CD-ROM interface, serial and parallel port, and the floppy drive. @@ -878,7 +879,6 @@ config ARCH_SHARK select ISA_DMA select NEED_MACH_MEMORY_H select PCI - select VIRT_TO_BUS select ZONE_DMA help Support for the StrongARM based Digital DNARD machine, also known @@ -1006,12 +1006,12 @@ config ARCH_MULTI_V4_V5 bool config ARCH_MULTI_V6 - bool "ARMv6 based platforms (ARM11)" + bool "ARMv6 based platforms (ARM11, Scorpion, ...)" select ARCH_MULTI_V6_V7 select CPU_V6 config ARCH_MULTI_V7 - bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)" + bool "ARMv7 based platforms (Cortex-A, PJ4, Krait)" default y select ARCH_MULTI_V6_V7 select ARCH_VEXPRESS @@ -1183,9 +1183,9 @@ config ARM_NR_BANKS default 8 config IWMMXT - bool "Enable iWMMXt support" if !CPU_PJ4 + bool "Enable iWMMXt support" depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 - default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 + default y if PXA27x || PXA3xx || ARCH_MMP help Enable support for iWMMXt context switching at run time if running on a CPU that supports it. @@ -1439,16 +1439,6 @@ config ARM_ERRATA_775420 to deadlock. This workaround puts DSB before executing ISB if an abort may occur on cache maintenance. -config ARM_ERRATA_798181 - bool "ARM errata: TLBI/DSB failure on Cortex-A15" - depends on CPU_V7 && SMP - help - On Cortex-A15 (r0p0..r3p2) the TLBI*IS/DSB operations are not - adequately shooting down all use of the old entries. This - option enables the Linux kernel workaround for this erratum - which sends an IPI to the CPUs that are running the same ASID - as the one being invalidated. - endmenu source "arch/arm/common/Kconfig" @@ -1472,6 +1462,10 @@ config ISA_DMA bool select ISA_DMA_API +config ARCH_NO_VIRT_TO_BUS + def_bool y + depends on !ARCH_RPC && !ARCH_NETWINDER && !ARCH_SHARK + # Select ISA DMA interface config ISA_DMA_API bool @@ -1663,16 +1657,13 @@ config LOCAL_TIMERS accounting to be spread across the timer interval, preventing a "thundering herd" at every timer tick. -# The GPIO number here must be sorted by descending number. In case of -# a multiplatform kernel, we just want the highest value required by the -# selected platforms. config ARCH_NR_GPIO int default 1024 if ARCH_SHMOBILE || ARCH_TEGRA - default 512 if SOC_OMAP5 default 355 if ARCH_U8500 - default 288 if ARCH_VT8500 || ARCH_SUNXI default 264 if MACH_H4700 + default 512 if SOC_OMAP5 + default 288 if ARCH_VT8500 || ARCH_SUNXI default 0 help Maximum number of GPIOs in the system. @@ -1896,9 +1887,8 @@ config XEN_DOM0 config XEN bool "Xen guest support on ARM (EXPERIMENTAL)" - depends on ARM && AEABI && OF + depends on ARM && OF depends on CPU_V7 && !CPU_V6 - depends on !GENERIC_ATOMIC64 help Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. diff --git a/trunk/arch/arm/Kconfig.debug b/trunk/arch/arm/Kconfig.debug index 9b31f4311ea2..acddddac7ee4 100644 --- a/trunk/arch/arm/Kconfig.debug +++ b/trunk/arch/arm/Kconfig.debug @@ -492,10 +492,9 @@ config DEBUG_IMX_UART_PORT DEBUG_IMX31_UART || \ DEBUG_IMX35_UART || \ DEBUG_IMX51_UART || \ - DEBUG_IMX53_UART || \ + DEBUG_IMX50_IMX53_UART || \ DEBUG_IMX6Q_UART default 1 - depends on ARCH_MXC help Choose UART port on which kernel low-level debug messages should be output. diff --git a/trunk/arch/arm/boot/Makefile b/trunk/arch/arm/boot/Makefile index 84aa2caf07ed..71768b8a1ab9 100644 --- a/trunk/arch/arm/boot/Makefile +++ b/trunk/arch/arm/boot/Makefile @@ -115,4 +115,4 @@ i: $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(obj)/Image System.map "$(INSTALL_PATH)" -subdir- := bootp compressed dts +subdir- := bootp compressed diff --git a/trunk/arch/arm/boot/compressed/Makefile b/trunk/arch/arm/boot/compressed/Makefile index afed28e37ea5..5cad8a6dadb0 100644 --- a/trunk/arch/arm/boot/compressed/Makefile +++ b/trunk/arch/arm/boot/compressed/Makefile @@ -120,7 +120,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) endif -ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj) +ccflags-y := -fpic -fno-builtin -I$(obj) asflags-y := -Wa,-march=all -DZIMAGE # Supply kernel BSS size to the decompressor via a linker symbol. diff --git a/trunk/arch/arm/boot/dts/armada-370-mirabox.dts b/trunk/arch/arm/boot/dts/armada-370-mirabox.dts index 3234875824dc..dd0c57dd9f30 100644 --- a/trunk/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/trunk/arch/arm/boot/dts/armada-370-mirabox.dts @@ -54,7 +54,7 @@ }; mvsdio@d00d4000 { - pinctrl-0 = <&sdio_pins3>; + pinctrl-0 = <&sdio_pins2>; pinctrl-names = "default"; status = "okay"; /* diff --git a/trunk/arch/arm/boot/dts/armada-370-rd.dts b/trunk/arch/arm/boot/dts/armada-370-rd.dts index 070bba4f2585..f8e4855bc9a5 100644 --- a/trunk/arch/arm/boot/dts/armada-370-rd.dts +++ b/trunk/arch/arm/boot/dts/armada-370-rd.dts @@ -64,13 +64,5 @@ status = "okay"; /* No CD or WP GPIOs */ }; - - usb@d0050000 { - status = "okay"; - }; - - usb@d0051000 { - status = "okay"; - }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-370-xp.dtsi b/trunk/arch/arm/boot/dts/armada-370-xp.dtsi index 5b708208b607..6f1acc75e155 100644 --- a/trunk/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/trunk/arch/arm/boot/dts/armada-370-xp.dtsi @@ -31,6 +31,7 @@ mpic: interrupt-controller@d0020000 { compatible = "marvell,mpic"; #interrupt-cells = <1>; + #address-cells = <1>; #size-cells = <1>; interrupt-controller; }; @@ -53,7 +54,7 @@ reg = <0xd0012000 0x100>; reg-shift = <2>; interrupts = <41>; - reg-io-width = <1>; + reg-io-width = <4>; status = "disabled"; }; serial@d0012100 { @@ -61,7 +62,7 @@ reg = <0xd0012100 0x100>; reg-shift = <2>; interrupts = <42>; - reg-io-width = <1>; + reg-io-width = <4>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/armada-370.dtsi b/trunk/arch/arm/boot/dts/armada-370.dtsi index a195debb67d3..8188d138020e 100644 --- a/trunk/arch/arm/boot/dts/armada-370.dtsi +++ b/trunk/arch/arm/boot/dts/armada-370.dtsi @@ -59,12 +59,6 @@ "mpp50", "mpp51", "mpp52"; marvell,function = "sd0"; }; - - sdio_pins3: sdio-pins3 { - marvell,pins = "mpp48", "mpp49", "mpp50", - "mpp51", "mpp52", "mpp53"; - marvell,function = "sd0"; - }; }; gpio0: gpio@d0018100 { diff --git a/trunk/arch/arm/boot/dts/armada-xp.dtsi b/trunk/arch/arm/boot/dts/armada-xp.dtsi index ca00d8326c87..1443949c165e 100644 --- a/trunk/arch/arm/boot/dts/armada-xp.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp.dtsi @@ -46,7 +46,7 @@ reg = <0xd0012200 0x100>; reg-shift = <2>; interrupts = <43>; - reg-io-width = <1>; + reg-io-width = <4>; status = "disabled"; }; serial@d0012300 { @@ -54,7 +54,7 @@ reg = <0xd0012300 0x100>; reg-shift = <2>; interrupts = <44>; - reg-io-width = <1>; + reg-io-width = <4>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi index a98c0d50fbbe..aa98e641931f 100644 --- a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi @@ -238,32 +238,8 @@ nand { pinctrl_nand: nand-0 { atmel,pins = - <3 0 0x1 0x0 /* PD0 periph A Read Enable */ - 3 1 0x1 0x0 /* PD1 periph A Write Enable */ - 3 2 0x1 0x0 /* PD2 periph A Address Latch Enable */ - 3 3 0x1 0x0 /* PD3 periph A Command Latch Enable */ - 3 4 0x0 0x1 /* PD4 gpio Chip Enable pin pull_up */ - 3 5 0x0 0x1 /* PD5 gpio RDY/BUSY pin pull_up */ - 3 6 0x1 0x0 /* PD6 periph A Data bit 0 */ - 3 7 0x1 0x0 /* PD7 periph A Data bit 1 */ - 3 8 0x1 0x0 /* PD8 periph A Data bit 2 */ - 3 9 0x1 0x0 /* PD9 periph A Data bit 3 */ - 3 10 0x1 0x0 /* PD10 periph A Data bit 4 */ - 3 11 0x1 0x0 /* PD11 periph A Data bit 5 */ - 3 12 0x1 0x0 /* PD12 periph A Data bit 6 */ - 3 13 0x1 0x0>; /* PD13 periph A Data bit 7 */ - }; - - pinctrl_nand_16bits: nand_16bits-0 { - atmel,pins = - <3 14 0x1 0x0 /* PD14 periph A Data bit 8 */ - 3 15 0x1 0x0 /* PD15 periph A Data bit 9 */ - 3 16 0x1 0x0 /* PD16 periph A Data bit 10 */ - 3 17 0x1 0x0 /* PD17 periph A Data bit 11 */ - 3 18 0x1 0x0 /* PD18 periph A Data bit 12 */ - 3 19 0x1 0x0 /* PD19 periph A Data bit 13 */ - 3 20 0x1 0x0 /* PD20 periph A Data bit 14 */ - 3 21 0x1 0x0>; /* PD21 periph A Data bit 15 */ + <3 4 0x0 0x1 /* PD5 gpio RDY pin pull_up */ + 3 5 0x0 0x1>; /* PD4 gpio enable pin pull_up */ }; }; diff --git a/trunk/arch/arm/boot/dts/bcm2835.dtsi b/trunk/arch/arm/boot/dts/bcm2835.dtsi index 7e0481e2441a..4bf2a8774aa7 100644 --- a/trunk/arch/arm/boot/dts/bcm2835.dtsi +++ b/trunk/arch/arm/boot/dts/bcm2835.dtsi @@ -105,7 +105,7 @@ compatible = "fixed-clock"; reg = <1>; #clock-cells = <0>; - clock-frequency = <250000000>; + clock-frequency = <150000000>; }; }; }; diff --git a/trunk/arch/arm/boot/dts/dbx5x0.dtsi b/trunk/arch/arm/boot/dts/dbx5x0.dtsi index aaa63d0a8096..69140ba99f46 100644 --- a/trunk/arch/arm/boot/dts/dbx5x0.dtsi +++ b/trunk/arch/arm/boot/dts/dbx5x0.dtsi @@ -191,8 +191,8 @@ prcmu: prcmu@80157000 { compatible = "stericsson,db8500-prcmu"; - reg = <0x80157000 0x1000>, <0x801b0000 0x8000>, <0x801b8000 0x1000>; - reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm"; + reg = <0x80157000 0x1000>; + reg-names = "prcmu"; interrupts = <0 47 0x4>; #address-cells = <1>; #size-cells = <1>; @@ -319,8 +319,9 @@ }; }; - ab8500 { + ab8500@5 { compatible = "stericsson,ab8500"; + reg = <5>; /* mailbox 5 is i2c */ interrupt-parent = <&intc>; interrupts = <0 40 0x4>; interrupt-controller; diff --git a/trunk/arch/arm/boot/dts/dove.dtsi b/trunk/arch/arm/boot/dts/dove.dtsi index f7509cafc377..67dbe20868a2 100644 --- a/trunk/arch/arm/boot/dts/dove.dtsi +++ b/trunk/arch/arm/boot/dts/dove.dtsi @@ -197,11 +197,6 @@ status = "disabled"; }; - rtc@d8500 { - compatible = "marvell,orion-rtc"; - reg = <0xd8500 0x20>; - }; - crypto: crypto@30000 { compatible = "marvell,orion-crypto"; reg = <0x30000 0x10000>, diff --git a/trunk/arch/arm/boot/dts/exynos4.dtsi b/trunk/arch/arm/boot/dts/exynos4.dtsi index 1a62bcf18aa3..e1347fceb5bc 100644 --- a/trunk/arch/arm/boot/dts/exynos4.dtsi +++ b/trunk/arch/arm/boot/dts/exynos4.dtsi @@ -275,27 +275,18 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x12680000 0x1000>; interrupts = <0 35 0>; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; }; pdma1: pdma@12690000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x12690000 0x1000>; interrupts = <0 36 0>; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; }; mdma1: mdma@12850000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x12850000 0x1000>; interrupts = <0 34 0>; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <1>; }; }; }; diff --git a/trunk/arch/arm/boot/dts/exynos5440.dtsi b/trunk/arch/arm/boot/dts/exynos5440.dtsi index 9a99755920c0..5f3562ad6746 100644 --- a/trunk/arch/arm/boot/dts/exynos5440.dtsi +++ b/trunk/arch/arm/boot/dts/exynos5440.dtsi @@ -142,18 +142,12 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x120000 0x1000>; interrupts = <0 34 0>; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; }; pdma1: pdma@121B0000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x121000 0x1000>; interrupts = <0 35 0>; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; }; }; diff --git a/trunk/arch/arm/boot/dts/href.dtsi b/trunk/arch/arm/boot/dts/href.dtsi index 379128eb9d98..592fb9dc35bd 100644 --- a/trunk/arch/arm/boot/dts/href.dtsi +++ b/trunk/arch/arm/boot/dts/href.dtsi @@ -221,7 +221,7 @@ }; }; - ab8500 { + ab8500@5 { ab8500-regulators { ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { regulator-name = "V-DISPLAY"; diff --git a/trunk/arch/arm/boot/dts/hrefv60plus.dts b/trunk/arch/arm/boot/dts/hrefv60plus.dts index 2b587a74b813..55f4191a626e 100644 --- a/trunk/arch/arm/boot/dts/hrefv60plus.dts +++ b/trunk/arch/arm/boot/dts/hrefv60plus.dts @@ -158,7 +158,7 @@ }; }; - ab8500 { + ab8500@5 { ab8500-regulators { ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { regulator-name = "V-DISPLAY"; diff --git a/trunk/arch/arm/boot/dts/imx28-m28evk.dts b/trunk/arch/arm/boot/dts/imx28-m28evk.dts index fd36e1cca104..6ce3d17c3a29 100644 --- a/trunk/arch/arm/boot/dts/imx28-m28evk.dts +++ b/trunk/arch/arm/boot/dts/imx28-m28evk.dts @@ -152,6 +152,7 @@ i2c0: i2c@80058000 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; + clock-frequency = <400000>; status = "okay"; sgtl5000: codec@0a { diff --git a/trunk/arch/arm/boot/dts/imx28-sps1.dts b/trunk/arch/arm/boot/dts/imx28-sps1.dts index 6c6a5442800a..e6cde8aa7fff 100644 --- a/trunk/arch/arm/boot/dts/imx28-sps1.dts +++ b/trunk/arch/arm/boot/dts/imx28-sps1.dts @@ -70,6 +70,7 @@ i2c0: i2c@80058000 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; + clock-frequency = <400000>; status = "okay"; rtc: rtc@51 { diff --git a/trunk/arch/arm/boot/dts/imx53-mba53.dts b/trunk/arch/arm/boot/dts/imx53-mba53.dts index 468c0a1d48d9..e54fffd48369 100644 --- a/trunk/arch/arm/boot/dts/imx53-mba53.dts +++ b/trunk/arch/arm/boot/dts/imx53-mba53.dts @@ -42,9 +42,10 @@ fsl,pins = <689 0x10000 /* DISP1_DRDY */ 482 0x10000 /* DISP1_HSYNC */ 489 0x10000 /* DISP1_VSYNC */ + 684 0x10000 /* DISP1_DAT_0 */ 515 0x10000 /* DISP1_DAT_22 */ 523 0x10000 /* DISP1_DAT_23 */ - 545 0x10000 /* DISP1_DAT_21 */ + 543 0x10000 /* DISP1_DAT_21 */ 553 0x10000 /* DISP1_DAT_20 */ 558 0x10000 /* DISP1_DAT_19 */ 564 0x10000 /* DISP1_DAT_18 */ diff --git a/trunk/arch/arm/boot/dts/imx6qdl.dtsi b/trunk/arch/arm/boot/dts/imx6qdl.dtsi index 281a223591ff..06ec460b4581 100644 --- a/trunk/arch/arm/boot/dts/imx6qdl.dtsi +++ b/trunk/arch/arm/boot/dts/imx6qdl.dtsi @@ -91,7 +91,6 @@ compatible = "arm,cortex-a9-twd-timer"; reg = <0x00a00600 0x20>; interrupts = <1 13 0xf01>; - clocks = <&clks 15>; }; L2: l2-cache@00a02000 { diff --git a/trunk/arch/arm/boot/dts/kirkwood-dns320.dts b/trunk/arch/arm/boot/dts/kirkwood-dns320.dts index c9c44b2f62d7..5bb0bf39d3b8 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-dns320.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-dns320.dts @@ -42,10 +42,12 @@ ocp@f1000000 { serial@12000 { + clock-frequency = <166666667>; status = "okay"; }; serial@12100 { + clock-frequency = <166666667>; status = "okay"; }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-dns325.dts b/trunk/arch/arm/boot/dts/kirkwood-dns325.dts index e4e4930dc5cf..d430713ea9b9 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-dns325.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-dns325.dts @@ -50,6 +50,7 @@ }; }; serial@12000 { + clock-frequency = <200000000>; status = "okay"; }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-dockstar.dts b/trunk/arch/arm/boot/dts/kirkwood-dockstar.dts index 0196cf6b0ef2..2e3dd34e21a5 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-dockstar.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-dockstar.dts @@ -37,6 +37,7 @@ }; }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-dreamplug.dts b/trunk/arch/arm/boot/dts/kirkwood-dreamplug.dts index 289e51d86372..ef2d8c705709 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -38,6 +38,7 @@ }; }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts b/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts index c3573be7b92c..1b133e0c566e 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts @@ -73,11 +73,11 @@ }; }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; nand@3000000 { - chip-delay = <40>; status = "okay"; partition@0 { diff --git a/trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts b/trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts index 5335b1aa8601..71902da33d63 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-ib62x0.dts @@ -51,6 +51,7 @@ }; }; serial@12000 { + clock-frequency = <200000000>; status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-iconnect.dts b/trunk/arch/arm/boot/dts/kirkwood-iconnect.dts index 12ccf74ac3c4..504f16be8b54 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -78,6 +78,7 @@ }; }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/trunk/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts index 3694e94f6e99..6cae4599c4b3 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts @@ -96,11 +96,11 @@ marvell,function = "gpio"; }; pmx_led_rebuild_brt_ctrl_1: pmx-led-rebuild-brt-ctrl-1 { - marvell,pins = "mpp46"; + marvell,pins = "mpp44"; marvell,function = "gpio"; }; pmx_led_rebuild_brt_ctrl_2: pmx-led-rebuild-brt-ctrl-2 { - marvell,pins = "mpp47"; + marvell,pins = "mpp45"; marvell,function = "gpio"; }; @@ -115,6 +115,7 @@ }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; @@ -157,14 +158,14 @@ gpios = <&gpio0 16 0>; linux,default-trigger = "default-on"; }; - rebuild_led { - label = "status:white:rebuild_led"; - gpios = <&gpio1 4 0>; - }; - health_led { + health_led1 { label = "status:red:health_led"; gpios = <&gpio1 5 0>; }; + health_led2 { + label = "status:white:health_led"; + gpios = <&gpio1 4 0>; + }; backup_led { label = "status:blue:backup_led"; gpios = <&gpio0 15 0>; diff --git a/trunk/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/trunk/arch/arm/boot/dts/kirkwood-km_kirkwood.dts index 5bbd0542cdd3..8db3123ac80f 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-km_kirkwood.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-km_kirkwood.dts @@ -34,6 +34,7 @@ }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts b/trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts index 9f55d95f35f5..9510c9ea666c 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-lschlv2.dts @@ -13,6 +13,7 @@ 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 index 5c84c118ed8d..739019c4cba9 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-lsxhl.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-lsxhl.dts @@ -13,6 +13,7 @@ ocp@f1000000 { serial@12000 { + clock-frequency = <200000000>; status = "okay"; }; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-mplcec4.dts b/trunk/arch/arm/boot/dts/kirkwood-mplcec4.dts index 758824118a9a..662dfd81b1ce 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-mplcec4.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-mplcec4.dts @@ -90,6 +90,7 @@ }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/trunk/arch/arm/boot/dts/kirkwood-ns2-common.dtsi index 6affd924fe11..e8e7ecef1650 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-ns2-common.dtsi +++ b/trunk/arch/arm/boot/dts/kirkwood-ns2-common.dtsi @@ -23,6 +23,7 @@ }; serial@12000 { + clock-frequency = <166666667>; status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-nsa310.dts b/trunk/arch/arm/boot/dts/kirkwood-nsa310.dts index a7412b937a8a..3a178cf708d7 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-nsa310.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-nsa310.dts @@ -117,6 +117,7 @@ }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/trunk/arch/arm/boot/dts/kirkwood-openblocks_a6.dts index d27f7245f8e7..ede7fe0d7a87 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-openblocks_a6.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-openblocks_a6.dts @@ -18,10 +18,12 @@ ocp@f1000000 { serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; serial@12100 { + clock-frequency = <200000000>; status = "ok"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood-topkick.dts b/trunk/arch/arm/boot/dts/kirkwood-topkick.dts index 66eb45b00b25..842ff95d60df 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-topkick.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-topkick.dts @@ -108,6 +108,7 @@ }; serial@12000 { + clock-frequency = <200000000>; status = "ok"; }; diff --git a/trunk/arch/arm/boot/dts/kirkwood.dtsi b/trunk/arch/arm/boot/dts/kirkwood.dtsi index fada7e6d24d8..2c738d9dc82a 100644 --- a/trunk/arch/arm/boot/dts/kirkwood.dtsi +++ b/trunk/arch/arm/boot/dts/kirkwood.dtsi @@ -38,7 +38,6 @@ interrupt-controller; #interrupt-cells = <2>; interrupts = <35>, <36>, <37>, <38>; - clocks = <&gate_clk 7>; }; gpio1: gpio@10140 { @@ -50,7 +49,6 @@ interrupt-controller; #interrupt-cells = <2>; interrupts = <39>, <40>, <41>; - clocks = <&gate_clk 7>; }; serial@12000 { @@ -59,6 +57,7 @@ reg-shift = <2>; interrupts = <33>; clocks = <&gate_clk 7>; + /* set clock-frequency in board dts */ status = "disabled"; }; @@ -68,6 +67,7 @@ reg-shift = <2>; interrupts = <34>; clocks = <&gate_clk 7>; + /* set clock-frequency in board dts */ status = "disabled"; }; @@ -75,7 +75,6 @@ compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc"; reg = <0x10300 0x20>; interrupts = <53>; - clocks = <&gate_clk 7>; }; spi@10600 { diff --git a/trunk/arch/arm/boot/dts/msm8660-surf.dts b/trunk/arch/arm/boot/dts/msm8660-surf.dts index 67f8670c4d6a..31f2157cd7d7 100644 --- a/trunk/arch/arm/boot/dts/msm8660-surf.dts +++ b/trunk/arch/arm/boot/dts/msm8660-surf.dts @@ -38,10 +38,4 @@ <0x19c00000 0x1000>; interrupts = <0 195 0x0>; }; - - qcom,ssbi@500000 { - compatible = "qcom,ssbi"; - reg = <0x500000 0x1000>; - qcom,controller-type = "pmic-arbiter"; - }; }; diff --git a/trunk/arch/arm/boot/dts/msm8960-cdp.dts b/trunk/arch/arm/boot/dts/msm8960-cdp.dts index c9b09a813a4b..9e621b5ad3dd 100644 --- a/trunk/arch/arm/boot/dts/msm8960-cdp.dts +++ b/trunk/arch/arm/boot/dts/msm8960-cdp.dts @@ -38,10 +38,4 @@ <0x16400000 0x1000>; interrupts = <0 154 0x0>; }; - - qcom,ssbi@500000 { - compatible = "qcom,ssbi"; - reg = <0x500000 0x1000>; - qcom,controller-type = "pmic-arbiter"; - }; }; diff --git a/trunk/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts b/trunk/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts index 0077fc8510b7..5a3a58b7e18f 100644 --- a/trunk/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts +++ b/trunk/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts @@ -11,7 +11,7 @@ / { model = "LaCie Ethernet Disk mini V2"; - compatible = "lacie,ethernet-disk-mini-v2", "marvell,orion5x-88f5182", "marvell,orion5x"; + compatible = "lacie,ethernet-disk-mini-v2", "marvell-orion5x-88f5182", "marvell,orion5x"; memory { reg = <0x00000000 0x4000000>; /* 64 MB */ diff --git a/trunk/arch/arm/boot/dts/orion5x.dtsi b/trunk/arch/arm/boot/dts/orion5x.dtsi index f7bec3b1ba32..8aad00f81ed9 100644 --- a/trunk/arch/arm/boot/dts/orion5x.dtsi +++ b/trunk/arch/arm/boot/dts/orion5x.dtsi @@ -13,9 +13,6 @@ compatible = "marvell,orion5x"; interrupt-parent = <&intc>; - aliases { - gpio0 = &gpio0; - }; intc: interrupt-controller { compatible = "marvell,orion-intc", "marvell,intc"; interrupt-controller; @@ -35,9 +32,7 @@ #gpio-cells = <2>; gpio-controller; reg = <0x10100 0x40>; - ngpios = <32>; - interrupt-controller; - #interrupt-cells = <2>; + ngpio = <32>; interrupts = <6>, <7>, <8>, <9>; }; @@ -96,7 +91,7 @@ reg = <0x90000 0x10000>, <0xf2200000 0x800>; reg-names = "regs", "sram"; - interrupts = <28>; + interrupts = <22>; status = "okay"; }; }; diff --git a/trunk/arch/arm/boot/dts/snowball.dts b/trunk/arch/arm/boot/dts/snowball.dts index d3ec32f6b790..27f31a5fa494 100644 --- a/trunk/arch/arm/boot/dts/snowball.dts +++ b/trunk/arch/arm/boot/dts/snowball.dts @@ -298,7 +298,7 @@ }; }; - ab8500 { + ab8500@5 { ab8500-regulators { ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { regulator-name = "V-DISPLAY"; diff --git a/trunk/arch/arm/boot/dts/socfpga.dtsi b/trunk/arch/arm/boot/dts/socfpga.dtsi index 7e8769bd5977..936d2306e7e1 100644 --- a/trunk/arch/arm/boot/dts/socfpga.dtsi +++ b/trunk/arch/arm/boot/dts/socfpga.dtsi @@ -75,9 +75,6 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0xffe01000 0x1000>; interrupts = <0 180 4>; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; }; }; diff --git a/trunk/arch/arm/boot/dts/spear1310.dtsi b/trunk/arch/arm/boot/dts/spear1310.dtsi index 122ae94076c8..1513c1927cc8 100644 --- a/trunk/arch/arm/boot/dts/spear1310.dtsi +++ b/trunk/arch/arm/boot/dts/spear1310.dtsi @@ -89,7 +89,7 @@ pinmux: pinmux@e0700000 { compatible = "st,spear1310-pinmux"; reg = <0xe0700000 0x1000>; - #gpio-range-cells = <3>; + #gpio-range-cells = <2>; }; apb { @@ -212,7 +212,7 @@ interrupt-controller; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 0 246>; + gpio-ranges = <&pinmux 0 246>; status = "disabled"; st-plgpio,ngpio = <246>; diff --git a/trunk/arch/arm/boot/dts/spear1340.dtsi b/trunk/arch/arm/boot/dts/spear1340.dtsi index c511c4772efd..34da11aa6795 100644 --- a/trunk/arch/arm/boot/dts/spear1340.dtsi +++ b/trunk/arch/arm/boot/dts/spear1340.dtsi @@ -63,7 +63,7 @@ pinmux: pinmux@e0700000 { compatible = "st,spear1340-pinmux"; reg = <0xe0700000 0x1000>; - #gpio-range-cells = <3>; + #gpio-range-cells = <2>; }; pwm: pwm@e0180000 { @@ -127,7 +127,7 @@ interrupt-controller; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 0 252>; + gpio-ranges = <&pinmux 0 252>; status = "disabled"; st-plgpio,ngpio = <250>; diff --git a/trunk/arch/arm/boot/dts/spear310.dtsi b/trunk/arch/arm/boot/dts/spear310.dtsi index 95372080eea6..ab45b8c81982 100644 --- a/trunk/arch/arm/boot/dts/spear310.dtsi +++ b/trunk/arch/arm/boot/dts/spear310.dtsi @@ -25,7 +25,7 @@ pinmux: pinmux@b4000000 { compatible = "st,spear310-pinmux"; reg = <0xb4000000 0x1000>; - #gpio-range-cells = <3>; + #gpio-range-cells = <2>; }; fsmc: flash@44000000 { @@ -102,7 +102,7 @@ interrupt-controller; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 0 102>; + gpio-ranges = <&pinmux 0 102>; status = "disabled"; st-plgpio,ngpio = <102>; diff --git a/trunk/arch/arm/boot/dts/spear320.dtsi b/trunk/arch/arm/boot/dts/spear320.dtsi index ffea342aeec9..caa5520b1fd4 100644 --- a/trunk/arch/arm/boot/dts/spear320.dtsi +++ b/trunk/arch/arm/boot/dts/spear320.dtsi @@ -24,7 +24,7 @@ pinmux: pinmux@b3000000 { compatible = "st,spear320-pinmux"; reg = <0xb3000000 0x1000>; - #gpio-range-cells = <3>; + #gpio-range-cells = <2>; }; clcd@90000000 { @@ -130,7 +130,7 @@ interrupt-controller; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 0 102>; + gpio-ranges = <&pinmux 0 102>; status = "disabled"; st-plgpio,ngpio = <102>; diff --git a/trunk/arch/arm/boot/dts/tegra20.dtsi b/trunk/arch/arm/boot/dts/tegra20.dtsi index 3d3f64d2111a..9a428931d042 100644 --- a/trunk/arch/arm/boot/dts/tegra20.dtsi +++ b/trunk/arch/arm/boot/dts/tegra20.dtsi @@ -118,7 +118,6 @@ compatible = "arm,cortex-a9-twd-timer"; reg = <0x50040600 0x20>; interrupts = <1 13 0x304>; - clocks = <&tegra_car 132>; }; intc: interrupt-controller { @@ -385,7 +384,7 @@ spi@7000d800 { compatible = "nvidia,tegra20-slink"; - reg = <0x7000d800 0x200>; + reg = <0x7000d480 0x200>; interrupts = <0 83 0x04>; nvidia,dma-request-selector = <&apbdma 17>; #address-cells = <1>; diff --git a/trunk/arch/arm/boot/dts/tegra30.dtsi b/trunk/arch/arm/boot/dts/tegra30.dtsi index dbf46c272562..767803e1fd55 100644 --- a/trunk/arch/arm/boot/dts/tegra30.dtsi +++ b/trunk/arch/arm/boot/dts/tegra30.dtsi @@ -119,7 +119,6 @@ compatible = "arm,cortex-a9-twd-timer"; reg = <0x50040600 0x20>; interrupts = <1 13 0xf04>; - clocks = <&tegra_car 214>; }; intc: interrupt-controller { @@ -372,7 +371,7 @@ spi@7000d800 { compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; - reg = <0x7000d800 0x200>; + reg = <0x7000d480 0x200>; interrupts = <0 83 0x04>; nvidia,dma-request-selector = <&apbdma 17>; #address-cells = <1>; diff --git a/trunk/arch/arm/boot/dts/vt8500-bv07.dts b/trunk/arch/arm/boot/dts/vt8500-bv07.dts index 877b33afa7ed..567cf4e8ab84 100644 --- a/trunk/arch/arm/boot/dts/vt8500-bv07.dts +++ b/trunk/arch/arm/boot/dts/vt8500-bv07.dts @@ -11,22 +11,26 @@ / { model = "Benign BV07 Netbook"; -}; -&fb { - bits-per-pixel = <16>; - display-timings { - native-mode = <&timing0>; - timing0: 800x480 { - clock-frequency = <0>; /* unused but required */ - hactive = <800>; - vactive = <480>; - hfront-porch = <40>; - hback-porch = <88>; - hsync-len = <0>; - vback-porch = <32>; - vfront-porch = <11>; - vsync-len = <1>; + /* + * Display node is based on Sascha Hauer's patch on dri-devel. + * Added a bpp property to calculate the size of the framebuffer + * until the binding is formalized. + */ + display: display@0 { + modes { + mode0: mode@0 { + hactive = <800>; + vactive = <480>; + hback-porch = <88>; + hfront-porch = <40>; + hsync-len = <0>; + vback-porch = <32>; + vfront-porch = <11>; + vsync-len = <1>; + clock = <0>; /* unused but required */ + bpp = <16>; /* non-standard but required */ + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/vt8500.dtsi b/trunk/arch/arm/boot/dts/vt8500.dtsi index 68c8dc644383..cf31ced46602 100644 --- a/trunk/arch/arm/boot/dts/vt8500.dtsi +++ b/trunk/arch/arm/boot/dts/vt8500.dtsi @@ -98,10 +98,12 @@ interrupts = <43>; }; - fb: fb@d8050800 { + fb@d800e400 { compatible = "via,vt8500-fb"; reg = <0xd800e400 0x400>; interrupts = <12>; + display = <&display>; + default-mode = <&mode0>; }; ge_rops@d8050400 { diff --git a/trunk/arch/arm/boot/dts/wm8505-ref.dts b/trunk/arch/arm/boot/dts/wm8505-ref.dts index edd2cec3d37f..fd4e248074c6 100644 --- a/trunk/arch/arm/boot/dts/wm8505-ref.dts +++ b/trunk/arch/arm/boot/dts/wm8505-ref.dts @@ -11,22 +11,26 @@ / { model = "Wondermedia WM8505 Netbook"; -}; -&fb { - bits-per-pixel = <32>; - display-timings { - native-mode = <&timing0>; - timing0: 800x480 { - clock-frequency = <0>; /* unused but required */ - hactive = <800>; - vactive = <480>; - hfront-porch = <40>; - hback-porch = <88>; - hsync-len = <0>; - vback-porch = <32>; - vfront-porch = <11>; - vsync-len = <1>; + /* + * Display node is based on Sascha Hauer's patch on dri-devel. + * Added a bpp property to calculate the size of the framebuffer + * until the binding is formalized. + */ + display: display@0 { + modes { + mode0: mode@0 { + hactive = <800>; + vactive = <480>; + hback-porch = <88>; + hfront-porch = <40>; + hsync-len = <0>; + vback-porch = <32>; + vfront-porch = <11>; + vsync-len = <1>; + clock = <0>; /* unused but required */ + bpp = <32>; /* non-standard but required */ + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/wm8505.dtsi b/trunk/arch/arm/boot/dts/wm8505.dtsi index bcf668d31b28..e74a1c0fb9a2 100644 --- a/trunk/arch/arm/boot/dts/wm8505.dtsi +++ b/trunk/arch/arm/boot/dts/wm8505.dtsi @@ -128,9 +128,11 @@ interrupts = <0>; }; - fb: fb@d8050800 { + fb@d8050800 { compatible = "wm,wm8505-fb"; reg = <0xd8050800 0x200>; + display = <&display>; + default-mode = <&mode0>; }; ge_rops@d8050400 { diff --git a/trunk/arch/arm/boot/dts/wm8650-mid.dts b/trunk/arch/arm/boot/dts/wm8650-mid.dts index 61671a0d9ede..cefd938f842f 100644 --- a/trunk/arch/arm/boot/dts/wm8650-mid.dts +++ b/trunk/arch/arm/boot/dts/wm8650-mid.dts @@ -11,24 +11,26 @@ / { model = "Wondermedia WM8650-MID Tablet"; -}; - -&fb { - bits-per-pixel = <16>; - display-timings { - native-mode = <&timing0>; - timing0: 800x480 { - clock-frequency = <0>; /* unused but required */ - hactive = <800>; - vactive = <480>; - hfront-porch = <40>; - hback-porch = <88>; - hsync-len = <0>; - vback-porch = <32>; - vfront-porch = <11>; - vsync-len = <1>; + /* + * Display node is based on Sascha Hauer's patch on dri-devel. + * Added a bpp property to calculate the size of the framebuffer + * until the binding is formalized. + */ + display: display@0 { + modes { + mode0: mode@0 { + hactive = <800>; + vactive = <480>; + hback-porch = <88>; + hfront-porch = <40>; + hsync-len = <0>; + vback-porch = <32>; + vfront-porch = <11>; + vsync-len = <1>; + clock = <0>; /* unused but required */ + bpp = <16>; /* non-standard but required */ + }; }; }; }; - diff --git a/trunk/arch/arm/boot/dts/wm8650.dtsi b/trunk/arch/arm/boot/dts/wm8650.dtsi index 9313407bbc30..db3c0a12e052 100644 --- a/trunk/arch/arm/boot/dts/wm8650.dtsi +++ b/trunk/arch/arm/boot/dts/wm8650.dtsi @@ -128,9 +128,11 @@ interrupts = <43>; }; - fb: fb@d8050800 { + fb@d8050800 { compatible = "wm,wm8505-fb"; reg = <0xd8050800 0x200>; + display = <&display>; + default-mode = <&mode0>; }; ge_rops@d8050400 { diff --git a/trunk/arch/arm/boot/dts/wm8850-w70v2.dts b/trunk/arch/arm/boot/dts/wm8850-w70v2.dts index 32d22532cd6c..fcc660c89540 100644 --- a/trunk/arch/arm/boot/dts/wm8850-w70v2.dts +++ b/trunk/arch/arm/boot/dts/wm8850-w70v2.dts @@ -15,6 +15,28 @@ / { model = "Wondermedia WM8850-W70v2 Tablet"; + /* + * Display node is based on Sascha Hauer's patch on dri-devel. + * Added a bpp property to calculate the size of the framebuffer + * until the binding is formalized. + */ + display: display@0 { + modes { + mode0: mode@0 { + hactive = <800>; + vactive = <480>; + hback-porch = <88>; + hfront-porch = <40>; + hsync-len = <0>; + vback-porch = <32>; + vfront-porch = <11>; + vsync-len = <1>; + clock = <0>; /* unused but required */ + bpp = <16>; /* non-standard but required */ + }; + }; + }; + backlight { compatible = "pwm-backlight"; pwms = <&pwm 0 50000 1>; /* duty inverted */ @@ -23,21 +45,3 @@ default-brightness-level = <5>; }; }; - -&fb { - bits-per-pixel = <16>; - display-timings { - native-mode = <&timing0>; - timing0: 800x480 { - clock-frequency = <0>; /* unused but required */ - hactive = <800>; - vactive = <480>; - hfront-porch = <40>; - hback-porch = <88>; - hsync-len = <0>; - vback-porch = <32>; - vfront-porch = <11>; - vsync-len = <1>; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/wm8850.dtsi b/trunk/arch/arm/boot/dts/wm8850.dtsi index 7149cd13e3b9..e8cbfdc87bba 100644 --- a/trunk/arch/arm/boot/dts/wm8850.dtsi +++ b/trunk/arch/arm/boot/dts/wm8850.dtsi @@ -135,9 +135,11 @@ }; }; - fb: fb@d8051700 { + fb@d8051700 { compatible = "wm,wm8505-fb"; reg = <0xd8051700 0x200>; + display = <&display>; + default-mode = <&mode0>; }; ge_rops@d8050400 { diff --git a/trunk/arch/arm/configs/mxs_defconfig b/trunk/arch/arm/configs/mxs_defconfig index 6a99e30f81d2..fbbc5bb022d5 100644 --- a/trunk/arch/arm/configs/mxs_defconfig +++ b/trunk/arch/arm/configs/mxs_defconfig @@ -116,7 +116,6 @@ CONFIG_SND_SOC=y CONFIG_SND_MXS_SOC=y CONFIG_SND_SOC_MXS_SGTL5000=y CONFIG_USB=y -CONFIG_USB_EHCI_HCD=y CONFIG_USB_CHIPIDEA=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_STORAGE=y diff --git a/trunk/arch/arm/configs/omap2plus_defconfig b/trunk/arch/arm/configs/omap2plus_defconfig index bd07864f14a0..b16bae2c9a60 100644 --- a/trunk/arch/arm/configs/omap2plus_defconfig +++ b/trunk/arch/arm/configs/omap2plus_defconfig @@ -126,8 +126,6 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_TWL4030_PWRBUTTON=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=32 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y diff --git a/trunk/arch/arm/include/asm/delay.h b/trunk/arch/arm/include/asm/delay.h index dff714d886d5..720799fd3a81 100644 --- a/trunk/arch/arm/include/asm/delay.h +++ b/trunk/arch/arm/include/asm/delay.h @@ -24,7 +24,7 @@ extern struct arm_delay_ops { void (*delay)(unsigned long); void (*const_udelay)(unsigned long); void (*udelay)(unsigned long); - unsigned long ticks_per_jiffy; + bool const_clock; } arm_delay_ops; #define __delay(n) arm_delay_ops.delay(n) diff --git a/trunk/arch/arm/include/asm/glue-cache.h b/trunk/arch/arm/include/asm/glue-cache.h index ea289e1435e7..cca9f15704ed 100644 --- a/trunk/arch/arm/include/asm/glue-cache.h +++ b/trunk/arch/arm/include/asm/glue-cache.h @@ -19,6 +19,14 @@ #undef _CACHE #undef MULTI_CACHE +#if defined(CONFIG_CPU_CACHE_V3) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v3 +# endif +#endif + #if defined(CONFIG_CPU_CACHE_V4) # ifdef _CACHE # define MULTI_CACHE 1 diff --git a/trunk/arch/arm/include/asm/hardware/iop3xx.h b/trunk/arch/arm/include/asm/hardware/iop3xx.h index ed94b1a366ae..02fe2fbe2477 100644 --- a/trunk/arch/arm/include/asm/hardware/iop3xx.h +++ b/trunk/arch/arm/include/asm/hardware/iop3xx.h @@ -37,7 +37,7 @@ extern int iop3xx_get_init_atu(void); * IOP3XX processor registers */ #define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000 -#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfedfe000 +#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfeffe000 #define IOP3XX_PERIPHERAL_SIZE 0x00002000 #define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\ IOP3XX_PERIPHERAL_SIZE - 1) diff --git a/trunk/arch/arm/include/asm/highmem.h b/trunk/arch/arm/include/asm/highmem.h index 91b99abe7a95..8c5e828f484d 100644 --- a/trunk/arch/arm/include/asm/highmem.h +++ b/trunk/arch/arm/include/asm/highmem.h @@ -41,13 +41,6 @@ extern void kunmap_high(struct page *page); #endif #endif -/* - * Needed to be able to broadcast the TLB invalidation for kmap. - */ -#ifdef CONFIG_ARM_ERRATA_798181 -#undef ARCH_NEEDS_KMAP_HIGH_GET -#endif - #ifdef ARCH_NEEDS_KMAP_HIGH_GET extern void *kmap_high_get(struct page *page); #else diff --git a/trunk/arch/arm/include/asm/mmu.h b/trunk/arch/arm/include/asm/mmu.h index e3d55547e755..9f77e7804f3b 100644 --- a/trunk/arch/arm/include/asm/mmu.h +++ b/trunk/arch/arm/include/asm/mmu.h @@ -5,15 +5,15 @@ typedef struct { #ifdef CONFIG_CPU_HAS_ASID - atomic64_t id; + u64 id; #endif - unsigned int vmalloc_seq; + unsigned int vmalloc_seq; } mm_context_t; #ifdef CONFIG_CPU_HAS_ASID #define ASID_BITS 8 #define ASID_MASK ((~0ULL) << ASID_BITS) -#define ASID(mm) ((mm)->context.id.counter & ~ASID_MASK) +#define ASID(mm) ((mm)->context.id & ~ASID_MASK) #else #define ASID(mm) (0) #endif @@ -26,7 +26,7 @@ typedef struct { * modified for 2.6 by Hyok S. Choi */ typedef struct { - unsigned long end_brk; + unsigned long end_brk; } mm_context_t; #endif diff --git a/trunk/arch/arm/include/asm/mmu_context.h b/trunk/arch/arm/include/asm/mmu_context.h index a7b85e0d0cc1..e1f644bc7cc5 100644 --- a/trunk/arch/arm/include/asm/mmu_context.h +++ b/trunk/arch/arm/include/asm/mmu_context.h @@ -25,9 +25,7 @@ void __check_vmalloc_seq(struct mm_struct *mm); #ifdef CONFIG_CPU_HAS_ASID void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk); -#define init_new_context(tsk,mm) ({ atomic64_set(&mm->context.id, 0); 0; }) - -DECLARE_PER_CPU(atomic64_t, active_asids); +#define init_new_context(tsk,mm) ({ mm->context.id = 0; }) #else /* !CONFIG_CPU_HAS_ASID */ diff --git a/trunk/arch/arm/include/asm/pgtable-3level.h b/trunk/arch/arm/include/asm/pgtable-3level.h index 86b8fe398b95..6ef8afd1b64c 100644 --- a/trunk/arch/arm/include/asm/pgtable-3level.h +++ b/trunk/arch/arm/include/asm/pgtable-3level.h @@ -111,7 +111,7 @@ #define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */ #define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */ #define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */ -#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ +#define L_PTE_S2_RDWR (_AT(pteval_t, 2) << 6) /* HAP[2:1] */ /* * Hyp-mode PL2 PTE definitions for LPAE. diff --git a/trunk/arch/arm/include/asm/tlbflush.h b/trunk/arch/arm/include/asm/tlbflush.h index ab865e65a84c..6e924d3a77eb 100644 --- a/trunk/arch/arm/include/asm/tlbflush.h +++ b/trunk/arch/arm/include/asm/tlbflush.h @@ -14,6 +14,7 @@ #include +#define TLB_V3_PAGE (1 << 0) #define TLB_V4_U_PAGE (1 << 1) #define TLB_V4_D_PAGE (1 << 2) #define TLB_V4_I_PAGE (1 << 3) @@ -21,6 +22,7 @@ #define TLB_V6_D_PAGE (1 << 5) #define TLB_V6_I_PAGE (1 << 6) +#define TLB_V3_FULL (1 << 8) #define TLB_V4_U_FULL (1 << 9) #define TLB_V4_D_FULL (1 << 10) #define TLB_V4_I_FULL (1 << 11) @@ -32,13 +34,10 @@ #define TLB_V6_D_ASID (1 << 17) #define TLB_V6_I_ASID (1 << 18) -#define TLB_V6_BP (1 << 19) - /* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */ -#define TLB_V7_UIS_PAGE (1 << 20) -#define TLB_V7_UIS_FULL (1 << 21) -#define TLB_V7_UIS_ASID (1 << 22) -#define TLB_V7_UIS_BP (1 << 23) +#define TLB_V7_UIS_PAGE (1 << 19) +#define TLB_V7_UIS_FULL (1 << 20) +#define TLB_V7_UIS_ASID (1 << 21) #define TLB_BARRIER (1 << 28) #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ @@ -50,6 +49,7 @@ * ============= * * We have the following to choose from: + * v3 - ARMv3 * v4 - ARMv4 without write buffer * v4wb - ARMv4 with write buffer without I TLB flush entry instruction * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction @@ -150,8 +150,7 @@ #define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ TLB_V6_I_FULL | TLB_V6_D_FULL | \ TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ - TLB_V6_I_ASID | TLB_V6_D_ASID | \ - TLB_V6_BP) + TLB_V6_I_ASID | TLB_V6_D_ASID) #ifdef CONFIG_CPU_TLB_V6 # define v6wbi_possible_flags v6wbi_tlb_flags @@ -167,11 +166,9 @@ #endif #define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ - TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | \ - TLB_V7_UIS_ASID | TLB_V7_UIS_BP) + TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) #define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ - TLB_V6_U_FULL | TLB_V6_U_PAGE | \ - TLB_V6_U_ASID | TLB_V6_BP) + TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID) #ifdef CONFIG_CPU_TLB_V7 @@ -327,6 +324,7 @@ static inline void local_flush_tlb_all(void) if (tlb_flag(TLB_WB)) dsb(); + tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); @@ -347,8 +345,9 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) if (tlb_flag(TLB_WB)) dsb(); - if (possible_tlb_flags & (TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { + if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { + tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); @@ -380,8 +379,9 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) if (tlb_flag(TLB_WB)) dsb(); - if (possible_tlb_flags & (TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && + if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { + tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr); tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr); tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr); @@ -412,6 +412,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) if (tlb_flag(TLB_WB)) dsb(); + tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr); tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); @@ -429,35 +430,6 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) } } -static inline void local_flush_bp_all(void) -{ - const int zero = 0; - const unsigned int __tlb_flag = __cpu_tlb_flags; - - if (tlb_flag(TLB_V7_UIS_BP)) - asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero)); - else if (tlb_flag(TLB_V6_BP)) - asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero)); - - if (tlb_flag(TLB_BARRIER)) - isb(); -} - -#ifdef CONFIG_ARM_ERRATA_798181 -static inline void dummy_flush_tlb_a15_erratum(void) -{ - /* - * Dummy TLBIMVAIS. Using the unmapped address 0 and ASID 0. - */ - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); - dsb(); -} -#else -static inline void dummy_flush_tlb_a15_erratum(void) -{ -} -#endif - /* * flush_pmd_entry * @@ -508,7 +480,6 @@ static inline void clean_pmd_entry(void *pmd) #define flush_tlb_kernel_page local_flush_tlb_kernel_page #define flush_tlb_range local_flush_tlb_range #define flush_tlb_kernel_range local_flush_tlb_kernel_range -#define flush_bp_all local_flush_bp_all #else extern void flush_tlb_all(void); extern void flush_tlb_mm(struct mm_struct *mm); @@ -516,7 +487,6 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr); extern void flush_tlb_kernel_page(unsigned long kaddr); extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); -extern void flush_bp_all(void); #endif /* diff --git a/trunk/arch/arm/include/asm/xen/events.h b/trunk/arch/arm/include/asm/xen/events.h index 8b1f37bfeeec..5c27696de14f 100644 --- a/trunk/arch/arm/include/asm/xen/events.h +++ b/trunk/arch/arm/include/asm/xen/events.h @@ -2,7 +2,6 @@ #define _ASM_ARM_XEN_EVENTS_H #include -#include enum ipi_vector { XEN_PLACEHOLDER_VECTOR, @@ -16,8 +15,26 @@ static inline int xen_irqs_disabled(struct pt_regs *regs) return raw_irqs_disabled_flags(regs->ARM_cpsr); } -#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr), \ - atomic64_t, \ - counter), (val)) +/* + * We cannot use xchg because it does not support 8-byte + * values. However it is safe to use {ldr,dtd}exd directly because all + * platforms which Xen can run on support those instructions. + */ +static inline xen_ulong_t xchg_xen_ulong(xen_ulong_t *ptr, xen_ulong_t val) +{ + xen_ulong_t oldval; + unsigned int tmp; + + wmb(); + asm volatile("@ xchg_xen_ulong\n" + "1: ldrexd %0, %H0, [%3]\n" + " strexd %1, %2, %H2, [%3]\n" + " teq %1, #0\n" + " bne 1b" + : "=&r" (oldval), "=&r" (tmp) + : "r" (val), "r" (ptr) + : "memory", "cc"); + return oldval; +} #endif /* _ASM_ARM_XEN_EVENTS_H */ diff --git a/trunk/arch/arm/include/uapi/asm/unistd.h b/trunk/arch/arm/include/uapi/asm/unistd.h index af33b44990ed..4da7cde70b5d 100644 --- a/trunk/arch/arm/include/uapi/asm/unistd.h +++ b/trunk/arch/arm/include/uapi/asm/unistd.h @@ -404,7 +404,7 @@ #define __NR_setns (__NR_SYSCALL_BASE+375) #define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) -#define __NR_kcmp (__NR_SYSCALL_BASE+378) + /* 378 for kcmp */ #define __NR_finit_module (__NR_SYSCALL_BASE+379) /* diff --git a/trunk/arch/arm/kernel/asm-offsets.c b/trunk/arch/arm/kernel/asm-offsets.c index 923eec7105cf..5ce738b43508 100644 --- a/trunk/arch/arm/kernel/asm-offsets.c +++ b/trunk/arch/arm/kernel/asm-offsets.c @@ -110,7 +110,7 @@ int main(void) BLANK(); #endif #ifdef CONFIG_CPU_HAS_ASID - DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter)); + DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); BLANK(); #endif DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); diff --git a/trunk/arch/arm/kernel/calls.S b/trunk/arch/arm/kernel/calls.S index c6ca7e376773..0cc57611fc4f 100644 --- a/trunk/arch/arm/kernel/calls.S +++ b/trunk/arch/arm/kernel/calls.S @@ -387,7 +387,7 @@ /* 375 */ CALL(sys_setns) CALL(sys_process_vm_readv) CALL(sys_process_vm_writev) - CALL(sys_kcmp) + CALL(sys_ni_syscall) /* reserved for sys_kcmp */ CALL(sys_finit_module) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index fefd7f971437..3248cde504ed 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -276,13 +276,7 @@ ENDPROC(ftrace_graph_caller_old) */ .macro mcount_enter -/* - * This pad compensates for the push {lr} at the call site. Note that we are - * unable to unwind through a function which does not otherwise save its lr. - */ - UNWIND(.pad #4) stmdb sp!, {r0-r3, lr} - UNWIND(.save {r0-r3, lr}) .endm .macro mcount_get_lr reg @@ -295,7 +289,6 @@ ENDPROC(ftrace_graph_caller_old) .endm ENTRY(__gnu_mcount_nc) -UNWIND(.fnstart) #ifdef CONFIG_DYNAMIC_FTRACE mov ip, lr ldmia sp!, {lr} @@ -303,22 +296,17 @@ UNWIND(.fnstart) #else __mcount #endif -UNWIND(.fnend) ENDPROC(__gnu_mcount_nc) #ifdef CONFIG_DYNAMIC_FTRACE ENTRY(ftrace_caller) -UNWIND(.fnstart) __ftrace_caller -UNWIND(.fnend) ENDPROC(ftrace_caller) #endif #ifdef CONFIG_FUNCTION_GRAPH_TRACER ENTRY(ftrace_graph_caller) -UNWIND(.fnstart) __ftrace_graph_caller -UNWIND(.fnend) ENDPROC(ftrace_graph_caller) #endif diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 8bac553fe213..486a15ae9011 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -184,22 +184,13 @@ __create_page_tables: orr r3, r3, #3 @ PGD block type mov r6, #4 @ PTRS_PER_PGD mov r7, #1 << (55 - 32) @ L_PGD_SWAPPER -1: -#ifdef CONFIG_CPU_ENDIAN_BE8 +1: str r3, [r0], #4 @ set bottom PGD entry bits str r7, [r0], #4 @ set top PGD entry bits - str r3, [r0], #4 @ set bottom PGD entry bits -#else - str r3, [r0], #4 @ set bottom PGD entry bits - str r7, [r0], #4 @ set top PGD entry bits -#endif add r3, r3, #0x1000 @ next PMD table subs r6, r6, #1 bne 1b add r4, r4, #0x1000 @ point to the PMD tables -#ifdef CONFIG_CPU_ENDIAN_BE8 - add r4, r4, #4 @ we only write the bottom word -#endif #endif ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags @@ -267,11 +258,6 @@ __create_page_tables: addne r6, r6, #1 << SECTION_SHIFT strne r6, [r3] -#if defined(CONFIG_ARM_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8) - sub r4, r4, #4 @ Fixup page table pointer - @ for 64-bit descriptors -#endif - #ifdef CONFIG_DEBUG_LL #if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING) /* @@ -290,16 +276,12 @@ __create_page_tables: orr r3, r7, r3, lsl #SECTION_SHIFT #ifdef CONFIG_ARM_LPAE mov r7, #1 << (54 - 32) @ XN -#ifdef CONFIG_CPU_ENDIAN_BE8 - str r7, [r0], #4 - str r3, [r0], #4 -#else - str r3, [r0], #4 - str r7, [r0], #4 -#endif #else orr r3, r3, #PMD_SECT_XN +#endif str r3, [r0], #4 +#ifdef CONFIG_ARM_LPAE + str r7, [r0], #4 #endif #else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */ diff --git a/trunk/arch/arm/kernel/hw_breakpoint.c b/trunk/arch/arm/kernel/hw_breakpoint.c index 1fd749ee4a1b..5eae53e7a2e1 100644 --- a/trunk/arch/arm/kernel/hw_breakpoint.c +++ b/trunk/arch/arm/kernel/hw_breakpoint.c @@ -966,7 +966,7 @@ static void reset_ctrl_regs(void *unused) } if (err) { - pr_warn_once("CPU %d debug is powered down!\n", cpu); + pr_warning("CPU %d debug is powered down!\n", cpu); cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); return; } @@ -987,7 +987,7 @@ static void reset_ctrl_regs(void *unused) isb(); if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { - pr_warn_once("CPU %d failed to disable vector catch\n", cpu); + pr_warning("CPU %d failed to disable vector catch\n", cpu); return; } @@ -1007,7 +1007,7 @@ static void reset_ctrl_regs(void *unused) } if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { - pr_warn_once("CPU %d failed to clear debug register pairs\n", cpu); + pr_warning("CPU %d failed to clear debug register pairs\n", cpu); return; } @@ -1023,7 +1023,7 @@ static void reset_ctrl_regs(void *unused) static int __cpuinit dbg_reset_notify(struct notifier_block *self, unsigned long action, void *cpu) { - if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE) + if (action == CPU_ONLINE) smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1); return NOTIFY_OK; @@ -1043,7 +1043,7 @@ static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action, return NOTIFY_OK; } -static struct notifier_block dbg_cpu_pm_nb = { +static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = { .notifier_call = dbg_cpu_pm_notify, }; diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 8c3094d0f7b7..31e0eb353cd8 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -253,10 +253,7 @@ validate_event(struct pmu_hw_events *hw_events, struct arm_pmu *armpmu = to_arm_pmu(event->pmu); struct pmu *leader_pmu = event->group_leader->pmu; - if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) - return 1; - - if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) + if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF) return 1; return armpmu->get_event_idx(hw_events, event) >= 0; @@ -403,7 +400,7 @@ __hw_perf_event_init(struct perf_event *event) } if (event->group_leader != event) { - if (validate_group(event) != 0) + if (validate_group(event) != 0); return -EINVAL; } @@ -487,7 +484,7 @@ const struct dev_pm_ops armpmu_dev_pm_ops = { SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL) }; -static void armpmu_init(struct arm_pmu *armpmu) +static void __init armpmu_init(struct arm_pmu *armpmu) { atomic_set(&armpmu->active_events, 0); mutex_init(&armpmu->reserve_mutex); diff --git a/trunk/arch/arm/kernel/perf_event_v7.c b/trunk/arch/arm/kernel/perf_event_v7.c index 039cffb053a7..8c79a9e70b83 100644 --- a/trunk/arch/arm/kernel/perf_event_v7.c +++ b/trunk/arch/arm/kernel/perf_event_v7.c @@ -774,7 +774,7 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] /* * PMXEVTYPER: Event selection reg */ -#define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */ +#define ARMV7_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */ #define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */ /* diff --git a/trunk/arch/arm/kernel/sched_clock.c b/trunk/arch/arm/kernel/sched_clock.c index 59d2adb764a9..bd6f56b9ec21 100644 --- a/trunk/arch/arm/kernel/sched_clock.c +++ b/trunk/arch/arm/kernel/sched_clock.c @@ -45,12 +45,12 @@ static u32 notrace jiffy_sched_clock_read(void) static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read; -static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift) +static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) { return (cyc * mult) >> shift; } -static unsigned long long notrace cyc_to_sched_clock(u32 cyc, u32 mask) +static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask) { u64 epoch_ns; u32 epoch_cyc; diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 234e339196c0..3f6cbb2e3eda 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -56,6 +56,7 @@ #include #include "atags.h" +#include "tcm.h" #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) @@ -352,23 +353,6 @@ void __init early_print(const char *str, ...) printk("%s", buf); } -static void __init cpuid_init_hwcaps(void) -{ - unsigned int divide_instrs; - - if (cpu_architecture() < CPU_ARCH_ARMv7) - return; - - divide_instrs = (read_cpuid_ext(CPUID_EXT_ISAR0) & 0x0f000000) >> 24; - - switch (divide_instrs) { - case 2: - elf_hwcap |= HWCAP_IDIVA; - case 1: - elf_hwcap |= HWCAP_IDIVT; - } -} - static void __init feat_v6_fixup(void) { int id = read_cpuid_id(); @@ -499,11 +483,8 @@ static void __init setup_processor(void) snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; - - cpuid_init_hwcaps(); - #ifndef CONFIG_ARM_THUMB - elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT); + elf_hwcap &= ~HWCAP_THUMB; #endif feat_v6_fixup(); @@ -543,7 +524,7 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size) size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); -#ifndef CONFIG_ARM_LPAE +#ifndef CONFIG_LPAE if (bank->start + size < bank->start) { printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " "32-bit physical address space\n", (long long)start); @@ -797,6 +778,8 @@ void __init setup_arch(char **cmdline_p) reserve_crashkernel(); + tcm_init(); + #ifdef CONFIG_MULTI_IRQ_HANDLER handle_arch_irq = mdesc->handle_irq; #endif diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 1f2ccccaf009..1bdfd87c8e41 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -285,7 +285,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * switch away from it before attempting any exclusive accesses. */ cpu_switch_mm(mm->pgd, mm); - local_flush_bp_all(); enter_lazy_tlb(mm, current); local_flush_tlb_all(); @@ -480,7 +479,7 @@ static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) evt->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_DUMMY; - evt->rating = 100; + evt->rating = 400; evt->mult = 1; evt->set_mode = broadcast_timer_set_mode; @@ -673,6 +672,9 @@ static int cpufreq_callback(struct notifier_block *nb, if (freq->flags & CPUFREQ_CONST_LOOPS) return NOTIFY_OK; + if (arm_delay_ops.const_clock) + return NOTIFY_OK; + if (!per_cpu(l_p_j_ref, cpu)) { per_cpu(l_p_j_ref, cpu) = per_cpu(cpu_data, cpu).loops_per_jiffy; diff --git a/trunk/arch/arm/kernel/smp_tlb.c b/trunk/arch/arm/kernel/smp_tlb.c index e82e1d248772..02c5d2ce23bf 100644 --- a/trunk/arch/arm/kernel/smp_tlb.c +++ b/trunk/arch/arm/kernel/smp_tlb.c @@ -12,7 +12,6 @@ #include #include -#include /**********************************************************************/ @@ -65,77 +64,12 @@ static inline void ipi_flush_tlb_kernel_range(void *arg) local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end); } -static inline void ipi_flush_bp_all(void *ignored) -{ - local_flush_bp_all(); -} - -#ifdef CONFIG_ARM_ERRATA_798181 -static int erratum_a15_798181(void) -{ - unsigned int midr = read_cpuid_id(); - - /* Cortex-A15 r0p0..r3p2 affected */ - if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2) - return 0; - return 1; -} -#else -static int erratum_a15_798181(void) -{ - return 0; -} -#endif - -static void ipi_flush_tlb_a15_erratum(void *arg) -{ - dmb(); -} - -static void broadcast_tlb_a15_erratum(void) -{ - if (!erratum_a15_798181()) - return; - - dummy_flush_tlb_a15_erratum(); - smp_call_function_many(cpu_online_mask, ipi_flush_tlb_a15_erratum, - NULL, 1); -} - -static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) -{ - int cpu; - cpumask_t mask = { CPU_BITS_NONE }; - - if (!erratum_a15_798181()) - return; - - dummy_flush_tlb_a15_erratum(); - for_each_online_cpu(cpu) { - if (cpu == smp_processor_id()) - continue; - /* - * We only need to send an IPI if the other CPUs are running - * the same ASID as the one being invalidated. There is no - * need for locking around the active_asids check since the - * switch_mm() function has at least one dmb() (as required by - * this workaround) in case a context switch happens on - * another CPU after the condition below. - */ - if (atomic64_read(&mm->context.id) == - atomic64_read(&per_cpu(active_asids, cpu))) - cpumask_set_cpu(cpu, &mask); - } - smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1); -} - void flush_tlb_all(void) { if (tlb_ops_need_broadcast()) on_each_cpu(ipi_flush_tlb_all, NULL, 1); else local_flush_tlb_all(); - broadcast_tlb_a15_erratum(); } void flush_tlb_mm(struct mm_struct *mm) @@ -144,7 +78,6 @@ void flush_tlb_mm(struct mm_struct *mm) on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); else local_flush_tlb_mm(mm); - broadcast_tlb_mm_a15_erratum(mm); } void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) @@ -157,7 +90,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) &ta, 1); } else local_flush_tlb_page(vma, uaddr); - broadcast_tlb_mm_a15_erratum(vma->vm_mm); } void flush_tlb_kernel_page(unsigned long kaddr) @@ -168,7 +100,6 @@ void flush_tlb_kernel_page(unsigned long kaddr) on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); } else local_flush_tlb_kernel_page(kaddr); - broadcast_tlb_a15_erratum(); } void flush_tlb_range(struct vm_area_struct *vma, @@ -183,7 +114,6 @@ void flush_tlb_range(struct vm_area_struct *vma, &ta, 1); } else local_flush_tlb_range(vma, start, end); - broadcast_tlb_mm_a15_erratum(vma->vm_mm); } void flush_tlb_kernel_range(unsigned long start, unsigned long end) @@ -195,13 +125,5 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end) on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1); } else local_flush_tlb_kernel_range(start, end); - broadcast_tlb_a15_erratum(); } -void flush_bp_all(void) -{ - if (tlb_ops_need_broadcast()) - on_each_cpu(ipi_flush_bp_all, NULL, 1); - else - local_flush_bp_all(); -} diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c index 3f2565037480..c092115d903a 100644 --- a/trunk/arch/arm/kernel/smp_twd.c +++ b/trunk/arch/arm/kernel/smp_twd.c @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -374,9 +373,6 @@ void __init twd_local_timer_of_register(void) struct device_node *np; int err; - if (!is_smp() || !setup_max_cpus) - return; - np = of_find_matching_node(NULL, twd_of_match); if (!np) return; diff --git a/trunk/arch/arm/kernel/suspend.c b/trunk/arch/arm/kernel/suspend.c index c59c97ea8268..358bca3a995e 100644 --- a/trunk/arch/arm/kernel/suspend.c +++ b/trunk/arch/arm/kernel/suspend.c @@ -68,7 +68,6 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) ret = __cpu_suspend(arg, fn); if (ret == 0) { cpu_switch_mm(mm->pgd, mm); - local_flush_bp_all(); local_flush_tlb_all(); } diff --git a/trunk/arch/arm/kernel/tcm.c b/trunk/arch/arm/kernel/tcm.c index f50f19e5c138..30ae6bb4a310 100644 --- a/trunk/arch/arm/kernel/tcm.c +++ b/trunk/arch/arm/kernel/tcm.c @@ -17,6 +17,7 @@ #include #include #include +#include "tcm.h" static struct gen_pool *tcm_pool; static bool dtcm_present; diff --git a/trunk/arch/arm/mm/tcm.h b/trunk/arch/arm/kernel/tcm.h similarity index 100% rename from trunk/arch/arm/mm/tcm.h rename to trunk/arch/arm/kernel/tcm.h diff --git a/trunk/arch/arm/kvm/arm.c b/trunk/arch/arm/kvm/arm.c index c1fe498983ac..5a936988eb24 100644 --- a/trunk/arch/arm/kvm/arm.c +++ b/trunk/arch/arm/kvm/arm.c @@ -201,7 +201,6 @@ int kvm_dev_ioctl_check_extension(long ext) break; case KVM_CAP_ARM_SET_DEVICE_ADDR: r = 1; - break; case KVM_CAP_NR_VCPUS: r = num_online_cpus(); break; diff --git a/trunk/arch/arm/kvm/coproc.c b/trunk/arch/arm/kvm/coproc.c index 7bed7556077a..4ea9a982269c 100644 --- a/trunk/arch/arm/kvm/coproc.c +++ b/trunk/arch/arm/kvm/coproc.c @@ -79,11 +79,11 @@ static bool access_dcsw(struct kvm_vcpu *vcpu, u32 val; int cpu; + cpu = get_cpu(); + if (!p->is_write) return read_from_write_only(vcpu, p); - cpu = get_cpu(); - cpumask_setall(&vcpu->arch.require_dcache_flush); cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush); diff --git a/trunk/arch/arm/kvm/vgic.c b/trunk/arch/arm/kvm/vgic.c index 0e4cfe123b38..c9a17316e9fe 100644 --- a/trunk/arch/arm/kvm/vgic.c +++ b/trunk/arch/arm/kvm/vgic.c @@ -883,7 +883,8 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) lr, irq, vgic_cpu->vgic_lr[lr]); BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT; - return true; + + goto out; } /* Try to use another LR for this interrupt */ @@ -897,6 +898,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) vgic_cpu->vgic_irq_lr_map[irq] = lr; set_bit(lr, vgic_cpu->lr_used); +out: if (!vgic_irq_is_edge(vcpu, irq)) vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI; @@ -1016,6 +1018,21 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr); + /* + * We do not need to take the distributor lock here, since the only + * action we perform is clearing the irq_active_bit for an EOIed + * level interrupt. There is a potential race with + * the queuing of an interrupt in __kvm_vgic_flush_hwstate(), where we + * check if the interrupt is already active. Two possibilities: + * + * - The queuing is occurring on the same vcpu: cannot happen, + * as we're already in the context of this vcpu, and + * executing the handler + * - The interrupt has been migrated to another vcpu, and we + * ignore this interrupt for this run. Big deal. It is still + * pending though, and will get considered when this vcpu + * exits. + */ if (vgic_cpu->vgic_misr & GICH_MISR_EOI) { /* * Some level interrupts have been EOIed. Clear their @@ -1037,13 +1054,6 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } else { vgic_cpu_irq_clear(vcpu, irq); } - - /* - * Despite being EOIed, the LR may not have - * been marked as empty. - */ - set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); - vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT; } } @@ -1054,8 +1064,9 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } /* - * Sync back the VGIC state after a guest run. The distributor lock is - * needed so we don't get preempted in the middle of the state processing. + * Sync back the VGIC state after a guest run. We do not really touch + * the distributor here (the irq_pending_on_cpu bit is safe to set), + * so there is no need for taking its lock. */ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { @@ -1101,14 +1112,10 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { - struct vgic_dist *dist = &vcpu->kvm->arch.vgic; - if (!irqchip_in_kernel(vcpu->kvm)) return; - spin_lock(&dist->lock); __kvm_vgic_sync_hwstate(vcpu); - spin_unlock(&dist->lock); } int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/arm/lib/delay.c b/trunk/arch/arm/lib/delay.c index 64dbfa57204a..6b93f6a1a3c7 100644 --- a/trunk/arch/arm/lib/delay.c +++ b/trunk/arch/arm/lib/delay.c @@ -58,7 +58,7 @@ static void __timer_delay(unsigned long cycles) static void __timer_const_udelay(unsigned long xloops) { unsigned long long loops = xloops; - loops *= arm_delay_ops.ticks_per_jiffy; + loops *= loops_per_jiffy; __timer_delay(loops >> UDELAY_SHIFT); } @@ -73,13 +73,11 @@ void __init register_current_timer_delay(const struct delay_timer *timer) pr_info("Switching to timer-based delay loop\n"); delay_timer = timer; lpj_fine = timer->freq / HZ; - - /* cpufreq may scale loops_per_jiffy, so keep a private copy */ - arm_delay_ops.ticks_per_jiffy = lpj_fine; + loops_per_jiffy = lpj_fine; arm_delay_ops.delay = __timer_delay; arm_delay_ops.const_udelay = __timer_const_udelay; arm_delay_ops.udelay = __timer_udelay; - + arm_delay_ops.const_clock = true; delay_calibrated = true; } else { pr_info("Ignoring duplicate/late registration of read_current_timer delay\n"); diff --git a/trunk/arch/arm/lib/memset.S b/trunk/arch/arm/lib/memset.S index 94b0650ea98f..650d5923ab83 100644 --- a/trunk/arch/arm/lib/memset.S +++ b/trunk/arch/arm/lib/memset.S @@ -14,15 +14,27 @@ .text .align 5 + .word 0 + +1: subs r2, r2, #4 @ 1 do we have enough + blt 5f @ 1 bytes to align with? + cmp r3, #2 @ 1 + strltb r1, [r0], #1 @ 1 + strleb r1, [r0], #1 @ 1 + strb r1, [r0], #1 @ 1 + add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) +/* + * The pointer is now aligned and the length is adjusted. Try doing the + * memset again. + */ ENTRY(memset) ands r3, r0, #3 @ 1 unaligned? - mov ip, r0 @ preserve r0 as return value - bne 6f @ 1 + bne 1b @ 1 /* - * we know that the pointer in ip is aligned to a word boundary. + * we know that the pointer in r0 is aligned to a word boundary. */ -1: orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #8 orr r1, r1, r1, lsl #16 mov r3, r1 cmp r2, #16 @@ -31,28 +43,29 @@ ENTRY(memset) #if ! CALGN(1)+0 /* - * We need 2 extra registers for this loop - use r8 and the LR + * We need an extra register for this loop - save the return address and + * use the LR */ - stmfd sp!, {r8, lr} - mov r8, r1 + str lr, [sp, #-4]! + mov ip, r1 mov lr, r1 2: subs r2, r2, #64 - stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time. - stmgeia ip!, {r1, r3, r8, lr} - stmgeia ip!, {r1, r3, r8, lr} - stmgeia ip!, {r1, r3, r8, lr} + stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time. + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} bgt 2b - ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go. + ldmeqfd sp!, {pc} @ Now <64 bytes to go. /* * No need to correct the count; we're only testing bits from now on */ tst r2, #32 - stmneia ip!, {r1, r3, r8, lr} - stmneia ip!, {r1, r3, r8, lr} + stmneia r0!, {r1, r3, ip, lr} + stmneia r0!, {r1, r3, ip, lr} tst r2, #16 - stmneia ip!, {r1, r3, r8, lr} - ldmfd sp!, {r8, lr} + stmneia r0!, {r1, r3, ip, lr} + ldr lr, [sp], #4 #else @@ -61,63 +74,54 @@ ENTRY(memset) * whole cache lines at once. */ - stmfd sp!, {r4-r8, lr} + stmfd sp!, {r4-r7, lr} mov r4, r1 mov r5, r1 mov r6, r1 mov r7, r1 - mov r8, r1 + mov ip, r1 mov lr, r1 cmp r2, #96 - tstgt ip, #31 + tstgt r0, #31 ble 3f - and r8, ip, #31 - rsb r8, r8, #32 - sub r2, r2, r8 - movs r8, r8, lsl #(32 - 4) - stmcsia ip!, {r4, r5, r6, r7} - stmmiia ip!, {r4, r5} - tst r8, #(1 << 30) - mov r8, r1 - strne r1, [ip], #4 + and ip, r0, #31 + rsb ip, ip, #32 + sub r2, r2, ip + movs ip, ip, lsl #(32 - 4) + stmcsia r0!, {r4, r5, r6, r7} + stmmiia r0!, {r4, r5} + tst ip, #(1 << 30) + mov ip, r1 + strne r1, [r0], #4 3: subs r2, r2, #64 - stmgeia ip!, {r1, r3-r8, lr} - stmgeia ip!, {r1, r3-r8, lr} + stmgeia r0!, {r1, r3-r7, ip, lr} + stmgeia r0!, {r1, r3-r7, ip, lr} bgt 3b - ldmeqfd sp!, {r4-r8, pc} + ldmeqfd sp!, {r4-r7, pc} tst r2, #32 - stmneia ip!, {r1, r3-r8, lr} + stmneia r0!, {r1, r3-r7, ip, lr} tst r2, #16 - stmneia ip!, {r4-r7} - ldmfd sp!, {r4-r8, lr} + stmneia r0!, {r4-r7} + ldmfd sp!, {r4-r7, lr} #endif 4: tst r2, #8 - stmneia ip!, {r1, r3} + stmneia r0!, {r1, r3} tst r2, #4 - strne r1, [ip], #4 + strne r1, [r0], #4 /* * When we get here, we've got less than 4 bytes to zero. We * may have an unaligned pointer as well. */ 5: tst r2, #2 - strneb r1, [ip], #1 - strneb r1, [ip], #1 + strneb r1, [r0], #1 + strneb r1, [r0], #1 tst r2, #1 - strneb r1, [ip], #1 + strneb r1, [r0], #1 mov pc, lr - -6: subs r2, r2, #4 @ 1 do we have enough - blt 5b @ 1 bytes to align with? - cmp r3, #2 @ 1 - strltb r1, [ip], #1 @ 1 - strleb r1, [ip], #1 @ 1 - strb r1, [ip], #1 @ 1 - add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) - b 1b ENDPROC(memset) diff --git a/trunk/arch/arm/mach-at91/board-foxg20.c b/trunk/arch/arm/mach-at91/board-foxg20.c index c20a870ea9c9..2ea7059b840b 100644 --- a/trunk/arch/arm/mach-at91/board-foxg20.c +++ b/trunk/arch/arm/mach-at91/board-foxg20.c @@ -176,7 +176,6 @@ static struct w1_gpio_platform_data w1_gpio_pdata = { /* If you choose to use a pin other than PB16 it needs to be 3.3V */ .pin = AT91_PIN_PB16, .is_open_drain = 1, - .ext_pullup_enable_pin = -EINVAL, }; static struct platform_device w1_device = { diff --git a/trunk/arch/arm/mach-at91/board-stamp9g20.c b/trunk/arch/arm/mach-at91/board-stamp9g20.c index 869cbecf00b7..a033b8df9fb2 100644 --- a/trunk/arch/arm/mach-at91/board-stamp9g20.c +++ b/trunk/arch/arm/mach-at91/board-stamp9g20.c @@ -188,7 +188,6 @@ static struct spi_board_info portuxg20_spi_devices[] = { static struct w1_gpio_platform_data w1_gpio_pdata = { .pin = AT91_PIN_PA29, .is_open_drain = 1, - .ext_pullup_enable_pin = -EINVAL, }; static struct platform_device w1_device = { diff --git a/trunk/arch/arm/mach-at91/include/mach/gpio.h b/trunk/arch/arm/mach-at91/include/mach/gpio.h index 5fc23771c154..eed465ab0dd7 100644 --- a/trunk/arch/arm/mach-at91/include/mach/gpio.h +++ b/trunk/arch/arm/mach-at91/include/mach/gpio.h @@ -209,14 +209,6 @@ extern int at91_get_gpio_value(unsigned pin); extern void at91_gpio_suspend(void); extern void at91_gpio_resume(void); -#ifdef CONFIG_PINCTRL_AT91 -extern void at91_pinctrl_gpio_suspend(void); -extern void at91_pinctrl_gpio_resume(void); -#else -static inline void at91_pinctrl_gpio_suspend(void) {} -static inline void at91_pinctrl_gpio_resume(void) {} -#endif - #endif /* __ASSEMBLY__ */ #endif diff --git a/trunk/arch/arm/mach-at91/irq.c b/trunk/arch/arm/mach-at91/irq.c index e0ca59171022..8e210262aeee 100644 --- a/trunk/arch/arm/mach-at91/irq.c +++ b/trunk/arch/arm/mach-at91/irq.c @@ -92,21 +92,23 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value) void at91_irq_suspend(void) { - int bit = -1; + int i = 0, bit; if (has_aic5()) { /* disable enabled irqs */ - while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) { + while ((bit = find_next_bit(backups, n_irqs, i)) < n_irqs) { at91_aic_write(AT91_AIC5_SSR, bit & AT91_AIC5_INTSEL_MSK); at91_aic_write(AT91_AIC5_IDCR, 1); + i = bit; } /* enable wakeup irqs */ - bit = -1; - while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) { + i = 0; + while ((bit = find_next_bit(wakeups, n_irqs, i)) < n_irqs) { at91_aic_write(AT91_AIC5_SSR, bit & AT91_AIC5_INTSEL_MSK); at91_aic_write(AT91_AIC5_IECR, 1); + i = bit; } } else { at91_aic_write(AT91_AIC_IDCR, *backups); @@ -116,21 +118,23 @@ void at91_irq_suspend(void) void at91_irq_resume(void) { - int bit = -1; + int i = 0, bit; if (has_aic5()) { /* disable wakeup irqs */ - while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) { + while ((bit = find_next_bit(wakeups, n_irqs, i)) < n_irqs) { at91_aic_write(AT91_AIC5_SSR, bit & AT91_AIC5_INTSEL_MSK); at91_aic_write(AT91_AIC5_IDCR, 1); + i = bit; } /* enable irqs disabled for suspend */ - bit = -1; - while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) { + i = 0; + while ((bit = find_next_bit(backups, n_irqs, i)) < n_irqs) { at91_aic_write(AT91_AIC5_SSR, bit & AT91_AIC5_INTSEL_MSK); at91_aic_write(AT91_AIC5_IECR, 1); + i = bit; } } else { at91_aic_write(AT91_AIC_IDCR, *wakeups); diff --git a/trunk/arch/arm/mach-at91/pm.c b/trunk/arch/arm/mach-at91/pm.c index 73f1f250403a..adb6db888a1f 100644 --- a/trunk/arch/arm/mach-at91/pm.c +++ b/trunk/arch/arm/mach-at91/pm.c @@ -201,10 +201,7 @@ extern u32 at91_slow_clock_sz; static int at91_pm_enter(suspend_state_t state) { - if (of_have_populated_dt()) - at91_pinctrl_gpio_suspend(); - else - at91_gpio_suspend(); + at91_gpio_suspend(); at91_irq_suspend(); pr_debug("AT91: PM - wake mask %08x, pm state %d\n", @@ -289,10 +286,7 @@ static int at91_pm_enter(suspend_state_t state) error: target_state = PM_SUSPEND_ON; at91_irq_resume(); - if (of_have_populated_dt()) - at91_pinctrl_gpio_resume(); - else - at91_gpio_resume(); + at91_gpio_resume(); return 0; } diff --git a/trunk/arch/arm/mach-cns3xxx/core.c b/trunk/arch/arm/mach-cns3xxx/core.c index 52e4bb5cf12d..e698f26cc0cb 100644 --- a/trunk/arch/arm/mach-cns3xxx/core.c +++ b/trunk/arch/arm/mach-cns3xxx/core.c @@ -22,9 +22,19 @@ static struct map_desc cns3xxx_io_desc[] __initdata = { { - .virtual = CNS3XXX_TC11MP_SCU_BASE_VIRT, - .pfn = __phys_to_pfn(CNS3XXX_TC11MP_SCU_BASE), - .length = SZ_8K, + .virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE), + .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT, diff --git a/trunk/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/trunk/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h index b1021aafa481..191c8e57f289 100644 --- a/trunk/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h +++ b/trunk/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h @@ -94,10 +94,10 @@ #define RTC_INTR_STS_OFFSET 0x34 #define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */ -#define CNS3XXX_MISC_BASE_VIRT 0xFB000000 /* Misc Control */ +#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */ #define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */ -#define CNS3XXX_PM_BASE_VIRT 0xFB001000 +#define CNS3XXX_PM_BASE_VIRT 0xFFF08000 #define PM_CLK_GATE_OFFSET 0x00 #define PM_SOFT_RST_OFFSET 0x04 @@ -109,7 +109,7 @@ #define PM_PLL_HM_PD_OFFSET 0x1C #define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */ -#define CNS3XXX_UART0_BASE_VIRT 0xFB002000 +#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000 #define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */ #define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000 @@ -130,7 +130,7 @@ #define CNS3XXX_I2S_BASE_VIRT 0xFFF10000 #define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */ -#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFB003000 +#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800 #define TIMER1_COUNTER_OFFSET 0x00 #define TIMER1_AUTO_RELOAD_OFFSET 0x04 @@ -227,16 +227,16 @@ * Testchip peripheral and fpga gic regions */ #define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */ -#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFB004000 +#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000 #define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */ -#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x100) +#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100 #define CNS3XXX_TC11MP_TWD_BASE 0x90000600 -#define CNS3XXX_TC11MP_TWD_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x600) +#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600 #define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */ -#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x1000) +#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000 #define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */ #define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000 diff --git a/trunk/arch/arm/mach-davinci/dma.c b/trunk/arch/arm/mach-davinci/dma.c index 45b7c71d9cc1..a685e9706b7b 100644 --- a/trunk/arch/arm/mach-davinci/dma.c +++ b/trunk/arch/arm/mach-davinci/dma.c @@ -743,9 +743,6 @@ EXPORT_SYMBOL(edma_free_channel); */ int edma_alloc_slot(unsigned ctlr, int slot) { - if (!edma_cc[ctlr]) - return -EINVAL; - if (slot >= 0) slot = EDMA_CHAN_SLOT(slot); diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/uncompress.h b/trunk/arch/arm/mach-ep93xx/include/mach/uncompress.h index b5cc77d2380b..d2afb4dd82ab 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/uncompress.h @@ -47,13 +47,9 @@ static void __raw_writel(unsigned int value, unsigned int ptr) static inline void putc(int c) { - int i; - - for (i = 0; i < 10000; i++) { - /* Transmit fifo not full? */ - if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF)) - break; - } + /* Transmit fifo not full? */ + while (__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF) + ; __raw_writeb(c, PHYS_UART_DATA); } diff --git a/trunk/arch/arm/mach-footbridge/Kconfig b/trunk/arch/arm/mach-footbridge/Kconfig index 0f2111a11315..abda5a18a664 100644 --- a/trunk/arch/arm/mach-footbridge/Kconfig +++ b/trunk/arch/arm/mach-footbridge/Kconfig @@ -67,7 +67,6 @@ config ARCH_NETWINDER select ISA select ISA_DMA select PCI - select VIRT_TO_BUS help Say Y here if you intend to run this kernel on the Rebel.COM NetWinder. Information about this machine can be found at: diff --git a/trunk/arch/arm/mach-highbank/hotplug.c b/trunk/arch/arm/mach-highbank/hotplug.c index 890cae23c12a..f30c52843396 100644 --- a/trunk/arch/arm/mach-highbank/hotplug.c +++ b/trunk/arch/arm/mach-highbank/hotplug.c @@ -28,11 +28,13 @@ extern void secondary_startup(void); */ void __ref highbank_cpu_die(unsigned int cpu) { - highbank_set_cpu_jump(cpu, phys_to_virt(0)); + flush_cache_all(); - flush_cache_louis(); + highbank_set_cpu_jump(cpu, phys_to_virt(0)); highbank_set_core_pwr(); - while (1) - cpu_do_idle(); + cpu_do_idle(); + + /* We should never return from idle */ + panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu); } diff --git a/trunk/arch/arm/mach-imx/clk-imx35.c b/trunk/arch/arm/mach-imx/clk-imx35.c index 2193c834f55c..74e3a34d78b8 100644 --- a/trunk/arch/arm/mach-imx/clk-imx35.c +++ b/trunk/arch/arm/mach-imx/clk-imx35.c @@ -257,7 +257,6 @@ int __init mx35_clocks_init(void) clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); - clk_register_clkdev(clk[admux_gate], "audmux", NULL); clk_prepare_enable(clk[spba_gate]); clk_prepare_enable(clk[gpio1_gate]); @@ -265,8 +264,6 @@ int __init mx35_clocks_init(void) clk_prepare_enable(clk[gpio3_gate]); clk_prepare_enable(clk[iim_gate]); clk_prepare_enable(clk[emi_gate]); - clk_prepare_enable(clk[max_gate]); - clk_prepare_enable(clk[iomuxc_gate]); /* * SCC is needed to boot via mmc after a watchdog reset. The clock code diff --git a/trunk/arch/arm/mach-imx/clk-imx6q.c b/trunk/arch/arm/mach-imx/clk-imx6q.c index d38e54f5b6d7..7b025ee528a5 100644 --- a/trunk/arch/arm/mach-imx/clk-imx6q.c +++ b/trunk/arch/arm/mach-imx/clk-imx6q.c @@ -115,7 +115,7 @@ static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m" static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; -static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; +static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", }; static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; @@ -172,7 +172,7 @@ static struct clk *clk[clk_max]; static struct clk_onecell_data clk_data; static enum mx6q_clks const clks_init_on[] __initconst = { - mmdc_ch0_axi, rom, pll1_sys, + mmdc_ch0_axi, rom, }; static struct clk_div_table clk_enet_ref_table[] = { @@ -443,6 +443,7 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); + clk_register_clkdev(clk[twd], NULL, "smp_twd"); clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); clk_register_clkdev(clk[ahb], "ahb", NULL); clk_register_clkdev(clk[cko1], "cko1", NULL); diff --git a/trunk/arch/arm/mach-imx/common.h b/trunk/arch/arm/mach-imx/common.h index 5bf4a97ab241..5a800bfcec5b 100644 --- a/trunk/arch/arm/mach-imx/common.h +++ b/trunk/arch/arm/mach-imx/common.h @@ -110,8 +110,6 @@ void tzic_handle_irq(struct pt_regs *); extern void imx_enable_cpu(int cpu, bool enable); extern void imx_set_cpu_jump(int cpu, void *jump_addr); -extern u32 imx_get_cpu_arg(int cpu); -extern void imx_set_cpu_arg(int cpu, u32 arg); extern void v7_cpu_resume(void); extern u32 *pl310_get_save_ptr(void); #ifdef CONFIG_SMP diff --git a/trunk/arch/arm/mach-imx/headsmp.S b/trunk/arch/arm/mach-imx/headsmp.S index a58c8b0527cc..921fc1555854 100644 --- a/trunk/arch/arm/mach-imx/headsmp.S +++ b/trunk/arch/arm/mach-imx/headsmp.S @@ -26,16 +26,16 @@ ENDPROC(v7_secondary_startup) #ifdef CONFIG_PM /* - * The following code must assume it is running from physical address - * where absolute virtual addresses to the data section have to be - * turned into relative ones. + * The following code is located into the .data section. This is to + * allow phys_l2x0_saved_regs to be accessed with a relative load + * as we are running on physical address here. */ + .data + .align #ifdef CONFIG_CACHE_L2X0 .macro pl310_resume - adr r0, l2x0_saved_regs_offset - ldr r2, [r0] - add r2, r2, r0 + ldr r2, phys_l2x0_saved_regs ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0 ldr r1, [r2, #L2X0_R_AUX_CTRL] @ get aux_ctrl value str r1, [r0, #L2X0_AUX_CTRL] @ restore aux_ctrl @@ -43,9 +43,9 @@ ENDPROC(v7_secondary_startup) str r1, [r0, #L2X0_CTRL] @ re-enable L2 .endm -l2x0_saved_regs_offset: - .word l2x0_saved_regs - . - + .globl phys_l2x0_saved_regs +phys_l2x0_saved_regs: + .long 0 #else .macro pl310_resume .endm diff --git a/trunk/arch/arm/mach-imx/hotplug.c b/trunk/arch/arm/mach-imx/hotplug.c index 361a253e2b63..7bc5fe15dda2 100644 --- a/trunk/arch/arm/mach-imx/hotplug.c +++ b/trunk/arch/arm/mach-imx/hotplug.c @@ -46,23 +46,11 @@ static inline void cpu_enter_lowpower(void) void imx_cpu_die(unsigned int cpu) { cpu_enter_lowpower(); - /* - * We use the cpu jumping argument register to sync with - * imx_cpu_kill() which is running on cpu0 and waiting for - * the register being cleared to kill the cpu. - */ - imx_set_cpu_arg(cpu, ~0); cpu_do_idle(); } int imx_cpu_kill(unsigned int cpu) { - unsigned long timeout = jiffies + msecs_to_jiffies(50); - - while (imx_get_cpu_arg(cpu) == 0) - if (time_after(jiffies, timeout)) - return 0; imx_enable_cpu(cpu, false); - imx_set_cpu_arg(cpu, 0); return 1; } diff --git a/trunk/arch/arm/mach-imx/imx25-dt.c b/trunk/arch/arm/mach-imx/imx25-dt.c index 82348391582a..03b65e5ea541 100644 --- a/trunk/arch/arm/mach-imx/imx25-dt.c +++ b/trunk/arch/arm/mach-imx/imx25-dt.c @@ -27,11 +27,6 @@ static const char * const imx25_dt_board_compat[] __initconst = { NULL }; -static void __init imx25_timer_init(void) -{ - mx25_clocks_init_dt(); -} - DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)") .map_io = mx25_map_io, .init_early = imx25_init_early, diff --git a/trunk/arch/arm/mach-imx/pm-imx6q.c b/trunk/arch/arm/mach-imx/pm-imx6q.c index 5faba7a3c95f..ee42d20cba19 100644 --- a/trunk/arch/arm/mach-imx/pm-imx6q.c +++ b/trunk/arch/arm/mach-imx/pm-imx6q.c @@ -22,6 +22,8 @@ #include "common.h" #include "hardware.h" +extern unsigned long phys_l2x0_saved_regs; + static int imx6q_suspend_finish(unsigned long val) { cpu_do_idle(); @@ -55,5 +57,18 @@ static const struct platform_suspend_ops imx6q_pm_ops = { void __init imx6q_pm_init(void) { + /* + * The l2x0 core code provides an infrastucture to save and restore + * l2x0 registers across suspend/resume cycle. But because imx6q + * retains L2 content during suspend and needs to resume L2 before + * MMU is enabled, it can only utilize register saving support and + * have to take care of restoring on its own. So we save physical + * address of the data structure used by l2x0 core to save registers, + * and later restore the necessary ones in imx6q resume entry. + */ +#ifdef CONFIG_CACHE_L2X0 + phys_l2x0_saved_regs = __pa(&l2x0_saved_regs); +#endif + suspend_set_ops(&imx6q_pm_ops); } diff --git a/trunk/arch/arm/mach-imx/src.c b/trunk/arch/arm/mach-imx/src.c index 09a742f8c7ab..e15f1555c59b 100644 --- a/trunk/arch/arm/mach-imx/src.c +++ b/trunk/arch/arm/mach-imx/src.c @@ -43,18 +43,6 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) src_base + SRC_GPR1 + cpu * 8); } -u32 imx_get_cpu_arg(int cpu) -{ - cpu = cpu_logical_map(cpu); - return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); -} - -void imx_set_cpu_arg(int cpu, u32 arg) -{ - cpu = cpu_logical_map(cpu); - writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); -} - void imx_src_prepare_restart(void) { u32 val; diff --git a/trunk/arch/arm/mach-ixp4xx/vulcan-setup.c b/trunk/arch/arm/mach-ixp4xx/vulcan-setup.c index d599e354ca57..d42730a1d4ab 100644 --- a/trunk/arch/arm/mach-ixp4xx/vulcan-setup.c +++ b/trunk/arch/arm/mach-ixp4xx/vulcan-setup.c @@ -163,7 +163,6 @@ static struct platform_device vulcan_max6369 = { static struct w1_gpio_platform_data vulcan_w1_gpio_pdata = { .pin = 14, - .ext_pullup_enable_pin = -EINVAL, }; static struct platform_device vulcan_w1_gpio = { diff --git a/trunk/arch/arm/mach-kirkwood/board-dt.c b/trunk/arch/arm/mach-kirkwood/board-dt.c index d367aa6b47bb..2e73e9d53f70 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dt.c +++ b/trunk/arch/arm/mach-kirkwood/board-dt.c @@ -41,12 +41,16 @@ static void __init kirkwood_legacy_clk_init(void) struct device_node *np = of_find_compatible_node( NULL, NULL, "marvell,kirkwood-gating-clock"); + struct of_phandle_args clkspec; - struct clk *clk; clkspec.np = np; clkspec.args_count = 1; + clkspec.args[0] = CGC_BIT_GE0; + orion_clkdev_add(NULL, "mv643xx_eth_port.0", + of_clk_get_from_provider(&clkspec)); + clkspec.args[0] = CGC_BIT_PEX0; orion_clkdev_add("0", "pcie", of_clk_get_from_provider(&clkspec)); @@ -55,24 +59,9 @@ static void __init kirkwood_legacy_clk_init(void) orion_clkdev_add("1", "pcie", of_clk_get_from_provider(&clkspec)); - clkspec.args[0] = CGC_BIT_SDIO; - orion_clkdev_add(NULL, "mvsdio", - of_clk_get_from_provider(&clkspec)); - - /* - * The ethernet interfaces forget the MAC address assigned by - * u-boot if the clocks are turned off. Until proper DT support - * is available we always enable them for now. - */ - clkspec.args[0] = CGC_BIT_GE0; - clk = of_clk_get_from_provider(&clkspec); - orion_clkdev_add(NULL, "mv643xx_eth_port.0", clk); - clk_prepare_enable(clk); - clkspec.args[0] = CGC_BIT_GE1; - clk = of_clk_get_from_provider(&clkspec); - orion_clkdev_add(NULL, "mv643xx_eth_port.1", clk); - clk_prepare_enable(clk); + orion_clkdev_add(NULL, "mv643xx_eth_port.1", + of_clk_get_from_provider(&clkspec)); } static void __init kirkwood_of_clk_init(void) diff --git a/trunk/arch/arm/mach-kirkwood/board-iomega_ix2_200.c b/trunk/arch/arm/mach-kirkwood/board-iomega_ix2_200.c index e5f70415905a..f655b2637b0e 100644 --- a/trunk/arch/arm/mach-kirkwood/board-iomega_ix2_200.c +++ b/trunk/arch/arm/mach-kirkwood/board-iomega_ix2_200.c @@ -20,15 +20,10 @@ static struct mv643xx_eth_platform_data iomega_ix2_200_ge00_data = { .duplex = DUPLEX_FULL, }; -static struct mv643xx_eth_platform_data iomega_ix2_200_ge01_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(11), -}; - void __init iomega_ix2_200_init(void) { /* * Basic setup. Needs to be called early. */ - kirkwood_ge00_init(&iomega_ix2_200_ge00_data); - kirkwood_ge01_init(&iomega_ix2_200_ge01_data); + kirkwood_ge01_init(&iomega_ix2_200_ge00_data); } diff --git a/trunk/arch/arm/mach-kirkwood/guruplug-setup.c b/trunk/arch/arm/mach-kirkwood/guruplug-setup.c index 08dd739aa709..1c6e736cbbf8 100644 --- a/trunk/arch/arm/mach-kirkwood/guruplug-setup.c +++ b/trunk/arch/arm/mach-kirkwood/guruplug-setup.c @@ -53,8 +53,6 @@ static struct mv_sata_platform_data guruplug_sata_data = { static struct mvsdio_platform_data guruplug_mvsdio_data = { /* unfortunately the CD signal has not been connected */ - .gpio_card_detect = -1, - .gpio_write_protect = -1, }; static struct gpio_led guruplug_led_pins[] = { diff --git a/trunk/arch/arm/mach-kirkwood/openrd-setup.c b/trunk/arch/arm/mach-kirkwood/openrd-setup.c index 6a6eb548307d..8ddd69fdc937 100644 --- a/trunk/arch/arm/mach-kirkwood/openrd-setup.c +++ b/trunk/arch/arm/mach-kirkwood/openrd-setup.c @@ -55,7 +55,6 @@ static struct mv_sata_platform_data openrd_sata_data = { static struct mvsdio_platform_data openrd_mvsdio_data = { .gpio_card_detect = 29, /* MPP29 used as SD card detect */ - .gpio_write_protect = -1, }; static unsigned int openrd_mpp_config[] __initdata = { diff --git a/trunk/arch/arm/mach-kirkwood/rd88f6281-setup.c b/trunk/arch/arm/mach-kirkwood/rd88f6281-setup.c index d24223166e06..c7d93b48926b 100644 --- a/trunk/arch/arm/mach-kirkwood/rd88f6281-setup.c +++ b/trunk/arch/arm/mach-kirkwood/rd88f6281-setup.c @@ -69,7 +69,6 @@ static struct mv_sata_platform_data rd88f6281_sata_data = { static struct mvsdio_platform_data rd88f6281_mvsdio_data = { .gpio_card_detect = 28, - .gpio_write_protect = -1, }; static unsigned int rd88f6281_mpp_config[] __initdata = { diff --git a/trunk/arch/arm/mach-mmp/gplugd.c b/trunk/arch/arm/mach-mmp/gplugd.c index f62b68d926f4..d1e2d595e79c 100644 --- a/trunk/arch/arm/mach-mmp/gplugd.c +++ b/trunk/arch/arm/mach-mmp/gplugd.c @@ -9,7 +9,6 @@ */ #include -#include #include #include diff --git a/trunk/arch/arm/mach-msm/timer.c b/trunk/arch/arm/mach-msm/timer.c index f9fd77e8f1f5..2969027f02fa 100644 --- a/trunk/arch/arm/mach-msm/timer.c +++ b/trunk/arch/arm/mach-msm/timer.c @@ -62,10 +62,7 @@ static int msm_timer_set_next_event(unsigned long cycles, { u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); - ctrl &= ~TIMER_ENABLE_EN; - writel_relaxed(ctrl, event_base + TIMER_ENABLE); - - writel_relaxed(ctrl, event_base + TIMER_CLEAR); + writel_relaxed(0, event_base + TIMER_CLEAR); writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); return 0; diff --git a/trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c b/trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c index d5970f5a1e8d..274ff58271de 100644 --- a/trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c +++ b/trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c @@ -44,8 +44,6 @@ #define ARMADA_370_XP_MAX_PER_CPU_IRQS (28) -#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5) - #define ACTIVE_DOORBELLS (8) static DEFINE_RAW_SPINLOCK(irq_controller_lock); @@ -61,26 +59,36 @@ static struct irq_domain *armada_370_xp_mpic_domain; */ static void armada_370_xp_irq_mask(struct irq_data *d) { +#ifdef CONFIG_SMP irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) + if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS) writel(hwirq, main_int_base + ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS); else writel(hwirq, per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); +#else + writel(irqd_to_hwirq(d), + per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); +#endif } static void armada_370_xp_irq_unmask(struct irq_data *d) { +#ifdef CONFIG_SMP irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) + if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS) writel(hwirq, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); else writel(hwirq, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); +#else + writel(irqd_to_hwirq(d), + per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); +#endif } #ifdef CONFIG_SMP @@ -136,14 +144,10 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { armada_370_xp_irq_mask(irq_get_irq_data(virq)); - if (hw != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) - writel(hw, per_cpu_int_base + - ARMADA_370_XP_INT_CLEAR_MASK_OFFS); - else - writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); + writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); irq_set_status_flags(virq, IRQ_LEVEL); - if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) { + if (hw < ARMADA_370_XP_MAX_PER_CPU_IRQS) { irq_set_percpu_devid(virq); irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip, handle_percpu_devid_irq); diff --git a/trunk/arch/arm/mach-mxs/icoll.c b/trunk/arch/arm/mach-mxs/icoll.c index e26eeba46598..8fb23af154b3 100644 --- a/trunk/arch/arm/mach-mxs/icoll.c +++ b/trunk/arch/arm/mach-mxs/icoll.c @@ -100,7 +100,7 @@ static struct irq_domain_ops icoll_irq_domain_ops = { .xlate = irq_domain_xlate_onecell, }; -static void __init icoll_of_init(struct device_node *np, +void __init icoll_of_init(struct device_node *np, struct device_node *interrupt_parent) { /* diff --git a/trunk/arch/arm/mach-mxs/mach-mxs.c b/trunk/arch/arm/mach-mxs/mach-mxs.c index e7b781d3788f..052186713347 100644 --- a/trunk/arch/arm/mach-mxs/mach-mxs.c +++ b/trunk/arch/arm/mach-mxs/mach-mxs.c @@ -41,6 +41,8 @@ static struct fb_videomode mx23evk_video_modes[] = { .lower_margin = 4, .hsync_len = 1, .vsync_len = 1, + .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT | + FB_SYNC_DOTCLK_FAILING_ACT, }, }; @@ -57,6 +59,8 @@ static struct fb_videomode mx28evk_video_modes[] = { .lower_margin = 10, .hsync_len = 10, .vsync_len = 10, + .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT | + FB_SYNC_DOTCLK_FAILING_ACT, }, }; @@ -73,6 +77,7 @@ static struct fb_videomode m28evk_video_modes[] = { .lower_margin = 45, .hsync_len = 1, .vsync_len = 1, + .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT, }, }; @@ -89,7 +94,9 @@ static struct fb_videomode apx4devkit_video_modes[] = { .lower_margin = 13, .hsync_len = 48, .vsync_len = 3, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | + FB_SYNC_DATA_ENABLE_HIGH_ACT | + FB_SYNC_DOTCLK_FAILING_ACT, }, }; @@ -106,7 +113,9 @@ static struct fb_videomode apf28dev_video_modes[] = { .lower_margin = 0x15, .hsync_len = 64, .vsync_len = 4, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | + FB_SYNC_DATA_ENABLE_HIGH_ACT | + FB_SYNC_DOTCLK_FAILING_ACT, }, }; @@ -123,6 +132,7 @@ static struct fb_videomode cfa10049_video_modes[] = { .lower_margin = 2, .hsync_len = 15, .vsync_len = 15, + .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT }, }; @@ -249,8 +259,6 @@ static void __init imx23_evk_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(mx23evk_video_modes); mxsfb_pdata.default_bpp = 32; mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; - mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT | - MXSFB_SYNC_DOTCLK_FAILING_ACT; } static inline void enable_clk_enet_out(void) @@ -270,8 +278,6 @@ static void __init imx28_evk_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(mx28evk_video_modes); mxsfb_pdata.default_bpp = 32; mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; - mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT | - MXSFB_SYNC_DOTCLK_FAILING_ACT; mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0); } @@ -291,7 +297,6 @@ static void __init m28evk_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(m28evk_video_modes); mxsfb_pdata.default_bpp = 16; mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT; - mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; } static void __init sc_sps1_init(void) @@ -317,8 +322,6 @@ static void __init apx4devkit_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(apx4devkit_video_modes); mxsfb_pdata.default_bpp = 32; mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; - mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT | - MXSFB_SYNC_DOTCLK_FAILING_ACT; } #define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0) @@ -399,18 +402,17 @@ static void __init cfa10049_init(void) { enable_clk_enet_out(); update_fec_mac_prop(OUI_CRYSTALFONTZ); - - mxsfb_pdata.mode_list = cfa10049_video_modes; - mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes); - mxsfb_pdata.default_bpp = 32; - mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT; - mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; } static void __init cfa10037_init(void) { enable_clk_enet_out(); update_fec_mac_prop(OUI_CRYSTALFONTZ); + + mxsfb_pdata.mode_list = cfa10049_video_modes; + mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes); + mxsfb_pdata.default_bpp = 32; + mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT; } static void __init apf28_init(void) @@ -421,8 +423,6 @@ static void __init apf28_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(apf28dev_video_modes); mxsfb_pdata.default_bpp = 16; mxsfb_pdata.ld_intf_width = STMLCDIF_16BIT; - mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT | - MXSFB_SYNC_DOTCLK_FAILING_ACT; } static void __init mxs_machine_init(void) diff --git a/trunk/arch/arm/mach-mxs/mm.c b/trunk/arch/arm/mach-mxs/mm.c index e63b7d87acbd..a4294aa9f301 100644 --- a/trunk/arch/arm/mach-mxs/mm.c +++ b/trunk/arch/arm/mach-mxs/mm.c @@ -18,7 +18,6 @@ #include #include -#include /* * Define the MX23 memory map. diff --git a/trunk/arch/arm/mach-mxs/ocotp.c b/trunk/arch/arm/mach-mxs/ocotp.c index 1dff46703753..54add60f94c9 100644 --- a/trunk/arch/arm/mach-mxs/ocotp.c +++ b/trunk/arch/arm/mach-mxs/ocotp.c @@ -19,7 +19,6 @@ #include /* for cpu_relax() */ #include -#include #define OCOTP_WORD_OFFSET 0x20 #define OCOTP_WORD_COUNT 0x20 diff --git a/trunk/arch/arm/mach-netx/generic.c b/trunk/arch/arm/mach-netx/generic.c index 1504b68f4c66..27c2cb7ab813 100644 --- a/trunk/arch/arm/mach-netx/generic.c +++ b/trunk/arch/arm/mach-netx/generic.c @@ -168,7 +168,7 @@ void __init netx_init_irq(void) { int irq; - vic_init(io_p2v(NETX_PA_VIC), NETX_IRQ_VIC_START, ~0, 0); + vic_init(io_p2v(NETX_PA_VIC), 0, ~0, 0); for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) { irq_set_chip_and_handler(irq, &netx_hif_chip, diff --git a/trunk/arch/arm/mach-netx/include/mach/irqs.h b/trunk/arch/arm/mach-netx/include/mach/irqs.h index 8f74a844a775..6ce914d54a30 100644 --- a/trunk/arch/arm/mach-netx/include/mach/irqs.h +++ b/trunk/arch/arm/mach-netx/include/mach/irqs.h @@ -17,42 +17,42 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define NETX_IRQ_VIC_START 64 -#define NETX_IRQ_SOFTINT (NETX_IRQ_VIC_START + 0) -#define NETX_IRQ_TIMER0 (NETX_IRQ_VIC_START + 1) -#define NETX_IRQ_TIMER1 (NETX_IRQ_VIC_START + 2) -#define NETX_IRQ_TIMER2 (NETX_IRQ_VIC_START + 3) -#define NETX_IRQ_SYSTIME_NS (NETX_IRQ_VIC_START + 4) -#define NETX_IRQ_SYSTIME_S (NETX_IRQ_VIC_START + 5) -#define NETX_IRQ_GPIO_15 (NETX_IRQ_VIC_START + 6) -#define NETX_IRQ_WATCHDOG (NETX_IRQ_VIC_START + 7) -#define NETX_IRQ_UART0 (NETX_IRQ_VIC_START + 8) -#define NETX_IRQ_UART1 (NETX_IRQ_VIC_START + 9) -#define NETX_IRQ_UART2 (NETX_IRQ_VIC_START + 10) -#define NETX_IRQ_USB (NETX_IRQ_VIC_START + 11) -#define NETX_IRQ_SPI (NETX_IRQ_VIC_START + 12) -#define NETX_IRQ_I2C (NETX_IRQ_VIC_START + 13) -#define NETX_IRQ_LCD (NETX_IRQ_VIC_START + 14) -#define NETX_IRQ_HIF (NETX_IRQ_VIC_START + 15) -#define NETX_IRQ_GPIO_0_14 (NETX_IRQ_VIC_START + 16) -#define NETX_IRQ_XPEC0 (NETX_IRQ_VIC_START + 17) -#define NETX_IRQ_XPEC1 (NETX_IRQ_VIC_START + 18) -#define NETX_IRQ_XPEC2 (NETX_IRQ_VIC_START + 19) -#define NETX_IRQ_XPEC3 (NETX_IRQ_VIC_START + 20) -#define NETX_IRQ_XPEC(no) (NETX_IRQ_VIC_START + 17 + (no)) -#define NETX_IRQ_MSYNC0 (NETX_IRQ_VIC_START + 21) -#define NETX_IRQ_MSYNC1 (NETX_IRQ_VIC_START + 22) -#define NETX_IRQ_MSYNC2 (NETX_IRQ_VIC_START + 23) -#define NETX_IRQ_MSYNC3 (NETX_IRQ_VIC_START + 24) -#define NETX_IRQ_IRQ_PHY (NETX_IRQ_VIC_START + 25) -#define NETX_IRQ_ISO_AREA (NETX_IRQ_VIC_START + 26) +#define NETX_IRQ_VIC_START 0 +#define NETX_IRQ_SOFTINT 0 +#define NETX_IRQ_TIMER0 1 +#define NETX_IRQ_TIMER1 2 +#define NETX_IRQ_TIMER2 3 +#define NETX_IRQ_SYSTIME_NS 4 +#define NETX_IRQ_SYSTIME_S 5 +#define NETX_IRQ_GPIO_15 6 +#define NETX_IRQ_WATCHDOG 7 +#define NETX_IRQ_UART0 8 +#define NETX_IRQ_UART1 9 +#define NETX_IRQ_UART2 10 +#define NETX_IRQ_USB 11 +#define NETX_IRQ_SPI 12 +#define NETX_IRQ_I2C 13 +#define NETX_IRQ_LCD 14 +#define NETX_IRQ_HIF 15 +#define NETX_IRQ_GPIO_0_14 16 +#define NETX_IRQ_XPEC0 17 +#define NETX_IRQ_XPEC1 18 +#define NETX_IRQ_XPEC2 19 +#define NETX_IRQ_XPEC3 20 +#define NETX_IRQ_XPEC(no) (17 + (no)) +#define NETX_IRQ_MSYNC0 21 +#define NETX_IRQ_MSYNC1 22 +#define NETX_IRQ_MSYNC2 23 +#define NETX_IRQ_MSYNC3 24 +#define NETX_IRQ_IRQ_PHY 25 +#define NETX_IRQ_ISO_AREA 26 /* int 27 is reserved */ /* int 28 is reserved */ -#define NETX_IRQ_TIMER3 (NETX_IRQ_VIC_START + 29) -#define NETX_IRQ_TIMER4 (NETX_IRQ_VIC_START + 30) +#define NETX_IRQ_TIMER3 29 +#define NETX_IRQ_TIMER4 30 /* int 31 is reserved */ -#define NETX_IRQS (NETX_IRQ_VIC_START + 32) +#define NETX_IRQS 32 /* for multiplexed irqs on gpio 0..14 */ #define NETX_IRQ_GPIO(x) (NETX_IRQS + (x)) diff --git a/trunk/arch/arm/mach-omap1/clock_data.c b/trunk/arch/arm/mach-omap1/clock_data.c index 6c4f766365a2..cb7c6ae2e3fc 100644 --- a/trunk/arch/arm/mach-omap1/clock_data.c +++ b/trunk/arch/arm/mach-omap1/clock_data.c @@ -538,6 +538,15 @@ static struct clk usb_hhc_ck16xx = { }; static struct clk usb_dc_ck = { + .name = "usb_dc_ck", + .ops = &clkops_generic, + /* Direct from ULPD, no parent */ + .rate = 48000000, + .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), + .enable_bit = USB_REQ_EN_SHIFT, +}; + +static struct clk usb_dc_ck7xx = { .name = "usb_dc_ck", .ops = &clkops_generic, /* Direct from ULPD, no parent */ @@ -718,7 +727,8 @@ static struct omap_clk omap_clks[] = { CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310), CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310), CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX), - CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX | CK_7XX), + CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX), + CLK(NULL, "usb_dc_ck", &usb_dc_ck7xx, CK_7XX), CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310), CLK(NULL, "mclk", &mclk_16xx, CK_16XX), CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310), diff --git a/trunk/arch/arm/mach-omap1/common.h b/trunk/arch/arm/mach-omap1/common.h index 14f7e9920479..fb18831e88aa 100644 --- a/trunk/arch/arm/mach-omap1/common.h +++ b/trunk/arch/arm/mach-omap1/common.h @@ -31,8 +31,6 @@ #include -#include - #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) void omap7xx_map_io(void); #else diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig index 8111cd9ff3e5..49ac3dfebef9 100644 --- a/trunk/arch/arm/mach-omap2/Kconfig +++ b/trunk/arch/arm/mach-omap2/Kconfig @@ -311,6 +311,9 @@ config MACH_OMAP_ZOOM2 default y select OMAP_PACKAGE_CBB select REGULATOR_FIXED_VOLTAGE if REGULATOR + select SERIAL_8250 + select SERIAL_8250_CONSOLE + select SERIAL_CORE_CONSOLE config MACH_OMAP_ZOOM3 bool "OMAP3630 Zoom3 board" @@ -318,6 +321,9 @@ config MACH_OMAP_ZOOM3 default y select OMAP_PACKAGE_CBP select REGULATOR_FIXED_VOLTAGE if REGULATOR + select SERIAL_8250 + select SERIAL_8250_CONSOLE + select SERIAL_CORE_CONSOLE config MACH_CM_T35 bool "CompuLab CM-T35/CM-T3730 modules" diff --git a/trunk/arch/arm/mach-omap2/board-generic.c b/trunk/arch/arm/mach-omap2/board-generic.c index e54a48060198..0274ff7a2a2b 100644 --- a/trunk/arch/arm/mach-omap2/board-generic.c +++ b/trunk/arch/arm/mach-omap2/board-generic.c @@ -102,7 +102,6 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") .init_irq = omap_intc_of_init, .handle_irq = omap3_intc_handle_irq, .init_machine = omap_generic_init, - .init_late = omap3_init_late, .init_time = omap3_sync32k_timer_init, .dt_compat = omap3_boards_compat, .restart = omap3xxx_restart, @@ -120,7 +119,6 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)") .init_irq = omap_intc_of_init, .handle_irq = omap3_intc_handle_irq, .init_machine = omap_generic_init, - .init_late = omap3_init_late, .init_time = omap3_secure_sync32k_timer_init, .dt_compat = omap3_gp_boards_compat, .restart = omap3xxx_restart, diff --git a/trunk/arch/arm/mach-omap2/board-rx51.c b/trunk/arch/arm/mach-omap2/board-rx51.c index d2ea68ea678a..f7c4616cbb60 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51.c +++ b/trunk/arch/arm/mach-omap2/board-rx51.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -99,7 +98,6 @@ static void __init rx51_init(void) sdrc_params = nokia_get_sdram_timings(); omap_sdrc_init(sdrc_params, sdrc_params); - usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(&musb_board_data); rx51_peripherals_init(); diff --git a/trunk/arch/arm/mach-omap2/cclock44xx_data.c b/trunk/arch/arm/mach-omap2/cclock44xx_data.c index 0c6834ae1fc4..3d58f335f173 100644 --- a/trunk/arch/arm/mach-omap2/cclock44xx_data.c +++ b/trunk/arch/arm/mach-omap2/cclock44xx_data.c @@ -52,13 +52,6 @@ */ #define OMAP4_DPLL_ABE_DEFFREQ 98304000 -/* - * OMAP4 USB DPLL default frequency. In OMAP4430 TRM version V, section - * "3.6.3.9.5 DPLL_USB Preferred Settings" shows that the preferred - * locked frequency for the USB DPLL is 960MHz. - */ -#define OMAP4_DPLL_USB_DEFFREQ 960000000 - /* Root clocks */ DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0); @@ -1018,10 +1011,6 @@ DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel, OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK, hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops); -DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0, - OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, - OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL); - DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0, OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); @@ -1549,7 +1538,6 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "per_mcbsp4_gfclk", &per_mcbsp4_gfclk, CK_443X), CLK(NULL, "hsmmc1_fclk", &hsmmc1_fclk, CK_443X), CLK(NULL, "hsmmc2_fclk", &hsmmc2_fclk, CK_443X), - CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X), CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X), CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X), CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X), @@ -1717,13 +1705,5 @@ int __init omap4xxx_clk_init(void) if (rc) pr_err("%s: failed to configure ABE DPLL!\n", __func__); - /* - * Lock USB DPLL on OMAP4 devices so that the L3INIT power - * domain can transition to retention state when not in use. - */ - rc = clk_set_rate(&dpll_usb_ck, OMAP4_DPLL_USB_DEFFREQ); - if (rc) - pr_err("%s: failed to configure USB DPLL!\n", __func__); - return 0; } diff --git a/trunk/arch/arm/mach-omap2/common.h b/trunk/arch/arm/mach-omap2/common.h index d6ba13e1c540..0a6b9c7a63da 100644 --- a/trunk/arch/arm/mach-omap2/common.h +++ b/trunk/arch/arm/mach-omap2/common.h @@ -108,6 +108,7 @@ void omap35xx_init_late(void); void omap3630_init_late(void); void am35xx_init_late(void); void ti81xx_init_late(void); +void omap4430_init_late(void); int omap2_common_pm_late_init(void); #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430) @@ -293,8 +294,5 @@ extern void omap_reserve(void); struct omap_hwmod; extern int omap_dss_reset(struct omap_hwmod *); -/* SoC specific clock initializer */ -extern int (*omap_clk_init)(void); - #endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ diff --git a/trunk/arch/arm/mach-omap2/gpmc.c b/trunk/arch/arm/mach-omap2/gpmc.c index 410e1bac7815..e4b16c8efe8b 100644 --- a/trunk/arch/arm/mach-omap2/gpmc.c +++ b/trunk/arch/arm/mach-omap2/gpmc.c @@ -1122,6 +1122,9 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t, /* TODO: remove, see function definition */ gpmc_convert_ps_to_ns(gpmc_t); + /* Now the GPMC is initialised, unreserve the chip-selects */ + gpmc_cs_map = 0; + return 0; } @@ -1380,9 +1383,6 @@ static int gpmc_probe(struct platform_device *pdev) if (IS_ERR_VALUE(gpmc_setup_irq())) dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); - /* Now the GPMC is initialised, unreserve the chip-selects */ - gpmc_cs_map = 0; - rc = gpmc_probe_dt(pdev); if (rc < 0) { clk_disable_unprepare(gpmc_l3_clk); diff --git a/trunk/arch/arm/mach-omap2/io.c b/trunk/arch/arm/mach-omap2/io.c index 5c445ca1e271..2c3fdd65387b 100644 --- a/trunk/arch/arm/mach-omap2/io.c +++ b/trunk/arch/arm/mach-omap2/io.c @@ -54,12 +54,6 @@ #include "prm3xxx.h" #include "prm44xx.h" -/* - * omap_clk_init: points to a function that does the SoC-specific - * clock initializations - */ -int (*omap_clk_init)(void); - /* * The machine specific code may provide the extra mapping besides the * default mapping provided here. @@ -403,7 +397,7 @@ void __init omap2420_init_early(void) omap242x_clockdomains_init(); omap2420_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap2420_clk_init; + omap2420_clk_init(); } void __init omap2420_init_late(void) @@ -433,7 +427,7 @@ void __init omap2430_init_early(void) omap243x_clockdomains_init(); omap2430_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap2430_clk_init; + omap2430_clk_init(); } void __init omap2430_init_late(void) @@ -468,7 +462,7 @@ void __init omap3_init_early(void) omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap3xxx_clk_init; + omap3xxx_clk_init(); } void __init omap3430_init_early(void) @@ -506,7 +500,7 @@ void __init ti81xx_init_early(void) omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap3xxx_clk_init; + omap3xxx_clk_init(); } void __init omap3_init_late(void) @@ -574,7 +568,7 @@ void __init am33xx_init_early(void) am33xx_clockdomains_init(); am33xx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = am33xx_clk_init; + am33xx_clk_init(); } #endif @@ -599,7 +593,7 @@ void __init omap4430_init_early(void) omap44xx_clockdomains_init(); omap44xx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap4xxx_clk_init; + omap4xxx_clk_init(); } void __init omap4430_init_late(void) diff --git a/trunk/arch/arm/mach-omap2/mux.c b/trunk/arch/arm/mach-omap2/mux.c index f82cf878d6af..6a217c98db54 100644 --- a/trunk/arch/arm/mach-omap2/mux.c +++ b/trunk/arch/arm/mach-omap2/mux.c @@ -211,6 +211,8 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, return -EINVAL; } + pr_err("%s: Could not find signal %s\n", __func__, muxname); + return -ENODEV; } @@ -232,8 +234,6 @@ int __init omap_mux_get_by_name(const char *muxname, return mux_mode; } - pr_err("%s: Could not find signal %s\n", __func__, muxname); - return -ENODEV; } @@ -739,9 +739,8 @@ static void __init omap_mux_dbg_create_entry( list_for_each_entry(e, &partition->muxmodes, node) { struct omap_mux *m = &e->mux; - (void)debugfs_create_file(m->muxnames[0], S_IWUSR | S_IRUGO, - mux_dbg_dir, m, - &omap_mux_dbg_signal_fops); + (void)debugfs_create_file(m->muxnames[0], S_IWUSR, mux_dbg_dir, + m, &omap_mux_dbg_signal_fops); } } diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index a202a4785104..c2c798c08c2b 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -1368,9 +1368,7 @@ static void _enable_sysc(struct omap_hwmod *oh) } if (sf & SYSC_HAS_MIDLEMODE) { - if (oh->flags & HWMOD_FORCE_MSTANDBY) { - idlemode = HWMOD_IDLEMODE_FORCE; - } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) { + if (oh->flags & HWMOD_SWSUP_MSTANDBY) { idlemode = HWMOD_IDLEMODE_NO; } else { if (sf & SYSC_HAS_ENAWAKEUP) @@ -1442,8 +1440,7 @@ static void _idle_sysc(struct omap_hwmod *oh) } if (sf & SYSC_HAS_MIDLEMODE) { - if ((oh->flags & HWMOD_SWSUP_MSTANDBY) || - (oh->flags & HWMOD_FORCE_MSTANDBY)) { + if (oh->flags & HWMOD_SWSUP_MSTANDBY) { idlemode = HWMOD_IDLEMODE_FORCE; } else { if (sf & SYSC_HAS_ENAWAKEUP) diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.h b/trunk/arch/arm/mach-omap2/omap_hwmod.h index d5dc935f6060..d43d9b608eda 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.h +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.h @@ -427,8 +427,8 @@ struct omap_hwmod_omap4_prcm { * * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out * of idle, rather than relying on module smart-idle - * HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and - * out of standby, rather than relying on module smart-standby + * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out + * of standby, rather than relying on module smart-standby * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for * SDRAM controller, etc. XXX probably belongs outside the main hwmod file * XXX Should be HWMOD_SETUP_NO_RESET @@ -459,10 +459,6 @@ struct omap_hwmod_omap4_prcm { * correctly, or this is being abused to deal with some PM latency * issues -- but we're currently suffering from a shortage of * folks who are able to track these issues down properly. - * HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device - * is kept in force-standby mode. Failing to do so causes PM problems - * with musb on OMAP3630 at least. Note that musb has a dedicated register - * to control MSTANDBY signal when MIDLEMODE is set to force-standby. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -475,7 +471,6 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_16BIT_REG (1 << 8) #define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) #define HWMOD_BLOCK_WFI (1 << 10) -#define HWMOD_FORCE_MSTANDBY (1 << 11) /* * omap_hwmod._int_flags definitions diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 5112d04e7b79..ac7e03ec952f 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1707,14 +1707,9 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = { * Erratum ID: i479 idle_req / idle_ack mechanism potentially * broken when autoidle is enabled * workaround is to disable the autoidle bit at module level. - * - * Enabling the device in any other MIDLEMODE setting but force-idle - * causes core_pwrdm not enter idle states at least on OMAP3630. - * Note that musb has OTG_FORCESTDBY register that controls MSTANDBY - * signal when MIDLEMODE is set to force-idle. */ .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE - | HWMOD_FORCE_MSTANDBY, + | HWMOD_SWSUP_MSTANDBY, }; /* usb_otg_hs */ diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index eaba9dc91a0d..0e47d2e1687c 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2719,17 +2719,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .name = "ocp2scp_usb_phy", .class = &omap44xx_ocp2scp_hwmod_class, .clkdm_name = "l3_init_clkdm", - /* - * ocp2scp_usb_phy_phy_48m is provided by the OMAP4 PRCM IP - * block as an "optional clock," and normally should never be - * specified as the main_clk for an OMAP IP block. However it - * turns out that this clock is actually the main clock for - * the ocp2scp_usb_phy IP block: - * http://lists.infradead.org/pipermail/linux-arm-kernel/2012-September/119943.html - * So listing ocp2scp_usb_phy_phy_48m as a main_clk here seems - * to be the best workaround. - */ - .main_clk = "ocp2scp_usb_phy_phy_48m", + .main_clk = "func_48m_fclk", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, diff --git a/trunk/arch/arm/mach-omap2/timer.c b/trunk/arch/arm/mach-omap2/timer.c index f62b509ed08d..2bdd4cf17a8f 100644 --- a/trunk/arch/arm/mach-omap2/timer.c +++ b/trunk/arch/arm/mach-omap2/timer.c @@ -547,8 +547,6 @@ static inline void __init realtime_counter_init(void) clksrc_nr, clksrc_src) \ void __init omap##name##_gptimer_timer_init(void) \ { \ - if (omap_clk_init) \ - omap_clk_init(); \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ @@ -558,8 +556,6 @@ void __init omap##name##_gptimer_timer_init(void) \ clksrc_nr, clksrc_src) \ void __init omap##name##_sync32k_timer_init(void) \ { \ - if (omap_clk_init) \ - omap_clk_init(); \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ /* Enable the use of clocksource="gp_timer" kernel parameter */ \ diff --git a/trunk/arch/arm/mach-pxa/raumfeld.c b/trunk/arch/arm/mach-pxa/raumfeld.c index 969b0ba7fa70..af41888acbd6 100644 --- a/trunk/arch/arm/mach-pxa/raumfeld.c +++ b/trunk/arch/arm/mach-pxa/raumfeld.c @@ -505,7 +505,6 @@ static struct w1_gpio_platform_data w1_gpio_platform_data = { .pin = GPIO_ONE_WIRE, .is_open_drain = 0, .enable_external_pullup = w1_enable_external_pullup, - .ext_pullup_enable_pin = -EINVAL, }; struct platform_device raumfeld_w1_gpio_device = { diff --git a/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h b/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h index 1e73f5fa8659..b7a9f4d469e8 100644 --- a/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -188,8 +188,10 @@ #if defined(CONFIG_CPU_S3C2416) #define NR_IRQS (IRQ_S3C2416_I2S1 + 1) +#elif defined(CONFIG_CPU_S3C2443) +#define NR_IRQS (IRQ_S3C2443_AC97+1) #else -#define NR_IRQS (IRQ_S3C2443_AC97 + 1) +#define NR_IRQS (IRQ_S3C2440_AC97+1) #endif /* compatibility define. */ diff --git a/trunk/arch/arm/mach-s3c24xx/irq.c b/trunk/arch/arm/mach-s3c24xx/irq.c index d8ba9bee4c7e..cb9f5e011e73 100644 --- a/trunk/arch/arm/mach-s3c24xx/irq.c +++ b/trunk/arch/arm/mach-s3c24xx/irq.c @@ -500,7 +500,7 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, base = (void *)0xfd000000; intc->reg_mask = base + 0xa4; - intc->reg_pending = base + 0xa8; + intc->reg_pending = base + 0x08; irq_num = 20; irq_start = S3C2410_IRQ(32); irq_offset = 4; diff --git a/trunk/arch/arm/mach-s5pv210/clock.c b/trunk/arch/arm/mach-s5pv210/clock.c index f051f53e35b7..fcdf52dbcc49 100644 --- a/trunk/arch/arm/mach-s5pv210/clock.c +++ b/trunk/arch/arm/mach-s5pv210/clock.c @@ -214,6 +214,11 @@ static struct clk clk_pcmcdclk2 = { .name = "pcmcdclk", }; +static struct clk dummy_apb_pclk = { + .name = "apb_pclk", + .id = -1, +}; + static struct clk *clkset_vpllsrc_list[] = { [0] = &clk_fin_vpll, [1] = &clk_sclk_hdmi27m, @@ -300,6 +305,18 @@ static struct clk_ops clk_fout_apll_ops = { static struct clk init_clocks_off[] = { { + .name = "dma", + .devname = "dma-pl330.0", + .parent = &clk_hclk_psys.clk, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "dma", + .devname = "dma-pl330.1", + .parent = &clk_hclk_psys.clk, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 4), + }, { .name = "rot", .parent = &clk_hclk_dsys.clk, .enable = s5pv210_clk_ip0_ctrl, @@ -556,20 +573,6 @@ static struct clk clk_hsmmc3 = { .ctrlbit = (1<<19), }; -static struct clk clk_pdma0 = { - .name = "pdma0", - .parent = &clk_hclk_psys.clk, - .enable = s5pv210_clk_ip0_ctrl, - .ctrlbit = (1 << 3), -}; - -static struct clk clk_pdma1 = { - .name = "pdma1", - .parent = &clk_hclk_psys.clk, - .enable = s5pv210_clk_ip0_ctrl, - .ctrlbit = (1 << 4), -}; - static struct clk *clkset_uart_list[] = { [6] = &clk_mout_mpll.clk, [7] = &clk_mout_epll.clk, @@ -1072,8 +1075,6 @@ static struct clk *clk_cdev[] = { &clk_hsmmc1, &clk_hsmmc2, &clk_hsmmc3, - &clk_pdma0, - &clk_pdma1, }; /* Clock initialisation code */ @@ -1332,8 +1333,6 @@ static struct clk_lookup s5pv210_clk_lookup[] = { CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), CLKDEV_INIT("s5pv210-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), CLKDEV_INIT("s5pv210-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), - CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0), - CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1), }; void __init s5pv210_register_clocks(void) @@ -1362,5 +1361,6 @@ void __init s5pv210_register_clocks(void) for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++) s3c_disable_clocks(clk_cdev[ptr], 1); + s3c24xx_register_clock(&dummy_apb_pclk); s3c_pwmclk_init(); } diff --git a/trunk/arch/arm/mach-s5pv210/mach-goni.c b/trunk/arch/arm/mach-s5pv210/mach-goni.c index e373de44a8b6..3a38f7b34b94 100644 --- a/trunk/arch/arm/mach-s5pv210/mach-goni.c +++ b/trunk/arch/arm/mach-s5pv210/mach-goni.c @@ -845,7 +845,7 @@ static struct fimc_source_info goni_camera_sensors[] = { .mux_id = 0, .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_VSYNC_ACTIVE_LOW, - .fimc_bus_type = FIMC_BUS_TYPE_ITU_601, + .bus_type = FIMC_BUS_TYPE_ITU_601, .board_info = &noon010pc30_board_info, .i2c_bus_num = 0, .clk_frequency = 16000000UL, diff --git a/trunk/arch/arm/mach-shmobile/board-marzen.c b/trunk/arch/arm/mach-shmobile/board-marzen.c index fec49ebc359a..cdcb799e802f 100644 --- a/trunk/arch/arm/mach-shmobile/board-marzen.c +++ b/trunk/arch/arm/mach-shmobile/board-marzen.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-spear3xx/spear3xx.c b/trunk/arch/arm/mach-spear3xx/spear3xx.c index d2b3937c4014..f9d754f90c59 100644 --- a/trunk/arch/arm/mach-spear3xx/spear3xx.c +++ b/trunk/arch/arm/mach-spear3xx/spear3xx.c @@ -14,7 +14,7 @@ #define pr_fmt(fmt) "SPEAr3xx: " fmt #include -#include +#include #include #include #include diff --git a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c index 7f2cb6c5e2c1..051b62c27102 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c @@ -81,6 +81,7 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { #endif struct mmci_platform_data mop500_sdi0_data = { + .ios_handler = mop500_sdi0_ios_handler, .ocr_mask = MMC_VDD_29_30, .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | diff --git a/trunk/arch/arm/mach-ux500/board-mop500.c b/trunk/arch/arm/mach-ux500/board-mop500.c index 87d2d7b38ce9..b03457881c4b 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.c +++ b/trunk/arch/arm/mach-ux500/board-mop500.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -440,15 +439,6 @@ static void mop500_prox_deactivate(struct device *dev) regulator_put(prox_regulator); } -void mop500_snowball_ethernet_clock_enable(void) -{ - struct clk *clk; - - clk = clk_get_sys("fsmc", NULL); - if (!IS_ERR(clk)) - clk_prepare_enable(clk); -} - static struct cryp_platform_data u8500_cryp1_platform_data = { .mem_to_engine = { .dir = STEDMA40_MEM_TO_PERIPH, @@ -693,8 +683,6 @@ static void __init snowball_init_machine(void) mop500_audio_init(parent); mop500_uart_init(parent); - mop500_snowball_ethernet_clock_enable(); - /* This board has full regulator constraints */ regulator_has_full_constraints(); } diff --git a/trunk/arch/arm/mach-ux500/board-mop500.h b/trunk/arch/arm/mach-ux500/board-mop500.h index d38951be70df..eaa605f5d90d 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.h +++ b/trunk/arch/arm/mach-ux500/board-mop500.h @@ -104,7 +104,6 @@ void __init mop500_pinmaps_init(void); void __init snowball_pinmaps_init(void); void __init hrefv60_pinmaps_init(void); void mop500_audio_init(struct device *parent); -void mop500_snowball_ethernet_clock_enable(void); int __init mop500_uib_init(void); void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, diff --git a/trunk/arch/arm/mach-ux500/cpu-db8500.c b/trunk/arch/arm/mach-ux500/cpu-db8500.c index f1a581844372..19235cf7bbe3 100644 --- a/trunk/arch/arm/mach-ux500/cpu-db8500.c +++ b/trunk/arch/arm/mach-ux500/cpu-db8500.c @@ -312,10 +312,9 @@ static void __init u8500_init_machine(void) /* Pinmaps must be in place before devices register */ if (of_machine_is_compatible("st-ericsson,mop500")) mop500_pinmaps_init(); - else if (of_machine_is_compatible("calaosystems,snowball-a9500")) { + else if (of_machine_is_compatible("calaosystems,snowball-a9500")) snowball_pinmaps_init(); - mop500_snowball_ethernet_clock_enable(); - } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) + else if (of_machine_is_compatible("st-ericsson,hrefv60+")) hrefv60_pinmaps_init(); else if (of_machine_is_compatible("st-ericsson,ccu9540")) {} /* TODO: Add pinmaps for ccu9540 board. */ diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 4045c4931a30..025d17328730 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -43,7 +43,7 @@ config CPU_ARM740T depends on !MMU select CPU_32v4T select CPU_ABRT_LV4T - select CPU_CACHE_V4 + select CPU_CACHE_V3 # although the core is v4t select CPU_CP15_MPU select CPU_PABRT_LEGACY help @@ -469,6 +469,9 @@ config CPU_PABRT_V7 bool # The cache model +config CPU_CACHE_V3 + bool + config CPU_CACHE_V4 bool diff --git a/trunk/arch/arm/mm/Makefile b/trunk/arch/arm/mm/Makefile index 9e51be96f635..4e333fa2756f 100644 --- a/trunk/arch/arm/mm/Makefile +++ b/trunk/arch/arm/mm/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o +obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o diff --git a/trunk/arch/arm/mm/cache-feroceon-l2.c b/trunk/arch/arm/mm/cache-feroceon-l2.c index 48bc3c0a87ce..dd3d59122cc3 100644 --- a/trunk/arch/arm/mm/cache-feroceon-l2.c +++ b/trunk/arch/arm/mm/cache-feroceon-l2.c @@ -343,7 +343,6 @@ void __init feroceon_l2_init(int __l2_wt_override) outer_cache.inv_range = feroceon_l2_inv_range; outer_cache.clean_range = feroceon_l2_clean_range; outer_cache.flush_range = feroceon_l2_flush_range; - outer_cache.inv_all = l2_inv_all; enable_l2(); diff --git a/trunk/arch/arm/mm/cache-l2x0.c b/trunk/arch/arm/mm/cache-l2x0.c index c465faca51b0..c2f37390308a 100644 --- a/trunk/arch/arm/mm/cache-l2x0.c +++ b/trunk/arch/arm/mm/cache-l2x0.c @@ -299,7 +299,7 @@ static void l2x0_unlock(u32 cache_id) int lockregs; int i; - switch (cache_id & L2X0_CACHE_ID_PART_MASK) { + switch (cache_id) { case L2X0_CACHE_ID_PART_L310: lockregs = 8; break; @@ -333,14 +333,15 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) if (cache_id_part_number_from_dt) cache_id = cache_id_part_number_from_dt; else - cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID); + cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID) + & L2X0_CACHE_ID_PART_MASK; aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); aux &= aux_mask; aux |= aux_val; /* Determine the number of ways */ - switch (cache_id & L2X0_CACHE_ID_PART_MASK) { + switch (cache_id) { case L2X0_CACHE_ID_PART_L310: if (aux & (1 << 16)) ways = 16; @@ -724,6 +725,7 @@ static const struct l2x0_of_data pl310_data = { .flush_all = l2x0_flush_all, .inv_all = l2x0_inv_all, .disable = l2x0_disable, + .set_debug = pl310_set_debug, }, }; @@ -812,9 +814,10 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask) data->save(); of_init = true; - memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache)); l2x0_init(l2x0_base, aux_val, aux_mask); + memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache)); + return 0; } #endif diff --git a/trunk/arch/arm/mm/cache-v3.S b/trunk/arch/arm/mm/cache-v3.S new file mode 100644 index 000000000000..8a3fadece8d3 --- /dev/null +++ b/trunk/arch/arm/mm/cache-v3.S @@ -0,0 +1,137 @@ +/* + * linux/arch/arm/mm/cache-v3.S + * + * Copyright (C) 1997-2002 Russell king + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include "proc-macros.S" + +/* + * flush_icache_all() + * + * Unconditionally clean and invalidate the entire icache. + */ +ENTRY(v3_flush_icache_all) + mov pc, lr +ENDPROC(v3_flush_icache_all) + +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + * + * - mm - mm_struct describing address space + */ +ENTRY(v3_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(v3_flush_kern_cache_all) + /* FALLTHROUGH */ + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - flags - vma_area_struct flags describing address space + */ +ENTRY(v3_flush_user_cache_range) + mov ip, #0 + mcreq p15, 0, ip, c7, c0, 0 @ flush ID cache + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_coherent_user_range) + mov r0, #0 + mov pc, lr + +/* + * flush_kern_dcache_area(void *page, size_t size) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - kernel address + * - size - region size + */ +ENTRY(v3_flush_kern_dcache_area) + /* FALLTHROUGH */ + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_dma_flush_range) + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ flush ID cache + mov pc, lr + +/* + * dma_unmap_area(start, size, dir) + * - start - kernel virtual start address + * - size - size of region + * - dir - DMA direction + */ +ENTRY(v3_dma_unmap_area) + teq r2, #DMA_TO_DEVICE + bne v3_dma_flush_range + /* FALLTHROUGH */ + +/* + * dma_map_area(start, size, dir) + * - start - kernel virtual start address + * - size - size of region + * - dir - DMA direction + */ +ENTRY(v3_dma_map_area) + mov pc, lr +ENDPROC(v3_dma_unmap_area) +ENDPROC(v3_dma_map_area) + + .globl v3_flush_kern_cache_louis + .equ v3_flush_kern_cache_louis, v3_flush_kern_cache_all + + __INITDATA + + @ define struct cpu_cache_fns (see and proc-macros.S) + define_cache_functions v3 diff --git a/trunk/arch/arm/mm/cache-v4.S b/trunk/arch/arm/mm/cache-v4.S index a7ba68f59f0c..43e5d77be677 100644 --- a/trunk/arch/arm/mm/cache-v4.S +++ b/trunk/arch/arm/mm/cache-v4.S @@ -58,7 +58,7 @@ ENTRY(v4_flush_kern_cache_all) ENTRY(v4_flush_user_cache_range) #ifdef CONFIG_CPU_CP15 mov ip, #0 - mcr p15, 0, ip, c7, c7, 0 @ flush ID cache + mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache mov pc, lr #else /* FALLTHROUGH */ diff --git a/trunk/arch/arm/mm/context.c b/trunk/arch/arm/mm/context.c index 2ac37372ef52..7a0511191f6b 100644 --- a/trunk/arch/arm/mm/context.c +++ b/trunk/arch/arm/mm/context.c @@ -48,7 +48,7 @@ static DEFINE_RAW_SPINLOCK(cpu_asid_lock); static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION); static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS); -DEFINE_PER_CPU(atomic64_t, active_asids); +static DEFINE_PER_CPU(atomic64_t, active_asids); static DEFINE_PER_CPU(u64, reserved_asids); static cpumask_t tlb_flush_pending; @@ -152,9 +152,9 @@ static int is_reserved_asid(u64 asid) return 0; } -static u64 new_context(struct mm_struct *mm, unsigned int cpu) +static void new_context(struct mm_struct *mm, unsigned int cpu) { - u64 asid = atomic64_read(&mm->context.id); + u64 asid = mm->context.id; u64 generation = atomic64_read(&asid_generation); if (asid != 0 && is_reserved_asid(asid)) { @@ -181,14 +181,13 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu) cpumask_clear(mm_cpumask(mm)); } - return asid; + mm->context.id = asid; } void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) { unsigned long flags; unsigned int cpu = smp_processor_id(); - u64 asid; if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq)) __check_vmalloc_seq(mm); @@ -199,27 +198,20 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) */ cpu_set_reserved_ttbr0(); - asid = atomic64_read(&mm->context.id); - if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) - && atomic64_xchg(&per_cpu(active_asids, cpu), asid)) + if (!((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS) + && atomic64_xchg(&per_cpu(active_asids, cpu), mm->context.id)) goto switch_mm_fastpath; raw_spin_lock_irqsave(&cpu_asid_lock, flags); /* Check that our ASID belongs to the current generation. */ - asid = atomic64_read(&mm->context.id); - if ((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) { - asid = new_context(mm, cpu); - atomic64_set(&mm->context.id, asid); - } + if ((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS) + new_context(mm, cpu); - if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) { - local_flush_bp_all(); - local_flush_tlb_all(); - dummy_flush_tlb_a15_erratum(); - } - - atomic64_set(&per_cpu(active_asids, cpu), asid); + atomic64_set(&per_cpu(active_asids, cpu), mm->context.id); cpumask_set_cpu(cpu, mm_cpumask(mm)); + + if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) + local_flush_tlb_all(); raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); switch_mm_fastpath: diff --git a/trunk/arch/arm/mm/dma-mapping.c b/trunk/arch/arm/mm/dma-mapping.c index e9db6b4bf65a..c7e3759f16d3 100644 --- a/trunk/arch/arm/mm/dma-mapping.c +++ b/trunk/arch/arm/mm/dma-mapping.c @@ -342,7 +342,6 @@ static int __init atomic_pool_init(void) { struct dma_pool *pool = &atomic_pool; pgprot_t prot = pgprot_dmacoherent(pgprot_kernel); - gfp_t gfp = GFP_KERNEL | GFP_DMA; unsigned long nr_pages = pool->size >> PAGE_SHIFT; unsigned long *bitmap; struct page *page; @@ -362,8 +361,8 @@ static int __init atomic_pool_init(void) ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page, atomic_pool_init); else - ptr = __alloc_remap_buffer(NULL, pool->size, gfp, prot, &page, - atomic_pool_init); + ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot, + &page, atomic_pool_init); if (ptr) { int i; diff --git a/trunk/arch/arm/mm/idmap.c b/trunk/arch/arm/mm/idmap.c index 5ee505c937d1..2dffc010cc41 100644 --- a/trunk/arch/arm/mm/idmap.c +++ b/trunk/arch/arm/mm/idmap.c @@ -141,7 +141,6 @@ void setup_mm_for_reboot(void) { /* Switch to the identity mapping. */ cpu_switch_mm(idmap_pgd, &init_mm); - local_flush_bp_all(); #ifdef CONFIG_CPU_HAS_ASID /* diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index a84ff763ac39..e95a996ab78f 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -34,7 +34,6 @@ #include #include "mm.h" -#include "tcm.h" /* * empty_zero_page is a special page that is used for @@ -599,60 +598,39 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, } while (pte++, addr += PAGE_SIZE, addr != end); } -static void __init map_init_section(pmd_t *pmd, unsigned long addr, - unsigned long end, phys_addr_t phys, - const struct mem_type *type) -{ -#ifndef CONFIG_ARM_LPAE - /* - * In classic MMU format, puds and pmds are folded in to - * the pgds. pmd_offset gives the PGD entry. PGDs refer to a - * group of L1 entries making up one logical pointer to - * an L2 table (2MB), where as PMDs refer to the individual - * L1 entries (1MB). Hence increment to get the correct - * offset for odd 1MB sections. - * (See arch/arm/include/asm/pgtable-2level.h) - */ - if (addr & SECTION_SIZE) - pmd++; -#endif - do { - *pmd = __pmd(phys | type->prot_sect); - phys += SECTION_SIZE; - } while (pmd++, addr += SECTION_SIZE, addr != end); - - flush_pmd_entry(pmd); -} - -static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, +static void __init alloc_init_section(pud_t *pud, unsigned long addr, unsigned long end, phys_addr_t phys, const struct mem_type *type) { pmd_t *pmd = pmd_offset(pud, addr); - unsigned long next; - do { - /* - * With LPAE, we must loop over to map - * all the pmds for the given range. - */ - next = pmd_addr_end(addr, end); + /* + * Try a section mapping - end, addr and phys must all be aligned + * to a section boundary. Note that PMDs refer to the individual + * L1 entries, whereas PGDs refer to a group of L1 entries making + * up one logical pointer to an L2 table. + */ + if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) { + pmd_t *p = pmd; - /* - * Try a section mapping - addr, next and phys must all be - * aligned to a section boundary. - */ - if (type->prot_sect && - ((addr | next | phys) & ~SECTION_MASK) == 0) { - map_init_section(pmd, addr, next, phys, type); - } else { - alloc_init_pte(pmd, addr, next, - __phys_to_pfn(phys), type); - } +#ifndef CONFIG_ARM_LPAE + if (addr & SECTION_SIZE) + pmd++; +#endif - phys += next - addr; + do { + *pmd = __pmd(phys | type->prot_sect); + phys += SECTION_SIZE; + } while (pmd++, addr += SECTION_SIZE, addr != end); - } while (pmd++, addr = next, addr != end); + flush_pmd_entry(p); + } else { + /* + * No need to loop; pte's aren't interested in the + * individual L1 entries. + */ + alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type); + } } static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, @@ -663,7 +641,7 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, do { next = pud_addr_end(addr, end); - alloc_init_pmd(pud, addr, next, phys, type); + alloc_init_section(pud, addr, next, phys, type); phys += next - addr; } while (pud++, addr = next, addr != end); } @@ -1278,7 +1256,6 @@ void __init paging_init(struct machine_desc *mdesc) dma_contiguous_remap(); devicemaps_init(mdesc); kmap_init(); - tcm_init(); top_pmd = pmd_off_k(0xffff0000); diff --git a/trunk/arch/arm/mm/proc-arm740.S b/trunk/arch/arm/mm/proc-arm740.S index fde2d2a794cf..dc5de5d53f20 100644 --- a/trunk/arch/arm/mm/proc-arm740.S +++ b/trunk/arch/arm/mm/proc-arm740.S @@ -77,27 +77,24 @@ __arm740_setup: mcr p15, 0, r0, c6, c0 @ set area 0, default ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM - ldr r3, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) - mov r4, #10 @ 11 is the minimum (4KB) -1: add r4, r4, #1 @ area size *= 2 - movs r3, r3, lsr #1 + ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 bne 1b @ count not zero r-shift - orr r0, r0, r4, lsl #1 @ the area register value + orr r0, r0, r2, lsl #1 @ the area register value orr r0, r0, #1 @ set enable bit mcr p15, 0, r0, c6, c1 @ set area 1, RAM ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH - ldr r3, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) - cmp r3, #0 - moveq r0, #0 - beq 2f - mov r4, #10 @ 11 is the minimum (4KB) -1: add r4, r4, #1 @ area size *= 2 - movs r3, r3, lsr #1 + ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 bne 1b @ count not zero r-shift - orr r0, r0, r4, lsl #1 @ the area register value + orr r0, r0, r2, lsl #1 @ the area register value orr r0, r0, #1 @ set enable bit -2: mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH + mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH mov r0, #0x06 mcr p15, 0, r0, c2, c0 @ Region 1&2 cacheable @@ -140,14 +137,13 @@ __arm740_proc_info: .long 0x41807400 .long 0xfffffff0 .long 0 - .long 0 b __arm740_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT .long cpu_arm740_name .long arm740_processor_functions .long 0 .long 0 - .long v4_cache_fns @ cache model + .long v3_cache_fns @ cache model .size __arm740_proc_info, . - __arm740_proc_info diff --git a/trunk/arch/arm/mm/proc-arm920.S b/trunk/arch/arm/mm/proc-arm920.S index 2556cf1c2da1..2c3b9421ab5e 100644 --- a/trunk/arch/arm/mm/proc-arm920.S +++ b/trunk/arch/arm/mm/proc-arm920.S @@ -387,7 +387,7 @@ ENTRY(cpu_arm920_set_pte_ext) /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ .globl cpu_arm920_suspend_size .equ cpu_arm920_suspend_size, 4 * 3 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_arm920_do_suspend) stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c13, c0, 0 @ PID diff --git a/trunk/arch/arm/mm/proc-arm926.S b/trunk/arch/arm/mm/proc-arm926.S index 344c8a548cc0..f1803f7e2972 100644 --- a/trunk/arch/arm/mm/proc-arm926.S +++ b/trunk/arch/arm/mm/proc-arm926.S @@ -402,7 +402,7 @@ ENTRY(cpu_arm926_set_pte_ext) /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ .globl cpu_arm926_suspend_size .equ cpu_arm926_suspend_size, 4 * 3 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_arm926_do_suspend) stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c13, c0, 0 @ PID diff --git a/trunk/arch/arm/mm/proc-mohawk.S b/trunk/arch/arm/mm/proc-mohawk.S index 0b60dd3d742a..82f9cdc751d6 100644 --- a/trunk/arch/arm/mm/proc-mohawk.S +++ b/trunk/arch/arm/mm/proc-mohawk.S @@ -350,7 +350,7 @@ ENTRY(cpu_mohawk_set_pte_ext) .globl cpu_mohawk_suspend_size .equ cpu_mohawk_suspend_size, 4 * 6 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_mohawk_do_suspend) stmfd sp!, {r4 - r9, lr} mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode diff --git a/trunk/arch/arm/mm/proc-sa1100.S b/trunk/arch/arm/mm/proc-sa1100.S index d92dfd081429..3aa0da11fd84 100644 --- a/trunk/arch/arm/mm/proc-sa1100.S +++ b/trunk/arch/arm/mm/proc-sa1100.S @@ -172,7 +172,7 @@ ENTRY(cpu_sa1100_set_pte_ext) .globl cpu_sa1100_suspend_size .equ cpu_sa1100_suspend_size, 4 * 3 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_sa1100_do_suspend) stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c3, c0, 0 @ domain ID diff --git a/trunk/arch/arm/mm/proc-syms.c b/trunk/arch/arm/mm/proc-syms.c index 054b491ff764..3e6210b4d6d4 100644 --- a/trunk/arch/arm/mm/proc-syms.c +++ b/trunk/arch/arm/mm/proc-syms.c @@ -17,9 +17,7 @@ #ifndef MULTI_CPU EXPORT_SYMBOL(cpu_dcache_clean_area); -#ifdef CONFIG_MMU EXPORT_SYMBOL(cpu_set_pte_ext); -#endif #else EXPORT_SYMBOL(processor); #endif diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index 5c07ee4fe3eb..bcaaa8de9325 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -138,7 +138,7 @@ ENTRY(cpu_v6_set_pte_ext) /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */ .globl cpu_v6_suspend_size .equ cpu_v6_suspend_size, 4 * 6 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_v6_do_suspend) stmfd sp!, {r4 - r9, lr} mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID diff --git a/trunk/arch/arm/mm/proc-v7-3level.S b/trunk/arch/arm/mm/proc-v7-3level.S index 6ffd78c0f9ab..50bf1dafc9ea 100644 --- a/trunk/arch/arm/mm/proc-v7-3level.S +++ b/trunk/arch/arm/mm/proc-v7-3level.S @@ -48,7 +48,7 @@ ENTRY(cpu_v7_switch_mm) #ifdef CONFIG_MMU mmid r1, r1 @ get mm->context.id - asid r3, r1 + and r3, r1, #0xff mov r3, r3, lsl #(48 - 32) @ ASID mcrr p15, 0, r0, r3, c2 @ set TTB 0 isb diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index f584d3f5b37c..3a3c015f8d5c 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -420,7 +420,7 @@ __v7_pj4b_proc_info: __v7_ca7mp_proc_info: .long 0x410fc070 .long 0xff0ffff0 - __v7_proc __v7_ca7mp_setup + __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info /* @@ -430,24 +430,9 @@ __v7_ca7mp_proc_info: __v7_ca15mp_proc_info: .long 0x410fc0f0 .long 0xff0ffff0 - __v7_proc __v7_ca15mp_setup + __v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV .size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info - /* - * Qualcomm Inc. Krait processors. - */ - .type __krait_proc_info, #object -__krait_proc_info: - .long 0x510f0400 @ Required ID value - .long 0xff0ffc00 @ Mask for ID - /* - * Some Krait processors don't indicate support for SDIV and UDIV - * instructions in the ARM instruction set, even though they actually - * do support them. - */ - __v7_proc __v7_setup, hwcaps = HWCAP_IDIV - .size __krait_proc_info, . - __krait_proc_info - /* * Match any ARMv7 processor core. */ diff --git a/trunk/arch/arm/mm/proc-xsc3.S b/trunk/arch/arm/mm/proc-xsc3.S index e8efd83b6f25..eb93d6487f35 100644 --- a/trunk/arch/arm/mm/proc-xsc3.S +++ b/trunk/arch/arm/mm/proc-xsc3.S @@ -413,7 +413,7 @@ ENTRY(cpu_xsc3_set_pte_ext) .globl cpu_xsc3_suspend_size .equ cpu_xsc3_suspend_size, 4 * 6 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_xsc3_do_suspend) stmfd sp!, {r4 - r9, lr} mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S index e766f889bfd6..25510361aa18 100644 --- a/trunk/arch/arm/mm/proc-xscale.S +++ b/trunk/arch/arm/mm/proc-xscale.S @@ -528,7 +528,7 @@ ENTRY(cpu_xscale_set_pte_ext) .globl cpu_xscale_suspend_size .equ cpu_xscale_suspend_size, 4 * 6 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_xscale_do_suspend) stmfd sp!, {r4 - r9, lr} mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode diff --git a/trunk/arch/arm/net/bpf_jit_32.c b/trunk/arch/arm/net/bpf_jit_32.c index a0bd8a755bdf..6828ef6ce80e 100644 --- a/trunk/arch/arm/net/bpf_jit_32.c +++ b/trunk/arch/arm/net/bpf_jit_32.c @@ -576,7 +576,7 @@ static int build_body(struct jit_ctx *ctx) /* x = ((*(frame + k)) & 0xf) << 2; */ ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL; /* the interpreter should deal with the negative K */ - if ((int)k < 0) + if (k < 0) return -1; /* offset in r1: we might have to take the slow path */ emit_mov_i(r_off, k, ctx); diff --git a/trunk/arch/arm/plat-orion/addr-map.c b/trunk/arch/arm/plat-orion/addr-map.c index 807ac8e5cbc0..febe3862873c 100644 --- a/trunk/arch/arm/plat-orion/addr-map.c +++ b/trunk/arch/arm/plat-orion/addr-map.c @@ -157,12 +157,9 @@ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i)); /* - * We only take care of entries for which the chip - * select is enabled, and that don't have high base - * address bits set (devices can only access the first - * 32 bits of the memory). + * Chip select enabled? */ - if ((size & 1) && !(base & 0xF)) { + if (size & 1) { struct mbus_dram_window *w; w = &orion_mbus_dram_info.cs[cs++]; diff --git a/trunk/arch/arm/plat-samsung/include/plat/fb.h b/trunk/arch/arm/plat-samsung/include/plat/fb.h index 9ae507270785..b885322717a1 100644 --- a/trunk/arch/arm/plat-samsung/include/plat/fb.h +++ b/trunk/arch/arm/plat-samsung/include/plat/fb.h @@ -15,7 +15,55 @@ #ifndef __PLAT_S3C_FB_H #define __PLAT_S3C_FB_H __FILE__ -#include +/* S3C_FB_MAX_WIN + * Set to the maximum number of windows that any of the supported hardware + * can use. Since the platform data uses this for an array size, having it + * set to the maximum of any version of the hardware can do is safe. + */ +#define S3C_FB_MAX_WIN (5) + +/** + * struct s3c_fb_pd_win - per window setup data + * @xres : The window X size. + * @yres : The window Y size. + * @virtual_x: The virtual X size. + * @virtual_y: The virtual Y size. + */ +struct s3c_fb_pd_win { + unsigned short default_bpp; + unsigned short max_bpp; + unsigned short xres; + unsigned short yres; + unsigned short virtual_x; + unsigned short virtual_y; +}; + +/** + * struct s3c_fb_platdata - S3C driver platform specific information + * @setup_gpio: Setup the external GPIO pins to the right state to transfer + * the data from the display system to the connected display + * device. + * @vidcon0: The base vidcon0 values to control the panel data format. + * @vidcon1: The base vidcon1 values to control the panel data output. + * @vtiming: Video timing when connected to a RGB type panel. + * @win: The setup data for each hardware window, or NULL for unused. + * @display_mode: The LCD output display mode. + * + * The platform data supplies the video driver with all the information + * it requires to work with the display(s) attached to the machine. It + * controls the initial mode, the number of display windows (0 is always + * the base framebuffer) that are initialised etc. + * + */ +struct s3c_fb_platdata { + void (*setup_gpio)(void); + + struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN]; + struct fb_videomode *vtiming; + + u32 vidcon0; + u32 vidcon1; +}; /** * s3c_fb_set_platdata() - Setup the FB device with platform data. diff --git a/trunk/arch/arm/plat-spear/Kconfig b/trunk/arch/arm/plat-spear/Kconfig index 8a08c31b5e20..739d016eb273 100644 --- a/trunk/arch/arm/plat-spear/Kconfig +++ b/trunk/arch/arm/plat-spear/Kconfig @@ -10,7 +10,7 @@ choice config ARCH_SPEAR13XX bool "ST SPEAr13xx with Device Tree" - select ARCH_HAS_CPUFREQ + select ARCH_HAVE_CPUFREQ select ARM_GIC select CPU_V7 select GPIO_SPEAR_SPICS diff --git a/trunk/arch/arm64/Kconfig b/trunk/arch/arm64/Kconfig index 9b6d19f74078..fd70a68387eb 100644 --- a/trunk/arch/arm64/Kconfig +++ b/trunk/arch/arm64/Kconfig @@ -9,6 +9,7 @@ config ARM64 select CLONE_BACKWARDS select COMMON_CLK select GENERIC_CLOCKEVENTS + select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IOMAP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/trunk/arch/arm64/Kconfig.debug b/trunk/arch/arm64/Kconfig.debug index 1a6bfe954d49..51493430f142 100644 --- a/trunk/arch/arm64/Kconfig.debug +++ b/trunk/arch/arm64/Kconfig.debug @@ -6,6 +6,17 @@ config FRAME_POINTER bool default y +config DEBUG_ERRORS + bool "Verbose kernel error messages" + depends on DEBUG_KERNEL + help + This option controls verbose debugging information which can be + printed when the kernel detects an internal error. This debugging + information is useful to kernel hackers when tracking down problems, + but mostly meaningless to other people. It's safe to say Y unless + you are concerned with the code size or don't want to see these + messages. + config DEBUG_STACK_USAGE bool "Enable stack utilization instrumentation" depends on DEBUG_KERNEL diff --git a/trunk/arch/arm64/configs/defconfig b/trunk/arch/arm64/configs/defconfig index 09bef29f3a09..9212c7880da7 100644 --- a/trunk/arch/arm64/configs/defconfig +++ b/trunk/arch/arm64/configs/defconfig @@ -82,3 +82,4 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y # CONFIG_FTRACE is not set CONFIG_ATOMIC64_SELFTEST=y +CONFIG_DEBUG_ERRORS=y diff --git a/trunk/arch/arm64/include/asm/ucontext.h b/trunk/arch/arm64/include/asm/ucontext.h index 42e04c877428..bde960720892 100644 --- a/trunk/arch/arm64/include/asm/ucontext.h +++ b/trunk/arch/arm64/include/asm/ucontext.h @@ -22,7 +22,7 @@ struct ucontext { stack_t uc_stack; sigset_t uc_sigmask; /* glibc uses a 1024-bit sigset_t */ - __u8 __unused[1024 / 8 - sizeof(sigset_t)]; + __u8 __unused[(1024 - sizeof(sigset_t)) / 8]; /* last for future expansion */ struct sigcontext uc_mcontext; }; diff --git a/trunk/arch/arm64/kernel/arm64ksyms.c b/trunk/arch/arm64/kernel/arm64ksyms.c index aa3e948f7885..cef3925eaf60 100644 --- a/trunk/arch/arm64/kernel/arm64ksyms.c +++ b/trunk/arch/arm64/kernel/arm64ksyms.c @@ -40,9 +40,7 @@ EXPORT_SYMBOL(__copy_to_user); EXPORT_SYMBOL(__clear_user); /* bitops */ -#ifdef CONFIG_SMP EXPORT_SYMBOL(__atomic_hash); -#endif /* physical memory */ EXPORT_SYMBOL(memstart_addr); diff --git a/trunk/arch/arm64/kernel/signal32.c b/trunk/arch/arm64/kernel/signal32.c index e393174fe859..7f4f3673f2bc 100644 --- a/trunk/arch/arm64/kernel/signal32.c +++ b/trunk/arch/arm64/kernel/signal32.c @@ -549,6 +549,7 @@ int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) { struct compat_rt_sigframe __user *frame; + compat_stack_t stack; int err = 0; frame = compat_get_sigframe(ka, regs, sizeof(*frame)); diff --git a/trunk/arch/arm64/mm/mmu.c b/trunk/arch/arm64/mm/mmu.c index 70b8cd4021c4..224b44ab534e 100644 --- a/trunk/arch/arm64/mm/mmu.c +++ b/trunk/arch/arm64/mm/mmu.c @@ -261,7 +261,7 @@ static void __init create_mapping(phys_addr_t phys, unsigned long virt, void __iomem * __init early_io_map(phys_addr_t phys, unsigned long virt) { unsigned long size, mask; - bool page64k = IS_ENABLED(CONFIG_ARM64_64K_PAGES); + bool page64k = IS_ENABLED(ARM64_64K_PAGES); pgd_t *pgd; pud_t *pud; pmd_t *pmd; diff --git a/trunk/arch/avr32/Kconfig b/trunk/arch/avr32/Kconfig index c1a868d398bd..9b89257b2cfd 100644 --- a/trunk/arch/avr32/Kconfig +++ b/trunk/arch/avr32/Kconfig @@ -7,7 +7,7 @@ config AVR32 select HAVE_OPROFILE select HAVE_KPROBES select HAVE_GENERIC_HARDIRQS - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select GENERIC_IRQ_PROBE select GENERIC_ATOMIC64 select HARDIRQS_SW_RESEND diff --git a/trunk/arch/avr32/include/asm/io.h b/trunk/arch/avr32/include/asm/io.h index fc6483f83ccc..cf60d0a9f176 100644 --- a/trunk/arch/avr32/include/asm/io.h +++ b/trunk/arch/avr32/include/asm/io.h @@ -165,10 +165,6 @@ BUILDIO_IOPORT(l, u32) #define readw_be __raw_readw #define readl_be __raw_readl -#define writeb_relaxed writeb -#define writew_relaxed writew -#define writel_relaxed writel - #define writeb_be __raw_writeb #define writew_be __raw_writew #define writel_be __raw_writel diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index c3f2e0bc644a..600494c70e96 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -33,7 +33,7 @@ config BLACKFIN select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_UID16 - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select ARCH_WANT_IPC_PARSE_VERSION select HAVE_GENERIC_HARDIRQS select GENERIC_ATOMIC64 diff --git a/trunk/arch/c6x/include/asm/irqflags.h b/trunk/arch/c6x/include/asm/irqflags.h index 2c71d5634ec2..cf78e09e18c3 100644 --- a/trunk/arch/c6x/include/asm/irqflags.h +++ b/trunk/arch/c6x/include/asm/irqflags.h @@ -27,7 +27,7 @@ static inline unsigned long arch_local_save_flags(void) /* set interrupt enabled status */ static inline void arch_local_irq_restore(unsigned long flags) { - asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags) : "memory"); + asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags)); } /* unconditionally enable interrupts */ diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index 06dd026533e3..bb0ac66cf533 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -43,7 +43,7 @@ config CRIS select GENERIC_ATOMIC64 select HAVE_GENERIC_HARDIRQS select HAVE_UID16 - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_IRQ_SHOW select GENERIC_IOMAP diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index 2ce731f9aa4d..12369b194c7b 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -6,7 +6,7 @@ config FRV select HAVE_PERF_EVENTS select HAVE_UID16 select HAVE_GENERIC_HARDIRQS - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select GENERIC_IRQ_SHOW select HAVE_DEBUG_BUGVERBOSE select ARCH_HAVE_NMI_SAFE_CMPXCHG diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig index 79250de1b12a..ae8551eb3736 100644 --- a/trunk/arch/h8300/Kconfig +++ b/trunk/arch/h8300/Kconfig @@ -5,7 +5,7 @@ config H8300 select HAVE_GENERIC_HARDIRQS select GENERIC_ATOMIC64 select HAVE_UID16 - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index e7e55a00f94f..33f3fdc0b214 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -26,7 +26,7 @@ config IA64 select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP select HAVE_VIRT_CPU_ACCOUNTING - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select ARCH_DISCARD_MEMBLOCK select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP @@ -187,7 +187,7 @@ config IA64_DIG config IA64_DIG_VTD bool "DIG+Intel+IOMMU" - select INTEL_IOMMU + select DMAR select PCI_MSI config IA64_HP_ZX1 diff --git a/trunk/arch/ia64/include/asm/futex.h b/trunk/arch/ia64/include/asm/futex.h index 76acbcd5c060..d2bf1fd5e44f 100644 --- a/trunk/arch/ia64/include/asm/futex.h +++ b/trunk/arch/ia64/include/asm/futex.h @@ -106,15 +106,16 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; { - register unsigned long r8 __asm ("r8") = 0; + register unsigned long r8 __asm ("r8"); unsigned long prev; __asm__ __volatile__( " mf;; \n" + " mov %0=r0 \n" " mov ar.ccv=%4;; \n" "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" " .xdata4 \"__ex_table\", 1b-., 2f-. \n" "[2:]" - : "+r" (r8), "=&r" (prev) + : "=r" (r8), "=r" (prev) : "r" (uaddr), "r" (newval), "rO" ((long) (unsigned) oldval) : "memory"); diff --git a/trunk/arch/ia64/include/asm/mca.h b/trunk/arch/ia64/include/asm/mca.h index 8c7096168716..43f96ab18fa0 100644 --- a/trunk/arch/ia64/include/asm/mca.h +++ b/trunk/arch/ia64/include/asm/mca.h @@ -143,7 +143,6 @@ extern unsigned long __per_cpu_mca[NR_CPUS]; extern int cpe_vector; extern int ia64_cpe_irq; extern void ia64_mca_init(void); -extern void ia64_mca_irq_init(void); extern void ia64_mca_cpu_init(void *); extern void ia64_os_mca_dispatch(void); extern void ia64_os_mca_dispatch_end(void); diff --git a/trunk/arch/ia64/include/asm/numa.h b/trunk/arch/ia64/include/asm/numa.h index 2db0a6c6daa5..2e27ef175652 100644 --- a/trunk/arch/ia64/include/asm/numa.h +++ b/trunk/arch/ia64/include/asm/numa.h @@ -67,13 +67,14 @@ extern int paddr_to_nid(unsigned long paddr); extern void map_cpu_to_node(int cpu, int nid); extern void unmap_cpu_from_node(int cpu, int nid); -extern void numa_clear_node(int cpu); + #else /* !CONFIG_NUMA */ #define map_cpu_to_node(cpu, nid) do{}while(0) #define unmap_cpu_from_node(cpu, nid) do{}while(0) + #define paddr_to_nid(addr) 0 -#define numa_clear_node(cpu) do { } while (0) + #endif /* CONFIG_NUMA */ #endif /* _ASM_IA64_NUMA_H */ diff --git a/trunk/arch/ia64/kernel/fsys.S b/trunk/arch/ia64/kernel/fsys.S index abc6dee3799c..c4cd45d97749 100644 --- a/trunk/arch/ia64/kernel/fsys.S +++ b/trunk/arch/ia64/kernel/fsys.S @@ -90,6 +90,53 @@ ENTRY(fsys_getpid) FSYS_RETURN END(fsys_getpid) +ENTRY(fsys_getppid) + .prologue + .altrp b6 + .body + add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16 + ;; + ld8 r17=[r17] // r17 = current->group_leader + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 + ;; + + ld4 r9=[r9] + add r17=IA64_TASK_REAL_PARENT_OFFSET,r17 // r17 = ¤t->group_leader->real_parent + ;; + and r9=TIF_ALLWORK_MASK,r9 + +1: ld8 r18=[r17] // r18 = current->group_leader->real_parent + ;; + cmp.ne p8,p0=0,r9 + add r8=IA64_TASK_TGID_OFFSET,r18 // r8 = ¤t->group_leader->real_parent->tgid + ;; + + /* + * The .acq is needed to ensure that the read of tgid has returned its data before + * we re-check "real_parent". + */ + ld4.acq r8=[r8] // r8 = current->group_leader->real_parent->tgid +#ifdef CONFIG_SMP + /* + * Re-read current->group_leader->real_parent. + */ + ld8 r19=[r17] // r19 = current->group_leader->real_parent +(p8) br.spnt.many fsys_fallback_syscall + ;; + cmp.ne p6,p0=r18,r19 // did real_parent change? + mov r19=0 // i must not leak kernel bits... +(p6) br.cond.spnt.few 1b // yes -> redo the read of tgid and the check + ;; + mov r17=0 // i must not leak kernel bits... + mov r18=0 // i must not leak kernel bits... +#else + mov r17=0 // i must not leak kernel bits... + mov r18=0 // i must not leak kernel bits... + mov r19=0 // i must not leak kernel bits... +#endif + FSYS_RETURN +END(fsys_getppid) + ENTRY(fsys_set_tid_address) .prologue .altrp b6 @@ -567,7 +614,7 @@ paravirt_fsyscall_table: data8 0 // chown data8 0 // lseek // 1040 data8 fsys_getpid // getpid - data8 0 // getppid + data8 fsys_getppid // getppid data8 0 // mount data8 0 // umount data8 0 // setuid // 1045 diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index 19f107be734e..ee33c3aaa2fc 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -76,7 +76,7 @@ * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ * * Note: The term "IRQ" is loosely used everywhere in Linux kernel to - * describe interrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ + * describeinterrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ * (isa_irq) is the only exception in this source code. */ @@ -1010,26 +1010,6 @@ iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) return 0; } -static int -iosapic_delete_rte(unsigned int irq, unsigned int gsi) -{ - struct iosapic_rte_info *rte, *temp; - - list_for_each_entry_safe(rte, temp, &iosapic_intr_info[irq].rtes, - rte_list) { - if (rte->iosapic->gsi_base + rte->rte_index == gsi) { - if (rte->refcnt) - return -EBUSY; - - list_del(&rte->rte_list); - kfree(rte); - return 0; - } - } - - return -EINVAL; -} - int iosapic_init(unsigned long phys_addr, unsigned int gsi_base) { int num_rte, err, index; @@ -1089,7 +1069,7 @@ int iosapic_init(unsigned long phys_addr, unsigned int gsi_base) int iosapic_remove(unsigned int gsi_base) { - int i, irq, index, err = 0; + int index, err = 0; unsigned long flags; spin_lock_irqsave(&iosapic_lock, flags); @@ -1107,16 +1087,6 @@ int iosapic_remove(unsigned int gsi_base) goto out; } - for (i = gsi_base; i < gsi_base + iosapic_lists[index].num_rte; i++) { - irq = __gsi_to_irq(i); - if (irq < 0) - continue; - - err = iosapic_delete_rte(irq, i); - if (err) - goto out; - } - iounmap(iosapic_lists[index].addr); iosapic_free(index); out: diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index f2c418281130..ad69606613eb 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -23,8 +23,6 @@ #include #include -#include - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -85,12 +83,6 @@ bool is_affinity_mask_valid(const struct cpumask *cpumask) #endif /* CONFIG_SMP */ -int __init arch_early_irq_init(void) -{ - ia64_mca_irq_init(); - return 0; -} - #ifdef CONFIG_HOTPLUG_CPU unsigned int vectors_in_migration[NR_IRQS]; diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index d7396dbb07bb..65bf9cd39044 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -2074,16 +2074,22 @@ ia64_mca_init(void) printk(KERN_INFO "MCA related initialization done\n"); } - /* - * These pieces cannot be done in ia64_mca_init() because it is called before - * early_irq_init() which would wipe out our percpu irq registrations. But we - * cannot leave them until ia64_mca_late_init() because by then all the other - * processors have been brought online and have set their own CMC vectors to - * point at a non-existant action. Called from arch_early_irq_init(). + * ia64_mca_late_init + * + * Opportunity to setup things that require initialization later + * than ia64_mca_init. Setup a timer to poll for CPEs if the + * platform doesn't support an interrupt driven mechanism. + * + * Inputs : None + * Outputs : Status */ -void __init ia64_mca_irq_init(void) +static int __init +ia64_mca_late_init(void) { + if (!mca_init) + return 0; + /* * Configure the CMCI/P vector and handler. Interrupts for CMC are * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c). @@ -2102,23 +2108,6 @@ void __init ia64_mca_irq_init(void) /* Setup the CPEI/P handler */ register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); #endif -} - -/* - * ia64_mca_late_init - * - * Opportunity to setup things that require initialization later - * than ia64_mca_init. Setup a timer to poll for CPEs if the - * platform doesn't support an interrupt driven mechanism. - * - * Inputs : None - * Outputs : Status - */ -static int __init -ia64_mca_late_init(void) -{ - if (!mca_init) - return 0; register_hotcpu_notifier(&mca_cpu_notifier); diff --git a/trunk/arch/ia64/kernel/mca_drv.c b/trunk/arch/ia64/kernel/mca_drv.c index 94f8bf777afa..9392e021c93b 100644 --- a/trunk/arch/ia64/kernel/mca_drv.c +++ b/trunk/arch/ia64/kernel/mca_drv.c @@ -349,7 +349,7 @@ init_record_index_pools(void) /* - 3 - */ slidx_pool.max_idx = (rec_max_size/sect_min_size) * 2 + 1; - slidx_pool.buffer = + slidx_pool.buffer = (slidx_list_t *) kmalloc(slidx_pool.max_idx * sizeof(slidx_list_t), GFP_KERNEL); return slidx_pool.buffer ? 0 : -ENOMEM; diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index 79521d5499f9..77597e5ea60a 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -849,6 +849,17 @@ static palinfo_entry_t palinfo_entries[]={ #define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries) +/* + * this array is used to keep track of the proc entries we create. This is + * required in the module mode when we need to remove all entries. The procfs code + * does not do recursion of deletion + * + * Notes: + * - +1 accounts for the cpuN directory entry in /proc/pal + */ +#define NR_PALINFO_PROC_ENTRIES (NR_CPUS*(NR_PALINFO_ENTRIES+1)) + +static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES]; static struct proc_dir_entry *palinfo_dir; /* @@ -960,32 +971,60 @@ palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, voi static void __cpuinit create_palinfo_proc_entries(unsigned int cpu) { +# define CPUSTR "cpu%d" + pal_func_cpu_u_t f; + struct proc_dir_entry **pdir; struct proc_dir_entry *cpu_dir; int j; - char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */ - sprintf(cpustr, "cpu%d", cpu); + char cpustr[sizeof(CPUSTR)]; + + + /* + * we keep track of created entries in a depth-first order for + * cleanup purposes. Each entry is stored into palinfo_proc_entries + */ + sprintf(cpustr,CPUSTR, cpu); cpu_dir = proc_mkdir(cpustr, palinfo_dir); - if (!cpu_dir) - return; f.req_cpu = cpu; + /* + * Compute the location to store per cpu entries + * We dont store the top level entry in this list, but + * remove it finally after removing all cpu entries. + */ + pdir = &palinfo_proc_entries[cpu*(NR_PALINFO_ENTRIES+1)]; + *pdir++ = cpu_dir; for (j=0; j < NR_PALINFO_ENTRIES; j++) { f.func_id = j; - create_proc_read_entry( - palinfo_entries[j].name, 0, cpu_dir, - palinfo_read_entry, (void *)f.value); + *pdir = create_proc_read_entry( + palinfo_entries[j].name, 0, cpu_dir, + palinfo_read_entry, (void *)f.value); + pdir++; } } static void remove_palinfo_proc_entries(unsigned int hcpu) { - char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */ - sprintf(cpustr, "cpu%d", hcpu); - remove_proc_subtree(cpustr, palinfo_dir); + int j; + struct proc_dir_entry *cpu_dir, **pdir; + + pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)]; + cpu_dir = *pdir; + *pdir++=NULL; + for (j=0; j < (NR_PALINFO_ENTRIES); j++) { + if ((*pdir)) { + remove_proc_entry ((*pdir)->name, cpu_dir); + *pdir ++= NULL; + } + } + + if (cpu_dir) { + remove_proc_entry(cpu_dir->name, palinfo_dir); + } } static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, @@ -1019,8 +1058,6 @@ palinfo_init(void) printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION); palinfo_dir = proc_mkdir("pal", NULL); - if (!palinfo_dir) - return -ENOMEM; /* Create palinfo dirs in /proc for all online cpus */ for_each_online_cpu(i) { @@ -1036,8 +1073,22 @@ palinfo_init(void) static void __exit palinfo_exit(void) { + int i = 0; + + /* remove all nodes: depth first pass. Could optimize this */ + for_each_online_cpu(i) { + remove_palinfo_proc_entries(i); + } + + /* + * Remove the top level entry finally + */ + remove_proc_entry(palinfo_dir->name, NULL); + + /* + * Unregister from cpu notifier callbacks + */ unregister_hotcpu_notifier(&palinfo_cpu_notifier); - remove_proc_subtree("pal", NULL); } module_init(palinfo_init); diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 2eda28414abb..433f5e8a2cd1 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -619,7 +619,6 @@ static struct file_system_type pfm_fs_type = { .mount = pfmfs_mount, .kill_sb = kill_anon_super, }; -MODULE_ALIAS_FS("pfmfs"); DEFINE_PER_CPU(unsigned long, pfm_syst_info); DEFINE_PER_CPU(struct task_struct *, pmu_owner); diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 6f7dc8b7b35c..e34f565f595a 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -291,6 +291,7 @@ cpu_idle (void) } if (!need_resched()) { + void (*idle)(void); #ifdef CONFIG_SMP min_xtp(); #endif @@ -298,7 +299,9 @@ cpu_idle (void) if (mark_idle) (*mark_idle)(1); - default_idle(); + if (!idle) + idle = default_idle; + (*idle)(); if (mark_idle) (*mark_idle)(0); #ifdef CONFIG_SMP diff --git a/trunk/arch/ia64/kvm/vtlb.c b/trunk/arch/ia64/kvm/vtlb.c index a7869f8f49a6..4332f7ee5203 100644 --- a/trunk/arch/ia64/kvm/vtlb.c +++ b/trunk/arch/ia64/kvm/vtlb.c @@ -256,7 +256,7 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte) "srlz.d;;" "ssm psr.i;;" "srlz.d;;" - : "=&r"(ret) : "r"(iha), "r"(pte) : "memory"); + : "=r"(ret) : "r"(iha), "r"(pte):"memory"); return ret; } diff --git a/trunk/arch/ia64/mm/ioremap.c b/trunk/arch/ia64/mm/ioremap.c index 43964cde6214..3dccdd8eb275 100644 --- a/trunk/arch/ia64/mm/ioremap.c +++ b/trunk/arch/ia64/mm/ioremap.c @@ -16,7 +16,7 @@ #include static inline void __iomem * -__ioremap_uc(unsigned long phys_addr) +__ioremap (unsigned long phys_addr) { return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr); } @@ -24,11 +24,7 @@ __ioremap_uc(unsigned long phys_addr) void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size) { - u64 attr; - attr = kern_mem_attribute(phys_addr, size); - if (attr & EFI_MEMORY_WB) - return (void __iomem *) phys_to_virt(phys_addr); - return __ioremap_uc(phys_addr); + return __ioremap(phys_addr); } void __iomem * @@ -51,7 +47,7 @@ ioremap (unsigned long phys_addr, unsigned long size) if (attr & EFI_MEMORY_WB) return (void __iomem *) phys_to_virt(phys_addr); else if (attr & EFI_MEMORY_UC) - return __ioremap_uc(phys_addr); + return __ioremap(phys_addr); /* * Some chipsets don't support UC access to memory. If @@ -97,7 +93,7 @@ ioremap (unsigned long phys_addr, unsigned long size) return (void __iomem *) (offset + (char __iomem *)addr); } - return __ioremap_uc(phys_addr); + return __ioremap(phys_addr); } EXPORT_SYMBOL(ioremap); @@ -107,7 +103,7 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size) if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB) return NULL; - return __ioremap_uc(phys_addr); + return __ioremap(phys_addr); } EXPORT_SYMBOL(ioremap_nocache); diff --git a/trunk/arch/ia64/mm/numa.c b/trunk/arch/ia64/mm/numa.c index def782e31aac..3efea7d0a351 100644 --- a/trunk/arch/ia64/mm/numa.c +++ b/trunk/arch/ia64/mm/numa.c @@ -73,11 +73,6 @@ int __meminit __early_pfn_to_nid(unsigned long pfn) return -1; } -void __cpuinit numa_clear_node(int cpu) -{ - unmap_cpu_from_node(cpu, NUMA_NO_NODE); -} - #ifdef CONFIG_MEMORY_HOTPLUG /* * SRAT information is stored in node_memblk[], then we can use SRAT diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index de1474ff0bc5..60532ab27346 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -459,16 +458,6 @@ void pcibios_fixup_bus(struct pci_bus *b) platform_pci_fixup_bus(b); } -void pcibios_add_bus(struct pci_bus *bus) -{ - acpi_pci_add_bus(bus); -} - -void pcibios_remove_bus(struct pci_bus *bus) -{ - acpi_pci_remove_bus(bus); -} - void pcibios_set_master (struct pci_dev *dev) { /* No special bus mastering setup handling */ diff --git a/trunk/arch/ia64/sn/kernel/tiocx.c b/trunk/arch/ia64/sn/kernel/tiocx.c index e35f6485c1fd..14c1711238c0 100644 --- a/trunk/arch/ia64/sn/kernel/tiocx.c +++ b/trunk/arch/ia64/sn/kernel/tiocx.c @@ -490,14 +490,11 @@ static int __init tiocx_init(void) { cnodeid_t cnodeid; int found_tiocx_device = 0; - int err; if (!ia64_platform_is("sn2")) return 0; - err = bus_register(&tiocx_bus_type); - if (err) - return err; + bus_register(&tiocx_bus_type); for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) { nasid_t nasid; diff --git a/trunk/arch/m32r/Kconfig b/trunk/arch/m32r/Kconfig index bcd17b206571..92623818a1fe 100644 --- a/trunk/arch/m32r/Kconfig +++ b/trunk/arch/m32r/Kconfig @@ -10,7 +10,7 @@ config M32R select ARCH_WANT_IPC_PARSE_VERSION select HAVE_DEBUG_BUGVERBOSE select HAVE_GENERIC_HARDIRQS - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select GENERIC_ATOMIC64 diff --git a/trunk/arch/m32r/include/uapi/asm/stat.h b/trunk/arch/m32r/include/uapi/asm/stat.h index 98470fe483b6..da4518f82d6d 100644 --- a/trunk/arch/m32r/include/uapi/asm/stat.h +++ b/trunk/arch/m32r/include/uapi/asm/stat.h @@ -63,10 +63,10 @@ struct stat64 { long long st_size; unsigned long st_blksize; -#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN) +#if defined(__BIG_ENDIAN) unsigned long __pad4; /* future possible st_blocks high bits */ unsigned long st_blocks; /* Number 512-byte blocks allocated. */ -#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) +#elif defined(__LITTLE_ENDIAN) unsigned long st_blocks; /* Number 512-byte blocks allocated. */ unsigned long __pad4; /* future possible st_blocks high bits */ #else diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 6de813370b8c..0e708c78e01c 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -8,7 +8,7 @@ config M68K select GENERIC_IRQ_SHOW select GENERIC_ATOMIC64 select HAVE_UID16 - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS select GENERIC_CPU_DEVICES select GENERIC_STRNCPY_FROM_USER if MMU diff --git a/trunk/arch/m68k/Kconfig.machine b/trunk/arch/m68k/Kconfig.machine index 7240584d3439..7cdf6b010381 100644 --- a/trunk/arch/m68k/Kconfig.machine +++ b/trunk/arch/m68k/Kconfig.machine @@ -310,6 +310,7 @@ config COBRA5282 config SOM5282EM bool "EMAC.Inc SOM5282EM board support" depends on M528x + select EMAC_INC help Support for the EMAC.Inc SOM5282EM module. diff --git a/trunk/arch/m68k/include/asm/MC68328.h b/trunk/arch/m68k/include/asm/MC68328.h index 4ebf098b8a1f..a337e56d09bf 100644 --- a/trunk/arch/m68k/include/asm/MC68328.h +++ b/trunk/arch/m68k/include/asm/MC68328.h @@ -293,7 +293,7 @@ /* * Here go the bitmasks themselves */ -#define IMR_MSPIM (1 << SPIM_IRQ_NUM) /* Mask SPI Master interrupt */ +#define IMR_MSPIM (1 << SPIM _IRQ_NUM) /* Mask SPI Master interrupt */ #define IMR_MTMR2 (1 << TMR2_IRQ_NUM) /* Mask Timer 2 interrupt */ #define IMR_MUART (1 << UART_IRQ_NUM) /* Mask UART interrupt */ #define IMR_MWDT (1 << WDT_IRQ_NUM) /* Mask Watchdog Timer interrupt */ @@ -327,7 +327,7 @@ #define IWR_ADDR 0xfffff308 #define IWR LONG_REF(IWR_ADDR) -#define IWR_SPIM (1 << SPIM_IRQ_NUM) /* SPI Master interrupt */ +#define IWR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ #define IWR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ #define IWR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ #define IWR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ @@ -357,7 +357,7 @@ #define ISR_ADDR 0xfffff30c #define ISR LONG_REF(ISR_ADDR) -#define ISR_SPIM (1 << SPIM_IRQ_NUM) /* SPI Master interrupt */ +#define ISR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ #define ISR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ #define ISR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ #define ISR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ @@ -391,7 +391,7 @@ #define IPR_ADDR 0xfffff310 #define IPR LONG_REF(IPR_ADDR) -#define IPR_SPIM (1 << SPIM_IRQ_NUM) /* SPI Master interrupt */ +#define IPR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ #define IPR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ #define IPR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ #define IPR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ @@ -757,7 +757,7 @@ /* 'EZ328-compatible definitions */ #define TCN_ADDR TCN1_ADDR -#define TCN TCN1 +#define TCN TCN /* * Timer Unit 1 and 2 Status Registers diff --git a/trunk/arch/m68k/include/asm/gpio.h b/trunk/arch/m68k/include/asm/gpio.h index 8cc83431805b..4395ffc51fdb 100644 --- a/trunk/arch/m68k/include/asm/gpio.h +++ b/trunk/arch/m68k/include/asm/gpio.h @@ -86,24 +86,4 @@ static inline int gpio_cansleep(unsigned gpio) return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); } -static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) -{ - int err; - - err = gpio_request(gpio, label); - if (err) - return err; - - if (flags & GPIOF_DIR_IN) - err = gpio_direction_input(gpio); - else - err = gpio_direction_output(gpio, - (flags & GPIOF_INIT_HIGH) ? 1 : 0); - - if (err) - gpio_free(gpio); - - return err; -} - #endif diff --git a/trunk/arch/m68k/kernel/setup_no.c b/trunk/arch/m68k/kernel/setup_no.c index 911ba472e6c4..71fb29938dba 100644 --- a/trunk/arch/m68k/kernel/setup_no.c +++ b/trunk/arch/m68k/kernel/setup_no.c @@ -57,9 +57,6 @@ void (*mach_reset)(void); void (*mach_halt)(void); void (*mach_power_off)(void); -#ifdef CONFIG_M68000 -#define CPU_NAME "MC68000" -#endif #ifdef CONFIG_M68328 #define CPU_NAME "MC68328" #endif diff --git a/trunk/arch/m68k/mm/init.c b/trunk/arch/m68k/mm/init.c index 519aad8fa812..afd8106fd83b 100644 --- a/trunk/arch/m68k/mm/init.c +++ b/trunk/arch/m68k/mm/init.c @@ -188,7 +188,7 @@ void __init mem_init(void) } } -#if defined(CONFIG_MMU) && !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) +#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) /* insert pointer tables allocated so far into the tablelist */ init_pointer_table((unsigned long)kernel_pg_dir); for (i = 0; i < PTRS_PER_PGD; i++) { diff --git a/trunk/arch/m68k/platform/coldfire/m528x.c b/trunk/arch/m68k/platform/coldfire/m528x.c index b03a9d271837..83b7dad7a84e 100644 --- a/trunk/arch/m68k/platform/coldfire/m528x.c +++ b/trunk/arch/m68k/platform/coldfire/m528x.c @@ -69,7 +69,7 @@ static void __init m528x_uarts_init(void) u8 port; /* make sure PUAPAR is set for UART0 and UART1 */ - port = readb(MCFGPIO_PUAPAR); + port = readb(MCF5282_GPIO_PUAPAR); port |= 0x03 | (0x03 << 2); writeb(port, MCFGPIO_PUAPAR); } diff --git a/trunk/arch/metag/include/asm/elf.h b/trunk/arch/metag/include/asm/elf.h index d2baf6961794..d63b9d0e57dd 100644 --- a/trunk/arch/metag/include/asm/elf.h +++ b/trunk/arch/metag/include/asm/elf.h @@ -100,6 +100,9 @@ typedef unsigned long elf_fpregset_t; #define ELF_PLATFORM (NULL) +#define SET_PERSONALITY(ex) \ + set_personality(PER_LINUX | (current->personality & (~PER_MASK))) + #define STACK_RND_MASK (0) #ifdef CONFIG_METAG_USER_TCM diff --git a/trunk/arch/metag/mm/Kconfig b/trunk/arch/metag/mm/Kconfig index 975f2f4e3ecf..cd7f2f2ad416 100644 --- a/trunk/arch/metag/mm/Kconfig +++ b/trunk/arch/metag/mm/Kconfig @@ -40,7 +40,6 @@ endchoice config NUMA bool "Non Uniform Memory Access (NUMA) Support" - select ARCH_WANT_NUMA_VARIABLE_LOCALITY help Some Meta systems have MMU-mappable on-chip memories with lower latencies than main memory. This enables support for diff --git a/trunk/arch/microblaze/Kconfig b/trunk/arch/microblaze/Kconfig index 1323fa2530eb..7843d11156e6 100644 --- a/trunk/arch/microblaze/Kconfig +++ b/trunk/arch/microblaze/Kconfig @@ -19,7 +19,7 @@ config MICROBLAZE select HAVE_DEBUG_KMEMLEAK select IRQ_DOMAIN select HAVE_GENERIC_HARDIRQS - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select GENERIC_PCI_IOMAP diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 51244bf97271..ae9c716c46bb 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -18,7 +18,7 @@ config MIPS select HAVE_KRETPROBES select HAVE_DEBUG_KMEMLEAK select ARCH_BINFMT_ELF_RANDOMIZE_PIE - select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT + select HAVE_ARCH_TRANSPARENT_HUGEPAGE select RTC_LIB if !MACH_LOONGSON select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE @@ -38,7 +38,7 @@ config MIPS select GENERIC_CLOCKEVENTS select GENERIC_CMOS_UPDATE select HAVE_MOD_ARCH_SPECIFIC - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select MODULES_USE_ELF_REL if MODULES select MODULES_USE_ELF_RELA if MODULES && 64BIT select CLONE_BACKWARDS @@ -657,7 +657,7 @@ config SNI_RM bool "SNI RM200/300/400" select FW_ARC if CPU_LITTLE_ENDIAN select FW_ARC32 if CPU_LITTLE_ENDIAN - select FW_SNIPROM if CPU_BIG_ENDIAN + select SNIPROM if CPU_BIG_ENDIAN select ARCH_MAY_HAVE_PC_FDC select BOOT_ELF32 select CEVT_R4K @@ -1144,7 +1144,7 @@ config DEFAULT_SGI_PARTITION config FW_ARC32 bool -config FW_SNIPROM +config SNIPROM bool config BOOT_ELF32 @@ -1493,6 +1493,7 @@ config CPU_XLP select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select CPU_HAS_LLSC select WEAK_ORDERING select WEAK_REORDERING_BEYOND_LLSC select CPU_HAS_PREFETCH diff --git a/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c b/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c index 9aa7d44898ed..ed1949c29508 100644 --- a/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -745,7 +745,10 @@ void __init board_prom_init(void) strcpy(cfe_version, "unknown"); printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); - bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET); + if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) { + printk(KERN_ERR PFX "invalid nvram checksum\n"); + return; + } board_name = bcm63xx_nvram_get_name(); /* find board by name */ diff --git a/trunk/arch/mips/bcm63xx/nvram.c b/trunk/arch/mips/bcm63xx/nvram.c index a4b8864f9307..620611680839 100644 --- a/trunk/arch/mips/bcm63xx/nvram.c +++ b/trunk/arch/mips/bcm63xx/nvram.c @@ -38,7 +38,7 @@ struct bcm963xx_nvram { static struct bcm963xx_nvram nvram; static int mac_addr_used; -void __init bcm63xx_nvram_init(void *addr) +int __init bcm63xx_nvram_init(void *addr) { unsigned int check_len; u32 crc, expected_crc; @@ -60,8 +60,9 @@ void __init bcm63xx_nvram_init(void *addr) crc = crc32_le(~0, (u8 *)&nvram, check_len); if (crc != expected_crc) - pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", - expected_crc, crc); + return -EINVAL; + + return 0; } u8 *bcm63xx_nvram_get_name(void) diff --git a/trunk/arch/mips/bcm63xx/setup.c b/trunk/arch/mips/bcm63xx/setup.c index 35e18e98beb9..314231be788c 100644 --- a/trunk/arch/mips/bcm63xx/setup.c +++ b/trunk/arch/mips/bcm63xx/setup.c @@ -157,4 +157,4 @@ int __init bcm63xx_register_devices(void) return board_register_devices(); } -arch_initcall(bcm63xx_register_devices); +device_initcall(bcm63xx_register_devices); diff --git a/trunk/arch/mips/cavium-octeon/setup.c b/trunk/arch/mips/cavium-octeon/setup.c index b0baa299f899..c594a3d4f743 100644 --- a/trunk/arch/mips/cavium-octeon/setup.c +++ b/trunk/arch/mips/cavium-octeon/setup.c @@ -174,10 +174,7 @@ static int octeon_kexec_prepare(struct kimage *image) static void octeon_generic_shutdown(void) { - int i; -#ifdef CONFIG_SMP - int cpu; -#endif + int cpu, i; struct cvmx_bootmem_desc *bootmem_desc; void *named_block_array_ptr; diff --git a/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 4e0b6bc1165e..62d6a3b4d3b7 100644 --- a/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h @@ -9,8 +9,10 @@ * * Initialized the local nvram copy from the target address and checks * its checksum. + * + * Returns 0 on success. */ -void bcm63xx_nvram_init(void *nvram); +int __init bcm63xx_nvram_init(void *nvram); /** * bcm63xx_nvram_get_name() - returns the board name according to nvram diff --git a/trunk/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h b/trunk/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h index 193c0912d38e..d9c828419037 100644 --- a/trunk/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h +++ b/trunk/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h @@ -28,7 +28,11 @@ /* #define cpu_has_prefetch ? */ #define cpu_has_mcheck 1 /* #define cpu_has_ejtag ? */ +#ifdef CONFIG_CPU_HAS_LLSC #define cpu_has_llsc 1 +#else +#define cpu_has_llsc 0 +#endif /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ diff --git a/trunk/arch/mips/include/asm/mipsregs.h b/trunk/arch/mips/include/asm/mipsregs.h index 0da44d422f5b..12b70c25906a 100644 --- a/trunk/arch/mips/include/asm/mipsregs.h +++ b/trunk/arch/mips/include/asm/mipsregs.h @@ -1166,10 +1166,7 @@ do { \ unsigned int __dspctl; \ \ __asm__ __volatile__( \ - " .set push \n" \ - " .set dsp \n" \ " rddsp %0, %x1 \n" \ - " .set pop \n" \ : "=r" (__dspctl) \ : "i" (mask)); \ __dspctl; \ @@ -1178,198 +1175,30 @@ do { \ #define wrdsp(val, mask) \ do { \ __asm__ __volatile__( \ - " .set push \n" \ - " .set dsp \n" \ " wrdsp %0, %x1 \n" \ - " .set pop \n" \ : \ : "r" (val), "i" (mask)); \ } while (0) -#define mflo0() \ -({ \ - long mflo0; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mflo %0, $ac0 \n" \ - " .set pop \n" \ - : "=r" (mflo0)); \ - mflo0; \ -}) - -#define mflo1() \ -({ \ - long mflo1; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mflo %0, $ac1 \n" \ - " .set pop \n" \ - : "=r" (mflo1)); \ - mflo1; \ -}) - -#define mflo2() \ -({ \ - long mflo2; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mflo %0, $ac2 \n" \ - " .set pop \n" \ - : "=r" (mflo2)); \ - mflo2; \ -}) - -#define mflo3() \ -({ \ - long mflo3; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mflo %0, $ac3 \n" \ - " .set pop \n" \ - : "=r" (mflo3)); \ - mflo3; \ -}) - -#define mfhi0() \ -({ \ - long mfhi0; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mfhi %0, $ac0 \n" \ - " .set pop \n" \ - : "=r" (mfhi0)); \ - mfhi0; \ -}) - -#define mfhi1() \ -({ \ - long mfhi1; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mfhi %0, $ac1 \n" \ - " .set pop \n" \ - : "=r" (mfhi1)); \ - mfhi1; \ -}) - -#define mfhi2() \ -({ \ - long mfhi2; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mfhi %0, $ac2 \n" \ - " .set pop \n" \ - : "=r" (mfhi2)); \ - mfhi2; \ -}) - -#define mfhi3() \ -({ \ - long mfhi3; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mfhi %0, $ac3 \n" \ - " .set pop \n" \ - : "=r" (mfhi3)); \ - mfhi3; \ -}) - - -#define mtlo0(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mtlo %0, $ac0 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mtlo1(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mtlo %0, $ac1 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mtlo2(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mtlo %0, $ac2 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mtlo3(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mtlo %0, $ac3 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mthi0(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mthi %0, $ac0 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mthi1(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mthi %0, $ac1 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mthi2(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mthi %0, $ac2 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mthi3(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mthi %0, $ac3 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) +#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;}) +#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;}) +#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;}) +#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;}) + +#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;}) +#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;}) +#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;}) +#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;}) + +#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x)) +#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x)) +#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x)) +#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x)) + +#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x)) +#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x)) +#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x)) +#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x)) #else diff --git a/trunk/arch/mips/include/asm/page.h b/trunk/arch/mips/include/asm/page.h index eab99e536b5c..99fc547af9d3 100644 --- a/trunk/arch/mips/include/asm/page.h +++ b/trunk/arch/mips/include/asm/page.h @@ -31,7 +31,7 @@ #define PAGE_SHIFT 16 #endif #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +#define PAGE_MASK (~(PAGE_SIZE - 1)) #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) diff --git a/trunk/arch/mips/include/asm/signal.h b/trunk/arch/mips/include/asm/signal.h index 8efe5a9e2c3e..197f6367c201 100644 --- a/trunk/arch/mips/include/asm/signal.h +++ b/trunk/arch/mips/include/asm/signal.h @@ -21,6 +21,6 @@ #include #include -#define __ARCH_HAS_IRIX_SIGACTION +#define __ARCH_HAS_ODD_SIGACTION #endif /* _ASM_SIGNAL_H */ diff --git a/trunk/arch/mips/include/uapi/asm/signal.h b/trunk/arch/mips/include/uapi/asm/signal.h index addb9f556b71..d6b18b4d0f3a 100644 --- a/trunk/arch/mips/include/uapi/asm/signal.h +++ b/trunk/arch/mips/include/uapi/asm/signal.h @@ -72,12 +72,6 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ * * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single * Unix names RESETHAND and NODEFER respectively. - * - * SA_RESTORER used to be defined as 0x04000000 but only the O32 ABI ever - * supported its use and no libc was using it, so the entire sa-restorer - * functionality was removed with lmo commit 39bffc12c3580ab for 2.5.48 - * retaining only the SA_RESTORER definition as a reminder to avoid - * accidental reuse of the mask bit. */ #define SA_ONSTACK 0x08000000 #define SA_RESETHAND 0x80000000 @@ -90,6 +84,8 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ #define SA_NOMASK SA_NODEFER #define SA_ONESHOT SA_RESETHAND +#define SA_RESTORER 0x04000000 /* Only for o32 */ + #define MINSIGSTKSZ 2048 #define SIGSTKSZ 8192 diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index de75fb50562b..f81d98f6184c 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -100,16 +100,29 @@ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o # -# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is not -# safe to unconditionnaly use the assembler -mdsp / -mdspr2 switches -# here because the compiler may use DSP ASE instructions (such as lwx) in -# code paths where we cannot check that the CPU we are running on supports it. -# Proper abstraction using HAVE_AS_DSP and macros is done in -# arch/mips/include/asm/mipsregs.h. +# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is safe +# to enable DSP assembler support here even if the MIPS Release 2 CPU we +# are targetting does not support DSP because all code-paths making use of +# it properly check that the running CPU *actually does* support these +# instructions. # ifeq ($(CONFIG_CPU_MIPSR2), y) CFLAGS_DSP = -DHAVE_AS_DSP +# +# Check if assembler supports DSP ASE +# +ifeq ($(call cc-option-yn,-mdsp), y) +CFLAGS_DSP += -mdsp +endif + +# +# Check if assembler supports DSP ASE Rev2 +# +ifeq ($(call cc-option-yn,-mdspr2), y) +CFLAGS_DSP += -mdspr2 +endif + CFLAGS_signal.o = $(CFLAGS_DSP) CFLAGS_signal32.o = $(CFLAGS_DSP) CFLAGS_process.o = $(CFLAGS_DSP) diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 5fe66a0c3224..6bfccc227a95 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -580,9 +580,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->tlbsize = 48; break; case PRID_IMP_VR41XX: - set_isa(c, MIPS_CPU_ISA_III); - c->options = R4K_OPTS; - c->tlbsize = 32; switch (c->processor_id & 0xf0) { case PRID_REV_VR4111: c->cputype = CPU_VR4111; @@ -607,7 +604,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "NEC VR4131"; } else { c->cputype = CPU_VR4133; - c->options |= MIPS_CPU_LLSC; __cpu_name[cpu] = "NEC VR4133"; } break; @@ -617,6 +613,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "NEC Vr41xx"; break; } + set_isa(c, MIPS_CPU_ISA_III); + c->options = R4K_OPTS; + c->tlbsize = 32; break; case PRID_IMP_R4300: c->cputype = CPU_R4300; @@ -1227,8 +1226,10 @@ __cpuinit void cpu_probe(void) if (c->options & MIPS_CPU_FPU) { c->fpu_id = cpu_get_fpu_id(); - if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | - MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { + if (c->isa_level == MIPS_CPU_ISA_M32R1 || + c->isa_level == MIPS_CPU_ISA_M32R2 || + c->isa_level == MIPS_CPU_ISA_M64R1 || + c->isa_level == MIPS_CPU_ISA_M64R2) { if (c->fpu_id & MIPS_FPIR_3D) c->ases |= MIPS_ASE_MIPS3D; } diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index db9655f08892..8eeee1c860c0 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -171,7 +171,7 @@ SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third, err = compat_sys_shmctl(first, second, compat_ptr(ptr)); break; default: - err = -ENOSYS; + err = -EINVAL; break; } diff --git a/trunk/arch/mips/kernel/mcount.S b/trunk/arch/mips/kernel/mcount.S index 33d067148e61..165867673357 100644 --- a/trunk/arch/mips/kernel/mcount.S +++ b/trunk/arch/mips/kernel/mcount.S @@ -46,9 +46,10 @@ PTR_L a5, PT_R9(sp) PTR_L a6, PT_R10(sp) PTR_L a7, PT_R11(sp) -#endif +#else PTR_ADDIU sp, PT_SIZE - .endm +#endif +.endm .macro RETURN_BACK jr ra @@ -67,11 +68,7 @@ NESTED(ftrace_caller, PT_SIZE, ra) .globl _mcount _mcount: b ftrace_stub -#ifdef CONFIG_32BIT - addiu sp,sp,8 -#else - nop -#endif + addiu sp,sp,8 /* When tracing is activated, it calls ftrace_caller+8 (aka here) */ lw t1, function_trace_stop diff --git a/trunk/arch/mips/kernel/proc.c b/trunk/arch/mips/kernel/proc.c index 7a54f74b7818..135c4aadccbe 100644 --- a/trunk/arch/mips/kernel/proc.c +++ b/trunk/arch/mips/kernel/proc.c @@ -67,7 +67,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (cpu_has_mips_r) { seq_printf(m, "isa\t\t\t:"); if (cpu_has_mips_1) - seq_printf(m, "%s", " mips1"); + seq_printf(m, "%s", "mips1"); if (cpu_has_mips_2) seq_printf(m, "%s", " mips2"); if (cpu_has_mips_3) diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index c3abb88170fc..a200b5bdbb87 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -1571,7 +1571,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) #ifdef CONFIG_64BIT status_set |= ST0_FR|ST0_KX|ST0_SX|ST0_UX; #endif - if (current_cpu_data.isa_level & MIPS_CPU_ISA_IV) + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) status_set |= ST0_XX; if (cpu_has_dsp) status_set |= ST0_MX; diff --git a/trunk/arch/mips/lib/bitops.c b/trunk/arch/mips/lib/bitops.c index a64daee740ee..81f1dcfdcab8 100644 --- a/trunk/arch/mips/lib/bitops.c +++ b/trunk/arch/mips/lib/bitops.c @@ -90,12 +90,12 @@ int __mips_test_and_set_bit(unsigned long nr, unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - int res; + unsigned long res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a) != 0; + res = (mask & *a); *a |= mask; raw_local_irq_restore(flags); return res; @@ -116,12 +116,12 @@ int __mips_test_and_set_bit_lock(unsigned long nr, unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - int res; + unsigned long res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a) != 0; + res = (mask & *a); *a |= mask; raw_local_irq_restore(flags); return res; @@ -141,12 +141,12 @@ int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - int res; + unsigned long res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a) != 0; + res = (mask & *a); *a &= ~mask; raw_local_irq_restore(flags); return res; @@ -166,12 +166,12 @@ int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - int res; + unsigned long res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a) != 0; + res = (mask & *a); *a ^= mask; raw_local_irq_restore(flags); return res; diff --git a/trunk/arch/mips/lib/csum_partial.S b/trunk/arch/mips/lib/csum_partial.S index a6adffbb4e5f..507147aebd41 100644 --- a/trunk/arch/mips/lib/csum_partial.S +++ b/trunk/arch/mips/lib/csum_partial.S @@ -270,7 +270,7 @@ LEAF(csum_partial) #endif /* odd buffer alignment? */ -#ifdef CONFIG_CPU_MIPSR2 +#ifdef CPU_MIPSR2 wsbh v1, sum movn sum, v1, t7 #else @@ -670,7 +670,7 @@ EXC( sb t0, NBYTES-2(dst), .Ls_exc) addu sum, v1 #endif -#ifdef CONFIG_CPU_MIPSR2 +#ifdef CPU_MIPSR2 wsbh v1, sum movn sum, v1, odd #else diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index 2078915eacb9..ecca559b8d7b 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -1247,8 +1247,10 @@ static void __cpuinit setup_scache(void) return; default: - if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | - MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { + if (c->isa_level == MIPS_CPU_ISA_M32R1 || + c->isa_level == MIPS_CPU_ISA_M32R2 || + c->isa_level == MIPS_CPU_ISA_M64R1 || + c->isa_level == MIPS_CPU_ISA_M64R2) { #ifdef CONFIG_MIPS_CPU_SCACHE if (mips_sc_init ()) { scache_size = c->scache.ways * c->scache.sets * c->scache.linesz; diff --git a/trunk/arch/mips/mm/sc-mips.c b/trunk/arch/mips/mm/sc-mips.c index df96da7e939b..93d937b4b1ba 100644 --- a/trunk/arch/mips/mm/sc-mips.c +++ b/trunk/arch/mips/mm/sc-mips.c @@ -98,8 +98,10 @@ static inline int __init mips_sc_probe(void) c->scache.flags |= MIPS_CACHE_NOT_PRESENT; /* Ignore anything but MIPSxx processors */ - if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | - MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2))) + if (c->isa_level != MIPS_CPU_ISA_M32R1 && + c->isa_level != MIPS_CPU_ISA_M32R2 && + c->isa_level != MIPS_CPU_ISA_M64R1 && + c->isa_level != MIPS_CPU_ISA_M64R2) return 0; /* Does this MIPS32/MIPS64 CPU have a config2 register? */ diff --git a/trunk/arch/mips/pci/pci-alchemy.c b/trunk/arch/mips/pci/pci-alchemy.c index d1faece21b6a..38a80c83fd67 100644 --- a/trunk/arch/mips/pci/pci-alchemy.c +++ b/trunk/arch/mips/pci/pci-alchemy.c @@ -19,7 +19,7 @@ #include #include -#ifdef CONFIG_PCI_DEBUG +#ifdef CONFIG_DEBUG_PCI #define DBG(x...) printk(KERN_DEBUG x) #else #define DBG(x...) do {} while (0) @@ -162,7 +162,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, if (status & (1 << 29)) { *data = 0xffffffff; error = -1; - DBG("alchemy-pci: master abort on cfg access %d bus %d dev %d\n", + DBG("alchemy-pci: master abort on cfg access %d bus %d dev %d", access_type, bus->number, device); } else if ((status >> 28) & 0xf) { DBG("alchemy-pci: PCI ERR detected: dev %d, status %lx\n", diff --git a/trunk/arch/mips/pci/pci.c b/trunk/arch/mips/pci/pci.c index 594e60d6a43b..0872f12f268d 100644 --- a/trunk/arch/mips/pci/pci.c +++ b/trunk/arch/mips/pci/pci.c @@ -115,6 +115,7 @@ static void pcibios_scanbus(struct pci_controller *hose) pci_bus_assign_resources(bus); pci_enable_bridges(bus); } + bus->dev.of_node = hose->of_node; } } @@ -168,13 +169,6 @@ void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) } } } - -struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) -{ - struct pci_controller *hose = bus->sysdata; - - return of_node_get(hose->of_node); -} #endif static DEFINE_MUTEX(pci_scan_mutex); diff --git a/trunk/arch/mn10300/Kconfig b/trunk/arch/mn10300/Kconfig index 428da175d073..b06c7360b1c6 100644 --- a/trunk/arch/mn10300/Kconfig +++ b/trunk/arch/mn10300/Kconfig @@ -8,7 +8,7 @@ config MN10300 select HAVE_ARCH_KGDB select GENERIC_ATOMIC64 select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA select OLD_SIGSUSPEND3 diff --git a/trunk/arch/openrisc/Kconfig b/trunk/arch/openrisc/Kconfig index 9ab3bf2eca8d..014a6482ed4c 100644 --- a/trunk/arch/openrisc/Kconfig +++ b/trunk/arch/openrisc/Kconfig @@ -9,9 +9,10 @@ config OPENRISC select OF_EARLY_FLATTREE select IRQ_DOMAIN select HAVE_MEMBLOCK - select ARCH_REQUIRE_GPIOLIB + select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_ARCH_TRACEHOOK select HAVE_GENERIC_HARDIRQS + select HAVE_VIRT_TO_BUS select GENERIC_IRQ_CHIP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 0339181bf3ac..a9ff712a2864 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -21,7 +21,7 @@ config PARISC select GENERIC_STRNCPY_FROM_USER select SYSCTL_ARCH_UNALIGN_ALLOW select HAVE_MOD_ARCH_SPECIFIC - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select MODULES_USE_ELF_RELA select CLONE_BACKWARDS select TTY # Needed for pdc_cons.c diff --git a/trunk/arch/parisc/Makefile b/trunk/arch/parisc/Makefile index 113e28206503..01d95e2f0581 100644 --- a/trunk/arch/parisc/Makefile +++ b/trunk/arch/parisc/Makefile @@ -65,10 +65,8 @@ ifndef CONFIG_FUNCTION_TRACER endif # Use long jumps instead of long branches (needed if your linker fails to -# link a too big vmlinux executable). Not enabled for building modules. -ifdef CONFIG_MLONGCALLS -KBUILD_CFLAGS_KERNEL += -mlong-calls -endif +# link a too big vmlinux executable) +cflags-$(CONFIG_MLONGCALLS) += -mlong-calls # select which processor to optimise for cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100 diff --git a/trunk/arch/parisc/include/asm/cacheflush.h b/trunk/arch/parisc/include/asm/cacheflush.h index f0e2784e7cca..79f694f3ad9b 100644 --- a/trunk/arch/parisc/include/asm/cacheflush.h +++ b/trunk/arch/parisc/include/asm/cacheflush.h @@ -140,10 +140,7 @@ static inline void *kmap(struct page *page) return page_address(page); } -static inline void kunmap(struct page *page) -{ - kunmap_parisc(page_address(page)); -} +#define kunmap(page) kunmap_parisc(page_address(page)) static inline void *kmap_atomic(struct page *page) { diff --git a/trunk/arch/parisc/include/asm/pgtable.h b/trunk/arch/parisc/include/asm/pgtable.h index 1e40d7f86be3..7df49fad29f9 100644 --- a/trunk/arch/parisc/include/asm/pgtable.h +++ b/trunk/arch/parisc/include/asm/pgtable.h @@ -16,8 +16,6 @@ #include #include -extern spinlock_t pa_dbit_lock; - /* * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel * memory. For the return value to be meaningful, ADDR must be >= @@ -46,11 +44,8 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned long); #define set_pte_at(mm, addr, ptep, pteval) \ do { \ - unsigned long flags; \ - spin_lock_irqsave(&pa_dbit_lock, flags); \ set_pte(ptep, pteval); \ purge_tlb_entries(mm, addr); \ - spin_unlock_irqrestore(&pa_dbit_lock, flags); \ } while (0) #endif /* !__ASSEMBLY__ */ @@ -440,46 +435,48 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { - pte_t pte; - unsigned long flags; - +#ifdef CONFIG_SMP if (!pte_young(*ptep)) return 0; - - spin_lock_irqsave(&pa_dbit_lock, flags); - pte = *ptep; - if (!pte_young(pte)) { - spin_unlock_irqrestore(&pa_dbit_lock, flags); + return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), &pte_val(*ptep)); +#else + pte_t pte = *ptep; + if (!pte_young(pte)) return 0; - } - set_pte(ptep, pte_mkold(pte)); - purge_tlb_entries(vma->vm_mm, addr); - spin_unlock_irqrestore(&pa_dbit_lock, flags); + set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte)); return 1; +#endif } +extern spinlock_t pa_dbit_lock; + struct mm_struct; static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t old_pte; - unsigned long flags; - spin_lock_irqsave(&pa_dbit_lock, flags); + spin_lock(&pa_dbit_lock); old_pte = *ptep; pte_clear(mm,addr,ptep); - purge_tlb_entries(mm, addr); - spin_unlock_irqrestore(&pa_dbit_lock, flags); + spin_unlock(&pa_dbit_lock); return old_pte; } static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - unsigned long flags; - spin_lock_irqsave(&pa_dbit_lock, flags); - set_pte(ptep, pte_wrprotect(*ptep)); +#ifdef CONFIG_SMP + unsigned long new, old; + + do { + old = pte_val(*ptep); + new = pte_val(pte_wrprotect(__pte (old))); + } while (cmpxchg((unsigned long *) ptep, old, new) != old); purge_tlb_entries(mm, addr); - spin_unlock_irqrestore(&pa_dbit_lock, flags); +#else + pte_t old_pte = *ptep; + set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); +#endif } #define pte_same(A,B) (pte_val(A) == pte_val(B)) diff --git a/trunk/arch/parisc/include/asm/uaccess.h b/trunk/arch/parisc/include/asm/uaccess.h index e0a82358517e..4ba2c93770f1 100644 --- a/trunk/arch/parisc/include/asm/uaccess.h +++ b/trunk/arch/parisc/include/asm/uaccess.h @@ -181,24 +181,30 @@ struct exception_data { #if !defined(CONFIG_64BIT) #define __put_kernel_asm64(__val,ptr) do { \ + u64 __val64 = (u64)(__val); \ + u32 hi = (__val64) >> 32; \ + u32 lo = (__val64) & 0xffffffff; \ __asm__ __volatile__ ( \ "\n1:\tstw %2,0(%1)" \ - "\n2:\tstw %R2,4(%1)\n\t" \ + "\n2:\tstw %3,4(%1)\n\t" \ ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ : "=r"(__pu_err) \ - : "r"(ptr), "r"(__val), "0"(__pu_err) \ + : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \ : "r1"); \ } while (0) #define __put_user_asm64(__val,ptr) do { \ + u64 __val64 = (u64)(__val); \ + u32 hi = (__val64) >> 32; \ + u32 lo = (__val64) & 0xffffffff; \ __asm__ __volatile__ ( \ "\n1:\tstw %2,0(%%sr3,%1)" \ - "\n2:\tstw %R2,4(%%sr3,%1)\n\t" \ + "\n2:\tstw %3,4(%%sr3,%1)\n\t" \ ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ : "=r"(__pu_err) \ - : "r"(ptr), "r"(__val), "0"(__pu_err) \ + : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \ : "r1"); \ } while (0) diff --git a/trunk/arch/parisc/kernel/cache.c b/trunk/arch/parisc/kernel/cache.c index 83ded26cad06..4b12890642eb 100644 --- a/trunk/arch/parisc/kernel/cache.c +++ b/trunk/arch/parisc/kernel/cache.c @@ -421,11 +421,14 @@ void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) /* Note: purge_tlb_entries can be called at startup with no context. */ - purge_tlb_start(flags); + /* Disable preemption while we play with %sr1. */ + preempt_disable(); mtsp(mm->context, 1); + purge_tlb_start(flags); pdtlb(addr); pitlb(addr); purge_tlb_end(flags); + preempt_enable(); } EXPORT_SYMBOL(purge_tlb_entries); diff --git a/trunk/arch/parisc/kernel/parisc_ksyms.c b/trunk/arch/parisc/kernel/parisc_ksyms.c index 568b2c61ea02..6795dc6c995f 100644 --- a/trunk/arch/parisc/kernel/parisc_ksyms.c +++ b/trunk/arch/parisc/kernel/parisc_ksyms.c @@ -120,13 +120,11 @@ extern void __ashrdi3(void); extern void __ashldi3(void); extern void __lshrdi3(void); extern void __muldi3(void); -extern void __ucmpdi2(void); EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__muldi3); -EXPORT_SYMBOL(__ucmpdi2); asmlinkage void * __canonicalize_funcptr_for_compare(void *); EXPORT_SYMBOL(__canonicalize_funcptr_for_compare); diff --git a/trunk/arch/parisc/lib/Makefile b/trunk/arch/parisc/lib/Makefile index 5651536ac733..5f2e6904d14a 100644 --- a/trunk/arch/parisc/lib/Makefile +++ b/trunk/arch/parisc/lib/Makefile @@ -2,7 +2,6 @@ # Makefile for parisc-specific library files # -lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \ - ucmpdi2.o +lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o obj-y := iomap.o diff --git a/trunk/arch/parisc/lib/ucmpdi2.c b/trunk/arch/parisc/lib/ucmpdi2.c deleted file mode 100644 index 149c016f32c5..000000000000 --- a/trunk/arch/parisc/lib/ucmpdi2.c +++ /dev/null @@ -1,25 +0,0 @@ -#include - -union ull_union { - unsigned long long ull; - struct { - unsigned int high; - unsigned int low; - } ui; -}; - -int __ucmpdi2(unsigned long long a, unsigned long long b) -{ - union ull_union au = {.ull = a}; - union ull_union bu = {.ull = b}; - - if (au.ui.high < bu.ui.high) - return 0; - else if (au.ui.high > bu.ui.high) - return 2; - if (au.ui.low < bu.ui.low) - return 0; - else if (au.ui.low > bu.ui.low) - return 2; - return 1; -} diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index ea5bb045983a..b89d7eb730a2 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -90,7 +90,6 @@ config GENERIC_GPIO config PPC bool default y - select BINFMT_ELF select OF select OF_EARLY_FLATTREE select HAVE_FTRACE_MCOUNT_RECORD @@ -99,7 +98,7 @@ config PPC select HAVE_FUNCTION_GRAPH_TRACER select SYSCTL_EXCEPTION_TRACE select ARCH_WANT_OPTIONAL_GPIOLIB - select VIRT_TO_BUS if !PPC64 + select HAVE_VIRT_TO_BUS if !PPC64 select HAVE_IDE select HAVE_IOREMAP_PROT select HAVE_EFFICIENT_UNALIGNED_ACCESS diff --git a/trunk/arch/powerpc/crypto/sha1-powerpc-asm.S b/trunk/arch/powerpc/crypto/sha1-powerpc-asm.S index 125e16520061..a5f8264d2d3c 100644 --- a/trunk/arch/powerpc/crypto/sha1-powerpc-asm.S +++ b/trunk/arch/powerpc/crypto/sha1-powerpc-asm.S @@ -113,7 +113,7 @@ STEPUP4((t)+16, fn) _GLOBAL(powerpc_sha_transform) - PPC_STLU r1,-INT_FRAME_SIZE(r1) + PPC_STLU r1,-STACKFRAMESIZE(r1) SAVE_8GPRS(14, r1) SAVE_10GPRS(22, r1) @@ -175,5 +175,5 @@ _GLOBAL(powerpc_sha_transform) REST_8GPRS(14, r1) REST_10GPRS(22, r1) - addi r1,r1,INT_FRAME_SIZE + addi r1,r1,STACKFRAMESIZE blr diff --git a/trunk/arch/powerpc/include/asm/bitops.h b/trunk/arch/powerpc/include/asm/bitops.h index 08bd299c75b1..ef918a2328bb 100644 --- a/trunk/arch/powerpc/include/asm/bitops.h +++ b/trunk/arch/powerpc/include/asm/bitops.h @@ -52,6 +52,8 @@ #define smp_mb__before_clear_bit() smp_mb() #define smp_mb__after_clear_bit() smp_mb() +#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7) + /* Macro for generating the ***_bits() functions */ #define DEFINE_BITOP(fn, op, prefix, postfix) \ static __inline__ void fn(unsigned long mask, \ diff --git a/trunk/arch/powerpc/include/asm/mmu-hash64.h b/trunk/arch/powerpc/include/asm/mmu-hash64.h index b59e06f507ea..2fdb47a19efd 100644 --- a/trunk/arch/powerpc/include/asm/mmu-hash64.h +++ b/trunk/arch/powerpc/include/asm/mmu-hash64.h @@ -343,16 +343,17 @@ extern void slb_set_size(u16 size); /* * VSID allocation (256MB segment) * - * We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated - * from mmu context id and effective segment id of the address. + * We first generate a 38-bit "proto-VSID". For kernel addresses this + * is equal to the ESID | 1 << 37, for user addresses it is: + * (context << USER_ESID_BITS) | (esid & ((1U << USER_ESID_BITS) - 1) * - * For user processes max context id is limited to ((1ul << 19) - 5) - * for kernel space, we use the top 4 context ids to map address as below - * NOTE: each context only support 64TB now. - * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ] - * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ] - * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ] - * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ] + * This splits the proto-VSID into the below range + * 0 - (2^(CONTEXT_BITS + USER_ESID_BITS) - 1) : User proto-VSID range + * 2^(CONTEXT_BITS + USER_ESID_BITS) - 2^(VSID_BITS) : Kernel proto-VSID range + * + * We also have CONTEXT_BITS + USER_ESID_BITS = VSID_BITS - 1 + * That is, we assign half of the space to user processes and half + * to the kernel. * * The proto-VSIDs are then scrambled into real VSIDs with the * multiplicative hash: @@ -362,49 +363,41 @@ extern void slb_set_size(u16 size); * VSID_MULTIPLIER is prime, so in particular it is * co-prime to VSID_MODULUS, making this a 1:1 scrambling function. * Because the modulus is 2^n-1 we can compute it efficiently without - * a divide or extra multiply (see below). The scramble function gives - * robust scattering in the hash table (at least based on some initial - * results). + * a divide or extra multiply (see below). * - * We also consider VSID 0 special. We use VSID 0 for slb entries mapping - * bad address. This enables us to consolidate bad address handling in - * hash_page. + * This scheme has several advantages over older methods: * - * We also need to avoid the last segment of the last context, because that - * would give a protovsid of 0x1fffffffff. That will result in a VSID 0 - * because of the modulo operation in vsid scramble. But the vmemmap - * (which is what uses region 0xf) will never be close to 64TB in size - * (it's 56 bytes per page of system memory). - */ - -#define CONTEXT_BITS 19 -#define ESID_BITS 18 -#define ESID_BITS_1T 6 - -/* - * 256MB segment - * The proto-VSID space has 2^(CONTEX_BITS + ESID_BITS) - 1 segments - * available for user + kernel mapping. The top 4 contexts are used for - * kernel mapping. Each segment contains 2^28 bytes. Each - * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts - * (19 == 37 + 28 - 46). + * - We have VSIDs allocated for every kernel address + * (i.e. everything above 0xC000000000000000), except the very top + * segment, which simplifies several things. + * + * - We allow for USER_ESID_BITS significant bits of ESID and + * CONTEXT_BITS bits of context for user addresses. + * i.e. 64T (46 bits) of address space for up to half a million contexts. + * + * - The scramble function gives robust scattering in the hash + * table (at least based on some initial results). The previous + * method was more susceptible to pathological cases giving excessive + * hash collisions. */ -#define MAX_USER_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 5) /* * This should be computed such that protovosid * vsid_mulitplier * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus */ #define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */ -#define VSID_BITS_256M (CONTEXT_BITS + ESID_BITS) +#define VSID_BITS_256M 38 #define VSID_MODULUS_256M ((1UL<= \ * 2^36-1, then r3+1 has the 2^36 bit set. So, if r3+1 has \ * the bit clear, r3 already has the answer we want, if it \ @@ -521,6 +513,34 @@ typedef struct { }) #endif /* 1 */ +/* + * This is only valid for addresses >= PAGE_OFFSET + * The proto-VSID space is divided into two class + * User: 0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1 + * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1 + * + * With KERNEL_START at 0xc000000000000000, the proto vsid for + * the kernel ends up with 0xc00000000 (36 bits). With 64TB + * support we need to have kernel proto-VSID in the + * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS. + */ +static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) +{ + unsigned long proto_vsid; + /* + * We need to make sure proto_vsid for the kernel is + * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T]) + */ + if (ssize == MMU_SEGSIZE_256M) { + proto_vsid = ea >> SID_SHIFT; + proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS)); + return vsid_scramble(proto_vsid, 256M); + } + proto_vsid = ea >> SID_SHIFT_1T; + proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T)); + return vsid_scramble(proto_vsid, 1T); +} + /* Returns the segment size indicator for a user address */ static inline int user_segment_size(unsigned long addr) { @@ -530,41 +550,17 @@ static inline int user_segment_size(unsigned long addr) return MMU_SEGSIZE_256M; } +/* This is only valid for user addresses (which are below 2^44) */ static inline unsigned long get_vsid(unsigned long context, unsigned long ea, int ssize) { - /* - * Bad address. We return VSID 0 for that - */ - if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) - return 0; - if (ssize == MMU_SEGSIZE_256M) - return vsid_scramble((context << ESID_BITS) + return vsid_scramble((context << USER_ESID_BITS) | (ea >> SID_SHIFT), 256M); - return vsid_scramble((context << ESID_BITS_1T) + return vsid_scramble((context << USER_ESID_BITS_1T) | (ea >> SID_SHIFT_1T), 1T); } -/* - * This is only valid for addresses >= PAGE_OFFSET - * - * For kernel space, we use the top 4 context ids to map address as below - * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ] - * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ] - * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ] - * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ] - */ -static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) -{ - unsigned long context; - - /* - * kernel take the top 4 context from the available range - */ - context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1; - return get_vsid(context, ea, ssize); -} #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_MMU_HASH64_H_ */ diff --git a/trunk/arch/powerpc/include/asm/reg.h b/trunk/arch/powerpc/include/asm/reg.h index c9c67fc888c9..e66586122030 100644 --- a/trunk/arch/powerpc/include/asm/reg.h +++ b/trunk/arch/powerpc/include/asm/reg.h @@ -266,8 +266,7 @@ #define SPRN_HSRR0 0x13A /* Hypervisor Save/Restore 0 */ #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ #define SPRN_FSCR 0x099 /* Facility Status & Control Register */ -#define FSCR_TAR (1 << (63-55)) /* Enable Target Address Register */ -#define FSCR_DSCR (1 << (63-61)) /* Enable Data Stream Control Register */ +#define FSCR_TAR (1<<8) /* Enable Target Adress Register */ #define SPRN_TAR 0x32f /* Target Address Register */ #define SPRN_LPCR 0x13E /* LPAR Control Register */ #define LPCR_VPM0 (1ul << (63-0)) diff --git a/trunk/arch/powerpc/include/asm/systbl.h b/trunk/arch/powerpc/include/asm/systbl.h index ebbec52d21bd..535b6d8a41cc 100644 --- a/trunk/arch/powerpc/include/asm/systbl.h +++ b/trunk/arch/powerpc/include/asm/systbl.h @@ -358,4 +358,3 @@ SYSCALL_SPU(setns) COMPAT_SYS(process_vm_readv) COMPAT_SYS(process_vm_writev) SYSCALL(finit_module) -SYSCALL(ni_syscall) /* sys_kcmp */ diff --git a/trunk/arch/powerpc/include/asm/unistd.h b/trunk/arch/powerpc/include/asm/unistd.h index 1487f0f12293..f25b5c45c435 100644 --- a/trunk/arch/powerpc/include/asm/unistd.h +++ b/trunk/arch/powerpc/include/asm/unistd.h @@ -12,7 +12,7 @@ #include -#define __NR_syscalls 355 +#define __NR_syscalls 354 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/trunk/arch/powerpc/include/uapi/asm/unistd.h b/trunk/arch/powerpc/include/uapi/asm/unistd.h index 74cb4d72d673..8c478c6c6b1e 100644 --- a/trunk/arch/powerpc/include/uapi/asm/unistd.h +++ b/trunk/arch/powerpc/include/uapi/asm/unistd.h @@ -376,7 +376,6 @@ #define __NR_process_vm_readv 351 #define __NR_process_vm_writev 352 #define __NR_finit_module 353 -#define __NR_kcmp 354 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ diff --git a/trunk/arch/powerpc/kernel/cpu_setup_power.S b/trunk/arch/powerpc/kernel/cpu_setup_power.S index ea847abb0d0a..d29facbf9a28 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_power.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_power.S @@ -48,7 +48,6 @@ _GLOBAL(__restore_cpu_power7) _GLOBAL(__setup_cpu_power8) mflr r11 - bl __init_FSCR bl __init_hvmode_206 mtlr r11 beqlr @@ -57,13 +56,13 @@ _GLOBAL(__setup_cpu_power8) mfspr r3,SPRN_LPCR oris r3, r3, LPCR_AIL_3@h bl __init_LPCR + bl __init_FSCR bl __init_TLB mtlr r11 blr _GLOBAL(__restore_cpu_power8) mflr r11 - bl __init_FSCR mfmsr r3 rldicl. r0,r3,4,63 beqlr @@ -116,7 +115,7 @@ __init_LPCR: __init_FSCR: mfspr r3,SPRN_FSCR - ori r3,r3,FSCR_TAR|FSCR_DSCR + ori r3,r3,FSCR_TAR mtspr SPRN_FSCR,r3 blr diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index 19599ef352bc..75a3d71b895d 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -275,7 +275,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_features = CPU_FTRS_PPC970, .cpu_user_features = COMMON_USER_POWER4 | PPC_FEATURE_HAS_ALTIVEC_COMP, - .mmu_features = MMU_FTRS_PPC970, + .mmu_features = MMU_FTR_HPTE_TABLE, .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 04d69c4a5ac2..256c5bf0adb7 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -304,7 +304,7 @@ syscall_exit_work: subi r12,r12,TI_FLAGS 4: /* Anything else left to do? */ - SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ + SET_DEFAULT_THREAD_PPR(r3, r9) /* Set thread.ppr = 3 */ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) beq .ret_from_except_lite @@ -657,7 +657,7 @@ resume_kernel: /* Clear _TIF_EMULATE_STACK_STORE flag */ lis r11,_TIF_EMULATE_STACK_STORE@h addi r5,r9,TI_FLAGS -0: ldarx r4,0,r5 + ldarx r4,0,r5 andc r4,r4,r11 stdcx. r4,0,r5 bne- 0b diff --git a/trunk/arch/powerpc/kernel/epapr_paravirt.c b/trunk/arch/powerpc/kernel/epapr_paravirt.c index d44a571e45a7..f3eab8594d9f 100644 --- a/trunk/arch/powerpc/kernel/epapr_paravirt.c +++ b/trunk/arch/powerpc/kernel/epapr_paravirt.c @@ -23,10 +23,8 @@ #include #include -#if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) extern void epapr_ev_idle(void); extern u32 epapr_ev_idle_start[]; -#endif bool epapr_paravirt_enabled; @@ -49,15 +47,11 @@ static int __init epapr_paravirt_init(void) for (i = 0; i < (len / 4); i++) { patch_instruction(epapr_hypercall_start + i, insts[i]); -#if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) patch_instruction(epapr_ev_idle_start + i, insts[i]); -#endif } -#if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) if (of_get_property(hyper_node, "has-idle", NULL)) ppc_md.power_save = epapr_ev_idle; -#endif epapr_paravirt_enabled = true; diff --git a/trunk/arch/powerpc/kernel/exceptions-64s.S b/trunk/arch/powerpc/kernel/exceptions-64s.S index 56bd92362ce1..a8a5361fb70c 100644 --- a/trunk/arch/powerpc/kernel/exceptions-64s.S +++ b/trunk/arch/powerpc/kernel/exceptions-64s.S @@ -74,13 +74,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \ mflr r10 ; \ ld r12,PACAKBASE(r13) ; \ LOAD_HANDLER(r12, system_call_entry_direct) ; \ - mtctr r12 ; \ + mtlr r12 ; \ mfspr r12,SPRN_SRR1 ; \ /* Re-use of r13... No spare regs to do this */ \ li r13,MSR_RI ; \ mtmsrd r13,1 ; \ GET_PACA(r13) ; /* get r13 back */ \ - bctr ; + blr ; #else /* We can branch directly */ #define SYSCALL_PSERIES_2_DIRECT \ @@ -1066,6 +1066,78 @@ unrecov_user_slb: #endif /* __DISABLED__ */ +/* + * r13 points to the PACA, r9 contains the saved CR, + * r12 contain the saved SRR1, SRR0 is still ready for return + * r3 has the faulting address + * r9 - r13 are saved in paca->exslb. + * r3 is saved in paca->slb_r3 + * We assume we aren't going to take any exceptions during this procedure. + */ +_GLOBAL(slb_miss_realmode) + mflr r10 +#ifdef CONFIG_RELOCATABLE + mtctr r11 +#endif + + stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ + std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ + + bl .slb_allocate_realmode + + /* All done -- return from exception. */ + + ld r10,PACA_EXSLB+EX_LR(r13) + ld r3,PACA_EXSLB+EX_R3(r13) + lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ + + mtlr r10 + + andi. r10,r12,MSR_RI /* check for unrecoverable exception */ + beq- 2f + +.machine push +.machine "power4" + mtcrf 0x80,r9 + mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ +.machine pop + + RESTORE_PPR_PACA(PACA_EXSLB, r9) + ld r9,PACA_EXSLB+EX_R9(r13) + ld r10,PACA_EXSLB+EX_R10(r13) + ld r11,PACA_EXSLB+EX_R11(r13) + ld r12,PACA_EXSLB+EX_R12(r13) + ld r13,PACA_EXSLB+EX_R13(r13) + rfid + b . /* prevent speculative execution */ + +2: mfspr r11,SPRN_SRR0 + ld r10,PACAKBASE(r13) + LOAD_HANDLER(r10,unrecov_slb) + mtspr SPRN_SRR0,r10 + ld r10,PACAKMSR(r13) + mtspr SPRN_SRR1,r10 + rfid + b . + +unrecov_slb: + EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) + DISABLE_INTS + bl .save_nvgprs +1: addi r3,r1,STACK_FRAME_OVERHEAD + bl .unrecoverable_exception + b 1b + + +#ifdef CONFIG_PPC_970_NAP +power4_fixup_nap: + andc r9,r9,r10 + std r9,TI_LOCAL_FLAGS(r11) + ld r10,_LINK(r1) /* make idle task do the */ + std r10,_NIP(r1) /* equivalent of a blr */ + blr +#endif + .align 7 .globl alignment_common alignment_common: @@ -1263,78 +1335,6 @@ _GLOBAL(opal_mc_secondary_handler) #endif /* CONFIG_PPC_POWERNV */ -/* - * r13 points to the PACA, r9 contains the saved CR, - * r12 contain the saved SRR1, SRR0 is still ready for return - * r3 has the faulting address - * r9 - r13 are saved in paca->exslb. - * r3 is saved in paca->slb_r3 - * We assume we aren't going to take any exceptions during this procedure. - */ -_GLOBAL(slb_miss_realmode) - mflr r10 -#ifdef CONFIG_RELOCATABLE - mtctr r11 -#endif - - stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ - std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ - - bl .slb_allocate_realmode - - /* All done -- return from exception. */ - - ld r10,PACA_EXSLB+EX_LR(r13) - ld r3,PACA_EXSLB+EX_R3(r13) - lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ - - mtlr r10 - - andi. r10,r12,MSR_RI /* check for unrecoverable exception */ - beq- 2f - -.machine push -.machine "power4" - mtcrf 0x80,r9 - mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ -.machine pop - - RESTORE_PPR_PACA(PACA_EXSLB, r9) - ld r9,PACA_EXSLB+EX_R9(r13) - ld r10,PACA_EXSLB+EX_R10(r13) - ld r11,PACA_EXSLB+EX_R11(r13) - ld r12,PACA_EXSLB+EX_R12(r13) - ld r13,PACA_EXSLB+EX_R13(r13) - rfid - b . /* prevent speculative execution */ - -2: mfspr r11,SPRN_SRR0 - ld r10,PACAKBASE(r13) - LOAD_HANDLER(r10,unrecov_slb) - mtspr SPRN_SRR0,r10 - ld r10,PACAKMSR(r13) - mtspr SPRN_SRR1,r10 - rfid - b . - -unrecov_slb: - EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) - DISABLE_INTS - bl .save_nvgprs -1: addi r3,r1,STACK_FRAME_OVERHEAD - bl .unrecoverable_exception - b 1b - - -#ifdef CONFIG_PPC_970_NAP -power4_fixup_nap: - andc r9,r9,r10 - std r9,TI_LOCAL_FLAGS(r11) - ld r10,_LINK(r1) /* make idle task do the */ - std r10,_NIP(r1) /* equivalent of a blr */ - blr -#endif - /* * Hash table stuff */ @@ -1452,36 +1452,20 @@ do_ste_alloc: _GLOBAL(do_stab_bolted) stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ - mfspr r11,SPRN_DAR /* ea */ - /* - * check for bad kernel/user address - * (ea & ~REGION_MASK) >= PGTABLE_RANGE - */ - rldicr. r9,r11,4,(63 - 46 - 4) - li r9,0 /* VSID = 0 for bad address */ - bne- 0f - - /* - * Calculate VSID: - * This is the kernel vsid, we take the top for context from - * the range. context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1 - * Here we know that (ea >> 60) == 0xc - */ - lis r9,(MAX_USER_CONTEXT + 1)@ha - addi r9,r9,(MAX_USER_CONTEXT + 1)@l - - srdi r10,r11,SID_SHIFT - rldimi r10,r9,ESID_BITS,0 /* proto vsid */ - ASM_VSID_SCRAMBLE(r10, r9, 256M) - rldic r9,r10,12,16 /* r9 = vsid << 12 */ - -0: /* Hash to the primary group */ ld r10,PACASTABVIRT(r13) - srdi r11,r11,SID_SHIFT + mfspr r11,SPRN_DAR + srdi r11,r11,28 rldimi r10,r11,7,52 /* r10 = first ste of the group */ + /* Calculate VSID */ + /* This is a kernel address, so protovsid = ESID | 1 << 37 */ + li r9,0x1 + rldimi r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0 + ASM_VSID_SCRAMBLE(r11, r9, 256M) + rldic r9,r11,12,16 /* r9 = vsid << 12 */ + /* Search the primary group for a free entry */ 1: ld r11,0(r10) /* Test valid bit of the current ste */ andi. r11,r11,0x80 diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 16e77a81ab4f..59dd545fdde1 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -555,12 +555,10 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new) new->thread.regs->msr |= (MSR_FP | new->thread.fpexc_mode); } -#ifdef CONFIG_ALTIVEC if (msr & MSR_VEC) { do_load_up_transact_altivec(&new->thread); new->thread.regs->msr |= MSR_VEC; } -#endif /* We may as well turn on VSX too since all the state is restored now */ if (msr & MSR_VSX) new->thread.regs->msr |= MSR_VSX; diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index 13f8d168b3f1..7f7fb7fd991b 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -2832,13 +2832,11 @@ static void unreloc_toc(void) { } #else -static void __reloc_toc(unsigned long offset, unsigned long nr_entries) +static void __reloc_toc(void *tocstart, unsigned long offset, + unsigned long nr_entries) { unsigned long i; - unsigned long *toc_entry; - - /* Get the start of the TOC by using r2 directly. */ - asm volatile("addi %0,2,-0x8000" : "=b" (toc_entry)); + unsigned long *toc_entry = (unsigned long *)tocstart; for (i = 0; i < nr_entries; i++) { *toc_entry = *toc_entry + offset; @@ -2852,7 +2850,8 @@ static void reloc_toc(void) unsigned long nr_entries = (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long); - __reloc_toc(offset, nr_entries); + /* Need to add offset to get at __prom_init_toc_start */ + __reloc_toc(__prom_init_toc_start + offset, offset, nr_entries); mb(); } @@ -2865,7 +2864,8 @@ static void unreloc_toc(void) mb(); - __reloc_toc(-offset, nr_entries); + /* __prom_init_toc_start has been relocated, no need to add offset */ + __reloc_toc(__prom_init_toc_start, -offset, nr_entries); } #endif #endif diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c index f9b30c68ba47..245c1b6a0858 100644 --- a/trunk/arch/powerpc/kernel/ptrace.c +++ b/trunk/arch/powerpc/kernel/ptrace.c @@ -1428,7 +1428,6 @@ static long ppc_set_hwdebug(struct task_struct *child, brk.address = bp_info->addr & ~7UL; brk.type = HW_BRK_TYPE_TRANSLATE; - brk.len = 8; if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) brk.type |= HW_BRK_TYPE_READ; if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index 95068bf569ad..3acb28e245b4 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -866,12 +866,10 @@ static long restore_tm_user_regs(struct pt_regs *regs, do_load_up_transact_fpu(¤t->thread); regs->msr |= (MSR_FP | current->thread.fpexc_mode); } -#ifdef CONFIG_ALTIVEC if (msr & MSR_VEC) { do_load_up_transact_altivec(¤t->thread); regs->msr |= MSR_VEC; } -#endif return 0; } diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index c1794286098c..995f8543cb57 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -522,12 +522,10 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, do_load_up_transact_fpu(¤t->thread); regs->msr |= (MSR_FP | current->thread.fpexc_mode); } -#ifdef CONFIG_ALTIVEC if (msr & MSR_VEC) { do_load_up_transact_altivec(¤t->thread); regs->msr |= MSR_VEC; } -#endif return err; } diff --git a/trunk/arch/powerpc/kernel/tm.S b/trunk/arch/powerpc/kernel/tm.S index 2da67e7a16d5..84dbace657ce 100644 --- a/trunk/arch/powerpc/kernel/tm.S +++ b/trunk/arch/powerpc/kernel/tm.S @@ -309,7 +309,6 @@ _GLOBAL(tm_recheckpoint) or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */ mtmsr r5 -#ifdef CONFIG_ALTIVEC /* FP and VEC registers: These are recheckpointed from thread.fpr[] * and thread.vr[] respectively. The thread.transact_fpr[] version * is more modern, and will be loaded subsequently by any FPUnavailable @@ -324,7 +323,6 @@ _GLOBAL(tm_recheckpoint) REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ ld r5, THREAD_VRSAVE(r3) mtspr SPRN_VRSAVE, r5 -#endif dont_restore_vec: andi. r0, r4, MSR_FP diff --git a/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c b/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c index 5d7d29a313eb..ead58e317294 100644 --- a/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -326,8 +326,8 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu) vcpu3s->context_id[0] = err; vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1) - << ESID_BITS) - 1; - vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << ESID_BITS; + << USER_ESID_BITS) - 1; + vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS; vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first; kvmppc_mmu_hpte_init(vcpu); diff --git a/trunk/arch/powerpc/kvm/e500.h b/trunk/arch/powerpc/kvm/e500.h index 33db48a8ce24..41cefd43655f 100644 --- a/trunk/arch/powerpc/kvm/e500.h +++ b/trunk/arch/powerpc/kvm/e500.h @@ -26,20 +26,17 @@ #define E500_PID_NUM 3 #define E500_TLB_NUM 2 -/* entry is mapped somewhere in host TLB */ -#define E500_TLB_VALID (1 << 0) -/* TLB1 entry is mapped by host TLB1, tracked by bitmaps */ -#define E500_TLB_BITMAP (1 << 1) -/* TLB1 entry is mapped by host TLB0 */ +#define E500_TLB_VALID 1 +#define E500_TLB_BITMAP 2 #define E500_TLB_TLB0 (1 << 2) struct tlbe_ref { - pfn_t pfn; /* valid only for TLB0, except briefly */ - unsigned int flags; /* E500_TLB_* */ + pfn_t pfn; + unsigned int flags; /* E500_TLB_* */ }; struct tlbe_priv { - struct tlbe_ref ref; + struct tlbe_ref ref; /* TLB0 only -- TLB1 uses tlb_refs */ }; #ifdef CONFIG_KVM_E500V2 @@ -66,6 +63,17 @@ struct kvmppc_vcpu_e500 { unsigned int gtlb_nv[E500_TLB_NUM]; + /* + * information associated with each host TLB entry -- + * TLB1 only for now. If/when guest TLB1 entries can be + * mapped with host TLB0, this will be used for that too. + * + * We don't want to use this for guest TLB0 because then we'd + * have the overhead of doing the translation again even if + * the entry is still in the guest TLB (e.g. we swapped out + * and back, and our host TLB entries got evicted). + */ + struct tlbe_ref *tlb_refs[E500_TLB_NUM]; unsigned int host_tlb1_nv; u32 svr; diff --git a/trunk/arch/powerpc/kvm/e500_mmu_host.c b/trunk/arch/powerpc/kvm/e500_mmu_host.c index 1c6a9d729df4..a222edfb9a9b 100644 --- a/trunk/arch/powerpc/kvm/e500_mmu_host.c +++ b/trunk/arch/powerpc/kvm/e500_mmu_host.c @@ -193,11 +193,8 @@ void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[tlbsel][esel].ref; /* Don't bother with unmapped entries */ - if (!(ref->flags & E500_TLB_VALID)) { - WARN(ref->flags & (E500_TLB_BITMAP | E500_TLB_TLB0), - "%s: flags %x\n", __func__, ref->flags); - WARN_ON(tlbsel == 1 && vcpu_e500->g2h_tlb1_map[esel]); - } + if (!(ref->flags & E500_TLB_VALID)) + return; if (tlbsel == 1 && ref->flags & E500_TLB_BITMAP) { u64 tmp = vcpu_e500->g2h_tlb1_map[esel]; @@ -251,7 +248,7 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, pfn_t pfn) { ref->pfn = pfn; - ref->flags |= E500_TLB_VALID; + ref->flags = E500_TLB_VALID; if (tlbe_is_writable(gtlbe)) kvm_set_pfn_dirty(pfn); @@ -260,7 +257,6 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref) { if (ref->flags & E500_TLB_VALID) { - /* FIXME: don't log bogus pfn for TLB1 */ trace_kvm_booke206_ref_release(ref->pfn, ref->flags); ref->flags = 0; } @@ -278,23 +274,36 @@ static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500) static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) { - int tlbsel; + int tlbsel = 0; int i; - for (tlbsel = 0; tlbsel <= 1; tlbsel++) { - for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) { - struct tlbe_ref *ref = - &vcpu_e500->gtlb_priv[tlbsel][i].ref; - kvmppc_e500_ref_release(ref); - } + for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) { + struct tlbe_ref *ref = + &vcpu_e500->gtlb_priv[tlbsel][i].ref; + kvmppc_e500_ref_release(ref); } } -void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu) +static void clear_tlb_refs(struct kvmppc_vcpu_e500 *vcpu_e500) { - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); + int stlbsel = 1; + int i; + kvmppc_e500_tlbil_all(vcpu_e500); + + for (i = 0; i < host_tlb_params[stlbsel].entries; i++) { + struct tlbe_ref *ref = + &vcpu_e500->tlb_refs[stlbsel][i]; + kvmppc_e500_ref_release(ref); + } + clear_tlb_privs(vcpu_e500); +} + +void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu) +{ + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); + clear_tlb_refs(vcpu_e500); clear_tlb1_bitmap(vcpu_e500); } @@ -449,6 +458,8 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1); } + /* Drop old ref and setup new one. */ + kvmppc_e500_ref_release(ref); kvmppc_e500_ref_setup(ref, gtlbe, pfn); kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, @@ -496,15 +507,14 @@ static int kvmppc_e500_tlb1_map_tlb1(struct kvmppc_vcpu_e500 *vcpu_e500, if (unlikely(vcpu_e500->host_tlb1_nv >= tlb1_max_shadow_size())) vcpu_e500->host_tlb1_nv = 0; + vcpu_e500->tlb_refs[1][sesel] = *ref; + vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel; + vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP; if (vcpu_e500->h2g_tlb1_rmap[sesel]) { - unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel] - 1; + unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel]; vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << sesel); } - - vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP; - vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel; - vcpu_e500->h2g_tlb1_rmap[sesel] = esel + 1; - WARN_ON(!(ref->flags & E500_TLB_VALID)); + vcpu_e500->h2g_tlb1_rmap[sesel] = esel; return sesel; } @@ -516,12 +526,13 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe, struct kvm_book3e_206_tlb_entry *stlbe, int esel) { - struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[1][esel].ref; + struct tlbe_ref ref; int sesel; int r; + ref.flags = 0; r = kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, stlbe, - ref); + &ref); if (r) return r; @@ -533,7 +544,7 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, } /* Otherwise map into TLB1 */ - sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, ref, esel); + sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, &ref, esel); write_stlbe(vcpu_e500, gtlbe, stlbe, 1, sesel); return 0; @@ -554,7 +565,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr, case 0: priv = &vcpu_e500->gtlb_priv[tlbsel][esel]; - /* Triggers after clear_tlb_privs or on initial mapping */ + /* Triggers after clear_tlb_refs or on initial mapping */ if (!(priv->ref.flags & E500_TLB_VALID)) { kvmppc_e500_tlb0_map(vcpu_e500, esel, &stlbe); } else { @@ -654,16 +665,35 @@ int e500_mmu_host_init(struct kvmppc_vcpu_e500 *vcpu_e500) host_tlb_params[0].entries / host_tlb_params[0].ways; host_tlb_params[1].sets = 1; + vcpu_e500->tlb_refs[0] = + kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[0].entries, + GFP_KERNEL); + if (!vcpu_e500->tlb_refs[0]) + goto err; + + vcpu_e500->tlb_refs[1] = + kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[1].entries, + GFP_KERNEL); + if (!vcpu_e500->tlb_refs[1]) + goto err; + vcpu_e500->h2g_tlb1_rmap = kzalloc(sizeof(unsigned int) * host_tlb_params[1].entries, GFP_KERNEL); if (!vcpu_e500->h2g_tlb1_rmap) - return -EINVAL; + goto err; return 0; + +err: + kfree(vcpu_e500->tlb_refs[0]); + kfree(vcpu_e500->tlb_refs[1]); + return -EINVAL; } void e500_mmu_host_uninit(struct kvmppc_vcpu_e500 *vcpu_e500) { kfree(vcpu_e500->h2g_tlb1_rmap); + kfree(vcpu_e500->tlb_refs[0]); + kfree(vcpu_e500->tlb_refs[1]); } diff --git a/trunk/arch/powerpc/kvm/e500mc.c b/trunk/arch/powerpc/kvm/e500mc.c index 2f4baa074b2e..1f89d26e65fb 100644 --- a/trunk/arch/powerpc/kvm/e500mc.c +++ b/trunk/arch/powerpc/kvm/e500mc.c @@ -108,8 +108,6 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) { } -static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu); - void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); @@ -138,11 +136,8 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) mtspr(SPRN_GDEAR, vcpu->arch.shared->dar); mtspr(SPRN_GESR, vcpu->arch.shared->esr); - if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || - __get_cpu_var(last_vcpu_on_cpu) != vcpu) { + if (vcpu->arch.oldpir != mfspr(SPRN_PIR)) kvmppc_e500_tlbil_all(vcpu_e500); - __get_cpu_var(last_vcpu_on_cpu) = vcpu; - } kvmppc_load_guest_fp(vcpu); } diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index f410c3e12c1e..1b6e1271719f 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -195,11 +195,6 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, unsigned long vpn = hpt_vpn(vaddr, vsid, ssize); unsigned long tprot = prot; - /* - * If we hit a bad address return error. - */ - if (!vsid) - return -1; /* Make kernel text executable */ if (overlaps_kernel_text(vaddr, vaddr + step)) tprot &= ~HPTE_R_N; @@ -764,8 +759,6 @@ void __init early_init_mmu(void) /* Initialize stab / SLB management */ if (mmu_has_feature(MMU_FTR_SLB)) slb_initialize(); - else - stab_initialize(get_paca()->stab_real); } #ifdef CONFIG_SMP @@ -929,6 +922,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n", ea, access, trap); + if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) { + DBG_LOW(" out of pgtable range !\n"); + return 1; + } + /* Get region & vsid */ switch (REGION_ID(ea)) { case USER_REGION_ID: @@ -959,11 +957,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) } DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid); - /* Bad address. */ - if (!vsid) { - DBG_LOW("Bad address!\n"); - return 1; - } /* Get pgdir */ pgdir = mm->pgd; if (pgdir == NULL) @@ -1133,8 +1126,6 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, /* Get VSID */ ssize = user_segment_size(ea); vsid = get_vsid(mm->context.id, ea, ssize); - if (!vsid) - return; /* Hash doesn't like irqs */ local_irq_save(flags); @@ -1242,9 +1233,6 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); - /* Don't create HPTE entries for bad address */ - if (!vsid) - return; ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr), mode, HPTE_V_BOLTED, mmu_linear_psize, mmu_kernel_ssize); diff --git a/trunk/arch/powerpc/mm/mmu_context_hash64.c b/trunk/arch/powerpc/mm/mmu_context_hash64.c index d1d1b92c5b99..40bc5b0ace54 100644 --- a/trunk/arch/powerpc/mm/mmu_context_hash64.c +++ b/trunk/arch/powerpc/mm/mmu_context_hash64.c @@ -29,6 +29,15 @@ static DEFINE_SPINLOCK(mmu_context_lock); static DEFINE_IDA(mmu_context_ida); +/* + * 256MB segment + * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments + * available for user mappings. Each segment contains 2^28 bytes. Each + * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts + * (19 == 37 + 28 - 46). + */ +#define MAX_CONTEXT ((1UL << CONTEXT_BITS) - 1) + int __init_new_context(void) { int index; @@ -47,7 +56,7 @@ int __init_new_context(void) else if (err) return err; - if (index > MAX_USER_CONTEXT) { + if (index > MAX_CONTEXT) { spin_lock(&mmu_context_lock); ida_remove(&mmu_context_ida, index); spin_unlock(&mmu_context_lock); diff --git a/trunk/arch/powerpc/mm/pgtable_64.c b/trunk/arch/powerpc/mm/pgtable_64.c index 654258f165ae..e212a271c7a4 100644 --- a/trunk/arch/powerpc/mm/pgtable_64.c +++ b/trunk/arch/powerpc/mm/pgtable_64.c @@ -61,7 +61,7 @@ #endif #ifdef CONFIG_PPC_STD_MMU_64 -#if TASK_SIZE_USER64 > (1UL << (ESID_BITS + SID_SHIFT)) +#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT)) #error TASK_SIZE_USER64 exceeds user VSID range #endif #endif diff --git a/trunk/arch/powerpc/mm/slb_low.S b/trunk/arch/powerpc/mm/slb_low.S index 17aa6dfceb34..1a16ca227757 100644 --- a/trunk/arch/powerpc/mm/slb_low.S +++ b/trunk/arch/powerpc/mm/slb_low.S @@ -31,15 +31,10 @@ * No other registers are examined or changed. */ _GLOBAL(slb_allocate_realmode) - /* - * check for bad kernel/user address - * (ea & ~REGION_MASK) >= PGTABLE_RANGE - */ - rldicr. r9,r3,4,(63 - 46 - 4) - bne- 8f + /* r3 = faulting address */ srdi r9,r3,60 /* get region */ - srdi r10,r3,SID_SHIFT /* get esid */ + srdi r10,r3,28 /* get esid */ cmpldi cr7,r9,0xc /* cmp PAGE_OFFSET for later use */ /* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */ @@ -61,14 +56,12 @@ _GLOBAL(slb_allocate_realmode) */ _GLOBAL(slb_miss_kernel_load_linear) li r11,0 + li r9,0x1 /* - * context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1 - * r9 = region id. + * for 1T we shift 12 bits more. slb_finish_load_1T will do + * the necessary adjustment */ - addis r9,r9,(MAX_USER_CONTEXT - 0xc + 1)@ha - addi r9,r9,(MAX_USER_CONTEXT - 0xc + 1)@l - - + rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0 BEGIN_FTR_SECTION b slb_finish_load END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) @@ -98,19 +91,24 @@ _GLOBAL(slb_miss_kernel_load_vmemmap) _GLOBAL(slb_miss_kernel_load_io) li r11,0 6: + li r9,0x1 /* - * context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1 - * r9 = region id. + * for 1T we shift 12 bits more. slb_finish_load_1T will do + * the necessary adjustment */ - addis r9,r9,(MAX_USER_CONTEXT - 0xc + 1)@ha - addi r9,r9,(MAX_USER_CONTEXT - 0xc + 1)@l - + rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0 BEGIN_FTR_SECTION b slb_finish_load END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) b slb_finish_load_1T -0: +0: /* user address: proto-VSID = context << 15 | ESID. First check + * if the address is within the boundaries of the user region + */ + srdi. r9,r10,USER_ESID_BITS + bne- 8f /* invalid ea bits set */ + + /* when using slices, we extract the psize off the slice bitmaps * and then we need to get the sllp encoding off the mmu_psize_defs * array. @@ -166,13 +164,15 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) ld r9,PACACONTEXTID(r13) BEGIN_FTR_SECTION cmpldi r10,0x1000 +END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) + rldimi r10,r9,USER_ESID_BITS,0 +BEGIN_FTR_SECTION bge slb_finish_load_1T END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) b slb_finish_load 8: /* invalid EA */ li r10,0 /* BAD_VSID */ - li r9,0 /* BAD_VSID */ li r11,SLB_VSID_USER /* flags don't much matter */ b slb_finish_load @@ -221,6 +221,8 @@ _GLOBAL(slb_allocate_user) /* get context to calculate proto-VSID */ ld r9,PACACONTEXTID(r13) + rldimi r10,r9,USER_ESID_BITS,0 + /* fall through slb_finish_load */ #endif /* __DISABLED__ */ @@ -229,10 +231,9 @@ _GLOBAL(slb_allocate_user) /* * Finish loading of an SLB entry and return * - * r3 = EA, r9 = context, r10 = ESID, r11 = flags, clobbers r9, cr7 = <> PAGE_OFFSET + * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9, cr7 = <> PAGE_OFFSET */ slb_finish_load: - rldimi r10,r9,ESID_BITS,0 ASM_VSID_SCRAMBLE(r10,r9,256M) /* * bits above VSID_BITS_256M need to be ignored from r10 @@ -297,11 +298,10 @@ _GLOBAL(slb_compare_rr_to_size) /* * Finish loading of a 1T SLB entry (for the kernel linear mapping) and return. * - * r3 = EA, r9 = context, r10 = ESID(256MB), r11 = flags, clobbers r9 + * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9 */ slb_finish_load_1T: - srdi r10,r10,(SID_SHIFT_1T - SID_SHIFT) /* get 1T ESID */ - rldimi r10,r9,ESID_BITS_1T,0 + srdi r10,r10,40-28 /* get 1T ESID */ ASM_VSID_SCRAMBLE(r10,r9,1T) /* * bits above VSID_BITS_1T need to be ignored from r10 diff --git a/trunk/arch/powerpc/mm/tlb_hash64.c b/trunk/arch/powerpc/mm/tlb_hash64.c index 023ec8a13f38..0d82ef50dc3f 100644 --- a/trunk/arch/powerpc/mm/tlb_hash64.c +++ b/trunk/arch/powerpc/mm/tlb_hash64.c @@ -82,11 +82,11 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, if (!is_kernel_addr(addr)) { ssize = user_segment_size(addr); vsid = get_vsid(mm->context.id, addr, ssize); + WARN_ON(vsid == 0); } else { vsid = get_kernel_vsid(addr, mmu_kernel_ssize); ssize = mmu_kernel_ssize; } - WARN_ON(vsid == 0); vpn = hpt_vpn(addr, vsid, ssize); rpte = __real_pte(__pte(pte), ptep); diff --git a/trunk/arch/powerpc/perf/power7-pmu.c b/trunk/arch/powerpc/perf/power7-pmu.c index 3c475d6267c7..b554879bd31e 100644 --- a/trunk/arch/powerpc/perf/power7-pmu.c +++ b/trunk/arch/powerpc/perf/power7-pmu.c @@ -420,20 +420,7 @@ static struct attribute_group power7_pmu_events_group = { .attrs = power7_events_attr, }; -PMU_FORMAT_ATTR(event, "config:0-19"); - -static struct attribute *power7_pmu_format_attr[] = { - &format_attr_event.attr, - NULL, -}; - -struct attribute_group power7_pmu_format_group = { - .name = "format", - .attrs = power7_pmu_format_attr, -}; - static const struct attribute_group *power7_pmu_attr_groups[] = { - &power7_pmu_format_group, &power7_pmu_events_group, NULL, }; diff --git a/trunk/arch/powerpc/platforms/85xx/sgy_cts1000.c b/trunk/arch/powerpc/platforms/85xx/sgy_cts1000.c index 7179726ba5c5..611e92f291c4 100644 --- a/trunk/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/trunk/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -69,7 +69,7 @@ static irqreturn_t gpio_halt_irq(int irq, void *__data) return IRQ_HANDLED; }; -static int gpio_halt_probe(struct platform_device *pdev) +static int __devinit gpio_halt_probe(struct platform_device *pdev) { enum of_gpio_flags flags; struct device_node *node = pdev->dev.of_node; @@ -128,7 +128,7 @@ static int gpio_halt_probe(struct platform_device *pdev) return 0; } -static int gpio_halt_remove(struct platform_device *pdev) +static int __devexit gpio_halt_remove(struct platform_device *pdev) { if (halt_node) { int gpio = of_get_gpio(halt_node, 0); @@ -165,7 +165,7 @@ static struct platform_driver gpio_halt_driver = { .of_match_table = gpio_halt_match, }, .probe = gpio_halt_probe, - .remove = gpio_halt_remove, + .remove = __devexit_p(gpio_halt_remove), }; module_platform_driver(gpio_halt_driver); diff --git a/trunk/arch/powerpc/platforms/Kconfig.cputype b/trunk/arch/powerpc/platforms/Kconfig.cputype index 18e3b76c78d7..cea2f09c4241 100644 --- a/trunk/arch/powerpc/platforms/Kconfig.cputype +++ b/trunk/arch/powerpc/platforms/Kconfig.cputype @@ -124,8 +124,9 @@ config 6xx select PPC_HAVE_PMU_SUPPORT config POWER3 + bool depends on PPC64 && PPC_BOOK3S - def_bool y + default y if !POWER4_ONLY config POWER4 depends on PPC64 && PPC_BOOK3S @@ -144,7 +145,8 @@ config TUNE_CELL but somewhat slower on other machines. This option only changes the scheduling of instructions, not the selection of instructions itself, so the resulting kernel will keep running on all other - machines. + machines. When building a kernel that is supposed to run only + on Cell, you should also select the POWER4_ONLY option. # this is temp to handle compat with arch=ppc config 8xx diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 3f3bb4cdbbec..863184b182f4 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -749,7 +749,6 @@ static struct file_system_type spufs_type = { .mount = spufs_mount, .kill_sb = kill_litter_super, }; -MODULE_ALIAS_FS("spufs"); static int __init spufs_init(void) { diff --git a/trunk/arch/powerpc/platforms/pseries/hvcserver.c b/trunk/arch/powerpc/platforms/pseries/hvcserver.c index 4557e91626c4..fcf4b4cbeaf3 100644 --- a/trunk/arch/powerpc/platforms/pseries/hvcserver.c +++ b/trunk/arch/powerpc/platforms/pseries/hvcserver.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -189,9 +188,9 @@ int hvcs_get_partner_info(uint32_t unit_address, struct list_head *head, = (unsigned int)last_p_partition_ID; /* copy the Null-term char too */ - strlcpy(&next_partner_info->location_code[0], + strncpy(&next_partner_info->location_code[0], (char *)&pi_buff[2], - sizeof(next_partner_info->location_code)); + strlen((char *)&pi_buff[2]) + 1); list_add_tail(&(next_partner_info->node), head); next_partner_info = NULL; diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index 299731e9036b..0da39fed355a 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -186,13 +186,7 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group) (0x1UL << 4), &dummy1, &dummy2); if (lpar_rc == H_SUCCESS) return i; - - /* - * The test for adjunct partition is performed before the - * ANDCOND test. H_RESOURCE may be returned, so we need to - * check for that as well. - */ - BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE); + BUG_ON(lpar_rc != H_NOT_FOUND); slot_offset++; slot_offset &= 0x7; diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index bda6ba6f3cf5..4b505370a1d5 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -134,7 +134,7 @@ config S390 select HAVE_SYSCALL_WRAPPERS select HAVE_UID16 if 32BIT select HAVE_VIRT_CPU_ACCOUNTING - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select INIT_ALL_POSSIBLE select KTIME_SCALAR if 32BIT select MODULES_USE_ELF_RELA @@ -375,6 +375,19 @@ config PACK_STACK Say Y if you are unsure. +config SMALL_STACK + def_bool n + prompt "Use 8kb for kernel stack instead of 16kb" + depends on PACK_STACK && 64BIT && !LOCKDEP + help + If you say Y here and the compiler supports the -mkernel-backchain + option the kernel will use a smaller kernel stack size. The reduced + size is 8kb instead of 16kb. This allows to run more threads on a + system and reduces the pressure on the memory management for higher + order page allocations. + + Say N if you are unsure. + config CHECK_STACK def_bool y prompt "Detect kernel stack overflow" diff --git a/trunk/arch/s390/Makefile b/trunk/arch/s390/Makefile index a7d68a467ce8..7e3ce78d4290 100644 --- a/trunk/arch/s390/Makefile +++ b/trunk/arch/s390/Makefile @@ -55,12 +55,22 @@ cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls ifeq ($(call cc-option-yn,-mkernel-backchain),y) cflags-$(CONFIG_PACK_STACK) += -mkernel-backchain -D__PACK_STACK aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK +cflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK +aflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK +ifdef CONFIG_SMALL_STACK +STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) ) +endif endif # new style option for packed stacks ifeq ($(call cc-option-yn,-mpacked-stack),y) cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK +cflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK +aflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK +ifdef CONFIG_SMALL_STACK +STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) ) +endif endif ifeq ($(call cc-option-yn,-mstack-size=8192 -mstack-guard=128),y) diff --git a/trunk/arch/s390/hypfs/hypfs_dbfs.c b/trunk/arch/s390/hypfs/hypfs_dbfs.c index bb5dd496614f..9fd4a40c6752 100644 --- a/trunk/arch/s390/hypfs/hypfs_dbfs.c +++ b/trunk/arch/s390/hypfs/hypfs_dbfs.c @@ -105,7 +105,9 @@ void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df) int hypfs_dbfs_init(void) { dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); - return PTR_RET(dbfs_dir); + if (IS_ERR(dbfs_dir)) + return PTR_ERR(dbfs_dir); + return 0; } void hypfs_dbfs_exit(void) diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c index 5f7d7ba2874c..8538015ed4a0 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -456,7 +456,6 @@ static struct file_system_type hypfs_type = { .mount = hypfs_mount, .kill_sb = hypfs_kill_super }; -MODULE_ALIAS_FS("s390_hypfs"); static const struct super_operations hypfs_s_ops = { .statfs = simple_statfs, diff --git a/trunk/arch/s390/include/asm/bitops.h b/trunk/arch/s390/include/asm/bitops.h index 4d8604e311f3..15422933c60b 100644 --- a/trunk/arch/s390/include/asm/bitops.h +++ b/trunk/arch/s390/include/asm/bitops.h @@ -61,6 +61,8 @@ extern const char _sb_findmap[]; #ifndef CONFIG_64BIT +#define __BITOPS_ALIGN 3 +#define __BITOPS_WORDSIZE 32 #define __BITOPS_OR "or" #define __BITOPS_AND "nr" #define __BITOPS_XOR "xr" @@ -79,6 +81,8 @@ extern const char _sb_findmap[]; #else /* CONFIG_64BIT */ +#define __BITOPS_ALIGN 7 +#define __BITOPS_WORDSIZE 64 #define __BITOPS_OR "ogr" #define __BITOPS_AND "ngr" #define __BITOPS_XOR "xgr" @@ -97,7 +101,8 @@ extern const char _sb_findmap[]; #endif /* CONFIG_64BIT */ -#define __BITOPS_WORDS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG) +#define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) +#define __BITOPS_BARRIER() asm volatile("" : : : "memory") #ifdef CONFIG_SMP /* @@ -109,9 +114,9 @@ static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make OR mask */ - mask = 1UL << (nr & (BITS_PER_LONG - 1)); + mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); } @@ -125,9 +130,9 @@ static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make AND mask */ - mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); + mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); } @@ -141,9 +146,9 @@ static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make XOR mask */ - mask = 1UL << (nr & (BITS_PER_LONG - 1)); + mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); } @@ -158,12 +163,12 @@ test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make OR/test mask */ - mask = 1UL << (nr & (BITS_PER_LONG - 1)); + mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); - barrier(); + __BITOPS_BARRIER(); return (old & mask) != 0; } @@ -177,12 +182,12 @@ test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make AND/test mask */ - mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); + mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); - barrier(); + __BITOPS_BARRIER(); return (old ^ new) != 0; } @@ -196,12 +201,12 @@ test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make XOR/test mask */ - mask = 1UL << (nr & (BITS_PER_LONG - 1)); + mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); - barrier(); + __BITOPS_BARRIER(); return (old & mask) != 0; } #endif /* CONFIG_SMP */ @@ -213,7 +218,7 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); asm volatile( " oc %O0(1,%R0),%1" : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); @@ -224,7 +229,7 @@ __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); *(unsigned char *) addr |= 1 << (nr & 7); } @@ -241,7 +246,7 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); asm volatile( " nc %O0(1,%R0),%1" : "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc" ); @@ -252,7 +257,7 @@ __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); *(unsigned char *) addr &= ~(1 << (nr & 7)); } @@ -268,7 +273,7 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); asm volatile( " xc %O0(1,%R0),%1" : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); @@ -279,7 +284,7 @@ __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); *(unsigned char *) addr ^= 1 << (nr & 7); } @@ -297,7 +302,7 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; asm volatile( " oc %O0(1,%R0),%1" @@ -316,7 +321,7 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; asm volatile( " nc %O0(1,%R0),%1" @@ -335,7 +340,7 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; asm volatile( " xc %O0(1,%R0),%1" @@ -371,7 +376,7 @@ static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr unsigned long addr; unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(volatile unsigned char *) addr; return (ch >> (nr & 7)) & 1; } @@ -379,7 +384,7 @@ static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr static inline int __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { return (((volatile char *) addr) - [(nr^(BITS_PER_LONG-8))>>3] & (1<<(nr&7))) != 0; + [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7))) != 0; } #define test_bit(nr,addr) \ @@ -688,18 +693,18 @@ static inline int find_next_bit_left(const unsigned long *addr, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { set = __flo_word(0, *p & (~0UL << bit)); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_bit_left(p, size); @@ -731,22 +736,22 @@ static inline int find_next_zero_bit (const unsigned long * addr, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * __ffz_word returns BITS_PER_LONG + * __ffz_word returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ set = __ffz_word(bit, *p >> bit); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_zero_bit(p, size); @@ -768,22 +773,22 @@ static inline int find_next_bit (const unsigned long * addr, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * __ffs_word returns BITS_PER_LONG + * __ffs_word returns __BITOPS_WORDSIZE * if no one bit is present in the word. */ set = __ffs_word(0, *p & (~0UL << bit)); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_bit(p, size); @@ -838,22 +843,22 @@ static inline int find_next_zero_bit_le(void *vaddr, unsigned long size, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * s390 version of ffz returns BITS_PER_LONG + * s390 version of ffz returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ set = __ffz_word(bit, __load_ulong_le(p, 0) >> bit); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_zero_bit_le(p, size); @@ -880,22 +885,22 @@ static inline int find_next_bit_le(void *vaddr, unsigned long size, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * s390 version of ffz returns BITS_PER_LONG + * s390 version of ffz returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ set = __ffs_word(0, __load_ulong_le(p, 0) & (~0UL << bit)); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_bit_le(p, size); diff --git a/trunk/arch/s390/include/asm/ccwdev.h b/trunk/arch/s390/include/asm/ccwdev.h index f201af8be580..e6061617a50b 100644 --- a/trunk/arch/s390/include/asm/ccwdev.h +++ b/trunk/arch/s390/include/asm/ccwdev.h @@ -220,8 +220,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) extern struct ccw_device *ccw_device_probe_console(void); -extern void ccw_device_wait_idle(struct ccw_device *); -extern int ccw_device_force_console(struct ccw_device *); +extern int ccw_device_force_console(void); int ccw_device_siosl(struct ccw_device *); diff --git a/trunk/arch/s390/include/asm/cio.h b/trunk/arch/s390/include/asm/cio.h index ffb898961c8d..ad2b924167d7 100644 --- a/trunk/arch/s390/include/asm/cio.h +++ b/trunk/arch/s390/include/asm/cio.h @@ -296,6 +296,8 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, return 0; } +extern void wait_cons_dev(void); + extern void css_schedule_reprobe(void); extern void reipl_ccw_dev(struct ccw_dev_id *id); diff --git a/trunk/arch/s390/include/asm/compat.h b/trunk/arch/s390/include/asm/compat.h index c1e7c646727c..f8c6df6cd1f0 100644 --- a/trunk/arch/s390/include/asm/compat.h +++ b/trunk/arch/s390/include/asm/compat.h @@ -70,22 +70,6 @@ typedef u32 compat_ulong_t; typedef u64 compat_u64; typedef u32 compat_uptr_t; -typedef struct { - u32 mask; - u32 addr; -} __aligned(8) psw_compat_t; - -typedef struct { - psw_compat_t psw; - u32 gprs[NUM_GPRS]; - u32 acrs[NUM_ACRS]; - u32 orig_gpr2; -} s390_compat_regs; - -typedef struct { - u32 gprs_high[NUM_GPRS]; -} s390_compat_regs_high; - struct compat_timespec { compat_time_t tv_sec; s32 tv_nsec; @@ -140,33 +124,18 @@ struct compat_flock64 { }; struct compat_statfs { - u32 f_type; - u32 f_bsize; - u32 f_blocks; - u32 f_bfree; - u32 f_bavail; - u32 f_files; - u32 f_ffree; - compat_fsid_t f_fsid; - u32 f_namelen; - u32 f_frsize; - u32 f_flags; - u32 f_spare[4]; -}; - -struct compat_statfs64 { - u32 f_type; - u32 f_bsize; - u64 f_blocks; - u64 f_bfree; - u64 f_bavail; - u64 f_files; - u64 f_ffree; + s32 f_type; + s32 f_bsize; + s32 f_blocks; + s32 f_bfree; + s32 f_bavail; + s32 f_files; + s32 f_ffree; compat_fsid_t f_fsid; - u32 f_namelen; - u32 f_frsize; - u32 f_flags; - u32 f_spare[4]; + s32 f_namelen; + s32 f_frsize; + s32 f_flags; + s32 f_spare[5]; }; #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff @@ -279,6 +248,8 @@ static inline int is_compat_task(void) return is_32bit_task(); } +#endif + static inline void __user *arch_compat_alloc_user_space(long len) { unsigned long stack; @@ -289,8 +260,6 @@ static inline void __user *arch_compat_alloc_user_space(long len) return (void __user *) (stack - len); } -#endif - struct compat_ipc64_perm { compat_key_t key; __compat_uid32_t uid; diff --git a/trunk/arch/s390/include/asm/cpu_mf.h b/trunk/arch/s390/include/asm/cpu_mf.h index c879fad404c8..f1eddd150dd7 100644 --- a/trunk/arch/s390/include/asm/cpu_mf.h +++ b/trunk/arch/s390/include/asm/cpu_mf.h @@ -12,7 +12,6 @@ #ifndef _ASM_S390_CPU_MF_H #define _ASM_S390_CPU_MF_H -#include #include #define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */ diff --git a/trunk/arch/s390/include/asm/eadm.h b/trunk/arch/s390/include/asm/eadm.h index dc9200ca32ed..8d4847191ecc 100644 --- a/trunk/arch/s390/include/asm/eadm.h +++ b/trunk/arch/s390/include/asm/eadm.h @@ -34,8 +34,6 @@ struct arsb { u32 reserved[4]; } __packed; -#define EQC_WR_PROHIBIT 22 - struct msb { u8 fmt:4; u8 oc:4; @@ -98,13 +96,11 @@ struct scm_device { #define OP_STATE_TEMP_ERR 2 #define OP_STATE_PERM_ERR 3 -enum scm_event {SCM_CHANGE, SCM_AVAIL}; - struct scm_driver { struct device_driver drv; int (*probe) (struct scm_device *scmdev); int (*remove) (struct scm_device *scmdev); - void (*notify) (struct scm_device *scmdev, enum scm_event event); + void (*notify) (struct scm_device *scmdev); void (*handler) (struct scm_device *scmdev, void *data, int error); }; diff --git a/trunk/arch/s390/include/asm/elf.h b/trunk/arch/s390/include/asm/elf.h index 78f4f8711d58..1bfdf24b85a2 100644 --- a/trunk/arch/s390/include/asm/elf.h +++ b/trunk/arch/s390/include/asm/elf.h @@ -119,8 +119,6 @@ */ #include -#include -#include #include typedef s390_fp_regs elf_fpregset_t; @@ -182,31 +180,18 @@ extern unsigned long elf_hwcap; extern char elf_platform[]; #define ELF_PLATFORM (elf_platform) -#ifndef CONFIG_COMPAT -#define SET_PERSONALITY(ex) \ -do { \ - set_personality(PER_LINUX | \ - (current->personality & (~PER_MASK))); \ - current_thread_info()->sys_call_table = \ - (unsigned long) &sys_call_table; \ -} while (0) -#else /* CONFIG_COMPAT */ +#ifdef CONFIG_64BIT #define SET_PERSONALITY(ex) \ do { \ if (personality(current->personality) != PER_LINUX32) \ set_personality(PER_LINUX | \ (current->personality & ~PER_MASK)); \ - if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ set_thread_flag(TIF_31BIT); \ - current_thread_info()->sys_call_table = \ - (unsigned long) &sys_call_table_emu; \ - } else { \ + else \ clear_thread_flag(TIF_31BIT); \ - current_thread_info()->sys_call_table = \ - (unsigned long) &sys_call_table; \ - } \ } while (0) -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_64BIT */ #define STACK_RND_MASK 0x7ffUL diff --git a/trunk/arch/s390/include/asm/io.h b/trunk/arch/s390/include/asm/io.h index 379d96e2105e..27cb32185ce1 100644 --- a/trunk/arch/s390/include/asm/io.h +++ b/trunk/arch/s390/include/asm/io.h @@ -50,6 +50,10 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr); #define ioremap_nocache(addr, size) ioremap(addr, size) #define ioremap_wc ioremap_nocache +/* TODO: s390 cannot support io_remap_pfn_range... */ +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + static inline void __iomem *ioremap(unsigned long offset, unsigned long size) { return (void __iomem *) offset; diff --git a/trunk/arch/s390/include/asm/pci.h b/trunk/arch/s390/include/asm/pci.h index 6c1801235db9..05333b7f0469 100644 --- a/trunk/arch/s390/include/asm/pci.h +++ b/trunk/arch/s390/include/asm/pci.h @@ -140,7 +140,6 @@ static inline bool zdev_enabled(struct zpci_dev *zdev) struct zpci_dev *zpci_alloc_device(void); int zpci_create_device(struct zpci_dev *); int zpci_enable_device(struct zpci_dev *); -int zpci_disable_device(struct zpci_dev *); void zpci_stop_device(struct zpci_dev *); void zpci_free_device(struct zpci_dev *); int zpci_scan_device(struct zpci_dev *); diff --git a/trunk/arch/s390/include/asm/pci_debug.h b/trunk/arch/s390/include/asm/pci_debug.h index 1ca5d1047c71..6bbec4265b6e 100644 --- a/trunk/arch/s390/include/asm/pci_debug.h +++ b/trunk/arch/s390/include/asm/pci_debug.h @@ -7,11 +7,14 @@ extern debug_info_t *pci_debug_msg_id; extern debug_info_t *pci_debug_err_id; #ifdef CONFIG_PCI_DEBUG -#define zpci_dbg(imp, fmt, args...) \ - debug_sprintf_event(pci_debug_msg_id, imp, fmt, ##args) +#define zpci_dbg(fmt, args...) \ + do { \ + if (pci_debug_msg_id->level >= 2) \ + debug_sprintf_event(pci_debug_msg_id, 2, fmt , ## args);\ + } while (0) #else /* !CONFIG_PCI_DEBUG */ -#define zpci_dbg(imp, fmt, args...) do { } while (0) +#define zpci_dbg(fmt, args...) do { } while (0) #endif #define zpci_err(text...) \ diff --git a/trunk/arch/s390/include/asm/pci_insn.h b/trunk/arch/s390/include/asm/pci_insn.h index e6a2bdd4d705..1486a98d5dad 100644 --- a/trunk/arch/s390/include/asm/pci_insn.h +++ b/trunk/arch/s390/include/asm/pci_insn.h @@ -1,6 +1,10 @@ #ifndef _ASM_S390_PCI_INSN_H #define _ASM_S390_PCI_INSN_H +#include + +#define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */ + /* Load/Store status codes */ #define ZPCI_PCI_ST_FUNC_NOT_ENABLED 4 #define ZPCI_PCI_ST_FUNC_IN_ERR 8 @@ -78,12 +82,199 @@ struct zpci_fib { u64 reserved7; } __packed; +/* Modify PCI Function Controls */ +static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) +{ + u8 cc; + + asm volatile ( + " .insn rxy,0xe300000000d0,%[req],%[fib]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib) + : : "cc"); + *status = req >> 24 & 0xff; + return cc; +} + +static inline int mpcifc_instr(u64 req, struct zpci_fib *fib) +{ + u8 cc, status; + + do { + cc = __mpcifc(req, fib, &status); + if (cc == 2) + msleep(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); + + if (cc) + printk_once(KERN_ERR "%s: error cc: %d status: %d\n", + __func__, cc, status); + return (cc) ? -EIO : 0; +} + +/* Refresh PCI Translations */ +static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) +{ + register u64 __addr asm("2") = addr; + register u64 __range asm("3") = range; + u8 cc; + + asm volatile ( + " .insn rre,0xb9d30000,%[fn],%[addr]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [fn] "+d" (fn) + : [addr] "d" (__addr), "d" (__range) + : "cc"); + *status = fn >> 24 & 0xff; + return cc; +} + +static inline int rpcit_instr(u64 fn, u64 addr, u64 range) +{ + u8 cc, status; + + do { + cc = __rpcit(fn, addr, range, &status); + if (cc == 2) + udelay(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); + + if (cc) + printk_once(KERN_ERR "%s: error cc: %d status: %d dma_addr: %Lx size: %Lx\n", + __func__, cc, status, addr, range); + return (cc) ? -EIO : 0; +} + +/* Store PCI function controls */ +static inline u8 __stpcifc(u32 handle, u8 space, struct zpci_fib *fib, u8 *status) +{ + u64 fn = (u64) handle << 32 | space << 16; + u8 cc; + + asm volatile ( + " .insn rxy,0xe300000000d4,%[fn],%[fib]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [fn] "+d" (fn), [fib] "=m" (*fib) + : : "cc"); + *status = fn >> 24 & 0xff; + return cc; +} + +/* Set Interruption Controls */ +static inline void sic_instr(u16 ctl, char *unused, u8 isc) +{ + asm volatile ( + " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" + : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); +} + +/* PCI Load */ +static inline u8 __pcilg(u64 *data, u64 req, u64 offset, u8 *status) +{ + register u64 __req asm("2") = req; + register u64 __offset asm("3") = offset; + u64 __data; + u8 cc; + + asm volatile ( + " .insn rre,0xb9d20000,%[data],%[req]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [data] "=d" (__data), [req] "+d" (__req) + : "d" (__offset) + : "cc"); + *status = __req >> 24 & 0xff; + *data = __data; + return cc; +} + +static inline int pcilg_instr(u64 *data, u64 req, u64 offset) +{ + u8 cc, status; + + do { + cc = __pcilg(data, req, offset, &status); + if (cc == 2) + udelay(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); + + if (cc) { + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", + __func__, cc, status, req, offset); + /* TODO: on IO errors set data to 0xff... + * here or in users of pcilg (le conversion)? + */ + } + return (cc) ? -EIO : 0; +} + +/* PCI Store */ +static inline u8 __pcistg(u64 data, u64 req, u64 offset, u8 *status) +{ + register u64 __req asm("2") = req; + register u64 __offset asm("3") = offset; + u8 cc; + + asm volatile ( + " .insn rre,0xb9d00000,%[data],%[req]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [req] "+d" (__req) + : "d" (__offset), [data] "d" (data) + : "cc"); + *status = __req >> 24 & 0xff; + return cc; +} + +static inline int pcistg_instr(u64 data, u64 req, u64 offset) +{ + u8 cc, status; + + do { + cc = __pcistg(data, req, offset, &status); + if (cc == 2) + udelay(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); + + if (cc) + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", + __func__, cc, status, req, offset); + return (cc) ? -EIO : 0; +} + +/* PCI Store Block */ +static inline u8 __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) +{ + u8 cc; + + asm volatile ( + " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [req] "+d" (req) + : [offset] "d" (offset), [data] "Q" (*data) + : "cc"); + *status = req >> 24 & 0xff; + return cc; +} + +static inline int pcistb_instr(const u64 *data, u64 req, u64 offset) +{ + u8 cc, status; + + do { + cc = __pcistb(data, req, offset, &status); + if (cc == 2) + udelay(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); -int s390pci_mod_fc(u64 req, struct zpci_fib *fib); -int s390pci_refresh_trans(u64 fn, u64 addr, u64 range); -int s390pci_load(u64 *data, u64 req, u64 offset); -int s390pci_store(u64 data, u64 req, u64 offset); -int s390pci_store_block(const u64 *data, u64 req, u64 offset); -void set_irq_ctrl(u16 ctl, char *unused, u8 isc); + if (cc) + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", + __func__, cc, status, req, offset); + return (cc) ? -EIO : 0; +} #endif diff --git a/trunk/arch/s390/include/asm/pci_io.h b/trunk/arch/s390/include/asm/pci_io.h index 83a9caa6ae53..5fd81f31d6c7 100644 --- a/trunk/arch/s390/include/asm/pci_io.h +++ b/trunk/arch/s390/include/asm/pci_io.h @@ -36,7 +36,7 @@ static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr) \ u64 data; \ int rc; \ \ - rc = s390pci_load(&data, req, ZPCI_OFFSET(addr)); \ + rc = pcilg_instr(&data, req, ZPCI_OFFSET(addr)); \ if (rc) \ data = -1ULL; \ return (RETTYPE) data; \ @@ -50,7 +50,7 @@ static inline void zpci_write_##VALTYPE(VALTYPE val, \ u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ u64 data = (VALTYPE) val; \ \ - s390pci_store(data, req, ZPCI_OFFSET(addr)); \ + pcistg_instr(data, req, ZPCI_OFFSET(addr)); \ } zpci_read(8, u64) @@ -83,18 +83,15 @@ static inline int zpci_write_single(u64 req, const u64 *data, u64 offset, u8 len val = 0; /* let FW report error */ break; } - return s390pci_store(val, req, offset); + return pcistg_instr(val, req, offset); } static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) { u64 data; - int cc; - - cc = s390pci_load(&data, req, offset); - if (cc) - goto out; + u8 cc; + cc = pcilg_instr(&data, req, offset); switch (len) { case 1: *((u8 *) dst) = (u8) data; @@ -109,13 +106,12 @@ static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) *((u64 *) dst) = (u64) data; break; } -out: return cc; } static inline int zpci_write_block(u64 req, const u64 *data, u64 offset) { - return s390pci_store_block(data, req, offset); + return pcistb_instr(data, req, offset); } static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) diff --git a/trunk/arch/s390/include/asm/pgtable.h b/trunk/arch/s390/include/asm/pgtable.h index 4a64c0e5428f..4a2930844d43 100644 --- a/trunk/arch/s390/include/asm/pgtable.h +++ b/trunk/arch/s390/include/asm/pgtable.h @@ -57,10 +57,6 @@ extern unsigned long zero_page_mask; (((unsigned long)(vaddr)) &zero_page_mask)))) #define __HAVE_COLOR_ZERO_PAGE -/* TODO: s390 cannot support io_remap_pfn_range... */ -#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ - remap_pfn_range(vma, vaddr, pfn, size, prot) - #endif /* !__ASSEMBLY__ */ /* @@ -348,7 +344,6 @@ extern unsigned long MODULES_END; #define _REGION3_ENTRY_CO 0x100 /* change-recording override */ /* Bits in the segment table entry */ -#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ @@ -764,8 +759,6 @@ void gmap_disable(struct gmap *gmap); int gmap_map_segment(struct gmap *gmap, unsigned long from, unsigned long to, unsigned long length); int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len); -unsigned long __gmap_translate(unsigned long address, struct gmap *); -unsigned long gmap_translate(unsigned long address, struct gmap *); unsigned long __gmap_fault(unsigned long address, struct gmap *); unsigned long gmap_fault(unsigned long address, struct gmap *); void gmap_discard(unsigned long from, unsigned long to, struct gmap *); @@ -1538,8 +1531,7 @@ extern int s390_enable_sie(void); /* * No page table caches to initialise */ -static inline void pgtable_cache_init(void) { } -static inline void check_pgt_cache(void) { } +#define pgtable_cache_init() do { } while (0) #include diff --git a/trunk/arch/s390/include/asm/processor.h b/trunk/arch/s390/include/asm/processor.h index 6b499870662f..94e749c90230 100644 --- a/trunk/arch/s390/include/asm/processor.h +++ b/trunk/arch/s390/include/asm/processor.h @@ -161,8 +161,7 @@ extern unsigned long thread_saved_pc(struct task_struct *t); extern void show_code(struct pt_regs *regs); extern void print_fn_code(unsigned char *code, unsigned long len); -extern int insn_to_mnemonic(unsigned char *instruction, char *buf, - unsigned int len); +extern int insn_to_mnemonic(unsigned char *instruction, char buf[8]); unsigned long get_wchan(struct task_struct *p); #define task_pt_regs(tsk) ((struct pt_regs *) \ diff --git a/trunk/arch/s390/include/asm/ptrace.h b/trunk/arch/s390/include/asm/ptrace.h index 559512a455da..3ee5da3bc10c 100644 --- a/trunk/arch/s390/include/asm/ptrace.h +++ b/trunk/arch/s390/include/asm/ptrace.h @@ -9,7 +9,9 @@ #include #ifndef __ASSEMBLY__ - +#ifndef __s390x__ +#else /* __s390x__ */ +#endif /* __s390x__ */ extern long psw_kernel_bits; extern long psw_user_bits; @@ -75,6 +77,8 @@ struct per_struct_kernel { #define PER_CONTROL_SUSPENSION 0x00400000UL #define PER_CONTROL_ALTERATION 0x00200000UL +#ifdef __s390x__ +#endif /* __s390x__ */ /* * These are defined as per linux/ptrace.h, which see. */ diff --git a/trunk/arch/s390/include/asm/syscall.h b/trunk/arch/s390/include/asm/syscall.h index cd29d2f4e4f3..fe7b99759e12 100644 --- a/trunk/arch/s390/include/asm/syscall.h +++ b/trunk/arch/s390/include/asm/syscall.h @@ -23,7 +23,6 @@ * type here is what we want [need] for both 32 bit and 64 bit systems. */ extern const unsigned int sys_call_table[]; -extern const unsigned int sys_call_table_emu[]; static inline long syscall_get_nr(struct task_struct *task, struct pt_regs *regs) diff --git a/trunk/arch/s390/include/asm/thread_info.h b/trunk/arch/s390/include/asm/thread_info.h index eb5f64d26d06..9e2cfe0349c3 100644 --- a/trunk/arch/s390/include/asm/thread_info.h +++ b/trunk/arch/s390/include/asm/thread_info.h @@ -14,8 +14,13 @@ #define THREAD_ORDER 1 #define ASYNC_ORDER 1 #else /* CONFIG_64BIT */ +#ifndef __SMALL_STACK #define THREAD_ORDER 2 #define ASYNC_ORDER 2 +#else +#define THREAD_ORDER 1 +#define ASYNC_ORDER 1 +#endif #endif /* CONFIG_64BIT */ #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) @@ -36,7 +41,6 @@ struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ - unsigned long sys_call_table; /* System call table address */ unsigned int cpu; /* current CPU */ int preempt_count; /* 0 => preemptable, <0 => BUG */ struct restart_block restart_block; diff --git a/trunk/arch/s390/include/asm/tlbflush.h b/trunk/arch/s390/include/asm/tlbflush.h index 6b32af30878c..1d8fe2b17ef6 100644 --- a/trunk/arch/s390/include/asm/tlbflush.h +++ b/trunk/arch/s390/include/asm/tlbflush.h @@ -74,6 +74,8 @@ static inline void __tlb_flush_idte(unsigned long asce) static inline void __tlb_flush_mm(struct mm_struct * mm) { + if (unlikely(cpumask_empty(mm_cpumask(mm)))) + return; /* * If the machine has IDTE we prefer to do a per mm flush * on all cpus instead of doing a local flush if the mm diff --git a/trunk/arch/s390/include/uapi/asm/ptrace.h b/trunk/arch/s390/include/uapi/asm/ptrace.h index 3aa9f1ec5b29..a5ca214b34fd 100644 --- a/trunk/arch/s390/include/uapi/asm/ptrace.h +++ b/trunk/arch/s390/include/uapi/asm/ptrace.h @@ -215,6 +215,12 @@ typedef struct unsigned long addr; } __attribute__ ((aligned(8))) psw_t; +typedef struct +{ + __u32 mask; + __u32 addr; +} __attribute__ ((aligned(8))) psw_compat_t; + #ifndef __s390x__ #define PSW_MASK_PER 0x40000000UL @@ -289,6 +295,20 @@ typedef struct unsigned long orig_gpr2; } s390_regs; +typedef struct +{ + psw_compat_t psw; + __u32 gprs[NUM_GPRS]; + __u32 acrs[NUM_ACRS]; + __u32 orig_gpr2; +} s390_compat_regs; + +typedef struct +{ + __u32 gprs_high[NUM_GPRS]; +} s390_compat_regs_high; + + /* * Now for the user space program event recording (trace) definitions. * The following structures are used only for the ptrace interface, don't diff --git a/trunk/arch/s390/include/uapi/asm/statfs.h b/trunk/arch/s390/include/uapi/asm/statfs.h index a61d538756f2..5acca0a34c20 100644 --- a/trunk/arch/s390/include/uapi/asm/statfs.h +++ b/trunk/arch/s390/include/uapi/asm/statfs.h @@ -7,6 +7,9 @@ #ifndef _S390_STATFS_H #define _S390_STATFS_H +#ifndef __s390x__ +#include +#else /* * We can't use because in 64-bit mode * we mix ints of different sizes in our struct statfs. @@ -18,33 +21,49 @@ typedef __kernel_fsid_t fsid_t; #endif struct statfs { - unsigned int f_type; - unsigned int f_bsize; - unsigned long f_blocks; - unsigned long f_bfree; - unsigned long f_bavail; - unsigned long f_files; - unsigned long f_ffree; + int f_type; + int f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; __kernel_fsid_t f_fsid; - unsigned int f_namelen; - unsigned int f_frsize; - unsigned int f_flags; - unsigned int f_spare[4]; + int f_namelen; + int f_frsize; + int f_flags; + int f_spare[4]; }; struct statfs64 { - unsigned int f_type; - unsigned int f_bsize; - unsigned long f_blocks; - unsigned long f_bfree; - unsigned long f_bavail; - unsigned long f_files; - unsigned long f_ffree; + int f_type; + int f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; __kernel_fsid_t f_fsid; - unsigned int f_namelen; - unsigned int f_frsize; - unsigned int f_flags; - unsigned int f_spare[4]; + int f_namelen; + int f_frsize; + int f_flags; + int f_spare[4]; }; +struct compat_statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_flags; + __u32 f_spare[4]; +}; + +#endif /* __s390x__ */ #endif diff --git a/trunk/arch/s390/kernel/Makefile b/trunk/arch/s390/kernel/Makefile index 1386fcaf4ef6..2ac311ef5c9b 100644 --- a/trunk/arch/s390/kernel/Makefile +++ b/trunk/arch/s390/kernel/Makefile @@ -13,14 +13,6 @@ endif # CFLAGS_smp.o := -Wno-nonnull -# -# Disable tailcall optimizations for stack / callchain walking functions -# since this might generate broken code when accessing register 15 and -# passing its content to other functions. -# -CFLAGS_stacktrace.o += -fno-optimize-sibling-calls -CFLAGS_dumpstack.o += -fno-optimize-sibling-calls - # # Pass UTS_MACHINE for user_regset definition # @@ -28,11 +20,10 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o -obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o -obj-y += debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o -obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o -obj-y += dumpstack.o +obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \ + processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \ + debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \ + sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) diff --git a/trunk/arch/s390/kernel/asm-offsets.c b/trunk/arch/s390/kernel/asm-offsets.c index 7a82f9f70100..fface87056eb 100644 --- a/trunk/arch/s390/kernel/asm-offsets.c +++ b/trunk/arch/s390/kernel/asm-offsets.c @@ -35,7 +35,6 @@ int main(void) DEFINE(__TI_task, offsetof(struct thread_info, task)); DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); DEFINE(__TI_flags, offsetof(struct thread_info, flags)); - DEFINE(__TI_sysc_table, offsetof(struct thread_info, sys_call_table)); DEFINE(__TI_cpu, offsetof(struct thread_info, cpu)); DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count)); DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer)); diff --git a/trunk/arch/s390/kernel/compat_signal.c b/trunk/arch/s390/kernel/compat_signal.c index c439ac9ced09..6de049fbe62d 100644 --- a/trunk/arch/s390/kernel/compat_signal.c +++ b/trunk/arch/s390/kernel/compat_signal.c @@ -362,7 +362,6 @@ static int setup_frame32(int sig, struct k_sigaction *ka, /* set extra registers only for synchronous signals */ regs->gprs[4] = regs->int_code & 127; regs->gprs[5] = regs->int_parm_long; - regs->gprs[6] = task_thread_info(current)->last_break; } /* Place signal number on stack to allow backtrace from handler. */ @@ -422,7 +421,6 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, regs->gprs[2] = map_signal(sig); regs->gprs[3] = (__force __u64) &frame->info; regs->gprs[4] = (__force __u64) &frame->uc; - regs->gprs[5] = task_thread_info(current)->last_break; return 0; give_sigsegv: diff --git a/trunk/arch/s390/kernel/dis.c b/trunk/arch/s390/kernel/dis.c index 7f4a4a8c847c..3ad5e9540160 100644 --- a/trunk/arch/s390/kernel/dis.c +++ b/trunk/arch/s390/kernel/dis.c @@ -1696,15 +1696,14 @@ static struct insn *find_insn(unsigned char *code) * insn_to_mnemonic - decode an s390 instruction * @instruction: instruction to decode * @buf: buffer to fill with mnemonic - * @len: length of buffer * * Decode the instruction at @instruction and store the corresponding - * mnemonic into @buf of length @len. + * mnemonic into @buf. * @buf is left unchanged if the instruction could not be decoded. * Returns: * %0 on success, %-ENOENT if the instruction was not found. */ -int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len) +int insn_to_mnemonic(unsigned char *instruction, char buf[8]) { struct insn *insn; @@ -1712,10 +1711,10 @@ int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len) if (!insn) return -ENOENT; if (insn->name[0] == '\0') - snprintf(buf, len, "%s", + snprintf(buf, 8, "%s", long_insn_name[(int) insn->name[1]]); else - snprintf(buf, len, "%.5s", insn->name); + snprintf(buf, 8, "%.5s", insn->name); return 0; } EXPORT_SYMBOL_GPL(insn_to_mnemonic); diff --git a/trunk/arch/s390/kernel/dumpstack.c b/trunk/arch/s390/kernel/dumpstack.c deleted file mode 100644 index 03dce39d01ee..000000000000 --- a/trunk/arch/s390/kernel/dumpstack.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Stack dumping functions - * - * Copyright IBM Corp. 1999, 2013 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_64BIT -#define LONG "%08lx " -#define FOURLONG "%08lx %08lx %08lx %08lx\n" -static int kstack_depth_to_print = 12; -#else /* CONFIG_64BIT */ -#define LONG "%016lx " -#define FOURLONG "%016lx %016lx %016lx %016lx\n" -static int kstack_depth_to_print = 20; -#endif /* CONFIG_64BIT */ - -/* - * For show_trace we have tree different stack to consider: - * - the panic stack which is used if the kernel stack has overflown - * - the asynchronous interrupt stack (cpu related) - * - the synchronous kernel stack (process related) - * The stack trace can start at any of the three stack and can potentially - * touch all of them. The order is: panic stack, async stack, sync stack. - */ -static unsigned long -__show_trace(unsigned long sp, unsigned long low, unsigned long high) -{ - struct stack_frame *sf; - struct pt_regs *regs; - - while (1) { - sp = sp & PSW_ADDR_INSN; - if (sp < low || sp > high - sizeof(*sf)) - return sp; - sf = (struct stack_frame *) sp; - printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); - print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); - /* Follow the backchain. */ - while (1) { - low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; - if (!sp) - break; - if (sp <= low || sp > high - sizeof(*sf)) - return sp; - sf = (struct stack_frame *) sp; - printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); - print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); - } - /* Zero backchain detected, check for interrupt frame. */ - sp = (unsigned long) (sf + 1); - if (sp <= low || sp > high - sizeof(*regs)) - return sp; - regs = (struct pt_regs *) sp; - printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); - print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); - low = sp; - sp = regs->gprs[15]; - } -} - -static void show_trace(struct task_struct *task, unsigned long *stack) -{ - register unsigned long __r15 asm ("15"); - unsigned long sp; - - sp = (unsigned long) stack; - if (!sp) - sp = task ? task->thread.ksp : __r15; - printk("Call Trace:\n"); -#ifdef CONFIG_CHECK_STACK - sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, - S390_lowcore.panic_stack); -#endif - sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, - S390_lowcore.async_stack); - if (task) - __show_trace(sp, (unsigned long) task_stack_page(task), - (unsigned long) task_stack_page(task) + THREAD_SIZE); - else - __show_trace(sp, S390_lowcore.thread_info, - S390_lowcore.thread_info + THREAD_SIZE); - if (!task) - task = current; - debug_show_held_locks(task); -} - -void show_stack(struct task_struct *task, unsigned long *sp) -{ - register unsigned long *__r15 asm ("15"); - unsigned long *stack; - int i; - - if (!sp) - stack = task ? (unsigned long *) task->thread.ksp : __r15; - else - stack = sp; - - for (i = 0; i < kstack_depth_to_print; i++) { - if (((addr_t) stack & (THREAD_SIZE-1)) == 0) - break; - if ((i * sizeof(long) % 32) == 0) - printk("%s ", i == 0 ? "" : "\n"); - printk(LONG, *stack++); - } - printk("\n"); - show_trace(task, sp); -} - -static void show_last_breaking_event(struct pt_regs *regs) -{ -#ifdef CONFIG_64BIT - printk("Last Breaking-Event-Address:\n"); - printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); - print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); -#endif -} - -/* - * The architecture-independent dump_stack generator - */ -void dump_stack(void) -{ - printk("CPU: %d %s %s %.*s\n", - task_thread_info(current)->cpu, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); - printk("Process %s (pid: %d, task: %p, ksp: %p)\n", - current->comm, current->pid, current, - (void *) current->thread.ksp); - show_stack(NULL, NULL); -} -EXPORT_SYMBOL(dump_stack); - -static inline int mask_bits(struct pt_regs *regs, unsigned long bits) -{ - return (regs->psw.mask & bits) / ((~bits + 1) & bits); -} - -void show_registers(struct pt_regs *regs) -{ - char *mode; - - mode = user_mode(regs) ? "User" : "Krnl"; - printk("%s PSW : %p %p", - mode, (void *) regs->psw.mask, - (void *) regs->psw.addr); - print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); - printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " - "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), - mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), - mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY), - mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT), - mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC), - mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM)); -#ifdef CONFIG_64BIT - printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA)); -#endif - printk("\n%s GPRS: " FOURLONG, mode, - regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); - printk(" " FOURLONG, - regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); - printk(" " FOURLONG, - regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]); - printk(" " FOURLONG, - regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); - show_code(regs); -} - -void show_regs(struct pt_regs *regs) -{ - printk("CPU: %d %s %s %.*s\n", - task_thread_info(current)->cpu, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); - printk("Process %s (pid: %d, task: %p, ksp: %p)\n", - current->comm, current->pid, current, - (void *) current->thread.ksp); - show_registers(regs); - /* Show stack backtrace if pt_regs is from kernel mode */ - if (!user_mode(regs)) - show_trace(NULL, (unsigned long *) regs->gprs[15]); - show_last_breaking_event(regs); -} - -static DEFINE_SPINLOCK(die_lock); - -void die(struct pt_regs *regs, const char *str) -{ - static int die_counter; - - oops_enter(); - lgr_info_log(); - debug_stop_all(); - console_verbose(); - spin_lock_irq(&die_lock); - bust_spinlocks(1); - printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); -#ifdef CONFIG_PREEMPT - printk("PREEMPT "); -#endif -#ifdef CONFIG_SMP - printk("SMP "); -#endif -#ifdef CONFIG_DEBUG_PAGEALLOC - printk("DEBUG_PAGEALLOC"); -#endif - printk("\n"); - notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); - print_modules(); - show_regs(regs); - bust_spinlocks(0); - add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - spin_unlock_irq(&die_lock); - if (in_interrupt()) - panic("Fatal exception in interrupt"); - if (panic_on_oops) - panic("Fatal exception: panic_on_oops"); - oops_exit(); - do_exit(SIGSEGV); -} diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S index 4d5e6f8a7978..550228523267 100644 --- a/trunk/arch/s390/kernel/entry.S +++ b/trunk/arch/s390/kernel/entry.S @@ -45,7 +45,6 @@ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SIZE = 1 << STACK_SHIFT -STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE #define BASED(name) name-system_call(%r13) @@ -98,10 +97,10 @@ STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE sra %r14,\shift jnz 1f CHECK_STACK 1<<\shift,\savearea - ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j 2f 1: l %r15,\stack # load target stack -2: la %r11,STACK_FRAME_OVERHEAD(%r15) +2: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) + la %r11,STACK_FRAME_OVERHEAD(%r15) .endm .macro ADD64 high,low,timer @@ -151,7 +150,7 @@ ENTRY(__switch_to) l %r4,__THREAD_info(%r2) # get thread_info of prev l %r5,__THREAD_info(%r3) # get thread_info of next lr %r15,%r5 - ahi %r15,STACK_INIT # end of kernel stack of next + ahi %r15,STACK_SIZE # end of kernel stack of next st %r3,__LC_CURRENT # store task struct of next st %r5,__LC_THREAD_INFO # store thread info of next st %r15,__LC_KERNEL_STACK # store end of kernel stack @@ -179,6 +178,7 @@ sysc_stm: l %r13,__LC_SVC_NEW_PSW+4 sysc_per: l %r15,__LC_KERNEL_STACK + ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs sysc_vtime: UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER @@ -188,7 +188,6 @@ sysc_vtime: mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC sysc_do_svc: oi __TI_flags+3(%r12),_TIF_SYSCALL - l %r10,__TI_sysc_table(%r12) # 31 bit system call table lh %r8,__PT_INT_CODE+2(%r11) sla %r8,2 # shift and test for svc0 jnz sysc_nr_ok @@ -199,6 +198,7 @@ sysc_do_svc: lr %r8,%r1 sla %r8,2 sysc_nr_ok: + l %r10,BASED(.Lsys_call_table) # 31 bit system call table xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) st %r2,__PT_ORIG_GPR2(%r11) st %r7,STACK_FRAME_OVERHEAD(%r15) @@ -359,11 +359,11 @@ ENTRY(pgm_check_handler) tm __LC_PGM_ILC+3,0x80 # check for per exception jnz pgm_svcper # -> single stepped svc 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC - ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j 2f 1: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER l %r15,__LC_KERNEL_STACK -2: la %r11,STACK_FRAME_OVERHEAD(%r15) +2: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) + la %r11,STACK_FRAME_OVERHEAD(%r15) stm %r0,%r7,__PT_R0(%r11) mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC stm %r8,%r9,__PT_PSW(%r11) @@ -485,6 +485,7 @@ io_work: # io_work_user: l %r1,__LC_KERNEL_STACK + ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) la %r11,STACK_FRAME_OVERHEAD(%r1) @@ -635,8 +636,7 @@ ENTRY(mcck_int_handler) UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER mcck_skip: SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT - stm %r0,%r7,__PT_R0(%r11) - mvc __PT_R8(32,%r11),__LC_GPREGS_SAVE_AREA+32 + mvc __PT_R0(64,%r11),__LC_GPREGS_SAVE_AREA stm %r8,%r9,__PT_PSW(%r11) xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) l %r1,BASED(.Ldo_machine_check) @@ -645,6 +645,7 @@ mcck_skip: tm __PT_PSW+1(%r11),0x01 # returning to user ? jno mcck_return l %r1,__LC_KERNEL_STACK # switch to kernel stack + ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) la %r11,STACK_FRAME_OVERHEAD(%r15) @@ -672,7 +673,6 @@ mcck_panic: sra %r14,PAGE_SHIFT jz 0f l %r15,__LC_PANIC_STACK - j mcck_skip 0: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j mcck_skip @@ -713,10 +713,12 @@ ENTRY(restart_int_handler) */ stack_overflow: l %r15,__LC_PANIC_STACK # change to panic stack - la %r11,STACK_FRAME_OVERHEAD(%r15) - stm %r0,%r7,__PT_R0(%r11) - stm %r8,%r9,__PT_PSW(%r11) + ahi %r15,-__PT_SIZE # create pt_regs + stm %r0,%r7,__PT_R0(%r15) + stm %r8,%r9,__PT_PSW(%r15) mvc __PT_R8(32,%r11),0(%r14) + lr %r15,%r11 + ahi %r15,-STACK_FRAME_OVERHEAD l %r1,BASED(1f) xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) lr %r2,%r11 # pass pointer to pt_regs @@ -796,14 +798,15 @@ cleanup_system_call: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER # set up saved register 11 l %r15,__LC_KERNEL_STACK - la %r9,STACK_FRAME_OVERHEAD(%r15) - st %r9,12(%r11) # r11 pt_regs pointer + ahi %r15,-__PT_SIZE + st %r15,12(%r11) # r11 pt_regs pointer # fill pt_regs - mvc __PT_R8(32,%r9),__LC_SAVE_AREA_SYNC - stm %r0,%r7,__PT_R0(%r9) - mvc __PT_PSW(8,%r9),__LC_SVC_OLD_PSW - mvc __PT_INT_CODE(4,%r9),__LC_SVC_ILC + mvc __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC + stm %r0,%r7,__PT_R0(%r15) + mvc __PT_PSW(8,%r15),__LC_SVC_OLD_PSW + mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC # setup saved register 15 + ahi %r15,-STACK_FRAME_OVERHEAD st %r15,28(%r11) # r15 stack pointer # set new psw address and exit l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000 @@ -906,6 +909,7 @@ cleanup_idle_wait: .Ltrace_enter: .long do_syscall_trace_enter .Ltrace_exit: .long do_syscall_trace_exit .Lschedule_tail: .long schedule_tail +.Lsys_call_table: .long sys_call_table .Lsysc_per: .long sysc_per + 0x80000000 #ifdef CONFIG_TRACE_IRQFLAGS .Lhardirqs_on: .long trace_hardirqs_on_caller diff --git a/trunk/arch/s390/kernel/entry.h b/trunk/arch/s390/kernel/entry.h index aa0ab02e9595..c3a736a3ed44 100644 --- a/trunk/arch/s390/kernel/entry.h +++ b/trunk/arch/s390/kernel/entry.h @@ -7,7 +7,6 @@ #include extern void *restart_stack; -extern unsigned long suspend_zero_pages; void system_call(void); void pgm_check_handler(void); diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S index 4c17eece707e..9c837c101297 100644 --- a/trunk/arch/s390/kernel/entry64.S +++ b/trunk/arch/s390/kernel/entry64.S @@ -39,7 +39,6 @@ __PT_R15 = __PT_GPRS + 120 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SIZE = 1 << STACK_SHIFT -STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_MCCK_PENDING | _TIF_PER_TRAP ) @@ -125,10 +124,10 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) srag %r14,%r14,\shift jnz 1f CHECK_STACK 1<<\shift,\savearea - aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j 2f 1: lg %r15,\stack # load target stack -2: la %r11,STACK_FRAME_OVERHEAD(%r15) +2: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) + la %r11,STACK_FRAME_OVERHEAD(%r15) .endm .macro UPDATE_VTIME scratch,enter_timer @@ -178,7 +177,7 @@ ENTRY(__switch_to) lg %r4,__THREAD_info(%r2) # get thread_info of prev lg %r5,__THREAD_info(%r3) # get thread_info of next lgr %r15,%r5 - aghi %r15,STACK_INIT # end of kernel stack of next + aghi %r15,STACK_SIZE # end of kernel stack of next stg %r3,__LC_CURRENT # store task struct of next stg %r5,__LC_THREAD_INFO # store thread info of next stg %r15,__LC_KERNEL_STACK # store end of kernel stack @@ -204,8 +203,10 @@ sysc_stmg: stmg %r8,%r15,__LC_SAVE_AREA_SYNC lg %r10,__LC_LAST_BREAK lg %r12,__LC_THREAD_INFO + larl %r13,system_call sysc_per: lg %r15,__LC_KERNEL_STACK + aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs sysc_vtime: UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER @@ -216,7 +217,6 @@ sysc_vtime: mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC sysc_do_svc: oi __TI_flags+7(%r12),_TIF_SYSCALL - lg %r10,__TI_sysc_table(%r12) # address of system call table llgh %r8,__PT_INT_CODE+2(%r11) slag %r8,%r8,2 # shift and test for svc 0 jnz sysc_nr_ok @@ -227,6 +227,13 @@ sysc_do_svc: sth %r1,__PT_INT_CODE+2(%r11) slag %r8,%r1,2 sysc_nr_ok: + larl %r10,sys_call_table # 64 bit system call table +#ifdef CONFIG_COMPAT + tm __TI_flags+5(%r12),(_TIF_31BIT>>16) + jno sysc_noemu + larl %r10,sys_call_table_emu # 31 bit system call table +sysc_noemu: +#endif xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) stg %r2,__PT_ORIG_GPR2(%r11) stg %r7,STACK_FRAME_OVERHEAD(%r15) @@ -382,7 +389,6 @@ ENTRY(pgm_check_handler) tm __LC_PGM_ILC+3,0x80 # check for per exception jnz pgm_svcper # -> single stepped svc 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC - aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j 2f 1: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER LAST_BREAK %r14 @@ -392,7 +398,8 @@ ENTRY(pgm_check_handler) tm __LC_PGM_ILC+2,0x02 # check for transaction abort jz 2f mvc __THREAD_trap_tdb(256,%r14),0(%r13) -2: la %r11,STACK_FRAME_OVERHEAD(%r15) +2: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) + la %r11,STACK_FRAME_OVERHEAD(%r15) stmg %r0,%r7,__PT_R0(%r11) mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC stmg %r8,%r9,__PT_PSW(%r11) @@ -519,6 +526,7 @@ io_work: # io_work_user: lg %r1,__LC_KERNEL_STACK + aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) la %r11,STACK_FRAME_OVERHEAD(%r1) @@ -670,9 +678,8 @@ ENTRY(mcck_int_handler) UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER LAST_BREAK %r14 mcck_skip: - lghi %r14,__LC_GPREGS_SAVE_AREA+64 - stmg %r0,%r7,__PT_R0(%r11) - mvc __PT_R8(64,%r11),0(%r14) + lghi %r14,__LC_GPREGS_SAVE_AREA + mvc __PT_R0(128,%r11),0(%r14) stmg %r8,%r9,__PT_PSW(%r11) xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) lgr %r2,%r11 # pass pointer to pt_regs @@ -680,6 +687,7 @@ mcck_skip: tm __PT_PSW+1(%r11),0x01 # returning to user ? jno mcck_return lg %r1,__LC_KERNEL_STACK # switch to kernel stack + aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) la %r11,STACK_FRAME_OVERHEAD(%r1) @@ -746,12 +754,14 @@ ENTRY(restart_int_handler) * Setup a pt_regs so that show_trace can provide a good call trace. */ stack_overflow: - lg %r15,__LC_PANIC_STACK # change to panic stack - la %r11,STACK_FRAME_OVERHEAD(%r15) + lg %r11,__LC_PANIC_STACK # change to panic stack + aghi %r11,-__PT_SIZE # create pt_regs stmg %r0,%r7,__PT_R0(%r11) stmg %r8,%r9,__PT_PSW(%r11) mvc __PT_R8(64,%r11),0(%r14) stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 + lgr %r15,%r11 + aghi %r15,-STACK_FRAME_OVERHEAD xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) lgr %r2,%r11 # pass pointer to pt_regs jg kernel_stack_overflow @@ -835,14 +845,15 @@ cleanup_system_call: mvc __TI_last_break(8,%r12),16(%r11) 0: # set up saved register r11 lg %r15,__LC_KERNEL_STACK - la %r9,STACK_FRAME_OVERHEAD(%r15) - stg %r9,24(%r11) # r11 pt_regs pointer + aghi %r15,-__PT_SIZE + stg %r15,24(%r11) # r11 pt_regs pointer # fill pt_regs - mvc __PT_R8(64,%r9),__LC_SAVE_AREA_SYNC - stmg %r0,%r7,__PT_R0(%r9) - mvc __PT_PSW(16,%r9),__LC_SVC_OLD_PSW - mvc __PT_INT_CODE(4,%r9),__LC_SVC_ILC + mvc __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC + stmg %r0,%r7,__PT_R0(%r15) + mvc __PT_PSW(16,%r15),__LC_SVC_OLD_PSW + mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC # setup saved register r15 + aghi %r15,-STACK_FRAME_OVERHEAD stg %r15,56(%r11) # r15 stack pointer # set new psw address and exit larl %r9,sysc_do_svc @@ -999,7 +1010,6 @@ sys_call_table: #ifdef CONFIG_COMPAT #define SYSCALL(esa,esame,emu) .long emu - .globl sys_call_table_emu sys_call_table_emu: #include "syscalls.S" #undef SYSCALL diff --git a/trunk/arch/s390/kernel/machine_kexec.c b/trunk/arch/s390/kernel/machine_kexec.c index ac2178161ec3..b3de27700016 100644 --- a/trunk/arch/s390/kernel/machine_kexec.c +++ b/trunk/arch/s390/kernel/machine_kexec.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -68,35 +67,6 @@ void setup_regs(void) memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area)); } -/* - * PM notifier callback for kdump - */ -static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, - void *ptr) -{ - switch (action) { - case PM_SUSPEND_PREPARE: - case PM_HIBERNATION_PREPARE: - if (crashk_res.start) - crash_map_reserved_pages(); - break; - case PM_POST_SUSPEND: - case PM_POST_HIBERNATION: - if (crashk_res.start) - crash_unmap_reserved_pages(); - break; - default: - return NOTIFY_DONE; - } - return NOTIFY_OK; -} - -static int __init machine_kdump_pm_init(void) -{ - pm_notifier(machine_kdump_pm_cb, 0); - return 0; -} -arch_initcall(machine_kdump_pm_init); #endif /* diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 0f419c5765c8..a5360de85ec7 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -377,14 +377,11 @@ static void __init setup_lowcore(void) PSW_MASK_DAT | PSW_MASK_MCHECK; lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; lc->clock_comparator = -1ULL; - lc->kernel_stack = ((unsigned long) &init_thread_union) - + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; lc->async_stack = (unsigned long) - __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) - + ASYNC_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; lc->panic_stack = (unsigned long) - __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) - + PAGE_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; lc->current_task = (unsigned long) init_thread_union.thread_info.task; lc->thread_info = (unsigned long) &init_thread_union; lc->machine_flags = S390_lowcore.machine_flags; @@ -574,8 +571,6 @@ static void __init setup_memory_end(void) /* Split remaining virtual space between 1:1 mapping & vmemmap array */ tmp = VMALLOC_START / (PAGE_SIZE + sizeof(struct page)); - /* vmemmap contains a multiple of PAGES_PER_SECTION struct pages */ - tmp = SECTION_ALIGN_UP(tmp); tmp = VMALLOC_START - tmp * sizeof(struct page); tmp &= ~((vmax >> 11) - 1); /* align to page table level */ tmp = min(tmp, 1UL << MAX_PHYSMEM_BITS); diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 8bde89eafd88..549c9d173c0f 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -181,10 +181,8 @@ static int __cpuinit pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) lc = pcpu->lowcore; memcpy(lc, &S390_lowcore, 512); memset((char *) lc + 512, 0, sizeof(*lc) - 512); - lc->async_stack = pcpu->async_stack + ASYNC_SIZE - - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); - lc->panic_stack = pcpu->panic_stack + PAGE_SIZE - - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + lc->async_stack = pcpu->async_stack + ASYNC_SIZE; + lc->panic_stack = pcpu->panic_stack + PAGE_SIZE; lc->cpu_nr = cpu; #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) { @@ -255,8 +253,7 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) struct _lowcore *lc = pcpu->lowcore; struct thread_info *ti = task_thread_info(tsk); - lc->kernel_stack = (unsigned long) task_stack_page(tsk) - + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + lc->kernel_stack = (unsigned long) task_stack_page(tsk) + THREAD_SIZE; lc->thread_info = (unsigned long) task_thread_info(tsk); lc->current_task = (unsigned long) tsk; lc->user_timer = ti->user_timer; @@ -813,10 +810,8 @@ void __init smp_prepare_boot_cpu(void) pcpu->state = CPU_STATE_CONFIGURED; pcpu->address = boot_cpu_address; pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); - pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE - + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); - pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE - + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); + pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE; + pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE; S390_lowcore.percpu_offset = __per_cpu_offset[0]; smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); set_cpu_present(0, true); diff --git a/trunk/arch/s390/kernel/suspend.c b/trunk/arch/s390/kernel/suspend.c index c479d2f9605b..aa1494d0e380 100644 --- a/trunk/arch/s390/kernel/suspend.c +++ b/trunk/arch/s390/kernel/suspend.c @@ -41,7 +41,6 @@ struct page_key_data { static struct page_key_data *page_key_data; static struct page_key_data *page_key_rp, *page_key_wp; static unsigned long page_key_rx, page_key_wx; -unsigned long suspend_zero_pages; /* * For each page in the hibernation image one additional byte is @@ -150,36 +149,6 @@ int pfn_is_nosave(unsigned long pfn) return 0; } -/* - * PM notifier callback for suspend - */ -static int suspend_pm_cb(struct notifier_block *nb, unsigned long action, - void *ptr) -{ - switch (action) { - case PM_SUSPEND_PREPARE: - case PM_HIBERNATION_PREPARE: - suspend_zero_pages = __get_free_pages(GFP_KERNEL, LC_ORDER); - if (!suspend_zero_pages) - return NOTIFY_BAD; - break; - case PM_POST_SUSPEND: - case PM_POST_HIBERNATION: - free_pages(suspend_zero_pages, LC_ORDER); - break; - default: - return NOTIFY_DONE; - } - return NOTIFY_OK; -} - -static int __init suspend_pm_init(void) -{ - pm_notifier(suspend_pm_cb, 0); - return 0; -} -arch_initcall(suspend_pm_init); - void save_processor_state(void) { /* swsusp_arch_suspend() actually saves all cpu register contents. diff --git a/trunk/arch/s390/kernel/swsusp_asm64.S b/trunk/arch/s390/kernel/swsusp_asm64.S index c487be4cfc81..d4ca4e0617b5 100644 --- a/trunk/arch/s390/kernel/swsusp_asm64.S +++ b/trunk/arch/s390/kernel/swsusp_asm64.S @@ -36,8 +36,8 @@ ENTRY(swsusp_arch_suspend) /* Store prefix register on stack */ stpx __SF_EMPTY(%r15) - /* Save prefix register contents for lowcore copy */ - llgf %r10,__SF_EMPTY(%r15) + /* Save prefix register contents for lowcore */ + llgf %r4,__SF_EMPTY(%r15) /* Get pointer to save area */ lghi %r1,0x1000 @@ -91,18 +91,7 @@ ENTRY(swsusp_arch_suspend) xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) spx __SF_EMPTY(%r15) - /* Save absolute zero pages */ - larl %r2,suspend_zero_pages - lg %r2,0(%r2) - lghi %r4,0 - lghi %r3,2*PAGE_SIZE - lghi %r5,2*PAGE_SIZE -1: mvcle %r2,%r4,0 - jo 1b - - /* Copy lowcore to absolute zero lowcore */ lghi %r2,0 - lgr %r4,%r10 lghi %r3,2*PAGE_SIZE lghi %r5,2*PAGE_SIZE 1: mvcle %r2,%r4,0 @@ -259,20 +248,8 @@ restore_registers: /* Load old stack */ lg %r15,0x2f8(%r13) - /* Save prefix register */ - mvc __SF_EMPTY(4,%r15),0x318(%r13) - - /* Restore absolute zero pages */ - lghi %r2,0 - larl %r4,suspend_zero_pages - lg %r4,0(%r4) - lghi %r3,2*PAGE_SIZE - lghi %r5,2*PAGE_SIZE -1: mvcle %r2,%r4,0 - jo 1b - /* Restore prefix register */ - spx __SF_EMPTY(%r15) + spx 0x318(%r13) /* Activate DAT */ stosm __SF_EMPTY(%r15),0x04 diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c index c5762324d9ee..13dd63fba367 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -12,16 +12,49 @@ * 'Traps.c' handles hardware traps and faults after we have saved some * state in 'asm.s'. */ -#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 +#include +#include +#include +#include +#include #include "entry.h" int show_unhandled_signals = 1; +#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) + +#ifndef CONFIG_64BIT +#define LONG "%08lx " +#define FOURLONG "%08lx %08lx %08lx %08lx\n" +static int kstack_depth_to_print = 12; +#else /* CONFIG_64BIT */ +#define LONG "%016lx " +#define FOURLONG "%016lx %016lx %016lx %016lx\n" +static int kstack_depth_to_print = 20; +#endif /* CONFIG_64BIT */ + static inline void __user *get_trap_ip(struct pt_regs *regs) { #ifdef CONFIG_64BIT @@ -39,6 +72,215 @@ static inline void __user *get_trap_ip(struct pt_regs *regs) #endif } +/* + * For show_trace we have tree different stack to consider: + * - the panic stack which is used if the kernel stack has overflown + * - the asynchronous interrupt stack (cpu related) + * - the synchronous kernel stack (process related) + * The stack trace can start at any of the three stack and can potentially + * touch all of them. The order is: panic stack, async stack, sync stack. + */ +static unsigned long +__show_trace(unsigned long sp, unsigned long low, unsigned long high) +{ + struct stack_frame *sf; + struct pt_regs *regs; + + while (1) { + sp = sp & PSW_ADDR_INSN; + if (sp < low || sp > high - sizeof(*sf)) + return sp; + sf = (struct stack_frame *) sp; + printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); + print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); + /* Follow the backchain. */ + while (1) { + low = sp; + sp = sf->back_chain & PSW_ADDR_INSN; + if (!sp) + break; + if (sp <= low || sp > high - sizeof(*sf)) + return sp; + sf = (struct stack_frame *) sp; + printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); + print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); + } + /* Zero backchain detected, check for interrupt frame. */ + sp = (unsigned long) (sf + 1); + if (sp <= low || sp > high - sizeof(*regs)) + return sp; + regs = (struct pt_regs *) sp; + printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); + print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); + low = sp; + sp = regs->gprs[15]; + } +} + +static void show_trace(struct task_struct *task, unsigned long *stack) +{ + register unsigned long __r15 asm ("15"); + unsigned long sp; + + sp = (unsigned long) stack; + if (!sp) + sp = task ? task->thread.ksp : __r15; + printk("Call Trace:\n"); +#ifdef CONFIG_CHECK_STACK + sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, + S390_lowcore.panic_stack); +#endif + sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, + S390_lowcore.async_stack); + if (task) + __show_trace(sp, (unsigned long) task_stack_page(task), + (unsigned long) task_stack_page(task) + THREAD_SIZE); + else + __show_trace(sp, S390_lowcore.thread_info, + S390_lowcore.thread_info + THREAD_SIZE); + if (!task) + task = current; + debug_show_held_locks(task); +} + +void show_stack(struct task_struct *task, unsigned long *sp) +{ + register unsigned long * __r15 asm ("15"); + unsigned long *stack; + int i; + + if (!sp) + stack = task ? (unsigned long *) task->thread.ksp : __r15; + else + stack = sp; + + for (i = 0; i < kstack_depth_to_print; i++) { + if (((addr_t) stack & (THREAD_SIZE-1)) == 0) + break; + if ((i * sizeof(long) % 32) == 0) + printk("%s ", i == 0 ? "" : "\n"); + printk(LONG, *stack++); + } + printk("\n"); + show_trace(task, sp); +} + +static void show_last_breaking_event(struct pt_regs *regs) +{ +#ifdef CONFIG_64BIT + printk("Last Breaking-Event-Address:\n"); + printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); + print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); +#endif +} + +/* + * The architecture-independent dump_stack generator + */ +void dump_stack(void) +{ + printk("CPU: %d %s %s %.*s\n", + task_thread_info(current)->cpu, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + printk("Process %s (pid: %d, task: %p, ksp: %p)\n", + current->comm, current->pid, current, + (void *) current->thread.ksp); + show_stack(NULL, NULL); +} +EXPORT_SYMBOL(dump_stack); + +static inline int mask_bits(struct pt_regs *regs, unsigned long bits) +{ + return (regs->psw.mask & bits) / ((~bits + 1) & bits); +} + +void show_registers(struct pt_regs *regs) +{ + char *mode; + + mode = user_mode(regs) ? "User" : "Krnl"; + printk("%s PSW : %p %p", + mode, (void *) regs->psw.mask, + (void *) regs->psw.addr); + print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); + printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " + "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), + mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), + mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY), + mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT), + mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC), + mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM)); +#ifdef CONFIG_64BIT + printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA)); +#endif + printk("\n%s GPRS: " FOURLONG, mode, + regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); + printk(" " FOURLONG, + regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); + printk(" " FOURLONG, + regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]); + printk(" " FOURLONG, + regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); + + show_code(regs); +} + +void show_regs(struct pt_regs *regs) +{ + printk("CPU: %d %s %s %.*s\n", + task_thread_info(current)->cpu, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + printk("Process %s (pid: %d, task: %p, ksp: %p)\n", + current->comm, current->pid, current, + (void *) current->thread.ksp); + show_registers(regs); + /* Show stack backtrace if pt_regs is from kernel mode */ + if (!user_mode(regs)) + show_trace(NULL, (unsigned long *) regs->gprs[15]); + show_last_breaking_event(regs); +} + +static DEFINE_SPINLOCK(die_lock); + +void die(struct pt_regs *regs, const char *str) +{ + static int die_counter; + + oops_enter(); + lgr_info_log(); + debug_stop_all(); + console_verbose(); + spin_lock_irq(&die_lock); + bust_spinlocks(1); + printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); +#ifdef CONFIG_PREEMPT + printk("PREEMPT "); +#endif +#ifdef CONFIG_SMP + printk("SMP "); +#endif +#ifdef CONFIG_DEBUG_PAGEALLOC + printk("DEBUG_PAGEALLOC"); +#endif + printk("\n"); + notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); + print_modules(); + show_regs(regs); + bust_spinlocks(0); + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); + spin_unlock_irq(&die_lock); + if (in_interrupt()) + panic("Fatal exception in interrupt"); + if (panic_on_oops) + panic("Fatal exception: panic_on_oops"); + oops_exit(); + do_exit(SIGSEGV); +} + static inline void report_user_fault(struct pt_regs *regs, int signr) { if ((task_pid_nr(current) > 1) && !show_unhandled_signals) diff --git a/trunk/arch/s390/kvm/trace.h b/trunk/arch/s390/kvm/trace.h index 53252d2d4720..2b29e62351d3 100644 --- a/trunk/arch/s390/kvm/trace.h +++ b/trunk/arch/s390/kvm/trace.h @@ -117,7 +117,7 @@ TRACE_EVENT(kvm_s390_intercept_instruction, __entry->instruction, insn_to_mnemonic((unsigned char *) &__entry->instruction, - __entry->insn, sizeof(__entry->insn)) ? + __entry->insn) ? "unknown" : __entry->insn) ); diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c index 466fb3383960..dff631d34b45 100644 --- a/trunk/arch/s390/lib/uaccess_pt.c +++ b/trunk/arch/s390/lib/uaccess_pt.c @@ -77,68 +77,41 @@ static size_t copy_in_kernel(size_t count, void __user *to, * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address * contains the (negative) exception code. */ -#ifdef CONFIG_64BIT -static unsigned long follow_table(struct mm_struct *mm, - unsigned long address, int write) +static __always_inline unsigned long follow_table(struct mm_struct *mm, + unsigned long addr, int write) { - unsigned long *table = (unsigned long *)__pa(mm->pgd); - - switch (mm->context.asce_bits & _ASCE_TYPE_MASK) { - case _ASCE_TYPE_REGION1: - table = table + ((address >> 53) & 0x7ff); - if (unlikely(*table & _REGION_ENTRY_INV)) - return -0x39UL; - table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - case _ASCE_TYPE_REGION2: - table = table + ((address >> 42) & 0x7ff); - if (unlikely(*table & _REGION_ENTRY_INV)) - return -0x3aUL; - table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - case _ASCE_TYPE_REGION3: - table = table + ((address >> 31) & 0x7ff); - if (unlikely(*table & _REGION_ENTRY_INV)) - return -0x3bUL; - table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - case _ASCE_TYPE_SEGMENT: - table = table + ((address >> 20) & 0x7ff); - if (unlikely(*table & _SEGMENT_ENTRY_INV)) - return -0x10UL; - if (unlikely(*table & _SEGMENT_ENTRY_LARGE)) { - if (write && (*table & _SEGMENT_ENTRY_RO)) - return -0x04UL; - return (*table & _SEGMENT_ENTRY_ORIGIN_LARGE) + - (address & ~_SEGMENT_ENTRY_ORIGIN_LARGE); - } - table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); - } - table = table + ((address >> 12) & 0xff); - if (unlikely(*table & _PAGE_INVALID)) - return -0x11UL; - if (write && (*table & _PAGE_RO)) - return -0x04UL; - return (*table & PAGE_MASK) + (address & ~PAGE_MASK); -} + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *ptep; -#else /* CONFIG_64BIT */ + pgd = pgd_offset(mm, addr); + if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) + return -0x3aUL; -static unsigned long follow_table(struct mm_struct *mm, - unsigned long address, int write) -{ - unsigned long *table = (unsigned long *)__pa(mm->pgd); + pud = pud_offset(pgd, addr); + if (pud_none(*pud) || unlikely(pud_bad(*pud))) + return -0x3bUL; - table = table + ((address >> 20) & 0x7ff); - if (unlikely(*table & _SEGMENT_ENTRY_INV)) + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) return -0x10UL; - table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); - table = table + ((address >> 12) & 0xff); - if (unlikely(*table & _PAGE_INVALID)) + if (pmd_large(*pmd)) { + if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) + return -0x04UL; + return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); + } + if (unlikely(pmd_bad(*pmd))) + return -0x10UL; + + ptep = pte_offset_map(pmd, addr); + if (!pte_present(*ptep)) return -0x11UL; - if (write && (*table & _PAGE_RO)) + if (write && (!pte_write(*ptep) || !pte_dirty(*ptep))) return -0x04UL; - return (*table & PAGE_MASK) + (address & ~PAGE_MASK); -} -#endif /* CONFIG_64BIT */ + return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK); +} static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, size_t n, int write_user) @@ -224,7 +197,7 @@ size_t copy_to_user_pt(size_t n, void __user *to, const void *from) static size_t clear_user_pt(size_t n, void __user *to) { - void *zpage = (void *) empty_zero_page; + void *zpage = &empty_zero_page; long done, size, ret; done = 0; diff --git a/trunk/arch/s390/mm/cmm.c b/trunk/arch/s390/mm/cmm.c index 9d84a1feefef..479e94282910 100644 --- a/trunk/arch/s390/mm/cmm.c +++ b/trunk/arch/s390/mm/cmm.c @@ -458,10 +458,12 @@ static int __init cmm_init(void) if (rc) goto out_pm; cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); - if (!IS_ERR(cmm_thread_ptr)) - return 0; + rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0; + if (rc) + goto out_kthread; + return 0; - rc = PTR_ERR(cmm_thread_ptr); +out_kthread: unregister_pm_notifier(&cmm_power_notifier); out_pm: unregister_oom_notifier(&cmm_oom_nb); diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 047c3e4c59a2..2fb9e63b8fc4 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -395,13 +395,8 @@ void __kprobes do_protection_exception(struct pt_regs *regs) int fault; trans_exc_code = regs->int_parm_long; - /* - * Protection exceptions are suppressing, decrement psw address. - * The exception to this rule are aborted transactions, for these - * the PSW already points to the correct location. - */ - if (!(regs->int_code & 0x200)) - regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); + /* Protection exception is suppressing, decrement psw address. */ + regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); /* * Check for low-address protection. This needs to be treated * as a special case because the translation exception code diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index 9f9c315b4c07..49ce6bb2c641 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -63,18 +63,10 @@ static unsigned long __init setup_zero_pages(void) break; case 0x2097: /* z10 */ case 0x2098: /* z10 */ - case 0x2817: /* z196 */ - case 0x2818: /* z196 */ - order = 2; - break; - case 0x2827: /* zEC12 */ default: - order = 5; + order = 2; break; } - /* Limit number of empty zero pages for small memory sizes */ - if (order > 2 && totalram_pages <= 16384) - order = 2; empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); if (!empty_zero_page) diff --git a/trunk/arch/s390/mm/pageattr.c b/trunk/arch/s390/mm/pageattr.c index 80adfbf75065..d21040ed5e59 100644 --- a/trunk/arch/s390/mm/pageattr.c +++ b/trunk/arch/s390/mm/pageattr.c @@ -9,25 +9,31 @@ #include #include -static inline unsigned long sske_frame(unsigned long addr, unsigned char skey) -{ - asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],9,0" - : [addr] "+a" (addr) : [skey] "d" (skey)); - return addr; -} - void storage_key_init_range(unsigned long start, unsigned long end) { - unsigned long boundary, size; + unsigned long boundary, function, size; while (start < end) { + if (MACHINE_HAS_EDAT2) { + /* set storage keys for a 2GB frame */ + function = 0x22000 | PAGE_DEFAULT_KEY; + size = 1UL << 31; + boundary = (start + size) & ~(size - 1); + if (boundary <= end) { + do { + start = pfmf(function, start); + } while (start < boundary); + continue; + } + } if (MACHINE_HAS_EDAT1) { /* set storage keys for a 1MB frame */ + function = 0x21000 | PAGE_DEFAULT_KEY; size = 1UL << 20; boundary = (start + size) & ~(size - 1); if (boundary <= end) { do { - start = sske_frame(start, PAGE_DEFAULT_KEY); + start = pfmf(function, start); } while (start < boundary); continue; } diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index bd954e96f51c..ae44d2a34313 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -379,183 +379,75 @@ int gmap_map_segment(struct gmap *gmap, unsigned long from, } EXPORT_SYMBOL_GPL(gmap_map_segment); -static unsigned long *gmap_table_walk(unsigned long address, struct gmap *gmap) +/* + * this function is assumed to be called with mmap_sem held + */ +unsigned long __gmap_fault(unsigned long address, struct gmap *gmap) { - unsigned long *table; + unsigned long *table, vmaddr, segment; + struct mm_struct *mm; + struct gmap_pgtable *mp; + struct gmap_rmap *rmap; + struct vm_area_struct *vma; + struct page *page; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + current->thread.gmap_addr = address; + mm = gmap->mm; + /* Walk the gmap address space page table */ table = gmap->table + ((address >> 53) & 0x7ff); if (unlikely(*table & _REGION_ENTRY_INV)) - return ERR_PTR(-EFAULT); + return -EFAULT; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); table = table + ((address >> 42) & 0x7ff); if (unlikely(*table & _REGION_ENTRY_INV)) - return ERR_PTR(-EFAULT); + return -EFAULT; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); table = table + ((address >> 31) & 0x7ff); if (unlikely(*table & _REGION_ENTRY_INV)) - return ERR_PTR(-EFAULT); + return -EFAULT; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); table = table + ((address >> 20) & 0x7ff); - return table; -} - -/** - * __gmap_translate - translate a guest address to a user space address - * @address: guest address - * @gmap: pointer to guest mapping meta data structure - * - * Returns user space address which corresponds to the guest address or - * -EFAULT if no such mapping exists. - * This function does not establish potentially missing page table entries. - * The mmap_sem of the mm that belongs to the address space must be held - * when this function gets called. - */ -unsigned long __gmap_translate(unsigned long address, struct gmap *gmap) -{ - unsigned long *segment_ptr, vmaddr, segment; - struct gmap_pgtable *mp; - struct page *page; - current->thread.gmap_addr = address; - segment_ptr = gmap_table_walk(address, gmap); - if (IS_ERR(segment_ptr)) - return PTR_ERR(segment_ptr); /* Convert the gmap address to an mm address. */ - segment = *segment_ptr; - if (!(segment & _SEGMENT_ENTRY_INV)) { + segment = *table; + if (likely(!(segment & _SEGMENT_ENTRY_INV))) { page = pfn_to_page(segment >> PAGE_SHIFT); mp = (struct gmap_pgtable *) page->index; return mp->vmaddr | (address & ~PMD_MASK); } else if (segment & _SEGMENT_ENTRY_RO) { vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; - return vmaddr | (address & ~PMD_MASK); - } - return -EFAULT; -} -EXPORT_SYMBOL_GPL(__gmap_translate); - -/** - * gmap_translate - translate a guest address to a user space address - * @address: guest address - * @gmap: pointer to guest mapping meta data structure - * - * Returns user space address which corresponds to the guest address or - * -EFAULT if no such mapping exists. - * This function does not establish potentially missing page table entries. - */ -unsigned long gmap_translate(unsigned long address, struct gmap *gmap) -{ - unsigned long rc; - - down_read(&gmap->mm->mmap_sem); - rc = __gmap_translate(address, gmap); - up_read(&gmap->mm->mmap_sem); - return rc; -} -EXPORT_SYMBOL_GPL(gmap_translate); - -static int gmap_connect_pgtable(unsigned long segment, - unsigned long *segment_ptr, - struct gmap *gmap) -{ - unsigned long vmaddr; - struct vm_area_struct *vma; - struct gmap_pgtable *mp; - struct gmap_rmap *rmap; - struct mm_struct *mm; - struct page *page; - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - - mm = gmap->mm; - vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; - vma = find_vma(mm, vmaddr); - if (!vma || vma->vm_start > vmaddr) - return -EFAULT; - /* Walk the parent mm page table */ - pgd = pgd_offset(mm, vmaddr); - pud = pud_alloc(mm, pgd, vmaddr); - if (!pud) - return -ENOMEM; - pmd = pmd_alloc(mm, pud, vmaddr); - if (!pmd) - return -ENOMEM; - if (!pmd_present(*pmd) && - __pte_alloc(mm, vma, pmd, vmaddr)) - return -ENOMEM; - /* pmd now points to a valid segment table entry. */ - rmap = kmalloc(sizeof(*rmap), GFP_KERNEL|__GFP_REPEAT); - if (!rmap) - return -ENOMEM; - /* Link gmap segment table entry location to page table. */ - page = pmd_page(*pmd); - mp = (struct gmap_pgtable *) page->index; - rmap->entry = segment_ptr; - spin_lock(&mm->page_table_lock); - if (*segment_ptr == segment) { + vma = find_vma(mm, vmaddr); + if (!vma || vma->vm_start > vmaddr) + return -EFAULT; + + /* Walk the parent mm page table */ + pgd = pgd_offset(mm, vmaddr); + pud = pud_alloc(mm, pgd, vmaddr); + if (!pud) + return -ENOMEM; + pmd = pmd_alloc(mm, pud, vmaddr); + if (!pmd) + return -ENOMEM; + if (!pmd_present(*pmd) && + __pte_alloc(mm, vma, pmd, vmaddr)) + return -ENOMEM; + /* pmd now points to a valid segment table entry. */ + rmap = kmalloc(sizeof(*rmap), GFP_KERNEL|__GFP_REPEAT); + if (!rmap) + return -ENOMEM; + /* Link gmap segment table entry location to page table. */ + page = pmd_page(*pmd); + mp = (struct gmap_pgtable *) page->index; + rmap->entry = table; + spin_lock(&mm->page_table_lock); list_add(&rmap->list, &mp->mapper); + spin_unlock(&mm->page_table_lock); /* Set gmap segment table entry to page table. */ - *segment_ptr = pmd_val(*pmd) & PAGE_MASK; - rmap = NULL; - } - spin_unlock(&mm->page_table_lock); - kfree(rmap); - return 0; -} - -static void gmap_disconnect_pgtable(struct mm_struct *mm, unsigned long *table) -{ - struct gmap_rmap *rmap, *next; - struct gmap_pgtable *mp; - struct page *page; - int flush; - - flush = 0; - spin_lock(&mm->page_table_lock); - page = pfn_to_page(__pa(table) >> PAGE_SHIFT); - mp = (struct gmap_pgtable *) page->index; - list_for_each_entry_safe(rmap, next, &mp->mapper, list) { - *rmap->entry = - _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | mp->vmaddr; - list_del(&rmap->list); - kfree(rmap); - flush = 1; - } - spin_unlock(&mm->page_table_lock); - if (flush) - __tlb_flush_global(); -} - -/* - * this function is assumed to be called with mmap_sem held - */ -unsigned long __gmap_fault(unsigned long address, struct gmap *gmap) -{ - unsigned long *segment_ptr, segment; - struct gmap_pgtable *mp; - struct page *page; - int rc; - - current->thread.gmap_addr = address; - segment_ptr = gmap_table_walk(address, gmap); - if (IS_ERR(segment_ptr)) - return -EFAULT; - /* Convert the gmap address to an mm address. */ - while (1) { - segment = *segment_ptr; - if (!(segment & _SEGMENT_ENTRY_INV)) { - /* Page table is present */ - page = pfn_to_page(segment >> PAGE_SHIFT); - mp = (struct gmap_pgtable *) page->index; - return mp->vmaddr | (address & ~PMD_MASK); - } - if (!(segment & _SEGMENT_ENTRY_RO)) - /* Nothing mapped in the gmap address space. */ - break; - rc = gmap_connect_pgtable(segment, segment_ptr, gmap); - if (rc) - return rc; + *table = pmd_val(*pmd) & PAGE_MASK; + return vmaddr | (address & ~PMD_MASK); } return -EFAULT; } @@ -619,6 +511,29 @@ void gmap_discard(unsigned long from, unsigned long to, struct gmap *gmap) } EXPORT_SYMBOL_GPL(gmap_discard); +void gmap_unmap_notifier(struct mm_struct *mm, unsigned long *table) +{ + struct gmap_rmap *rmap, *next; + struct gmap_pgtable *mp; + struct page *page; + int flush; + + flush = 0; + spin_lock(&mm->page_table_lock); + page = pfn_to_page(__pa(table) >> PAGE_SHIFT); + mp = (struct gmap_pgtable *) page->index; + list_for_each_entry_safe(rmap, next, &mp->mapper, list) { + *rmap->entry = + _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | mp->vmaddr; + list_del(&rmap->list); + kfree(rmap); + flush = 1; + } + spin_unlock(&mm->page_table_lock); + if (flush) + __tlb_flush_global(); +} + static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, unsigned long vmaddr) { @@ -671,8 +586,8 @@ static inline void page_table_free_pgste(unsigned long *table) { } -static inline void gmap_disconnect_pgtable(struct mm_struct *mm, - unsigned long *table) +static inline void gmap_unmap_notifier(struct mm_struct *mm, + unsigned long *table) { } @@ -738,7 +653,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) unsigned int bit, mask; if (mm_has_pgste(mm)) { - gmap_disconnect_pgtable(mm, table); + gmap_unmap_notifier(mm, table); return page_table_free_pgste(table); } /* Free 1K/2K page table fragment of a 4K page */ @@ -781,7 +696,7 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table) mm = tlb->mm; if (mm_has_pgste(mm)) { - gmap_disconnect_pgtable(mm, table); + gmap_unmap_notifier(mm, table); table = (unsigned long *) (__pa(table) | FRAG_MASK); tlb_remove_table(tlb, table); return; diff --git a/trunk/arch/s390/net/bpf_jit_comp.c b/trunk/arch/s390/net/bpf_jit_comp.c index 82f165f8078c..0972e91cced2 100644 --- a/trunk/arch/s390/net/bpf_jit_comp.c +++ b/trunk/arch/s390/net/bpf_jit_comp.c @@ -747,9 +747,10 @@ void bpf_jit_compile(struct sk_filter *fp) if (!bpf_jit_enable) return; - addrs = kcalloc(fp->len, sizeof(*addrs), GFP_KERNEL); + addrs = kmalloc(fp->len * sizeof(*addrs), GFP_KERNEL); if (addrs == NULL) return; + memset(addrs, 0, fp->len * sizeof(*addrs)); memset(&jit, 0, sizeof(cjit)); memset(&cjit, 0, sizeof(cjit)); diff --git a/trunk/arch/s390/pci/Makefile b/trunk/arch/s390/pci/Makefile index 086a2e37935d..f0f426a113ce 100644 --- a/trunk/arch/s390/pci/Makefile +++ b/trunk/arch/s390/pci/Makefile @@ -2,5 +2,5 @@ # Makefile for the s390 PCI subsystem. # -obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o pci_sysfs.o \ - pci_event.o pci_debug.o pci_insn.o +obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \ + pci_sysfs.o pci_event.o pci_debug.o diff --git a/trunk/arch/s390/pci/pci.c b/trunk/arch/s390/pci/pci.c index e6f15b5d8b7d..27b4c17855b9 100644 --- a/trunk/arch/s390/pci/pci.c +++ b/trunk/arch/s390/pci/pci.c @@ -99,6 +99,9 @@ static int __read_mostly aisb_max; static struct kmem_cache *zdev_irq_cache; static struct kmem_cache *zdev_fmb_cache; +debug_info_t *pci_debug_msg_id; +debug_info_t *pci_debug_err_id; + static inline int irq_to_msi_nr(unsigned int irq) { return irq & ZPCI_MSI_MASK; @@ -176,7 +179,7 @@ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, fib->aisb = (u64) bucket->aisb + aisb / 8; fib->aisbo = aisb & ZPCI_MSI_MASK; - rc = s390pci_mod_fc(req, fib); + rc = mpcifc_instr(req, fib); pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); free_page((unsigned long) fib); @@ -206,7 +209,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args fib->iota = args->iota; fib->fmb_addr = args->fmb_addr; - rc = s390pci_mod_fc(req, fib); + rc = mpcifc_instr(req, fib); free_page((unsigned long) fib); return rc; } @@ -246,9 +249,10 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev) if (zdev->fmb) return -EINVAL; - zdev->fmb = kmem_cache_zalloc(zdev_fmb_cache, GFP_KERNEL); + zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL); if (!zdev->fmb) return -ENOMEM; + memset(zdev->fmb, 0, sizeof(*zdev->fmb)); WARN_ON((u64) zdev->fmb & 0xf); args.fmb_addr = virt_to_phys(zdev->fmb); @@ -280,12 +284,12 @@ static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) u64 data; int rc; - rc = s390pci_load(&data, req, offset); - if (!rc) { - data = data << ((8 - len) * 8); - data = le64_to_cpu(data); + rc = pcilg_instr(&data, req, offset); + data = data << ((8 - len) * 8); + data = le64_to_cpu(data); + if (!rc) *val = (u32) data; - } else + else *val = 0xffffffff; return rc; } @@ -298,7 +302,7 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) data = cpu_to_le64(data); data = data >> ((8 - len) * 8); - rc = s390pci_store(data, req, offset); + rc = pcistg_instr(data, req, offset); return rc; } @@ -405,28 +409,20 @@ static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { struct zpci_dev *zdev = get_zdev_by_bus(bus); - int ret; if (!zdev || devfn != ZPCI_DEVFN) - ret = -ENODEV; - else - ret = zpci_cfg_load(zdev, where, val, size); - - return ret; + return 0; + return zpci_cfg_load(zdev, where, val, size); } static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { struct zpci_dev *zdev = get_zdev_by_bus(bus); - int ret; if (!zdev || devfn != ZPCI_DEVFN) - ret = -ENODEV; - else - ret = zpci_cfg_store(zdev, where, val, size); - - return ret; + return 0; + return zpci_cfg_store(zdev, where, val, size); } static struct pci_ops pci_root_ops = { @@ -478,7 +474,7 @@ static void zpci_irq_handler(void *dont, void *need) } /* enable interrupts again */ - set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); + sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); /* check again to not lose initiative */ rmb(); @@ -600,6 +596,19 @@ static void zpci_map_resources(struct zpci_dev *zdev) } }; +static void zpci_unmap_resources(struct pci_dev *pdev) +{ + resource_size_t len; + int i; + + for (i = 0; i < PCI_BAR_COUNT; i++) { + len = pci_resource_len(pdev, i); + if (!len) + continue; + pci_iounmap(pdev, (void *) pdev->resource[i].start); + } +}; + struct zpci_dev *zpci_alloc_device(void) { struct zpci_dev *zdev; @@ -627,6 +636,32 @@ void zpci_free_device(struct zpci_dev *zdev) kfree(zdev); } +/* Called on removal of pci_dev, leaves zpci and bus device */ +static void zpci_remove_device(struct pci_dev *pdev) +{ + struct zpci_dev *zdev = get_zdev(pdev); + + dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); + zdev->state = ZPCI_FN_STATE_CONFIGURED; + zpci_dma_exit_device(zdev); + zpci_fmb_disable_device(zdev); + zpci_sysfs_remove_device(&pdev->dev); + zpci_unmap_resources(pdev); + list_del(&zdev->entry); /* can be called from init */ + zdev->pdev = NULL; +} + +static void zpci_scan_devices(void) +{ + struct zpci_dev *zdev; + + mutex_lock(&zpci_list_lock); + list_for_each_entry(zdev, &zpci_list, entry) + if (zdev->state == ZPCI_FN_STATE_CONFIGURED) + zpci_scan_device(zdev); + mutex_unlock(&zpci_list_lock); +} + /* * Too late for any s390 specific setup, since interrupts must be set up * already which requires DMA setup too and the pci scan will access the @@ -653,6 +688,12 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask) return 0; } +void pcibios_disable_device(struct pci_dev *pdev) +{ + zpci_remove_device(pdev); + pdev->sysdata = NULL; +} + int pcibios_add_platform_entries(struct pci_dev *pdev) { return zpci_sysfs_add_device(&pdev->dev); @@ -748,7 +789,7 @@ static int __init zpci_irq_init(void) spin_lock_init(&bucket->lock); /* set summary to 1 to be called every time for the ISC */ *zpci_irq_si = 1; - set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); + sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); return 0; out_ai: @@ -831,19 +872,7 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) spin_unlock(&zpci_iomap_lock); } -int pcibios_add_device(struct pci_dev *pdev) -{ - struct zpci_dev *zdev = get_zdev(pdev); - - zdev->pdev = pdev; - zpci_debug_init_device(zdev); - zpci_fmb_enable_device(zdev); - zpci_map_resources(zdev); - - return 0; -} - -static int zpci_scan_bus(struct zpci_dev *zdev) +static int zpci_create_device_bus(struct zpci_dev *zdev) { struct resource *res; LIST_HEAD(resources); @@ -880,8 +909,8 @@ static int zpci_scan_bus(struct zpci_dev *zdev) pci_add_resource(&resources, res); } - zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, - zdev, &resources); + zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, + zdev, &resources); if (!zdev->bus) return -EIO; @@ -930,13 +959,6 @@ int zpci_enable_device(struct zpci_dev *zdev) } EXPORT_SYMBOL_GPL(zpci_enable_device); -int zpci_disable_device(struct zpci_dev *zdev) -{ - zpci_dma_exit_device(zdev); - return clp_disable_fh(zdev); -} -EXPORT_SYMBOL_GPL(zpci_disable_device); - int zpci_create_device(struct zpci_dev *zdev) { int rc; @@ -945,16 +967,9 @@ int zpci_create_device(struct zpci_dev *zdev) if (rc) goto out; - if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { - rc = zpci_enable_device(zdev); - if (rc) - goto out_free; - - zdev->state = ZPCI_FN_STATE_ONLINE; - } - rc = zpci_scan_bus(zdev); + rc = zpci_create_device_bus(zdev); if (rc) - goto out_disable; + goto out_bus; mutex_lock(&zpci_list_lock); list_add_tail(&zdev->entry, &zpci_list); @@ -962,12 +977,21 @@ int zpci_create_device(struct zpci_dev *zdev) hotplug_ops->create_slot(zdev); mutex_unlock(&zpci_list_lock); + if (zdev->state == ZPCI_FN_STATE_STANDBY) + return 0; + + rc = zpci_enable_device(zdev); + if (rc) + goto out_start; return 0; -out_disable: - if (zdev->state == ZPCI_FN_STATE_ONLINE) - zpci_disable_device(zdev); -out_free: +out_start: + mutex_lock(&zpci_list_lock); + list_del(&zdev->entry); + if (hotplug_ops) + hotplug_ops->remove_slot(zdev); + mutex_unlock(&zpci_list_lock); +out_bus: zpci_free_domain(zdev); out: return rc; @@ -992,9 +1016,15 @@ int zpci_scan_device(struct zpci_dev *zdev) goto out; } + zpci_debug_init_device(zdev); + zpci_fmb_enable_device(zdev); + zpci_map_resources(zdev); pci_bus_add_devices(zdev->bus); + /* now that pdev was added to the bus mark it as used */ + zdev->state = ZPCI_FN_STATE_ONLINE; return 0; + out: zpci_dma_exit_device(zdev); clp_disable_fh(zdev); @@ -1057,13 +1087,13 @@ void zpci_deregister_hp_ops(void) } EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); -unsigned int s390_pci_probe; +unsigned int s390_pci_probe = 1; EXPORT_SYMBOL_GPL(s390_pci_probe); char * __init pcibios_setup(char *str) { - if (!strcmp(str, "on")) { - s390_pci_probe = 1; + if (!strcmp(str, "off")) { + s390_pci_probe = 0; return NULL; } return str; @@ -1108,6 +1138,7 @@ static int __init pci_base_init(void) if (rc) goto out_find; + zpci_scan_devices(); return 0; out_find: diff --git a/trunk/arch/s390/pci/pci_clp.c b/trunk/arch/s390/pci/pci_clp.c index bd34359d1546..f339fe2feb15 100644 --- a/trunk/arch/s390/pci/pci_clp.c +++ b/trunk/arch/s390/pci/pci_clp.c @@ -13,7 +13,6 @@ #include #include #include -#include #include /* @@ -145,7 +144,6 @@ int clp_add_pci_device(u32 fid, u32 fh, int configured) struct zpci_dev *zdev; int rc; - zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, configured); zdev = zpci_alloc_device(); if (IS_ERR(zdev)) return PTR_ERR(zdev); @@ -206,8 +204,8 @@ static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) *fh = rrb->response.fh; else { - zpci_dbg(0, "SPF fh:%x, cc:%d, resp:%x\n", *fh, rc, - rrb->response.hdr.rsp); + pr_err("Set PCI FN failed with response: %x cc: %d\n", + rrb->response.hdr.rsp, rc); rc = -EIO; } clp_free_block(rrb); @@ -223,8 +221,6 @@ int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as) if (!rc) /* Success -> store enabled handle in zdev */ zdev->fh = fh; - - zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc); return rc; } @@ -241,8 +237,9 @@ int clp_disable_fh(struct zpci_dev *zdev) if (!rc) /* Success -> store disabled handle in zdev */ zdev->fh = fh; - - zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc); + else + dev_err(&zdev->pdev->dev, + "Failed to disable fn handle: 0x%x\n", fh); return rc; } diff --git a/trunk/arch/s390/pci/pci_debug.c b/trunk/arch/s390/pci/pci_debug.c index 771b82359af4..a5d07bc2a547 100644 --- a/trunk/arch/s390/pci/pci_debug.c +++ b/trunk/arch/s390/pci/pci_debug.c @@ -11,17 +11,12 @@ #include #include #include -#include #include #include #include static struct dentry *debugfs_root; -debug_info_t *pci_debug_msg_id; -EXPORT_SYMBOL_GPL(pci_debug_msg_id); -debug_info_t *pci_debug_err_id; -EXPORT_SYMBOL_GPL(pci_debug_err_id); static char *pci_perf_names[] = { /* hardware counters */ @@ -173,6 +168,7 @@ int __init zpci_debug_init(void) return -EINVAL; debug_register_view(pci_debug_msg_id, &debug_sprintf_view); debug_set_level(pci_debug_msg_id, 3); + zpci_dbg("Debug view initialized\n"); /* error log */ pci_debug_err_id = debug_register("pci_error", 2, 1, 16); @@ -180,6 +176,7 @@ int __init zpci_debug_init(void) return -EINVAL; debug_register_view(pci_debug_err_id, &debug_hex_ascii_view); debug_set_level(pci_debug_err_id, 6); + zpci_err("Debug view initialized\n"); debugfs_root = debugfs_create_dir("pci", NULL); return 0; diff --git a/trunk/arch/s390/pci/pci_dma.c b/trunk/arch/s390/pci/pci_dma.c index f8e69d5bc0a9..a547419907c3 100644 --- a/trunk/arch/s390/pci/pci_dma.c +++ b/trunk/arch/s390/pci/pci_dma.c @@ -169,9 +169,8 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa, * needs to be redone! */ goto no_refresh; - - rc = s390pci_refresh_trans((u64) zdev->fh << 32, start_dma_addr, - nr_pages * PAGE_SIZE); + rc = rpcit_instr((u64) zdev->fh << 32, start_dma_addr, + nr_pages * PAGE_SIZE); no_refresh: spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags); @@ -269,6 +268,8 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, int flags = ZPCI_PTE_VALID; dma_addr_t dma_addr; + WARN_ON_ONCE(offset > PAGE_SIZE); + /* This rounds up number of pages based on size and offset */ nr_pages = iommu_num_pages(pa, size, PAGE_SIZE); iommu_page_index = dma_alloc_iommu(zdev, nr_pages); @@ -290,7 +291,7 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) { atomic64_add(nr_pages, (atomic64_t *) &zdev->fmb->mapped_pages); - return dma_addr + (offset & ~PAGE_MASK); + return dma_addr + offset; } out_free: diff --git a/trunk/arch/s390/pci/pci_insn.c b/trunk/arch/s390/pci/pci_insn.c deleted file mode 100644 index 22eeb9d7ffeb..000000000000 --- a/trunk/arch/s390/pci/pci_insn.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * s390 specific pci instructions - * - * Copyright IBM Corp. 2013 - */ - -#include -#include -#include -#include -#include - -#define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */ - -/* Modify PCI Function Controls */ -static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) -{ - u8 cc; - - asm volatile ( - " .insn rxy,0xe300000000d0,%[req],%[fib]\n" - " ipm %[cc]\n" - " srl %[cc],28\n" - : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib) - : : "cc"); - *status = req >> 24 & 0xff; - return cc; -} - -int s390pci_mod_fc(u64 req, struct zpci_fib *fib) -{ - u8 cc, status; - - do { - cc = __mpcifc(req, fib, &status); - if (cc == 2) - msleep(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d\n", - __func__, cc, status); - return (cc) ? -EIO : 0; -} - -/* Refresh PCI Translations */ -static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) -{ - register u64 __addr asm("2") = addr; - register u64 __range asm("3") = range; - u8 cc; - - asm volatile ( - " .insn rre,0xb9d30000,%[fn],%[addr]\n" - " ipm %[cc]\n" - " srl %[cc],28\n" - : [cc] "=d" (cc), [fn] "+d" (fn) - : [addr] "d" (__addr), "d" (__range) - : "cc"); - *status = fn >> 24 & 0xff; - return cc; -} - -int s390pci_refresh_trans(u64 fn, u64 addr, u64 range) -{ - u8 cc, status; - - do { - cc = __rpcit(fn, addr, range, &status); - if (cc == 2) - udelay(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d dma_addr: %Lx size: %Lx\n", - __func__, cc, status, addr, range); - return (cc) ? -EIO : 0; -} - -/* Set Interruption Controls */ -void set_irq_ctrl(u16 ctl, char *unused, u8 isc) -{ - asm volatile ( - " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" - : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); -} - -/* PCI Load */ -static inline int __pcilg(u64 *data, u64 req, u64 offset, u8 *status) -{ - register u64 __req asm("2") = req; - register u64 __offset asm("3") = offset; - int cc = -ENXIO; - u64 __data; - - asm volatile ( - " .insn rre,0xb9d20000,%[data],%[req]\n" - "0: ipm %[cc]\n" - " srl %[cc],28\n" - "1:\n" - EX_TABLE(0b, 1b) - : [cc] "+d" (cc), [data] "=d" (__data), [req] "+d" (__req) - : "d" (__offset) - : "cc"); - *status = __req >> 24 & 0xff; - if (!cc) - *data = __data; - - return cc; -} - -int s390pci_load(u64 *data, u64 req, u64 offset) -{ - u8 status; - int cc; - - do { - cc = __pcilg(data, req, offset, &status); - if (cc == 2) - udelay(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", - __func__, cc, status, req, offset); - return (cc > 0) ? -EIO : cc; -} -EXPORT_SYMBOL_GPL(s390pci_load); - -/* PCI Store */ -static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status) -{ - register u64 __req asm("2") = req; - register u64 __offset asm("3") = offset; - int cc = -ENXIO; - - asm volatile ( - " .insn rre,0xb9d00000,%[data],%[req]\n" - "0: ipm %[cc]\n" - " srl %[cc],28\n" - "1:\n" - EX_TABLE(0b, 1b) - : [cc] "+d" (cc), [req] "+d" (__req) - : "d" (__offset), [data] "d" (data) - : "cc"); - *status = __req >> 24 & 0xff; - return cc; -} - -int s390pci_store(u64 data, u64 req, u64 offset) -{ - u8 status; - int cc; - - do { - cc = __pcistg(data, req, offset, &status); - if (cc == 2) - udelay(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", - __func__, cc, status, req, offset); - return (cc > 0) ? -EIO : cc; -} -EXPORT_SYMBOL_GPL(s390pci_store); - -/* PCI Store Block */ -static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) -{ - int cc = -ENXIO; - - asm volatile ( - " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n" - "0: ipm %[cc]\n" - " srl %[cc],28\n" - "1:\n" - EX_TABLE(0b, 1b) - : [cc] "+d" (cc), [req] "+d" (req) - : [offset] "d" (offset), [data] "Q" (*data) - : "cc"); - *status = req >> 24 & 0xff; - return cc; -} - -int s390pci_store_block(const u64 *data, u64 req, u64 offset) -{ - u8 status; - int cc; - - do { - cc = __pcistb(data, req, offset, &status); - if (cc == 2) - udelay(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", - __func__, cc, status, req, offset); - return (cc > 0) ? -EIO : cc; -} -EXPORT_SYMBOL_GPL(s390pci_store_block); diff --git a/trunk/arch/s390/pci/pci_msi.c b/trunk/arch/s390/pci/pci_msi.c index b097aed05a9b..0297931335e1 100644 --- a/trunk/arch/s390/pci/pci_msi.c +++ b/trunk/arch/s390/pci/pci_msi.c @@ -18,9 +18,8 @@ /* mapping of irq numbers to msi_desc */ static struct hlist_head *msi_hash; -static const unsigned int msi_hash_bits = 8; -#define MSI_HASH_BUCKETS (1U << msi_hash_bits) -#define msi_hashfn(nr) hash_long(nr, msi_hash_bits) +static unsigned int msihash_shift = 6; +#define msi_hashfn(nr) hash_long(nr, msihash_shift) static DEFINE_SPINLOCK(msi_map_lock); @@ -75,7 +74,6 @@ int zpci_setup_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi, map->irq = nr; map->msi = msi; zdev->msi_map[nr & ZPCI_MSI_MASK] = map; - INIT_HLIST_NODE(&map->msi_chain); pr_debug("%s hashing irq: %u to bucket nr: %llu\n", __func__, nr, msi_hashfn(nr)); @@ -127,11 +125,11 @@ int __init zpci_msihash_init(void) { unsigned int i; - msi_hash = kmalloc(MSI_HASH_BUCKETS * sizeof(*msi_hash), GFP_KERNEL); + msi_hash = kmalloc(256 * sizeof(*msi_hash), GFP_KERNEL); if (!msi_hash) return -ENOMEM; - for (i = 0; i < MSI_HASH_BUCKETS; i++) + for (i = 0; i < (1U << msihash_shift); i++) INIT_HLIST_HEAD(&msi_hash[i]); return 0; } diff --git a/trunk/arch/score/Kconfig b/trunk/arch/score/Kconfig index c8def8bc9020..e569aa1fd2ba 100644 --- a/trunk/arch/score/Kconfig +++ b/trunk/arch/score/Kconfig @@ -12,7 +12,7 @@ config SCORE select GENERIC_CPU_DEVICES select GENERIC_CLOCKEVENTS select HAVE_MOD_ARCH_SPECIFIC - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select MODULES_USE_ELF_REL select CLONE_BACKWARDS diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 3d361f236308..289127d5241c 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -84,6 +84,12 @@ config ARCH_DEFCONFIG default "arch/sparc/configs/sparc32_defconfig" if SPARC32 default "arch/sparc/configs/sparc64_defconfig" if SPARC64 +# CONFIG_BITS can be used at source level to get 32/64 bits +config BITS + int + default 32 if SPARC32 + default 64 if SPARC64 + config IOMMU_HELPER bool default y if SPARC64 @@ -191,7 +197,7 @@ config RWSEM_XCHGADD_ALGORITHM config GENERIC_HWEIGHT bool - default y + default y if !ULTRA_HAS_POPULATION_COUNT config GENERIC_CALIBRATE_DELAY bool diff --git a/trunk/arch/sparc/include/asm/Kbuild b/trunk/arch/sparc/include/asm/Kbuild index ff18e3cfb6b1..e26d430ce2fd 100644 --- a/trunk/arch/sparc/include/asm/Kbuild +++ b/trunk/arch/sparc/include/asm/Kbuild @@ -2,16 +2,11 @@ generic-y += clkdev.h -generic-y += cputime.h generic-y += div64.h -generic-y += emergency-restart.h generic-y += exec.h generic-y += local64.h -generic-y += mutex.h generic-y += irq_regs.h generic-y += local.h generic-y += module.h -generic-y += serial.h generic-y += trace_clock.h -generic-y += types.h generic-y += word-at-a-time.h diff --git a/trunk/arch/sparc/include/asm/cputime.h b/trunk/arch/sparc/include/asm/cputime.h new file mode 100644 index 000000000000..1a642b81e019 --- /dev/null +++ b/trunk/arch/sparc/include/asm/cputime.h @@ -0,0 +1,6 @@ +#ifndef __SPARC_CPUTIME_H +#define __SPARC_CPUTIME_H + +#include + +#endif /* __SPARC_CPUTIME_H */ diff --git a/trunk/arch/sparc/include/asm/emergency-restart.h b/trunk/arch/sparc/include/asm/emergency-restart.h new file mode 100644 index 000000000000..108d8c48e42e --- /dev/null +++ b/trunk/arch/sparc/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/sparc/include/asm/mutex.h b/trunk/arch/sparc/include/asm/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/trunk/arch/sparc/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/sparc/include/asm/pgtable_64.h b/trunk/arch/sparc/include/asm/pgtable_64.h index 7619f2f792af..08fcce90316b 100644 --- a/trunk/arch/sparc/include/asm/pgtable_64.h +++ b/trunk/arch/sparc/include/asm/pgtable_64.h @@ -915,7 +915,6 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); } -#include #include /* We provide our own get_unmapped_area to cope with VA holes and diff --git a/trunk/arch/sparc/include/asm/serial.h b/trunk/arch/sparc/include/asm/serial.h new file mode 100644 index 000000000000..f90d61c28059 --- /dev/null +++ b/trunk/arch/sparc/include/asm/serial.h @@ -0,0 +1,6 @@ +#ifndef __SPARC_SERIAL_H +#define __SPARC_SERIAL_H + +#define BASE_BAUD ( 1843200 / 16 ) + +#endif /* __SPARC_SERIAL_H */ diff --git a/trunk/arch/sparc/include/asm/smp_32.h b/trunk/arch/sparc/include/asm/smp_32.h index 3c8917f054de..b73da3c5f10a 100644 --- a/trunk/arch/sparc/include/asm/smp_32.h +++ b/trunk/arch/sparc/include/asm/smp_32.h @@ -36,6 +36,7 @@ typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); void cpu_panic(void); +extern void smp4m_irq_rotate(int cpu); /* * General functions that each host system must provide. @@ -45,6 +46,7 @@ void sun4m_init_smp(void); void sun4d_init_smp(void); void smp_callin(void); +void smp_boot_cpus(void); void smp_store_cpu_info(int); void smp_resched_interrupt(void); @@ -105,6 +107,9 @@ extern int hard_smp_processor_id(void); #define raw_smp_processor_id() (current_thread_info()->cpu) +#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier +#define prof_counter(__cpu) cpu_data(__cpu).counter + void smp_setup_cpu_possible_map(void); #endif /* !(__ASSEMBLY__) */ diff --git a/trunk/arch/sparc/include/asm/spitfire.h b/trunk/arch/sparc/include/asm/spitfire.h index 6b67e50fb9b4..d06a26601753 100644 --- a/trunk/arch/sparc/include/asm/spitfire.h +++ b/trunk/arch/sparc/include/asm/spitfire.h @@ -45,7 +45,6 @@ #define SUN4V_CHIP_NIAGARA3 0x03 #define SUN4V_CHIP_NIAGARA4 0x04 #define SUN4V_CHIP_NIAGARA5 0x05 -#define SUN4V_CHIP_SPARC64X 0x8a #define SUN4V_CHIP_UNKNOWN 0xff #ifndef __ASSEMBLY__ diff --git a/trunk/arch/sparc/include/asm/switch_to_64.h b/trunk/arch/sparc/include/asm/switch_to_64.h index c7de3323819c..cad36f56fa03 100644 --- a/trunk/arch/sparc/include/asm/switch_to_64.h +++ b/trunk/arch/sparc/include/asm/switch_to_64.h @@ -18,7 +18,8 @@ do { \ * and 2 stores in this critical code path. -DaveM */ #define switch_to(prev, next, last) \ -do { save_and_clear_fpu(); \ +do { flush_tlb_pending(); \ + save_and_clear_fpu(); \ /* If you are tempted to conditionalize the following */ \ /* so that ASI is only written if it changes, think again. */ \ __asm__ __volatile__("wr %%g0, %0, %%asi" \ diff --git a/trunk/arch/sparc/include/asm/tlbflush_64.h b/trunk/arch/sparc/include/asm/tlbflush_64.h index f0d6a9700f4c..2ef463494153 100644 --- a/trunk/arch/sparc/include/asm/tlbflush_64.h +++ b/trunk/arch/sparc/include/asm/tlbflush_64.h @@ -11,40 +11,24 @@ struct tlb_batch { struct mm_struct *mm; unsigned long tlb_nr; - unsigned long active; unsigned long vaddrs[TLB_BATCH_NR]; }; extern void flush_tsb_kernel_range(unsigned long start, unsigned long end); extern void flush_tsb_user(struct tlb_batch *tb); -extern void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr); /* TLB flush operations. */ -static inline void flush_tlb_mm(struct mm_struct *mm) -{ -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long vmaddr) -{ -} - -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ -} - -#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE - extern void flush_tlb_pending(void); -extern void arch_enter_lazy_mmu_mode(void); -extern void arch_leave_lazy_mmu_mode(void); -#define arch_flush_lazy_mmu_mode() do {} while (0) + +#define flush_tlb_range(vma,start,end) \ + do { (void)(start); flush_tlb_pending(); } while (0) +#define flush_tlb_page(vma,addr) flush_tlb_pending() +#define flush_tlb_mm(mm) flush_tlb_pending() /* Local cpu only. */ extern void __flush_tlb_all(void); -extern void __flush_tlb_page(unsigned long context, unsigned long vaddr); + extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); #ifndef CONFIG_SMP @@ -54,24 +38,15 @@ do { flush_tsb_kernel_range(start,end); \ __flush_tlb_kernel_range(start,end); \ } while (0) -static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) -{ - __flush_tlb_page(CTX_HWBITS(mm->context), vaddr); -} - #else /* CONFIG_SMP */ extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); -extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr); #define flush_tlb_kernel_range(start, end) \ do { flush_tsb_kernel_range(start,end); \ smp_flush_tlb_kernel_range(start, end); \ } while (0) -#define global_flush_tlb_page(mm, vaddr) \ - smp_flush_tlb_page(mm, vaddr) - #endif /* ! CONFIG_SMP */ #endif /* _SPARC64_TLBFLUSH_H */ diff --git a/trunk/arch/sparc/include/uapi/asm/Kbuild b/trunk/arch/sparc/include/uapi/asm/Kbuild index b5843ee09fb5..ce175aff71b7 100644 --- a/trunk/arch/sparc/include/uapi/asm/Kbuild +++ b/trunk/arch/sparc/include/uapi/asm/Kbuild @@ -44,6 +44,7 @@ header-y += swab.h header-y += termbits.h header-y += termios.h header-y += traps.h +header-y += types.h header-y += uctx.h header-y += unistd.h header-y += utrap.h diff --git a/trunk/arch/sparc/include/uapi/asm/types.h b/trunk/arch/sparc/include/uapi/asm/types.h new file mode 100644 index 000000000000..383d156cde9c --- /dev/null +++ b/trunk/arch/sparc/include/uapi/asm/types.h @@ -0,0 +1,17 @@ +#ifndef _SPARC_TYPES_H +#define _SPARC_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. + */ + +#if defined(__sparc__) + +#include + +#endif /* defined(__sparc__) */ + +#endif /* defined(_SPARC_TYPES_H) */ diff --git a/trunk/arch/sparc/kernel/cpu.c b/trunk/arch/sparc/kernel/cpu.c index 5c5125895db8..a6c94a2bf9d4 100644 --- a/trunk/arch/sparc/kernel/cpu.c +++ b/trunk/arch/sparc/kernel/cpu.c @@ -493,12 +493,6 @@ static void __init sun4v_cpu_probe(void) sparc_pmu_type = "niagara5"; break; - case SUN4V_CHIP_SPARC64X: - sparc_cpu_type = "SPARC64-X"; - sparc_fpu_type = "SPARC64-X integrated FPU"; - sparc_pmu_type = "sparc64-x"; - break; - default: printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", prom_cpu_compatible); diff --git a/trunk/arch/sparc/kernel/head_64.S b/trunk/arch/sparc/kernel/head_64.S index 26b706a1867d..2feb15c35d9e 100644 --- a/trunk/arch/sparc/kernel/head_64.S +++ b/trunk/arch/sparc/kernel/head_64.S @@ -134,8 +134,6 @@ prom_niagara_prefix: .asciz "SUNW,UltraSPARC-T" prom_sparc_prefix: .asciz "SPARC-" -prom_sparc64x_prefix: - .asciz "SPARC64-X" .align 4 prom_root_compatible: .skip 64 @@ -414,7 +412,7 @@ sun4v_chip_type: cmp %g2, 'T' be,pt %xcc, 70f cmp %g2, 'M' - bne,pn %xcc, 49f + bne,pn %xcc, 4f nop 70: ldub [%g1 + 7], %g2 @@ -427,7 +425,7 @@ sun4v_chip_type: cmp %g2, '5' be,pt %xcc, 5f mov SUN4V_CHIP_NIAGARA5, %g4 - ba,pt %xcc, 49f + ba,pt %xcc, 4f nop 91: sethi %hi(prom_cpu_compatible), %g1 @@ -441,25 +439,6 @@ sun4v_chip_type: mov SUN4V_CHIP_NIAGARA2, %g4 4: - /* Athena */ - sethi %hi(prom_cpu_compatible), %g1 - or %g1, %lo(prom_cpu_compatible), %g1 - sethi %hi(prom_sparc64x_prefix), %g7 - or %g7, %lo(prom_sparc64x_prefix), %g7 - mov 9, %g3 -41: ldub [%g7], %g2 - ldub [%g1], %g4 - cmp %g2, %g4 - bne,pn %icc, 49f - add %g7, 1, %g7 - subcc %g3, 1, %g3 - bne,pt %xcc, 41b - add %g1, 1, %g1 - mov SUN4V_CHIP_SPARC64X, %g4 - ba,pt %xcc, 5f - nop - -49: mov SUN4V_CHIP_UNKNOWN, %g4 5: sethi %hi(sun4v_chip_type), %g2 or %g2, %lo(sun4v_chip_type), %g2 diff --git a/trunk/arch/sparc/kernel/leon_pci_grpci2.c b/trunk/arch/sparc/kernel/leon_pci_grpci2.c index 4d1487138d26..fc4320886a3a 100644 --- a/trunk/arch/sparc/kernel/leon_pci_grpci2.c +++ b/trunk/arch/sparc/kernel/leon_pci_grpci2.c @@ -186,8 +186,6 @@ struct grpci2_cap_first { #define CAP9_IOMAP_OFS 0x20 #define CAP9_BARSIZE_OFS 0x24 -#define TGT 256 - struct grpci2_priv { struct leon_pci_info info; /* must be on top of this structure */ struct grpci2_regs *regs; @@ -239,12 +237,8 @@ static int grpci2_cfg_r32(struct grpci2_priv *priv, unsigned int bus, if (where & 0x3) return -EINVAL; - if (bus == 0) { - devfn += (0x8 * 6); /* start at AD16=Device0 */ - } else if (bus == TGT) { - bus = 0; - devfn = 0; /* special case: bridge controller itself */ - } + if (bus == 0 && PCI_SLOT(devfn) != 0) + devfn += (0x8 * 6); /* Select bus */ spin_lock_irqsave(&grpci2_dev_lock, flags); @@ -309,12 +303,8 @@ static int grpci2_cfg_w32(struct grpci2_priv *priv, unsigned int bus, if (where & 0x3) return -EINVAL; - if (bus == 0) { - devfn += (0x8 * 6); /* start at AD16=Device0 */ - } else if (bus == TGT) { - bus = 0; - devfn = 0; /* special case: bridge controller itself */ - } + if (bus == 0 && PCI_SLOT(devfn) != 0) + devfn += (0x8 * 6); /* Select bus */ spin_lock_irqsave(&grpci2_dev_lock, flags); @@ -378,7 +368,7 @@ static int grpci2_read_config(struct pci_bus *bus, unsigned int devfn, unsigned int busno = bus->number; int ret; - if (PCI_SLOT(devfn) > 15 || busno > 255) { + if (PCI_SLOT(devfn) > 15 || (PCI_SLOT(devfn) == 0 && busno == 0)) { *val = ~0; return 0; } @@ -416,7 +406,7 @@ static int grpci2_write_config(struct pci_bus *bus, unsigned int devfn, struct grpci2_priv *priv = grpci2priv; unsigned int busno = bus->number; - if (PCI_SLOT(devfn) > 15 || busno > 255) + if (PCI_SLOT(devfn) > 15 || (PCI_SLOT(devfn) == 0 && busno == 0)) return 0; #ifdef GRPCI2_DEBUG_CFGACCESS @@ -588,15 +578,15 @@ void grpci2_hw_init(struct grpci2_priv *priv) REGSTORE(regs->ahbmst_map[i], priv->pci_area); /* Get the GRPCI2 Host PCI ID */ - grpci2_cfg_r32(priv, TGT, 0, PCI_VENDOR_ID, &priv->pciid); + grpci2_cfg_r32(priv, 0, 0, PCI_VENDOR_ID, &priv->pciid); /* Get address to first (always defined) capability structure */ - grpci2_cfg_r8(priv, TGT, 0, PCI_CAPABILITY_LIST, &capptr); + grpci2_cfg_r8(priv, 0, 0, PCI_CAPABILITY_LIST, &capptr); /* Enable/Disable Byte twisting */ - grpci2_cfg_r32(priv, TGT, 0, capptr+CAP9_IOMAP_OFS, &io_map); + grpci2_cfg_r32(priv, 0, 0, capptr+CAP9_IOMAP_OFS, &io_map); io_map = (io_map & ~0x1) | (priv->bt_enabled ? 1 : 0); - grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_IOMAP_OFS, io_map); + grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_IOMAP_OFS, io_map); /* Setup the Host's PCI Target BARs for other peripherals to access, * and do DMA to the host's memory. The target BARs can be sized and @@ -627,18 +617,17 @@ void grpci2_hw_init(struct grpci2_priv *priv) pciadr = 0; } } - grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_BARSIZE_OFS+i*4, - bar_sz); - grpci2_cfg_w32(priv, TGT, 0, PCI_BASE_ADDRESS_0+i*4, pciadr); - grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_BAR_OFS+i*4, ahbadr); + grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_BARSIZE_OFS+i*4, bar_sz); + grpci2_cfg_w32(priv, 0, 0, PCI_BASE_ADDRESS_0+i*4, pciadr); + grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_BAR_OFS+i*4, ahbadr); printk(KERN_INFO " TGT BAR[%d]: 0x%08x (PCI)-> 0x%08x\n", i, pciadr, ahbadr); } /* set as bus master and enable pci memory responses */ - grpci2_cfg_r32(priv, TGT, 0, PCI_COMMAND, &data); + grpci2_cfg_r32(priv, 0, 0, PCI_COMMAND, &data); data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - grpci2_cfg_w32(priv, TGT, 0, PCI_COMMAND, data); + grpci2_cfg_w32(priv, 0, 0, PCI_COMMAND, data); /* Enable Error respone (CPU-TRAP) on illegal memory access. */ REGSTORE(regs->ctrl, CTRL_ER | CTRL_PE); diff --git a/trunk/arch/sparc/kernel/smp_64.c b/trunk/arch/sparc/kernel/smp_64.c index ca64d2a86ec0..537eb66abd06 100644 --- a/trunk/arch/sparc/kernel/smp_64.c +++ b/trunk/arch/sparc/kernel/smp_64.c @@ -849,7 +849,7 @@ void smp_tsb_sync(struct mm_struct *mm) } extern unsigned long xcall_flush_tlb_mm; -extern unsigned long xcall_flush_tlb_page; +extern unsigned long xcall_flush_tlb_pending; extern unsigned long xcall_flush_tlb_kernel_range; extern unsigned long xcall_fetch_glob_regs; extern unsigned long xcall_fetch_glob_pmu; @@ -1074,56 +1074,23 @@ void smp_flush_tlb_mm(struct mm_struct *mm) put_cpu(); } -struct tlb_pending_info { - unsigned long ctx; - unsigned long nr; - unsigned long *vaddrs; -}; - -static void tlb_pending_func(void *info) -{ - struct tlb_pending_info *t = info; - - __flush_tlb_pending(t->ctx, t->nr, t->vaddrs); -} - void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) { u32 ctx = CTX_HWBITS(mm->context); - struct tlb_pending_info info; int cpu = get_cpu(); - info.ctx = ctx; - info.nr = nr; - info.vaddrs = vaddrs; - if (mm == current->mm && atomic_read(&mm->mm_users) == 1) cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); else - smp_call_function_many(mm_cpumask(mm), tlb_pending_func, - &info, 1); + smp_cross_call_masked(&xcall_flush_tlb_pending, + ctx, nr, (unsigned long) vaddrs, + mm_cpumask(mm)); __flush_tlb_pending(ctx, nr, vaddrs); put_cpu(); } -void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) -{ - unsigned long context = CTX_HWBITS(mm->context); - int cpu = get_cpu(); - - if (mm == current->mm && atomic_read(&mm->mm_users) == 1) - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); - else - smp_cross_call_masked(&xcall_flush_tlb_page, - context, vaddr, 0, - mm_cpumask(mm)); - __flush_tlb_page(context, vaddr); - - put_cpu(); -} - void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end) { start &= PAGE_MASK; diff --git a/trunk/arch/sparc/lib/bitext.c b/trunk/arch/sparc/lib/bitext.c index 8ec4e9c0251a..48d00e72ce15 100644 --- a/trunk/arch/sparc/lib/bitext.c +++ b/trunk/arch/sparc/lib/bitext.c @@ -119,7 +119,11 @@ void bit_map_clear(struct bit_map *t, int offset, int len) void bit_map_init(struct bit_map *t, unsigned long *map, int size) { - bitmap_zero(map, size); + + if ((size & 07) != 0) + BUG(); + memset(map, 0, size>>3); + memset(t, 0, sizeof *t); spin_lock_init(&t->lock); t->map = map; diff --git a/trunk/arch/sparc/mm/iommu.c b/trunk/arch/sparc/mm/iommu.c index 28f96f27c768..0f4f7191fbba 100644 --- a/trunk/arch/sparc/mm/iommu.c +++ b/trunk/arch/sparc/mm/iommu.c @@ -34,7 +34,7 @@ #define IOMMU_RNGE IOMMU_RNGE_256MB #define IOMMU_START 0xF0000000 #define IOMMU_WINSIZE (256*1024*1024U) -#define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 256KB */ +#define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 265KB */ #define IOMMU_ORDER 6 /* 4096 * (1<<6) */ /* srmmu.c */ diff --git a/trunk/arch/sparc/mm/srmmu.c b/trunk/arch/sparc/mm/srmmu.c index 036c2797dece..c38bb72e3e80 100644 --- a/trunk/arch/sparc/mm/srmmu.c +++ b/trunk/arch/sparc/mm/srmmu.c @@ -280,9 +280,7 @@ static void __init srmmu_nocache_init(void) SRMMU_NOCACHE_ALIGN_MAX, 0UL); memset(srmmu_nocache_pool, 0, srmmu_nocache_size); - srmmu_nocache_bitmap = - __alloc_bootmem(BITS_TO_LONGS(bitmap_bits) * sizeof(long), - SMP_CACHE_BYTES, 0UL); + srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL); bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits); srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); diff --git a/trunk/arch/sparc/mm/tlb.c b/trunk/arch/sparc/mm/tlb.c index 83d89bcb44af..ba6ae7ffdc2c 100644 --- a/trunk/arch/sparc/mm/tlb.c +++ b/trunk/arch/sparc/mm/tlb.c @@ -24,17 +24,11 @@ static DEFINE_PER_CPU(struct tlb_batch, tlb_batch); void flush_tlb_pending(void) { struct tlb_batch *tb = &get_cpu_var(tlb_batch); - struct mm_struct *mm = tb->mm; - if (!tb->tlb_nr) - goto out; + if (tb->tlb_nr) { + flush_tsb_user(tb); - flush_tsb_user(tb); - - if (CTX_VALID(mm->context)) { - if (tb->tlb_nr == 1) { - global_flush_tlb_page(mm, tb->vaddrs[0]); - } else { + if (CTX_VALID(tb->mm->context)) { #ifdef CONFIG_SMP smp_flush_tlb_pending(tb->mm, tb->tlb_nr, &tb->vaddrs[0]); @@ -43,30 +37,12 @@ void flush_tlb_pending(void) tb->tlb_nr, &tb->vaddrs[0]); #endif } + tb->tlb_nr = 0; } - tb->tlb_nr = 0; - -out: put_cpu_var(tlb_batch); } -void arch_enter_lazy_mmu_mode(void) -{ - struct tlb_batch *tb = &__get_cpu_var(tlb_batch); - - tb->active = 1; -} - -void arch_leave_lazy_mmu_mode(void) -{ - struct tlb_batch *tb = &__get_cpu_var(tlb_batch); - - if (tb->tlb_nr) - flush_tlb_pending(); - tb->active = 0; -} - static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, bool exec) { @@ -84,12 +60,6 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, nr = 0; } - if (!tb->active) { - global_flush_tlb_page(mm, vaddr); - flush_tsb_user_page(mm, vaddr); - goto out; - } - if (nr == 0) tb->mm = mm; @@ -98,7 +68,6 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, if (nr >= TLB_BATCH_NR) flush_tlb_pending(); -out: put_cpu_var(tlb_batch); } diff --git a/trunk/arch/sparc/mm/tsb.c b/trunk/arch/sparc/mm/tsb.c index 2cc3bce5ee91..428982b9becf 100644 --- a/trunk/arch/sparc/mm/tsb.c +++ b/trunk/arch/sparc/mm/tsb.c @@ -7,10 +7,11 @@ #include #include #include -#include +#include +#include #include +#include #include -#include #include extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; @@ -45,56 +46,28 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end) } } -static void __flush_tsb_one_entry(unsigned long tsb, unsigned long v, - unsigned long hash_shift, - unsigned long nentries) -{ - unsigned long tag, ent, hash; - - v &= ~0x1UL; - hash = tsb_hash(v, hash_shift, nentries); - ent = tsb + (hash * sizeof(struct tsb)); - tag = (v >> 22UL); - - tsb_flush(ent, tag); -} - static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift, unsigned long tsb, unsigned long nentries) { unsigned long i; - for (i = 0; i < tb->tlb_nr; i++) - __flush_tsb_one_entry(tsb, tb->vaddrs[i], hash_shift, nentries); -} - -void flush_tsb_user(struct tlb_batch *tb) -{ - struct mm_struct *mm = tb->mm; - unsigned long nentries, base, flags; + for (i = 0; i < tb->tlb_nr; i++) { + unsigned long v = tb->vaddrs[i]; + unsigned long tag, ent, hash; - spin_lock_irqsave(&mm->context.lock, flags); + v &= ~0x1UL; - base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb; - nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; - if (tlb_type == cheetah_plus || tlb_type == hypervisor) - base = __pa(base); - __flush_tsb_one(tb, PAGE_SHIFT, base, nentries); + hash = tsb_hash(v, hash_shift, nentries); + ent = tsb + (hash * sizeof(struct tsb)); + tag = (v >> 22UL); -#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) - if (mm->context.tsb_block[MM_TSB_HUGE].tsb) { - base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb; - nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; - if (tlb_type == cheetah_plus || tlb_type == hypervisor) - base = __pa(base); - __flush_tsb_one(tb, HPAGE_SHIFT, base, nentries); + tsb_flush(ent, tag); } -#endif - spin_unlock_irqrestore(&mm->context.lock, flags); } -void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) +void flush_tsb_user(struct tlb_batch *tb) { + struct mm_struct *mm = tb->mm; unsigned long nentries, base, flags; spin_lock_irqsave(&mm->context.lock, flags); @@ -103,7 +76,7 @@ void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; if (tlb_type == cheetah_plus || tlb_type == hypervisor) base = __pa(base); - __flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries); + __flush_tsb_one(tb, PAGE_SHIFT, base, nentries); #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) if (mm->context.tsb_block[MM_TSB_HUGE].tsb) { @@ -111,7 +84,7 @@ void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; if (tlb_type == cheetah_plus || tlb_type == hypervisor) base = __pa(base); - __flush_tsb_one_entry(base, vaddr, HPAGE_SHIFT, nentries); + __flush_tsb_one(tb, HPAGE_SHIFT, base, nentries); } #endif spin_unlock_irqrestore(&mm->context.lock, flags); diff --git a/trunk/arch/sparc/mm/ultra.S b/trunk/arch/sparc/mm/ultra.S index 432aa0cb1b38..f8e13d421fcb 100644 --- a/trunk/arch/sparc/mm/ultra.S +++ b/trunk/arch/sparc/mm/ultra.S @@ -52,33 +52,6 @@ __flush_tlb_mm: /* 18 insns */ nop nop - .align 32 - .globl __flush_tlb_page -__flush_tlb_page: /* 22 insns */ - /* %o0 = context, %o1 = vaddr */ - rdpr %pstate, %g7 - andn %g7, PSTATE_IE, %g2 - wrpr %g2, %pstate - mov SECONDARY_CONTEXT, %o4 - ldxa [%o4] ASI_DMMU, %g2 - stxa %o0, [%o4] ASI_DMMU - andcc %o1, 1, %g0 - andn %o1, 1, %o3 - be,pn %icc, 1f - or %o3, 0x10, %o3 - stxa %g0, [%o3] ASI_IMMU_DEMAP -1: stxa %g0, [%o3] ASI_DMMU_DEMAP - membar #Sync - stxa %g2, [%o4] ASI_DMMU - sethi %hi(KERNBASE), %o4 - flush %o4 - retl - wrpr %g7, 0x0, %pstate - nop - nop - nop - nop - .align 32 .globl __flush_tlb_pending __flush_tlb_pending: /* 26 insns */ @@ -230,31 +203,6 @@ __cheetah_flush_tlb_mm: /* 19 insns */ retl wrpr %g7, 0x0, %pstate -__cheetah_flush_tlb_page: /* 22 insns */ - /* %o0 = context, %o1 = vaddr */ - rdpr %pstate, %g7 - andn %g7, PSTATE_IE, %g2 - wrpr %g2, 0x0, %pstate - wrpr %g0, 1, %tl - mov PRIMARY_CONTEXT, %o4 - ldxa [%o4] ASI_DMMU, %g2 - srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3 - sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3 - or %o0, %o3, %o0 /* Preserve nucleus page size fields */ - stxa %o0, [%o4] ASI_DMMU - andcc %o1, 1, %g0 - be,pn %icc, 1f - andn %o1, 1, %o3 - stxa %g0, [%o3] ASI_IMMU_DEMAP -1: stxa %g0, [%o3] ASI_DMMU_DEMAP - membar #Sync - stxa %g2, [%o4] ASI_DMMU - sethi %hi(KERNBASE), %o4 - flush %o4 - wrpr %g0, 0, %tl - retl - wrpr %g7, 0x0, %pstate - __cheetah_flush_tlb_pending: /* 27 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ rdpr %pstate, %g7 @@ -321,20 +269,6 @@ __hypervisor_flush_tlb_mm: /* 10 insns */ retl nop -__hypervisor_flush_tlb_page: /* 11 insns */ - /* %o0 = context, %o1 = vaddr */ - mov %o0, %g2 - mov %o1, %o0 /* ARG0: vaddr + IMMU-bit */ - mov %g2, %o1 /* ARG1: mmu context */ - mov HV_MMU_ALL, %o2 /* ARG2: flags */ - srlx %o0, PAGE_SHIFT, %o0 - sllx %o0, PAGE_SHIFT, %o0 - ta HV_MMU_UNMAP_ADDR_TRAP - brnz,pn %o0, __hypervisor_tlb_tl0_error - mov HV_MMU_UNMAP_ADDR_TRAP, %o1 - retl - nop - __hypervisor_flush_tlb_pending: /* 16 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ sllx %o1, 3, %g1 @@ -405,13 +339,6 @@ cheetah_patch_cachetlbops: call tlb_patch_one mov 19, %o2 - sethi %hi(__flush_tlb_page), %o0 - or %o0, %lo(__flush_tlb_page), %o0 - sethi %hi(__cheetah_flush_tlb_page), %o1 - or %o1, %lo(__cheetah_flush_tlb_page), %o1 - call tlb_patch_one - mov 22, %o2 - sethi %hi(__flush_tlb_pending), %o0 or %o0, %lo(__flush_tlb_pending), %o0 sethi %hi(__cheetah_flush_tlb_pending), %o1 @@ -470,9 +397,10 @@ xcall_flush_tlb_mm: /* 21 insns */ nop nop - .globl xcall_flush_tlb_page -xcall_flush_tlb_page: /* 17 insns */ - /* %g5=context, %g1=vaddr */ + .globl xcall_flush_tlb_pending +xcall_flush_tlb_pending: /* 21 insns */ + /* %g5=context, %g1=nr, %g7=vaddrs[] */ + sllx %g1, 3, %g1 mov PRIMARY_CONTEXT, %g4 ldxa [%g4] ASI_DMMU, %g2 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4 @@ -480,16 +408,20 @@ xcall_flush_tlb_page: /* 17 insns */ or %g5, %g4, %g5 mov PRIMARY_CONTEXT, %g4 stxa %g5, [%g4] ASI_DMMU - andcc %g1, 0x1, %g0 +1: sub %g1, (1 << 3), %g1 + ldx [%g7 + %g1], %g5 + andcc %g5, 0x1, %g0 be,pn %icc, 2f - andn %g1, 0x1, %g5 + + andn %g5, 0x1, %g5 stxa %g0, [%g5] ASI_IMMU_DEMAP 2: stxa %g0, [%g5] ASI_DMMU_DEMAP membar #Sync + brnz,pt %g1, 1b + nop stxa %g2, [%g4] ASI_DMMU retry nop - nop .globl xcall_flush_tlb_kernel_range xcall_flush_tlb_kernel_range: /* 25 insns */ @@ -724,13 +656,15 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */ membar #Sync retry - .globl __hypervisor_xcall_flush_tlb_page -__hypervisor_xcall_flush_tlb_page: /* 17 insns */ - /* %g5=ctx, %g1=vaddr */ + .globl __hypervisor_xcall_flush_tlb_pending +__hypervisor_xcall_flush_tlb_pending: /* 21 insns */ + /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */ + sllx %g1, 3, %g1 mov %o0, %g2 mov %o1, %g3 mov %o2, %g4 - mov %g1, %o0 /* ARG0: virtual address */ +1: sub %g1, (1 << 3), %g1 + ldx [%g7 + %g1], %o0 /* ARG0: virtual address */ mov %g5, %o1 /* ARG1: mmu context */ mov HV_MMU_ALL, %o2 /* ARG2: flags */ srlx %o0, PAGE_SHIFT, %o0 @@ -739,6 +673,8 @@ __hypervisor_xcall_flush_tlb_page: /* 17 insns */ mov HV_MMU_UNMAP_ADDR_TRAP, %g6 brnz,a,pn %o0, __hypervisor_tlb_xcall_error mov %o0, %g5 + brnz,pt %g1, 1b + nop mov %g2, %o0 mov %g3, %o1 mov %g4, %o2 @@ -821,13 +757,6 @@ hypervisor_patch_cachetlbops: call tlb_patch_one mov 10, %o2 - sethi %hi(__flush_tlb_page), %o0 - or %o0, %lo(__flush_tlb_page), %o0 - sethi %hi(__hypervisor_flush_tlb_page), %o1 - or %o1, %lo(__hypervisor_flush_tlb_page), %o1 - call tlb_patch_one - mov 11, %o2 - sethi %hi(__flush_tlb_pending), %o0 or %o0, %lo(__flush_tlb_pending), %o0 sethi %hi(__hypervisor_flush_tlb_pending), %o1 @@ -859,12 +788,12 @@ hypervisor_patch_cachetlbops: call tlb_patch_one mov 21, %o2 - sethi %hi(xcall_flush_tlb_page), %o0 - or %o0, %lo(xcall_flush_tlb_page), %o0 - sethi %hi(__hypervisor_xcall_flush_tlb_page), %o1 - or %o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1 + sethi %hi(xcall_flush_tlb_pending), %o0 + or %o0, %lo(xcall_flush_tlb_pending), %o0 + sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1 + or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1 call tlb_patch_one - mov 17, %o2 + mov 21, %o2 sethi %hi(xcall_flush_tlb_kernel_range), %o0 or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 diff --git a/trunk/arch/tile/Kconfig b/trunk/arch/tile/Kconfig index 25877aebc685..ff496ab1e794 100644 --- a/trunk/arch/tile/Kconfig +++ b/trunk/arch/tile/Kconfig @@ -17,7 +17,7 @@ config TILE select GENERIC_IRQ_SHOW select HAVE_DEBUG_BUGVERBOSE select HAVE_SYSCALL_WRAPPERS if TILEGX - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select SYS_HYPERVISOR select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CLOCKEVENTS diff --git a/trunk/arch/tile/configs/tilegx_defconfig b/trunk/arch/tile/configs/tilegx_defconfig index 47684815e5c8..8c5eff6d6df5 100644 --- a/trunk/arch/tile/configs/tilegx_defconfig +++ b/trunk/arch/tile/configs/tilegx_defconfig @@ -330,6 +330,7 @@ CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID456=m +CONFIG_MULTICORE_RAID456=y CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m CONFIG_DM_DEBUG=y diff --git a/trunk/arch/tile/configs/tilepro_defconfig b/trunk/arch/tile/configs/tilepro_defconfig index dd2b8f0c631f..e7a3dfcbcda7 100644 --- a/trunk/arch/tile/configs/tilepro_defconfig +++ b/trunk/arch/tile/configs/tilepro_defconfig @@ -324,6 +324,7 @@ CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID456=m +CONFIG_MULTICORE_RAID456=y CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m CONFIG_DM_DEBUG=y diff --git a/trunk/arch/tile/include/asm/compat.h b/trunk/arch/tile/include/asm/compat.h index 78f1f2ded86c..001d418a8957 100644 --- a/trunk/arch/tile/include/asm/compat.h +++ b/trunk/arch/tile/include/asm/compat.h @@ -288,9 +288,6 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags, long compat_sys_fallocate(int fd, int mode, u32 offset_lo, u32 offset_hi, u32 len_lo, u32 len_hi); -long compat_sys_llseek(unsigned int fd, unsigned int offset_high, - unsigned int offset_low, loff_t __user * result, - unsigned int origin); /* Assembly trampoline to avoid clobbering r0. */ long _compat_sys_rt_sigreturn(void); diff --git a/trunk/arch/tile/include/asm/irqflags.h b/trunk/arch/tile/include/asm/irqflags.h index c96f9bbb760d..241c0bb60b12 100644 --- a/trunk/arch/tile/include/asm/irqflags.h +++ b/trunk/arch/tile/include/asm/irqflags.h @@ -40,15 +40,7 @@ #include #include -/* - * Set and clear kernel interrupt masks. - * - * NOTE: __insn_mtspr() is a compiler builtin marked as a memory - * clobber. We rely on it being equivalent to a compiler barrier in - * this code since arch_local_irq_save() and friends must act as - * compiler barriers. This compiler semantic is baked into enough - * places that the compiler will maintain it going forward. - */ +/* Set and clear kernel interrupt masks. */ #if CHIP_HAS_SPLIT_INTR_MASK() #if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32 || INT_MEM_ERROR >= 32 # error Fix assumptions about which word various interrupts are in diff --git a/trunk/arch/tile/kernel/compat.c b/trunk/arch/tile/kernel/compat.c index 6ea4cdb3c6a0..7f72401b4f45 100644 --- a/trunk/arch/tile/kernel/compat.c +++ b/trunk/arch/tile/kernel/compat.c @@ -32,65 +32,50 @@ * adapt the usual convention. */ -COMPAT_SYSCALL_DEFINE4(truncate64, char __user *, filename, u32, dummy, - u32, low, u32, high) +long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high) { return sys_truncate(filename, ((loff_t)high << 32) | low); } -COMPAT_SYSCALL_DEFINE4(ftruncate64, unsigned int, fd, u32, dummy, - u32, low, u32, high) +long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high) { return sys_ftruncate(fd, ((loff_t)high << 32) | low); } -COMPAT_SYSCALL_DEFINE6(pread64, unsigned int, fd, char __user *, ubuf, - size_t, count, u32, dummy, u32, low, u32, high) +long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count, + u32 dummy, u32 low, u32 high) { return sys_pread64(fd, ubuf, count, ((loff_t)high << 32) | low); } -COMPAT_SYSCALL_DEFINE6(pwrite64, unsigned int, fd, char __user *, ubuf, - size_t, count, u32, dummy, u32, low, u32, high) +long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count, + u32 dummy, u32 low, u32 high) { return sys_pwrite64(fd, ubuf, count, ((loff_t)high << 32) | low); } -COMPAT_SYSCALL_DEFINE4(lookup_dcookie, u32, low, u32, high, - char __user *, buf, size_t, len) +long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len) { return sys_lookup_dcookie(((loff_t)high << 32) | low, buf, len); } -COMPAT_SYSCALL_DEFINE6(sync_file_range2, int, fd, unsigned int, flags, - u32, offset_lo, u32, offset_hi, - u32, nbytes_lo, u32, nbytes_hi) +long compat_sys_sync_file_range2(int fd, unsigned int flags, + u32 offset_lo, u32 offset_hi, + u32 nbytes_lo, u32 nbytes_hi) { return sys_sync_file_range(fd, ((loff_t)offset_hi << 32) | offset_lo, ((loff_t)nbytes_hi << 32) | nbytes_lo, flags); } -COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode, - u32, offset_lo, u32, offset_hi, - u32, len_lo, u32, len_hi) +long compat_sys_fallocate(int fd, int mode, + u32 offset_lo, u32 offset_hi, + u32 len_lo, u32 len_hi) { return sys_fallocate(fd, mode, ((loff_t)offset_hi << 32) | offset_lo, ((loff_t)len_hi << 32) | len_lo); } -/* - * Avoid bug in generic sys_llseek() that specifies offset_high and - * offset_low as "unsigned long", thus making it possible to pass - * a sign-extended high 32 bits in offset_low. - */ -COMPAT_SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned int, offset_high, - unsigned int, offset_low, loff_t __user *, result, - unsigned int, origin) -{ - return sys_llseek(fd, offset_high, offset_low, result, origin); -} - /* Provide the compat syscall number to call mapping. */ #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), @@ -98,7 +83,6 @@ COMPAT_SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned int, offset_high, /* See comments in sys.c */ #define compat_sys_fadvise64_64 sys32_fadvise64_64 #define compat_sys_readahead sys32_readahead -#define sys_llseek compat_sys_llseek /* Call the assembly trampolines where necessary. */ #define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn diff --git a/trunk/arch/tile/kernel/setup.c b/trunk/arch/tile/kernel/setup.c index 7a5aa1a7864e..d1e15f7b59c6 100644 --- a/trunk/arch/tile/kernel/setup.c +++ b/trunk/arch/tile/kernel/setup.c @@ -1004,8 +1004,15 @@ void __cpuinit setup_cpu(int boot) #ifdef CONFIG_BLK_DEV_INITRD +/* + * Note that the kernel can potentially support other compression + * techniques than gz, though we don't do so by default. If we ever + * decide to do so we can either look for other filename extensions, + * or just allow a file with this name to be compressed with an + * arbitrary compressor (somewhat counterintuitively). + */ static int __initdata set_initramfs_file; -static char __initdata initramfs_file[128] = "initramfs"; +static char __initdata initramfs_file[128] = "initramfs.cpio.gz"; static int __init setup_initramfs_file(char *str) { @@ -1019,9 +1026,9 @@ static int __init setup_initramfs_file(char *str) early_param("initramfs_file", setup_initramfs_file); /* - * We look for a file called "initramfs" in the hvfs. If there is one, we - * allocate some memory for it and it will be unpacked to the initramfs. - * If it's compressed, the initd code will uncompress it first. + * We look for an "initramfs.cpio.gz" file in the hvfs. + * If there is one, we allocate some memory for it and it will be + * unpacked to the initramfs. */ static void __init load_hv_initrd(void) { @@ -1031,16 +1038,10 @@ static void __init load_hv_initrd(void) fd = hv_fs_findfile((HV_VirtAddr) initramfs_file); if (fd == HV_ENOENT) { - if (set_initramfs_file) { + if (set_initramfs_file) pr_warning("No such hvfs initramfs file '%s'\n", initramfs_file); - return; - } else { - /* Try old backwards-compatible name. */ - fd = hv_fs_findfile((HV_VirtAddr)"initramfs.cpio.gz"); - if (fd == HV_ENOENT) - return; - } + return; } BUG_ON(fd < 0); stat = hv_fs_fstat(fd); diff --git a/trunk/arch/um/drivers/chan.h b/trunk/arch/um/drivers/chan.h index c512b0306dd4..78f1b8999964 100644 --- a/trunk/arch/um/drivers/chan.h +++ b/trunk/arch/um/drivers/chan.h @@ -37,7 +37,7 @@ extern int console_write_chan(struct chan *chan, const char *buf, extern int console_open_chan(struct line *line, struct console *co); extern void deactivate_chan(struct chan *chan, int irq); extern void reactivate_chan(struct chan *chan, int irq); -extern void chan_enable_winch(struct chan *chan, struct tty_port *port); +extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty); extern int enable_chan(struct line *line); extern void close_chan(struct line *line); extern int chan_window_size(struct line *line, diff --git a/trunk/arch/um/drivers/chan_kern.c b/trunk/arch/um/drivers/chan_kern.c index 80b47cb71e0a..15c553c239a1 100644 --- a/trunk/arch/um/drivers/chan_kern.c +++ b/trunk/arch/um/drivers/chan_kern.c @@ -122,10 +122,10 @@ static int open_chan(struct list_head *chans) return err; } -void chan_enable_winch(struct chan *chan, struct tty_port *port) +void chan_enable_winch(struct chan *chan, struct tty_struct *tty) { if (chan && chan->primary && chan->ops->winch) - register_winch(chan->fd, port); + register_winch(chan->fd, tty); } static void line_timer_cb(struct work_struct *work) diff --git a/trunk/arch/um/drivers/chan_user.c b/trunk/arch/um/drivers/chan_user.c index 3fd7c3efdb18..9be670ad23b5 100644 --- a/trunk/arch/um/drivers/chan_user.c +++ b/trunk/arch/um/drivers/chan_user.c @@ -216,7 +216,7 @@ static int winch_thread(void *arg) } } -static int winch_tramp(int fd, struct tty_port *port, int *fd_out, +static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out, unsigned long *stack_out) { struct winch_data data; @@ -271,7 +271,7 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out, return err; } -void register_winch(int fd, struct tty_port *port) +void register_winch(int fd, struct tty_struct *tty) { unsigned long stack; int pid, thread, count, thread_fd = -1; @@ -281,17 +281,17 @@ void register_winch(int fd, struct tty_port *port) return; pid = tcgetpgrp(fd); - if (is_skas_winch(pid, fd, port)) { - register_winch_irq(-1, fd, -1, port, 0); + if (is_skas_winch(pid, fd, tty)) { + register_winch_irq(-1, fd, -1, tty, 0); return; } if (pid == -1) { - thread = winch_tramp(fd, port, &thread_fd, &stack); + thread = winch_tramp(fd, tty, &thread_fd, &stack); if (thread < 0) return; - register_winch_irq(thread_fd, fd, thread, port, stack); + register_winch_irq(thread_fd, fd, thread, tty, stack); count = write(thread_fd, &c, sizeof(c)); if (count != sizeof(c)) diff --git a/trunk/arch/um/drivers/chan_user.h b/trunk/arch/um/drivers/chan_user.h index 03f1b565c5f9..dc693298eb8f 100644 --- a/trunk/arch/um/drivers/chan_user.h +++ b/trunk/arch/um/drivers/chan_user.h @@ -38,10 +38,10 @@ extern int generic_window_size(int fd, void *unused, unsigned short *rows_out, unsigned short *cols_out); extern void generic_free(void *data); -struct tty_port; -extern void register_winch(int fd, struct tty_port *port); +struct tty_struct; +extern void register_winch(int fd, struct tty_struct *tty); extern void register_winch_irq(int fd, int tty_fd, int pid, - struct tty_port *port, unsigned long stack); + struct tty_struct *tty, unsigned long stack); #define __channel_help(fn, prefix) \ __uml_help(fn, prefix "[0-9]*=\n" \ diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index be541cf69fd2..f1b38571f94e 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -305,7 +305,7 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty) return ret; if (!line->sigio) { - chan_enable_winch(line->chan_out, port); + chan_enable_winch(line->chan_out, tty); line->sigio = 1; } @@ -315,22 +315,8 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty) return 0; } -static void unregister_winch(struct tty_struct *tty); - -static void line_destruct(struct tty_port *port) -{ - struct tty_struct *tty = tty_port_tty_get(port); - struct line *line = tty->driver_data; - - if (line->sigio) { - unregister_winch(tty); - line->sigio = 0; - } -} - static const struct tty_port_operations line_port_ops = { .activate = line_activate, - .destruct = line_destruct, }; int line_open(struct tty_struct *tty, struct file *filp) @@ -354,6 +340,18 @@ int line_install(struct tty_driver *driver, struct tty_struct *tty, return 0; } +static void unregister_winch(struct tty_struct *tty); + +void line_cleanup(struct tty_struct *tty) +{ + struct line *line = tty->driver_data; + + if (line->sigio) { + unregister_winch(tty); + line->sigio = 0; + } +} + void line_close(struct tty_struct *tty, struct file * filp) { struct line *line = tty->driver_data; @@ -603,7 +601,7 @@ struct winch { int fd; int tty_fd; int pid; - struct tty_port *port; + struct tty_struct *tty; unsigned long stack; struct work_struct work; }; @@ -657,7 +655,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) goto out; } } - tty = tty_port_tty_get(winch->port); + tty = winch->tty; if (tty != NULL) { line = tty->driver_data; if (line != NULL) { @@ -665,7 +663,6 @@ static irqreturn_t winch_interrupt(int irq, void *data) &tty->winsize.ws_col); kill_pgrp(tty->pgrp, SIGWINCH, 1); } - tty_kref_put(tty); } out: if (winch->fd != -1) @@ -673,7 +670,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) return IRQ_HANDLED; } -void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port, +void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, unsigned long stack) { struct winch *winch; @@ -688,7 +685,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port, .fd = fd, .tty_fd = tty_fd, .pid = pid, - .port = port, + .tty = tty, .stack = stack }); if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, @@ -717,18 +714,15 @@ static void unregister_winch(struct tty_struct *tty) { struct list_head *ele, *next; struct winch *winch; - struct tty_struct *wtty; spin_lock(&winch_handler_lock); list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); - wtty = tty_port_tty_get(winch->port); - if (wtty == tty) { + if (winch->tty == tty) { free_winch(winch); break; } - tty_kref_put(wtty); } spin_unlock(&winch_handler_lock); } diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index 39f186252e02..d8926c303629 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -218,7 +218,6 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&lp->lock, flags); len = (*lp->write)(lp->fd, skb, lp); - skb_tx_timestamp(skb); if (len == skb->len) { dev->stats.tx_packets++; @@ -282,7 +281,6 @@ static void uml_net_get_drvinfo(struct net_device *dev, static const struct ethtool_ops uml_net_ethtool_ops = { .get_drvinfo = uml_net_get_drvinfo, .get_link = ethtool_op_get_link, - .get_ts_info = ethtool_op_get_ts_info, }; static void uml_net_user_timer_expire(unsigned long _conn) diff --git a/trunk/arch/um/drivers/ssl.c b/trunk/arch/um/drivers/ssl.c index b8d14fa52059..16fdd0a0f9d6 100644 --- a/trunk/arch/um/drivers/ssl.c +++ b/trunk/arch/um/drivers/ssl.c @@ -105,6 +105,7 @@ static const struct tty_operations ssl_ops = { .throttle = line_throttle, .unthrottle = line_unthrottle, .install = ssl_install, + .cleanup = line_cleanup, .hangup = line_hangup, }; diff --git a/trunk/arch/um/drivers/stdio_console.c b/trunk/arch/um/drivers/stdio_console.c index 7b361f36ca96..827777af3f6d 100644 --- a/trunk/arch/um/drivers/stdio_console.c +++ b/trunk/arch/um/drivers/stdio_console.c @@ -110,6 +110,7 @@ static const struct tty_operations console_ops = { .set_termios = line_set_termios, .throttle = line_throttle, .unthrottle = line_unthrottle, + .cleanup = line_cleanup, .hangup = line_hangup, }; diff --git a/trunk/arch/um/os-Linux/signal.c b/trunk/arch/um/os-Linux/signal.c index 9d9f1b4bf826..b1469fe93295 100644 --- a/trunk/arch/um/os-Linux/signal.c +++ b/trunk/arch/um/os-Linux/signal.c @@ -15,7 +15,7 @@ #include #include "internal.h" -void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = { +void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = { [SIGTRAP] = relay_signal, [SIGFPE] = relay_signal, [SIGILL] = relay_signal, diff --git a/trunk/arch/um/os-Linux/start_up.c b/trunk/arch/um/os-Linux/start_up.c index 337518c5042a..da4b9e9999fd 100644 --- a/trunk/arch/um/os-Linux/start_up.c +++ b/trunk/arch/um/os-Linux/start_up.c @@ -15,8 +15,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/trunk/arch/unicore32/Kconfig b/trunk/arch/unicore32/Kconfig index 2943e3acdf0c..dc50b157fc83 100644 --- a/trunk/arch/unicore32/Kconfig +++ b/trunk/arch/unicore32/Kconfig @@ -9,7 +9,7 @@ config UNICORE32 select GENERIC_ATOMIC64 select HAVE_KERNEL_LZO select HAVE_KERNEL_LZMA - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select ARCH_HAVE_CUSTOM_GPIO_H select GENERIC_FIND_FIRST_BIT select GENERIC_IRQ_PROBE diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 15b5cef4aa38..a4f24f5b1218 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -112,7 +112,7 @@ config X86 select GENERIC_STRNLEN_USER select HAVE_CONTEXT_TRACKING if X86_64 select HAVE_IRQ_TIME_ACCOUNTING - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select MODULES_USE_ELF_REL if X86_32 select MODULES_USE_ELF_RELA if X86_64 select CLONE_BACKWARDS if X86_32 @@ -1549,7 +1549,6 @@ config X86_SMAP config EFI bool "EFI runtime service support" depends on ACPI - select UCS2_STRING ---help--- This enables the kernel to use EFI runtime services that are available (such as the EFI variable services). diff --git a/trunk/arch/x86/boot/compressed/Makefile b/trunk/arch/x86/boot/compressed/Makefile index 5ef205c5f37b..8a84501acb1b 100644 --- a/trunk/arch/x86/boot/compressed/Makefile +++ b/trunk/arch/x86/boot/compressed/Makefile @@ -4,7 +4,7 @@ # create a compressed vmlinux image from the original vmlinux # -targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo +targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo head_$(BITS).o misc.o string.o cmdline.o early_serial_console.o piggy.o KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC @@ -29,6 +29,7 @@ VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ $(obj)/piggy.o $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone +$(obj)/efi_stub_$(BITS).o: KBUILD_CLFAGS += -fshort-wchar -mno-red-zone ifeq ($(CONFIG_EFI_STUB), y) VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o @@ -42,7 +43,7 @@ OBJCOPYFLAGS_vmlinux.bin := -R .comment -S $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) -targets += $(patsubst $(obj)/%,%,$(VMLINUX_OBJS)) vmlinux.bin.all vmlinux.relocs +targets += vmlinux.bin.all vmlinux.relocs CMD_RELOCS = arch/x86/tools/relocs quiet_cmd_relocs = RELOCS $@ diff --git a/trunk/arch/x86/boot/compressed/eboot.c b/trunk/arch/x86/boot/compressed/eboot.c index 35ee62fccf98..c205035a6b96 100644 --- a/trunk/arch/x86/boot/compressed/eboot.c +++ b/trunk/arch/x86/boot/compressed/eboot.c @@ -251,51 +251,6 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) *size = len; } -static efi_status_t setup_efi_vars(struct boot_params *params) -{ - struct setup_data *data; - struct efi_var_bootdata *efidata; - u64 store_size, remaining_size, var_size; - efi_status_t status; - - if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION) - return EFI_UNSUPPORTED; - - data = (struct setup_data *)(unsigned long)params->hdr.setup_data; - - while (data && data->next) - data = (struct setup_data *)(unsigned long)data->next; - - status = efi_call_phys4((void *)sys_table->runtime->query_variable_info, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, &store_size, - &remaining_size, &var_size); - - if (status != EFI_SUCCESS) - return status; - - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, sizeof(*efidata), &efidata); - - if (status != EFI_SUCCESS) - return status; - - efidata->data.type = SETUP_EFI_VARS; - efidata->data.len = sizeof(struct efi_var_bootdata) - - sizeof(struct setup_data); - efidata->data.next = 0; - efidata->store_size = store_size; - efidata->remaining_size = remaining_size; - efidata->max_var_size = var_size; - - if (data) - data->next = (unsigned long)efidata; - else - params->hdr.setup_data = (unsigned long)efidata; - -} - static efi_status_t setup_efi_pci(struct boot_params *params) { efi_pci_io_protocol *pci; @@ -1202,8 +1157,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, setup_graphics(boot_params); - setup_efi_vars(boot_params); - setup_efi_pci(boot_params); status = efi_call_phys3(sys_table->boottime->allocate_pool, diff --git a/trunk/arch/x86/include/asm/bootparam_utils.h b/trunk/arch/x86/include/asm/bootparam_utils.h index 653668d140f9..5b5e9cb774b5 100644 --- a/trunk/arch/x86/include/asm/bootparam_utils.h +++ b/trunk/arch/x86/include/asm/bootparam_utils.h @@ -14,29 +14,13 @@ * analysis of kexec-tools; if other broken bootloaders initialize a * different set of fields we will need to figure out how to disambiguate. * - * Note: efi_info is commonly left uninitialized, but that field has a - * private magic, so it is better to leave it unchanged. */ static void sanitize_boot_params(struct boot_params *boot_params) { - /* - * IMPORTANT NOTE TO BOOTLOADER AUTHORS: do not simply clear - * this field. The purpose of this field is to guarantee - * compliance with the x86 boot spec located in - * Documentation/x86/boot.txt . That spec says that the - * *whole* structure should be cleared, after which only the - * portion defined by struct setup_header (boot_params->hdr) - * should be copied in. - * - * If you're having an issue because the sentinel is set, you - * need to change the whole structure to be cleared, not this - * (or any other) individual field, or you will soon have - * problems again. - */ if (boot_params->sentinel) { - /* fields in boot_params are left uninitialized, clear them */ + /*fields in boot_params are not valid, clear them */ memset(&boot_params->olpc_ofw_header, 0, - (char *)&boot_params->efi_info - + (char *)&boot_params->alt_mem_k - (char *)&boot_params->olpc_ofw_header); memset(&boot_params->kbd_status, 0, (char *)&boot_params->hdr - diff --git a/trunk/arch/x86/include/asm/efi.h b/trunk/arch/x86/include/asm/efi.h index 2fb5d5884e23..60c89f30c727 100644 --- a/trunk/arch/x86/include/asm/efi.h +++ b/trunk/arch/x86/include/asm/efi.h @@ -102,13 +102,6 @@ extern void efi_call_phys_epilog(void); extern void efi_unmap_memmap(void); extern void efi_memory_uc(u64 addr, unsigned long size); -struct efi_var_bootdata { - struct setup_data data; - u64 store_size; - u64 remaining_size; - u64 max_var_size; -}; - #ifdef CONFIG_EFI static inline bool efi_is_native(void) diff --git a/trunk/arch/x86/include/asm/kprobes.h b/trunk/arch/x86/include/asm/kprobes.h index 5a6d2873f80e..d3ddd17405d0 100644 --- a/trunk/arch/x86/include/asm/kprobes.h +++ b/trunk/arch/x86/include/asm/kprobes.h @@ -77,7 +77,6 @@ struct arch_specific_insn { * a post_handler or break_handler). */ int boostable; - bool if_modifier; }; struct arch_optimized_insn { diff --git a/trunk/arch/x86/include/asm/kvm_host.h b/trunk/arch/x86/include/asm/kvm_host.h index 4979778cc7fb..635a74d22409 100644 --- a/trunk/arch/x86/include/asm/kvm_host.h +++ b/trunk/arch/x86/include/asm/kvm_host.h @@ -414,8 +414,8 @@ struct kvm_vcpu_arch { gpa_t time; struct pvclock_vcpu_time_info hv_clock; unsigned int hw_tsc_khz; - struct gfn_to_hva_cache pv_time; - bool pv_time_enabled; + unsigned int time_offset; + struct page *time_page; /* set guest stopped flag in pvclock flags field */ bool pvclock_set_guest_stopped_request; diff --git a/trunk/arch/x86/include/asm/paravirt.h b/trunk/arch/x86/include/asm/paravirt.h index 7361e47db79f..5edd1742cfd0 100644 --- a/trunk/arch/x86/include/asm/paravirt.h +++ b/trunk/arch/x86/include/asm/paravirt.h @@ -703,10 +703,7 @@ static inline void arch_leave_lazy_mmu_mode(void) PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); } -static inline void arch_flush_lazy_mmu_mode(void) -{ - PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush); -} +void arch_flush_lazy_mmu_mode(void); static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, phys_addr_t phys, pgprot_t flags) diff --git a/trunk/arch/x86/include/asm/paravirt_types.h b/trunk/arch/x86/include/asm/paravirt_types.h index b3b0ec1dac86..142236ed83af 100644 --- a/trunk/arch/x86/include/asm/paravirt_types.h +++ b/trunk/arch/x86/include/asm/paravirt_types.h @@ -91,7 +91,6 @@ struct pv_lazy_ops { /* Set deferred update mode, used for batching operations. */ void (*enter)(void); void (*leave)(void); - void (*flush)(void); }; struct pv_time_ops { @@ -680,7 +679,6 @@ void paravirt_end_context_switch(struct task_struct *next); void paravirt_enter_lazy_mmu(void); void paravirt_leave_lazy_mmu(void); -void paravirt_flush_lazy_mmu(void); void _paravirt_nop(void); u32 _paravirt_ident_32(u32); diff --git a/trunk/arch/x86/include/asm/syscall.h b/trunk/arch/x86/include/asm/syscall.h index 2e188d68397c..1ace47b62592 100644 --- a/trunk/arch/x86/include/asm/syscall.h +++ b/trunk/arch/x86/include/asm/syscall.h @@ -29,13 +29,13 @@ extern const unsigned long sys_call_table[]; */ static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return regs->orig_ax; + return regs->orig_ax & __SYSCALL_MASK; } static inline void syscall_rollback(struct task_struct *task, struct pt_regs *regs) { - regs->ax = regs->orig_ax; + regs->ax = regs->orig_ax & __SYSCALL_MASK; } static inline long syscall_get_error(struct task_struct *task, diff --git a/trunk/arch/x86/include/asm/tlb.h b/trunk/arch/x86/include/asm/tlb.h index c7797307fc2b..4fef20773b8f 100644 --- a/trunk/arch/x86/include/asm/tlb.h +++ b/trunk/arch/x86/include/asm/tlb.h @@ -7,7 +7,7 @@ #define tlb_flush(tlb) \ { \ - if (!tlb->fullmm && !tlb->need_flush_all) \ + if (tlb->fullmm == 0) \ flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \ else \ flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL); \ diff --git a/trunk/arch/x86/include/asm/xen/hypercall.h b/trunk/arch/x86/include/asm/xen/hypercall.h index e709884d0ef9..c20d1ce62dc6 100644 --- a/trunk/arch/x86/include/asm/xen/hypercall.h +++ b/trunk/arch/x86/include/asm/xen/hypercall.h @@ -382,14 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str) return _hypercall3(int, console_io, cmd, count, str); } -extern int __must_check xen_physdev_op_compat(int, void *); +extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); static inline int HYPERVISOR_physdev_op(int cmd, void *arg) { int rc = _hypercall2(int, physdev_op, cmd, arg); if (unlikely(rc == -ENOSYS)) - rc = xen_physdev_op_compat(cmd, arg); + rc = HYPERVISOR_physdev_op_compat(cmd, arg); return rc; } diff --git a/trunk/arch/x86/include/uapi/asm/bootparam.h b/trunk/arch/x86/include/uapi/asm/bootparam.h index 08744242b8d2..c15ddaf90710 100644 --- a/trunk/arch/x86/include/uapi/asm/bootparam.h +++ b/trunk/arch/x86/include/uapi/asm/bootparam.h @@ -6,7 +6,6 @@ #define SETUP_E820_EXT 1 #define SETUP_DTB 2 #define SETUP_PCI 3 -#define SETUP_EFI_VARS 4 /* ram_size flags */ #define RAMDISK_IMAGE_START_MASK 0x07FF diff --git a/trunk/arch/x86/include/uapi/asm/msr-index.h b/trunk/arch/x86/include/uapi/asm/msr-index.h index 7a060f4b411f..892ce40a7470 100644 --- a/trunk/arch/x86/include/uapi/asm/msr-index.h +++ b/trunk/arch/x86/include/uapi/asm/msr-index.h @@ -44,7 +44,6 @@ #define SNB_C1_AUTO_UNDEMOTE (1UL << 27) #define SNB_C3_AUTO_UNDEMOTE (1UL << 28) -#define MSR_PLATFORM_INFO 0x000000ce #define MSR_MTRRcap 0x000000fe #define MSR_IA32_BBL_CR_CTL 0x00000119 #define MSR_IA32_BBL_CR_CTL3 0x0000011e diff --git a/trunk/arch/x86/kernel/cpu/mshyperv.c b/trunk/arch/x86/kernel/cpu/mshyperv.c index 8f4be53ea04b..a7d26d83fb70 100644 --- a/trunk/arch/x86/kernel/cpu/mshyperv.c +++ b/trunk/arch/x86/kernel/cpu/mshyperv.c @@ -35,6 +35,13 @@ static bool __init ms_hyperv_platform(void) if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) return false; + /* + * Xen emulates Hyper-V to support enlightened Windows. + * Check to see first if we are on a Xen Hypervisor. + */ + if (xen_cpuid_base()) + return false; + cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); @@ -75,6 +82,12 @@ static void __init ms_hyperv_init_platform(void) if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); +#if IS_ENABLED(CONFIG_HYPERV) + /* + * Setup the IDT for hypervisor callback. + */ + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); +#endif } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { @@ -90,11 +103,6 @@ static irq_handler_t vmbus_isr; void hv_register_vmbus_handler(int irq, irq_handler_t handler) { - /* - * Setup the IDT for hypervisor callback. - */ - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); - vmbus_irq = irq; vmbus_isr = handler; } diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c index cc45deb791b0..529c8931fc02 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c @@ -101,10 +101,6 @@ static struct event_constraint intel_snb_event_constraints[] __read_mostly = FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ - INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */ - INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */ - INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */ - INTEL_UEVENT_CONSTRAINT(0x06a3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */ INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */ INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ @@ -153,14 +149,8 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly = }; static struct extra_reg intel_snb_extra_regs[] __read_mostly = { - INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), - INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), - EVENT_EXTRA_END -}; - -static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { - INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), - INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), + INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0), + INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1), EVENT_EXTRA_END }; @@ -2103,10 +2093,7 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_snb_event_constraints; x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; x86_pmu.pebs_aliases = intel_pebs_aliases_snb; - if (boot_cpu_data.x86_model == 45) - x86_pmu.extra_regs = intel_snbep_extra_regs; - else - x86_pmu.extra_regs = intel_snb_extra_regs; + x86_pmu.extra_regs = intel_snb_extra_regs; /* all extra regs are per-cpu when HT is on */ x86_pmu.er_flags |= ERF_HAS_RSP_1; x86_pmu.er_flags |= ERF_NO_HT_SHARING; @@ -2132,10 +2119,7 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_ivb_event_constraints; x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints; x86_pmu.pebs_aliases = intel_pebs_aliases_snb; - if (boot_cpu_data.x86_model == 62) - x86_pmu.extra_regs = intel_snbep_extra_regs; - else - x86_pmu.extra_regs = intel_snb_extra_regs; + x86_pmu.extra_regs = intel_snb_extra_regs; /* all extra regs are per-cpu when HT is on */ x86_pmu.er_flags |= ERF_HAS_RSP_1; x86_pmu.er_flags |= ERF_NO_HT_SHARING; 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 26830f3af0df..826054a4f2ee 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -314,11 +314,10 @@ int intel_pmu_drain_bts_buffer(void) if (top <= at) return 0; - memset(®s, 0, sizeof(regs)); - ds->bts_index = ds->bts_buffer_base; perf_sample_data_init(&data, 0, event->hw.last_period); + regs.ip = 0; /* * Prepare a generic sample, i.e. fill in the invariant fields. @@ -730,13 +729,3 @@ void intel_ds_init(void) } } } - -void perf_restore_debug_store(void) -{ - struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds); - - if (!x86_pmu.bts && !x86_pmu.pebs) - return; - - wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds); -} diff --git a/trunk/arch/x86/kernel/kprobes/core.c b/trunk/arch/x86/kernel/kprobes/core.c index 7bfe318d3d8a..3f06e6149981 100644 --- a/trunk/arch/x86/kernel/kprobes/core.c +++ b/trunk/arch/x86/kernel/kprobes/core.c @@ -375,9 +375,6 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p) else p->ainsn.boostable = -1; - /* Check whether the instruction modifies Interrupt Flag or not */ - p->ainsn.if_modifier = is_IF_modifier(p->ainsn.insn); - /* Also, displacement change doesn't affect the first byte */ p->opcode = p->ainsn.insn[0]; } @@ -437,7 +434,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, __this_cpu_write(current_kprobe, p); kcb->kprobe_saved_flags = kcb->kprobe_old_flags = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF)); - if (p->ainsn.if_modifier) + if (is_IF_modifier(p->ainsn.insn)) kcb->kprobe_saved_flags &= ~X86_EFLAGS_IF; } diff --git a/trunk/arch/x86/kernel/microcode_core_early.c b/trunk/arch/x86/kernel/microcode_core_early.c index 833d51d6ee06..577db8417d15 100644 --- a/trunk/arch/x86/kernel/microcode_core_early.c +++ b/trunk/arch/x86/kernel/microcode_core_early.c @@ -45,6 +45,9 @@ static int __cpuinit x86_vendor(void) u32 eax = 0x00000000; u32 ebx, ecx = 0, edx; + if (!have_cpuid_p()) + return X86_VENDOR_UNKNOWN; + native_cpuid(&eax, &ebx, &ecx, &edx); if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) @@ -56,45 +59,18 @@ static int __cpuinit x86_vendor(void) return X86_VENDOR_UNKNOWN; } -static int __cpuinit x86_family(void) -{ - u32 eax = 0x00000001; - u32 ebx, ecx = 0, edx; - int x86; - - native_cpuid(&eax, &ebx, &ecx, &edx); - - x86 = (eax >> 8) & 0xf; - if (x86 == 15) - x86 += (eax >> 20) & 0xff; - - return x86; -} - void __init load_ucode_bsp(void) { - int vendor, x86; - - if (!have_cpuid_p()) - return; + int vendor = x86_vendor(); - vendor = x86_vendor(); - x86 = x86_family(); - - if (vendor == X86_VENDOR_INTEL && x86 >= 6) + if (vendor == X86_VENDOR_INTEL) load_ucode_intel_bsp(); } void __cpuinit load_ucode_ap(void) { - int vendor, x86; - - if (!have_cpuid_p()) - return; - - vendor = x86_vendor(); - x86 = x86_family(); + int vendor = x86_vendor(); - if (vendor == X86_VENDOR_INTEL && x86 >= 6) + if (vendor == X86_VENDOR_INTEL) load_ucode_intel_ap(); } diff --git a/trunk/arch/x86/kernel/microcode_intel_early.c b/trunk/arch/x86/kernel/microcode_intel_early.c index d893e8ed8ac9..7890bc838952 100644 --- a/trunk/arch/x86/kernel/microcode_intel_early.c +++ b/trunk/arch/x86/kernel/microcode_intel_early.c @@ -90,13 +90,13 @@ microcode_phys(struct microcode_intel **mc_saved_tmp, struct microcode_intel ***mc_saved; mc_saved = (struct microcode_intel ***) - __pa_nodebug(&mc_saved_data->mc_saved); + __pa_symbol(&mc_saved_data->mc_saved); for (i = 0; i < mc_saved_data->mc_saved_count; i++) { struct microcode_intel *p; p = *(struct microcode_intel **) - __pa_nodebug(mc_saved_data->mc_saved + i); - mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p); + __pa(mc_saved_data->mc_saved + i); + mc_saved_tmp[i] = (struct microcode_intel *)__pa(p); } } #endif @@ -562,7 +562,7 @@ scan_microcode(unsigned long start, unsigned long end, struct cpio_data cd; long offset = 0; #ifdef CONFIG_X86_32 - char *p = (char *)__pa_nodebug(ucode_name); + char *p = (char *)__pa_symbol(ucode_name); #else char *p = ucode_name; #endif @@ -630,8 +630,8 @@ static void __cpuinit print_ucode(struct ucode_cpu_info *uci) if (mc_intel == NULL) return; - delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info); - current_mc_date_p = (int *)__pa_nodebug(¤t_mc_date); + delay_ucode_info_p = (int *)__pa_symbol(&delay_ucode_info); + current_mc_date_p = (int *)__pa_symbol(¤t_mc_date); *delay_ucode_info_p = 1; *current_mc_date_p = mc_intel->hdr.date; @@ -659,8 +659,8 @@ static inline void __cpuinit print_ucode(struct ucode_cpu_info *uci) } #endif -static int __cpuinit apply_microcode_early(struct mc_saved_data *mc_saved_data, - struct ucode_cpu_info *uci) +static int apply_microcode_early(struct mc_saved_data *mc_saved_data, + struct ucode_cpu_info *uci) { struct microcode_intel *mc_intel; unsigned int val[2]; @@ -741,15 +741,15 @@ load_ucode_intel_bsp(void) #ifdef CONFIG_X86_32 struct boot_params *boot_params_p; - boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params); + boot_params_p = (struct boot_params *)__pa_symbol(&boot_params); ramdisk_image = boot_params_p->hdr.ramdisk_image; ramdisk_size = boot_params_p->hdr.ramdisk_size; initrd_start_early = ramdisk_image; initrd_end_early = initrd_start_early + ramdisk_size; _load_ucode_intel_bsp( - (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), - (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), + (struct mc_saved_data *)__pa_symbol(&mc_saved_data), + (unsigned long *)__pa_symbol(&mc_saved_in_initrd), initrd_start_early, initrd_end_early, &uci); #else ramdisk_image = boot_params.hdr.ramdisk_image; @@ -772,10 +772,10 @@ void __cpuinit load_ucode_intel_ap(void) unsigned long *initrd_start_p; mc_saved_in_initrd_p = - (unsigned long *)__pa_nodebug(mc_saved_in_initrd); - mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data); - initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start); - initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p); + (unsigned long *)__pa_symbol(mc_saved_in_initrd); + mc_saved_data_p = (struct mc_saved_data *)__pa_symbol(&mc_saved_data); + initrd_start_p = (unsigned long *)__pa_symbol(&initrd_start); + initrd_start_addr = (unsigned long)__pa_symbol(*initrd_start_p); #else mc_saved_data_p = &mc_saved_data; mc_saved_in_initrd_p = mc_saved_in_initrd; diff --git a/trunk/arch/x86/kernel/paravirt.c b/trunk/arch/x86/kernel/paravirt.c index 8bfb335f74bb..17fff18a1031 100644 --- a/trunk/arch/x86/kernel/paravirt.c +++ b/trunk/arch/x86/kernel/paravirt.c @@ -263,18 +263,6 @@ void paravirt_leave_lazy_mmu(void) leave_lazy(PARAVIRT_LAZY_MMU); } -void paravirt_flush_lazy_mmu(void) -{ - preempt_disable(); - - if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { - arch_leave_lazy_mmu_mode(); - arch_enter_lazy_mmu_mode(); - } - - preempt_enable(); -} - void paravirt_start_context_switch(struct task_struct *prev) { BUG_ON(preemptible()); @@ -304,6 +292,18 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) return this_cpu_read(paravirt_lazy_mode); } +void arch_flush_lazy_mmu_mode(void) +{ + preempt_disable(); + + if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { + arch_leave_lazy_mmu_mode(); + arch_enter_lazy_mmu_mode(); + } + + preempt_enable(); +} + struct pv_info pv_info = { .name = "bare hardware", .paravirt_enabled = 0, @@ -475,7 +475,6 @@ struct pv_mmu_ops pv_mmu_ops = { .lazy_mode = { .enter = paravirt_nop, .leave = paravirt_nop, - .flush = paravirt_nop, }, .set_fixmap = native_set_fixmap, diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index fae9134a2de9..84d32855f65c 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -171,15 +171,9 @@ static struct resource bss_resource = { #ifdef CONFIG_X86_32 /* cpu data as detected by the assembly code in head.S */ -struct cpuinfo_x86 new_cpu_data __cpuinitdata = { - .wp_works_ok = -1, - .fdiv_bug = -1, -}; +struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1}; /* common cpu data for all cpus */ -struct cpuinfo_x86 boot_cpu_data __read_mostly = { - .wp_works_ok = -1, - .fdiv_bug = -1, -}; +struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1}; EXPORT_SYMBOL(boot_cpu_data); unsigned int def_to_bigsmp; @@ -507,14 +501,11 @@ static void __init memblock_x86_reserve_range_setup_data(void) /* * Keep the crash kernel below this limit. On 32 bits earlier kernels * would limit the kernel to the low 512 MiB due to mapping restrictions. - * On 64bit, old kexec-tools need to under 896MiB. */ #ifdef CONFIG_X86_32 -# define CRASH_KERNEL_ADDR_LOW_MAX (512 << 20) -# define CRASH_KERNEL_ADDR_HIGH_MAX (512 << 20) +# define CRASH_KERNEL_ADDR_MAX (512 << 20) #else -# define CRASH_KERNEL_ADDR_LOW_MAX (896UL<<20) -# define CRASH_KERNEL_ADDR_HIGH_MAX MAXMEM +# define CRASH_KERNEL_ADDR_MAX MAXMEM #endif static void __init reserve_crashkernel_low(void) @@ -524,35 +515,19 @@ static void __init reserve_crashkernel_low(void) unsigned long long low_base = 0, low_size = 0; unsigned long total_low_mem; unsigned long long base; - bool auto_set = false; int ret; total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); - /* crashkernel=Y,low */ ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base); - if (ret != 0) { - /* - * two parts from lib/swiotlb.c: - * swiotlb size: user specified with swiotlb= or default. - * swiotlb overflow buffer: now is hardcoded to 32k. - * We round it to 8M for other buffers that - * may need to stay low too. - */ - low_size = swiotlb_size_or_default() + (8UL<<20); - auto_set = true; - } else { - /* passed with crashkernel=0,low ? */ - if (!low_size) - return; - } + if (ret != 0 || low_size <= 0) + return; low_base = memblock_find_in_range(low_size, (1ULL<<32), low_size, alignment); if (!low_base) { - if (!auto_set) - pr_info("crashkernel low reservation failed - No suitable area found.\n"); + pr_info("crashkernel low reservation failed - No suitable area found.\n"); return; } @@ -573,22 +548,14 @@ static void __init reserve_crashkernel(void) const unsigned long long alignment = 16<<20; /* 16M */ unsigned long long total_mem; unsigned long long crash_size, crash_base; - bool high = false; int ret; total_mem = memblock_phys_mem_size(); - /* crashkernel=XM */ ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base); - if (ret != 0 || crash_size <= 0) { - /* crashkernel=X,high */ - ret = parse_crashkernel_high(boot_command_line, total_mem, - &crash_size, &crash_base); - if (ret != 0 || crash_size <= 0) - return; - high = true; - } + if (ret != 0 || crash_size <= 0) + return; /* 0 means: find the address automatically */ if (crash_base <= 0) { @@ -596,9 +563,7 @@ static void __init reserve_crashkernel(void) * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX */ crash_base = memblock_find_in_range(alignment, - high ? CRASH_KERNEL_ADDR_HIGH_MAX : - CRASH_KERNEL_ADDR_LOW_MAX, - crash_size, alignment); + CRASH_KERNEL_ADDR_MAX, crash_size, alignment); if (!crash_base) { pr_info("crashkernel reservation failed - No suitable area found.\n"); diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index 9f190a2a00e9..a6ceaedc396a 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -1365,8 +1365,9 @@ static inline void mwait_play_dead(void) unsigned int eax, ebx, ecx, edx; unsigned int highest_cstate = 0; unsigned int highest_subcstate = 0; - void *mwait_ptr; int i; + void *mwait_ptr; + struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info); if (!this_cpu_has(X86_FEATURE_MWAIT)) return; diff --git a/trunk/arch/x86/kvm/lapic.c b/trunk/arch/x86/kvm/lapic.c index f77df1c5de6e..02b51dd4e4ad 100644 --- a/trunk/arch/x86/kvm/lapic.c +++ b/trunk/arch/x86/kvm/lapic.c @@ -1857,7 +1857,7 @@ int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data) if (!pv_eoi_enabled(vcpu)) return 0; return kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_eoi.data, - addr, sizeof(u8)); + addr); } void kvm_lapic_init(void) diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index e1721324c271..f71500af1f81 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -1406,15 +1406,25 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) unsigned long flags, this_tsc_khz; struct kvm_vcpu_arch *vcpu = &v->arch; struct kvm_arch *ka = &v->kvm->arch; + void *shared_kaddr; s64 kernel_ns, max_kernel_ns; u64 tsc_timestamp, host_tsc; - struct pvclock_vcpu_time_info guest_hv_clock; + struct pvclock_vcpu_time_info *guest_hv_clock; u8 pvclock_flags; bool use_master_clock; kernel_ns = 0; host_tsc = 0; + /* Keep irq disabled to prevent changes to the clock */ + local_irq_save(flags); + this_tsc_khz = __get_cpu_var(cpu_tsc_khz); + if (unlikely(this_tsc_khz == 0)) { + local_irq_restore(flags); + kvm_make_request(KVM_REQ_CLOCK_UPDATE, v); + return 1; + } + /* * If the host uses TSC clock, then passthrough TSC as stable * to the guest. @@ -1426,15 +1436,6 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) kernel_ns = ka->master_kernel_ns; } spin_unlock(&ka->pvclock_gtod_sync_lock); - - /* Keep irq disabled to prevent changes to the clock */ - local_irq_save(flags); - this_tsc_khz = __get_cpu_var(cpu_tsc_khz); - if (unlikely(this_tsc_khz == 0)) { - local_irq_restore(flags); - kvm_make_request(KVM_REQ_CLOCK_UPDATE, v); - return 1; - } if (!use_master_clock) { host_tsc = native_read_tsc(); kernel_ns = get_kernel_ns(); @@ -1462,7 +1463,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) local_irq_restore(flags); - if (!vcpu->pv_time_enabled) + if (!vcpu->time_page) return 0; /* @@ -1524,12 +1525,12 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) */ vcpu->hv_clock.version += 2; - if (unlikely(kvm_read_guest_cached(v->kvm, &vcpu->pv_time, - &guest_hv_clock, sizeof(guest_hv_clock)))) - return 0; + shared_kaddr = kmap_atomic(vcpu->time_page); + + guest_hv_clock = shared_kaddr + vcpu->time_offset; /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */ - pvclock_flags = (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED); + pvclock_flags = (guest_hv_clock->flags & PVCLOCK_GUEST_STOPPED); if (vcpu->pvclock_set_guest_stopped_request) { pvclock_flags |= PVCLOCK_GUEST_STOPPED; @@ -1542,9 +1543,12 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) vcpu->hv_clock.flags = pvclock_flags; - kvm_write_guest_cached(v->kvm, &vcpu->pv_time, - &vcpu->hv_clock, - sizeof(vcpu->hv_clock)); + memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock, + sizeof(vcpu->hv_clock)); + + kunmap_atomic(shared_kaddr); + + mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT); return 0; } @@ -1823,8 +1827,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) return 0; } - if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa, - sizeof(u32))) + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa)) return 1; vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS); @@ -1834,7 +1837,10 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) static void kvmclock_reset(struct kvm_vcpu *vcpu) { - vcpu->arch.pv_time_enabled = false; + if (vcpu->arch.time_page) { + kvm_release_page_dirty(vcpu->arch.time_page); + vcpu->arch.time_page = NULL; + } } static void accumulate_steal_time(struct kvm_vcpu *vcpu) @@ -1941,7 +1947,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) break; case MSR_KVM_SYSTEM_TIME_NEW: case MSR_KVM_SYSTEM_TIME: { - u64 gpa_offset; kvmclock_reset(vcpu); vcpu->arch.time = data; @@ -1951,14 +1956,14 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (!(data & 1)) break; - gpa_offset = data & ~(PAGE_MASK | 1); + /* ...but clean it before doing the actual write */ + vcpu->arch.time_offset = data & ~(PAGE_MASK | 1); - if (kvm_gfn_to_hva_cache_init(vcpu->kvm, - &vcpu->arch.pv_time, data & ~1ULL, - sizeof(struct pvclock_vcpu_time_info))) - vcpu->arch.pv_time_enabled = false; - else - vcpu->arch.pv_time_enabled = true; + vcpu->arch.time_page = + gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT); + + if (is_error_page(vcpu->arch.time_page)) + vcpu->arch.time_page = NULL; break; } @@ -1975,8 +1980,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 1; if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime, - data & KVM_STEAL_VALID_BITS, - sizeof(struct kvm_steal_time))) + data & KVM_STEAL_VALID_BITS)) return 1; vcpu->arch.st.msr_val = data; @@ -2963,7 +2967,7 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, */ static int kvm_set_guest_paused(struct kvm_vcpu *vcpu) { - if (!vcpu->arch.pv_time_enabled) + if (!vcpu->arch.time_page) return -EINVAL; vcpu->arch.pvclock_set_guest_stopped_request = true; kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); @@ -6714,7 +6718,6 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) goto fail_free_wbinvd_dirty_mask; vcpu->arch.ia32_tsc_adjust_msr = 0x0; - vcpu->arch.pv_time_enabled = false; kvm_async_pf_hash_reset(vcpu); kvm_pmu_init(vcpu); diff --git a/trunk/arch/x86/lguest/boot.c b/trunk/arch/x86/lguest/boot.c index 7114c63f047d..1cbd89ca5569 100644 --- a/trunk/arch/x86/lguest/boot.c +++ b/trunk/arch/x86/lguest/boot.c @@ -1334,7 +1334,6 @@ __init void lguest_init(void) pv_mmu_ops.read_cr3 = lguest_read_cr3; pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode; - pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu; pv_mmu_ops.pte_update = lguest_pte_update; pv_mmu_ops.pte_update_defer = lguest_pte_update; diff --git a/trunk/arch/x86/lib/usercopy_64.c b/trunk/arch/x86/lib/usercopy_64.c index 906fea315791..05928aae911e 100644 --- a/trunk/arch/x86/lib/usercopy_64.c +++ b/trunk/arch/x86/lib/usercopy_64.c @@ -74,10 +74,10 @@ copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest) char c; unsigned zero_len; - for (; len; --len, to++) { + for (; len; --len) { if (__get_user_nocheck(c, from++, sizeof(char))) break; - if (__put_user_nocheck(c, to, sizeof(char))) + if (__put_user_nocheck(c, to++, sizeof(char))) break; } diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index 0e883364abb5..2b97525246d4 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -378,12 +378,10 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) if (pgd_none(*pgd_ref)) return -1; - if (pgd_none(*pgd)) { + if (pgd_none(*pgd)) set_pgd(pgd, *pgd_ref); - arch_flush_lazy_mmu_mode(); - } else { + else BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); - } /* * Below here mismatches are bugs because these lower tables diff --git a/trunk/arch/x86/mm/init.c b/trunk/arch/x86/mm/init.c index 59b7fc453277..4903a03ae876 100644 --- a/trunk/arch/x86/mm/init.c +++ b/trunk/arch/x86/mm/init.c @@ -410,8 +410,9 @@ void __init init_mem_mapping(void) /* the ISA range is always mapped regardless of memory holes */ init_memory_mapping(0, ISA_END_ADDRESS); - /* xen has big range in reserved near end of ram, skip it at first.*/ - addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE, PMD_SIZE); + /* xen has big range in reserved near end of ram, skip it at first */ + addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE, + PAGE_SIZE); real_end = addr + PMD_SIZE; /* step_size need to be small so pgt_buf from BRK could cover it */ diff --git a/trunk/arch/x86/mm/pageattr-test.c b/trunk/arch/x86/mm/pageattr-test.c index 0e38951e65eb..b0086567271c 100644 --- a/trunk/arch/x86/mm/pageattr-test.c +++ b/trunk/arch/x86/mm/pageattr-test.c @@ -68,7 +68,7 @@ static int print_split(struct split_state *s) s->gpg++; i += GPS/PAGE_SIZE; } else if (level == PG_LEVEL_2M) { - if ((pte_val(*pte) & _PAGE_PRESENT) && !(pte_val(*pte) & _PAGE_PSE)) { + if (!(pte_val(*pte) & _PAGE_PSE)) { printk(KERN_ERR "%lx level %d but not PSE %Lx\n", addr, level, (u64)pte_val(*pte)); diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index fb4e73ec24d8..091934e1d0d9 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -467,7 +467,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, * We are safe now. Check whether the new pgprot is the same: */ old_pte = *kpte; - old_prot = req_prot = pte_pgprot(old_pte); + old_prot = new_prot = req_prot = pte_pgprot(old_pte); pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); pgprot_val(req_prot) |= pgprot_val(cpa->mask_set); @@ -478,12 +478,12 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL * for the ancient hardware that doesn't support it. */ - if (pgprot_val(req_prot) & _PAGE_PRESENT) - pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL; + if (pgprot_val(new_prot) & _PAGE_PRESENT) + pgprot_val(new_prot) |= _PAGE_PSE | _PAGE_GLOBAL; else - pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); + pgprot_val(new_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); - req_prot = canon_pgprot(req_prot); + new_prot = canon_pgprot(new_prot); /* * old_pte points to the large page base address. So we need @@ -1413,8 +1413,6 @@ void kernel_map_pages(struct page *page, int numpages, int enable) * but that can deadlock->flush only current cpu: */ __flush_tlb_all(); - - arch_flush_lazy_mmu_mode(); } #ifdef CONFIG_HIBERNATION diff --git a/trunk/arch/x86/mm/pat.c b/trunk/arch/x86/mm/pat.c index 657438858e83..2610bd93c896 100644 --- a/trunk/arch/x86/mm/pat.c +++ b/trunk/arch/x86/mm/pat.c @@ -563,13 +563,6 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags) if (base > __pa(high_memory-1)) return 0; - /* - * some areas in the middle of the kernel identity range - * are not mapped, like the PCI space. - */ - if (!page_is_ram(base >> PAGE_SHIFT)) - return 0; - id_sz = (__pa(high_memory-1) <= base + size) ? __pa(high_memory) - base : size; diff --git a/trunk/arch/x86/mm/pgtable.c b/trunk/arch/x86/mm/pgtable.c index 17fda6a8b3c2..193350b51f90 100644 --- a/trunk/arch/x86/mm/pgtable.c +++ b/trunk/arch/x86/mm/pgtable.c @@ -58,13 +58,6 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); - /* - * NOTE! For PAE, any changes to the top page-directory-pointer-table - * entries need a full cr3 reload to flush. - */ -#ifdef CONFIG_X86_PAE - tlb->need_flush_all = 1; -#endif tlb_remove_page(tlb, virt_to_page(pmd)); } diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 305c68b8d538..901177d75ff5 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -171,16 +170,6 @@ void pcibios_fixup_bus(struct pci_bus *b) pcibios_fixup_device_resources(dev); } -void pcibios_add_bus(struct pci_bus *bus) -{ - acpi_pci_add_bus(bus); -} - -void pcibios_remove_bus(struct pci_bus *bus) -{ - acpi_pci_remove_bus(bus); -} - /* * Only use DMI information to set this if nothing was passed * on the kernel command line (which was parsed earlier). diff --git a/trunk/arch/x86/pci/xen.c b/trunk/arch/x86/pci/xen.c index 4a9be6ddf054..94e76620460f 100644 --- a/trunk/arch/x86/pci/xen.c +++ b/trunk/arch/x86/pci/xen.c @@ -177,7 +177,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) goto error; i = 0; list_for_each_entry(msidesc, &dev->msi_list, list) { - irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0, (type == PCI_CAP_ID_MSIX) ? "pcifront-msi-x" : "pcifront-msi", @@ -244,7 +244,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) dev_dbg(&dev->dev, "xen: msi already bound to pirq=%d\n", pirq); } - irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0, (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi", DOMID_SELF); @@ -326,7 +326,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) } ret = xen_bind_pirq_msi_to_irq(dev, msidesc, - map_irq.pirq, + map_irq.pirq, map_irq.index, (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi", domid); diff --git a/trunk/arch/x86/platform/efi/efi.c b/trunk/arch/x86/platform/efi/efi.c index e4a86a677ce1..5f2ecaf3f9d8 100644 --- a/trunk/arch/x86/platform/efi/efi.c +++ b/trunk/arch/x86/platform/efi/efi.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -52,13 +51,6 @@ #define EFI_DEBUG 1 -/* - * There's some additional metadata associated with each - * variable. Intel's reference implementation is 60 bytes - bump that - * to account for potential alignment constraints - */ -#define VAR_METADATA_SIZE 64 - struct efi __read_mostly efi = { .mps = EFI_INVALID_TABLE_ADDR, .acpi = EFI_INVALID_TABLE_ADDR, @@ -77,13 +69,6 @@ struct efi_memory_map memmap; static struct efi efi_phys __initdata; static efi_system_table_t efi_systab __initdata; -static u64 efi_var_store_size; -static u64 efi_var_remaining_size; -static u64 efi_var_max_var_size; -static u64 boot_used_size; -static u64 boot_var_size; -static u64 active_size; - unsigned long x86_efi_facility; /* @@ -113,15 +98,6 @@ static int __init setup_add_efi_memmap(char *arg) } early_param("add_efi_memmap", setup_add_efi_memmap); -static bool efi_no_storage_paranoia; - -static int __init setup_storage_paranoia(char *arg) -{ - efi_no_storage_paranoia = true; - return 0; -} -early_param("efi_no_storage_paranoia", setup_storage_paranoia); - static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) { @@ -186,53 +162,8 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor) { - efi_status_t status; - static bool finished = false; - static u64 var_size; - - status = efi_call_virt3(get_next_variable, - name_size, name, vendor); - - if (status == EFI_NOT_FOUND) { - finished = true; - if (var_size < boot_used_size) { - boot_var_size = boot_used_size - var_size; - active_size += boot_var_size; - } else { - printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n"); - } - } - - if (boot_used_size && !finished) { - unsigned long size; - u32 attr; - efi_status_t s; - void *tmp; - - s = virt_efi_get_variable(name, vendor, &attr, &size, NULL); - - if (s != EFI_BUFFER_TOO_SMALL || !size) - return status; - - tmp = kmalloc(size, GFP_ATOMIC); - - if (!tmp) - return status; - - s = virt_efi_get_variable(name, vendor, &attr, &size, tmp); - - if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) { - var_size += size; - var_size += ucs2_strsize(name, 1024); - active_size += size; - active_size += VAR_METADATA_SIZE; - active_size += ucs2_strsize(name, 1024); - } - - kfree(tmp); - } - - return status; + return efi_call_virt3(get_next_variable, + name_size, name, vendor); } static efi_status_t virt_efi_set_variable(efi_char16_t *name, @@ -241,34 +172,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, unsigned long data_size, void *data) { - efi_status_t status; - u32 orig_attr = 0; - unsigned long orig_size = 0; - - status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size, - NULL); - - if (status != EFI_BUFFER_TOO_SMALL) - orig_size = 0; - - status = efi_call_virt5(set_variable, - name, vendor, attr, - data_size, data); - - if (status == EFI_SUCCESS) { - if (orig_size) { - active_size -= orig_size; - active_size -= ucs2_strsize(name, 1024); - active_size -= VAR_METADATA_SIZE; - } - if (data_size) { - active_size += data_size; - active_size += ucs2_strsize(name, 1024); - active_size += VAR_METADATA_SIZE; - } - } - - return status; + return efi_call_virt5(set_variable, + name, vendor, attr, + data_size, data); } static efi_status_t virt_efi_query_variable_info(u32 attr, @@ -776,9 +682,6 @@ void __init efi_init(void) char vendor[100] = "unknown"; int i = 0; void *tmp; - struct setup_data *data; - struct efi_var_bootdata *efi_var_data; - u64 pa_data; #ifdef CONFIG_X86_32 if (boot_params.efi_info.efi_systab_hi || @@ -796,22 +699,6 @@ void __init efi_init(void) if (efi_systab_init(efi_phys.systab)) return; - pa_data = boot_params.hdr.setup_data; - while (pa_data) { - data = early_ioremap(pa_data, sizeof(*efi_var_data)); - if (data->type == SETUP_EFI_VARS) { - efi_var_data = (struct efi_var_bootdata *)data; - - efi_var_store_size = efi_var_data->store_size; - efi_var_remaining_size = efi_var_data->remaining_size; - efi_var_max_var_size = efi_var_data->max_var_size; - } - pa_data = data->next; - early_iounmap(data, sizeof(*efi_var_data)); - } - - boot_used_size = efi_var_store_size - efi_var_remaining_size; - set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); /* @@ -1112,48 +999,3 @@ u64 efi_mem_attributes(unsigned long phys_addr) } return 0; } - -/* - * Some firmware has serious problems when using more than 50% of the EFI - * variable store, i.e. it triggers bugs that can brick machines. Ensure that - * we never use more than this safe limit. - * - * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable - * store. - */ -efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) -{ - efi_status_t status; - u64 storage_size, remaining_size, max_size; - - status = efi.query_variable_info(attributes, &storage_size, - &remaining_size, &max_size); - if (status != EFI_SUCCESS) - return status; - - if (!max_size && remaining_size > size) - printk_once(KERN_ERR FW_BUG "Broken EFI implementation" - " is returning MaxVariableSize=0\n"); - /* - * Some firmware implementations refuse to boot if there's insufficient - * space in the variable store. We account for that by refusing the - * write if permitting it would reduce the available space to under - * 50%. However, some firmware won't reclaim variable space until - * after the used (not merely the actively used) space drops below - * a threshold. We can approximate that case with the value calculated - * above. If both the firmware and our calculations indicate that the - * available space would drop below 50%, refuse the write. - */ - - if (!storage_size || size > remaining_size || - (max_size && size > max_size)) - return EFI_OUT_OF_RESOURCES; - - if (!efi_no_storage_paranoia && - ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && - (remaining_size - size < storage_size / 2))) - return EFI_OUT_OF_RESOURCES; - - return EFI_SUCCESS; -} -EXPORT_SYMBOL_GPL(efi_query_variable_store); diff --git a/trunk/arch/x86/power/cpu.c b/trunk/arch/x86/power/cpu.c index 3c68768d7a75..120cee1c3f8d 100644 --- a/trunk/arch/x86/power/cpu.c +++ b/trunk/arch/x86/power/cpu.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -229,7 +228,6 @@ static void __restore_processor_state(struct saved_context *ctxt) do_fpu_end(); x86_platform.restore_sched_clock_state(); mtrr_bp_restore(); - perf_restore_debug_store(); } /* Needed by apm.c */ diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index ddbd54a9b845..c8e1c7b95c3b 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -1307,55 +1306,6 @@ static const struct machine_ops xen_machine_ops __initconst = { .emergency_restart = xen_emergency_restart, }; -static void __init xen_boot_params_init_edd(void) -{ -#if IS_ENABLED(CONFIG_EDD) - struct xen_platform_op op; - struct edd_info *edd_info; - u32 *mbr_signature; - unsigned nr; - int ret; - - edd_info = boot_params.eddbuf; - mbr_signature = boot_params.edd_mbr_sig_buffer; - - op.cmd = XENPF_firmware_info; - - op.u.firmware_info.type = XEN_FW_DISK_INFO; - for (nr = 0; nr < EDDMAXNR; nr++) { - struct edd_info *info = edd_info + nr; - - op.u.firmware_info.index = nr; - info->params.length = sizeof(info->params); - set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, - &info->params); - ret = HYPERVISOR_dom0_op(&op); - if (ret) - break; - -#define C(x) info->x = op.u.firmware_info.u.disk_info.x - C(device); - C(version); - C(interface_support); - C(legacy_max_cylinder); - C(legacy_max_head); - C(legacy_sectors_per_track); -#undef C - } - boot_params.eddbuf_entries = nr; - - op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; - for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { - op.u.firmware_info.index = nr; - ret = HYPERVISOR_dom0_op(&op); - if (ret) - break; - mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; - } - boot_params.edd_mbr_sig_buf_entries = nr; -#endif -} - /* * Set up the GDT and segment registers for -fstack-protector. Until * we do this, we have to be careful not to call any stack-protected @@ -1558,8 +1508,6 @@ asmlinkage void __init xen_start_kernel(void) /* Avoid searching for BIOS MP tables */ x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.mpparse.get_smp_config = x86_init_uint_noop; - - xen_boot_params_init_edd(); } #ifdef CONFIG_PCI /* PCI BIOS service won't work from a PV guest. */ @@ -1641,11 +1589,8 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self, switch (action) { case CPU_UP_PREPARE: xen_vcpu_setup(cpu); - if (xen_have_vector_callback) { + if (xen_have_vector_callback) xen_init_lock_cpu(cpu); - if (xen_feature(XENFEAT_hvm_safe_pvclock)) - xen_setup_timer(cpu); - } break; default: break; diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index e006c18d288a..e8e34938c57d 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1467,6 +1467,8 @@ static void __init xen_write_cr3_init(unsigned long cr3) __xen_write_cr3(true, cr3); xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */ + + pv_mmu_ops.write_cr3 = &xen_write_cr3; } #endif @@ -1748,18 +1750,14 @@ static void *m2v(phys_addr_t maddr) } /* Set the page permissions on an identity-mapped pages */ -static void set_page_prot_flags(void *addr, pgprot_t prot, unsigned long flags) +static void set_page_prot(void *addr, pgprot_t prot) { unsigned long pfn = __pa(addr) >> PAGE_SHIFT; pte_t pte = pfn_pte(pfn, prot); - if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, flags)) + if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0)) BUG(); } -static void set_page_prot(void *addr, pgprot_t prot) -{ - return set_page_prot_flags(addr, prot, UVMF_NONE); -} #ifdef CONFIG_X86_32 static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) { @@ -1843,12 +1841,12 @@ static void __init check_pt_base(unsigned long *pt_base, unsigned long *pt_end, unsigned long addr) { if (*pt_base == PFN_DOWN(__pa(addr))) { - set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); + set_page_prot((void *)addr, PAGE_KERNEL); clear_page((void *)addr); (*pt_base)++; } if (*pt_end == PFN_DOWN(__pa(addr))) { - set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); + set_page_prot((void *)addr, PAGE_KERNEL); clear_page((void *)addr); (*pt_end)--; } @@ -2124,7 +2122,6 @@ static void __init xen_post_allocator_init(void) #endif #ifdef CONFIG_X86_64 - pv_mmu_ops.write_cr3 = &xen_write_cr3; SetPagePinned(virt_to_page(level3_user_vsyscall)); #endif xen_mark_init_mm_pinned(); @@ -2200,7 +2197,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { .lazy_mode = { .enter = paravirt_enter_lazy_mmu, .leave = xen_leave_lazy_mmu, - .flush = paravirt_flush_lazy_mmu, }, .set_fixmap = xen_set_fixmap, diff --git a/trunk/arch/x86/xen/smp.c b/trunk/arch/x86/xen/smp.c index 0d466d7c7175..09ea61d2e02f 100644 --- a/trunk/arch/x86/xen/smp.c +++ b/trunk/arch/x86/xen/smp.c @@ -144,13 +144,6 @@ static int xen_smp_intr_init(unsigned int cpu) goto fail; per_cpu(xen_callfuncsingle_irq, cpu) = rc; - /* - * The IRQ worker on PVHVM goes through the native path and uses the - * IPI mechanism. - */ - if (xen_hvm_domain()) - return 0; - callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, cpu, @@ -174,9 +167,6 @@ static int xen_smp_intr_init(unsigned int cpu) if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0) unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); - if (xen_hvm_domain()) - return rc; - if (per_cpu(xen_irq_work, cpu) >= 0) unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); @@ -428,7 +418,7 @@ static int xen_cpu_disable(void) static void xen_cpu_die(unsigned int cpu) { - while (xen_pv_domain() && HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { + while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { current->state = TASK_UNINTERRUPTIBLE; schedule_timeout(HZ/10); } @@ -436,8 +426,7 @@ static void xen_cpu_die(unsigned int cpu) unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); - if (!xen_hvm_domain()) - unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); xen_uninit_lock_cpu(cpu); xen_teardown_timer(cpu); } @@ -668,7 +657,11 @@ static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) static void xen_hvm_cpu_die(unsigned int cpu) { - xen_cpu_die(cpu); + unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); native_cpu_die(cpu); } diff --git a/trunk/arch/x86/xen/spinlock.c b/trunk/arch/x86/xen/spinlock.c index 8b54603ce816..f7a080ef0354 100644 --- a/trunk/arch/x86/xen/spinlock.c +++ b/trunk/arch/x86/xen/spinlock.c @@ -364,16 +364,6 @@ void __cpuinit xen_init_lock_cpu(int cpu) int irq; const char *name; - WARN(per_cpu(lock_kicker_irq, cpu) > 0, "spinlock on CPU%d exists on IRQ%d!\n", - cpu, per_cpu(lock_kicker_irq, cpu)); - - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) - return; - name = kasprintf(GFP_KERNEL, "spinlock%d", cpu); irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR, cpu, @@ -392,26 +382,11 @@ void __cpuinit xen_init_lock_cpu(int cpu) void xen_uninit_lock_cpu(int cpu) { - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) - return; - unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL); - per_cpu(lock_kicker_irq, cpu) = -1; } void __init xen_init_spinlocks(void) { - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) - return; - BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); pv_lock_ops.spin_is_locked = xen_spin_is_locked; diff --git a/trunk/arch/x86/xen/time.c b/trunk/arch/x86/xen/time.c index 3d88bfdf9e1c..0296a9522501 100644 --- a/trunk/arch/x86/xen/time.c +++ b/trunk/arch/x86/xen/time.c @@ -377,7 +377,7 @@ static const struct clock_event_device xen_vcpuop_clockevent = { static const struct clock_event_device *xen_clockevent = &xen_timerop_clockevent; -static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events) = { .irq = -1 }; +static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events); static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) { @@ -401,9 +401,6 @@ void xen_setup_timer(int cpu) struct clock_event_device *evt; int irq; - evt = &per_cpu(xen_clock_events, cpu); - WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu); - printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); name = kasprintf(GFP_KERNEL, "timer%d", cpu); @@ -416,6 +413,7 @@ void xen_setup_timer(int cpu) IRQF_FORCE_RESUME, name, NULL); + evt = &per_cpu(xen_clock_events, cpu); memcpy(evt, xen_clockevent, sizeof(*evt)); evt->cpumask = cpumask_of(cpu); @@ -428,7 +426,6 @@ void xen_teardown_timer(int cpu) BUG_ON(cpu == 0); evt = &per_cpu(xen_clock_events, cpu); unbind_from_irqhandler(evt->irq, NULL); - evt->irq = -1; } void xen_setup_cpu_clockevents(void) @@ -500,11 +497,7 @@ static void xen_hvm_setup_cpu_clockevents(void) { int cpu = smp_processor_id(); xen_setup_runstate_info(cpu); - /* - * xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence - * doing it xen_hvm_cpu_notify (which gets called by smp_init during - * early bootup and also during CPU hotplug events). - */ + xen_setup_timer(cpu); xen_setup_cpu_clockevents(); } diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index b09de49dbec5..35876ffac11d 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -9,7 +9,7 @@ config XTENSA select HAVE_IDE select GENERIC_ATOMIC64 select HAVE_GENERIC_HARDIRQS - select VIRT_TO_BUS + select HAVE_VIRT_TO_BUS select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select MODULES_USE_ELF_RELA diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 7c288358a745..074b758efc42 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -39,7 +39,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap); EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); -EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug); DEFINE_IDA(blk_queue_ida); diff --git a/trunk/block/blk-flush.c b/trunk/block/blk-flush.c index cc2b827a853c..db8f1b507857 100644 --- a/trunk/block/blk-flush.c +++ b/trunk/block/blk-flush.c @@ -444,7 +444,7 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask, * copied from blk_rq_pos(rq). */ if (error_sector) - *error_sector = bio->bi_sector; + *error_sector = bio->bi_sector; if (!bio_flagged(bio, BIO_UPTODATE)) ret = -EIO; diff --git a/trunk/block/blk-sysfs.c b/trunk/block/blk-sysfs.c index 5efc5a647183..6206a934eb8c 100644 --- a/trunk/block/blk-sysfs.c +++ b/trunk/block/blk-sysfs.c @@ -229,8 +229,6 @@ queue_store_##name(struct request_queue *q, const char *page, size_t count) \ unsigned long val; \ ssize_t ret; \ ret = queue_var_store(&val, page, count); \ - if (ret < 0) \ - return ret; \ if (neg) \ val = !val; \ \ diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 20625eed5511..3c001fba80c7 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -1111,8 +1111,7 @@ struct class block_class = { .name = "block", }; -static char *block_devnode(struct device *dev, umode_t *mode, - kuid_t *uid, kgid_t *gid) +static char *block_devnode(struct device *dev, umode_t *mode) { struct gendisk *disk = dev_to_disk(dev); diff --git a/trunk/crypto/algif_hash.c b/trunk/crypto/algif_hash.c index 0262210cad38..ef5356cd280a 100644 --- a/trunk/crypto/algif_hash.c +++ b/trunk/crypto/algif_hash.c @@ -161,8 +161,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock, else if (len < ds) msg->msg_flags |= MSG_TRUNC; - msg->msg_namelen = 0; - lock_sock(sk); if (ctx->more) { ctx->more = 0; diff --git a/trunk/crypto/algif_skcipher.c b/trunk/crypto/algif_skcipher.c index a1c4f0a55583..6a6dfc062d2a 100644 --- a/trunk/crypto/algif_skcipher.c +++ b/trunk/crypto/algif_skcipher.c @@ -432,7 +432,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, long copied = 0; lock_sock(sk); - msg->msg_namelen = 0; for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; iovlen--, iov++) { unsigned long seglen = iov->iov_len; diff --git a/trunk/crypto/gcm.c b/trunk/crypto/gcm.c index 13ccbda34ff9..137ad1ec5438 100644 --- a/trunk/crypto/gcm.c +++ b/trunk/crypto/gcm.c @@ -44,7 +44,6 @@ struct crypto_rfc4543_ctx { struct crypto_rfc4543_req_ctx { u8 auth_tag[16]; - u8 assocbuf[32]; struct scatterlist cipher[1]; struct scatterlist payload[2]; struct scatterlist assoc[2]; @@ -1134,19 +1133,9 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2); assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); - if (req->assoc->length == req->assoclen) { - sg_init_table(assoc, 2); - sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, - req->assoc->offset); - } else { - BUG_ON(req->assoclen > sizeof(rctx->assocbuf)); - - scatterwalk_map_and_copy(rctx->assocbuf, req->assoc, 0, - req->assoclen, 0); - - sg_init_table(assoc, 2); - sg_set_buf(assoc, rctx->assocbuf, req->assoclen); - } + sg_init_table(assoc, 2); + sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, + req->assoc->offset); scatterwalk_crypto_chain(assoc, payload, 0, 2); aead_request_set_tfm(subreq, ctx->child); diff --git a/trunk/drivers/Kconfig b/trunk/drivers/Kconfig index 78a956e286e6..202fa6d051b9 100644 --- a/trunk/drivers/Kconfig +++ b/trunk/drivers/Kconfig @@ -52,8 +52,6 @@ source "drivers/i2c/Kconfig" source "drivers/spi/Kconfig" -source "drivers/ssbi/Kconfig" - source "drivers/hsi/Kconfig" source "drivers/pps/Kconfig" diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index 4865ed24708a..dce39a95fa71 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -114,7 +114,6 @@ obj-y += firmware/ obj-$(CONFIG_CRYPTO) += crypto/ obj-$(CONFIG_SUPERH) += sh/ obj-$(CONFIG_ARCH_SHMOBILE) += sh/ -obj-$(CONFIG_SSBI) += ssbi/ ifndef CONFIG_ARCH_USES_GETTIMEOFFSET obj-y += clocksource/ endif diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 4bf68c8d4797..92ed9692c47e 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -396,7 +396,7 @@ config ACPI_CUSTOM_METHOD config ACPI_BGRT bool "Boottime Graphics Resource Table support" - depends on EFI && X86 + depends on EFI help This driver adds support for exposing the ACPI Boottime Graphics Resource Table, which allows the operating system to obtain diff --git a/trunk/drivers/acpi/acpi_i2c.c b/trunk/drivers/acpi/acpi_i2c.c index a82c7626aa9b..82045e3f5cac 100644 --- a/trunk/drivers/acpi/acpi_i2c.c +++ b/trunk/drivers/acpi/acpi_i2c.c @@ -90,7 +90,7 @@ void acpi_i2c_register_devices(struct i2c_adapter *adapter) acpi_handle handle; acpi_status status; - handle = ACPI_HANDLE(adapter->dev.parent); + handle = ACPI_HANDLE(&adapter->dev); if (!handle) return; diff --git a/trunk/drivers/acpi/apei/cper.c b/trunk/drivers/acpi/apei/cper.c index fefc2ca7cc3e..1e5d8a40101e 100644 --- a/trunk/drivers/acpi/apei/cper.c +++ b/trunk/drivers/acpi/apei/cper.c @@ -405,7 +405,7 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus) return rc; data_len = estatus->data_length; gdata = (struct acpi_hest_generic_data *)(estatus + 1); - while (data_len >= sizeof(*gdata)) { + while (data_len > sizeof(*gdata)) { gedata_len = gdata->error_data_length; if (gedata_len > data_len - sizeof(*gdata)) return -EINVAL; diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 40a84cc6740c..ef6f155469b5 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -36,11 +36,12 @@ int register_acpi_bus_type(struct acpi_bus_type *type) { if (acpi_disabled) return -ENODEV; - if (type && type->match && type->find_device) { + if (type && type->bus && type->find_device) { down_write(&bus_type_sem); list_add_tail(&type->list, &bus_type_list); up_write(&bus_type_sem); - printk(KERN_INFO PREFIX "bus type %s registered\n", type->name); + printk(KERN_INFO PREFIX "bus type %s registered\n", + type->bus->name); return 0; } return -ENODEV; @@ -55,21 +56,24 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type) down_write(&bus_type_sem); list_del_init(&type->list); up_write(&bus_type_sem); - printk(KERN_INFO PREFIX "bus type %s unregistered\n", - type->name); + printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", + type->bus->name); return 0; } return -ENODEV; } EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); -static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) +static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) { struct acpi_bus_type *tmp, *ret = NULL; + if (!type) + return NULL; + down_read(&bus_type_sem); list_for_each_entry(tmp, &bus_type_list, list) { - if (tmp->match(dev)) { + if (tmp->bus == type) { ret = tmp; break; } @@ -78,6 +82,22 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) return ret; } +static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) +{ + struct acpi_bus_type *tmp; + int ret = -ENODEV; + + down_read(&bus_type_sem); + list_for_each_entry(tmp, &bus_type_list, list) { + if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) { + ret = 0; + break; + } + } + up_read(&bus_type_sem); + return ret; +} + static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used, void *addr_p, void **ret_p) { @@ -241,12 +261,29 @@ static int acpi_unbind_one(struct device *dev) static int acpi_platform_notify(struct device *dev) { - struct acpi_bus_type *type = acpi_get_bus_type(dev); + struct acpi_bus_type *type; acpi_handle handle; int ret; ret = acpi_bind_one(dev, NULL); - if (ret && type) { + if (ret && (!dev->bus || !dev->parent)) { + /* bridge devices genernally haven't bus or parent */ + ret = acpi_find_bridge_device(dev, &handle); + if (!ret) { + ret = acpi_bind_one(dev, handle); + if (ret) + goto out; + } + } + + type = acpi_get_bus_type(dev->bus); + if (ret) { + if (!type || !type->find_device) { + DBG("No ACPI bus support for %s\n", dev_name(dev)); + ret = -EINVAL; + goto out; + } + ret = type->find_device(dev, &handle); if (ret) { DBG("Unable to get handle for %s\n", dev_name(dev)); @@ -279,7 +316,7 @@ static int acpi_platform_notify_remove(struct device *dev) { struct acpi_bus_type *type; - type = acpi_get_bus_type(dev); + type = acpi_get_bus_type(dev->bus); if (type && type->cleanup) type->cleanup(dev); diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index ac8688b89705..0ac546d5e53f 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -65,12 +65,44 @@ static struct acpi_scan_handler pci_root_handler = { .detach = acpi_pci_root_remove, }; -/* Lock to protect both acpi_pci_roots lists */ +/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ static DEFINE_MUTEX(acpi_pci_root_lock); static LIST_HEAD(acpi_pci_roots); +static LIST_HEAD(acpi_pci_drivers); static DEFINE_MUTEX(osc_lock); +int acpi_pci_register_driver(struct acpi_pci_driver *driver) +{ + int n = 0; + struct acpi_pci_root *root; + + mutex_lock(&acpi_pci_root_lock); + list_add_tail(&driver->node, &acpi_pci_drivers); + if (driver->add) + list_for_each_entry(root, &acpi_pci_roots, node) { + driver->add(root); + n++; + } + mutex_unlock(&acpi_pci_root_lock); + + return n; +} +EXPORT_SYMBOL(acpi_pci_register_driver); + +void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) +{ + struct acpi_pci_root *root; + + mutex_lock(&acpi_pci_root_lock); + list_del(&driver->node); + if (driver->remove) + list_for_each_entry(root, &acpi_pci_roots, node) + driver->remove(root); + mutex_unlock(&acpi_pci_root_lock); +} +EXPORT_SYMBOL(acpi_pci_unregister_driver); + /** * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge * @handle - the ACPI CA node in question. @@ -381,7 +413,9 @@ static int acpi_pci_root_add(struct acpi_device *device, acpi_status status; int result; struct acpi_pci_root *root; + struct acpi_pci_driver *driver; u32 flags, base_flags; + bool is_osc_granted = false; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) @@ -442,30 +476,6 @@ static int acpi_pci_root_add(struct acpi_device *device, flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; acpi_pci_osc_support(root, flags); - /* - * TBD: Need PCI interface for enumeration/configuration of roots. - */ - - mutex_lock(&acpi_pci_root_lock); - list_add_tail(&root->node, &acpi_pci_roots); - mutex_unlock(&acpi_pci_root_lock); - - /* - * Scan the Root Bridge - * -------------------- - * Must do this prior to any attempt to bind the root device, as the - * PCI namespace does not get created until this call is made (and - * thus the root bridge's pci_dev does not exist). - */ - root->bus = pci_acpi_scan_root(root); - if (!root->bus) { - printk(KERN_ERR PREFIX - "Bus %04x:%02x not present in PCI namespace\n", - root->segment, (unsigned int)root->secondary.start); - result = -ENODEV; - goto out_del_root; - } - /* Indicate support for various _OSC capabilities. */ if (pci_ext_cfg_avail()) flags |= OSC_EXT_PCI_CONFIG_SUPPORT; @@ -484,7 +494,6 @@ static int acpi_pci_root_add(struct acpi_device *device, flags = base_flags; } } - if (!pcie_ports_disabled && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL @@ -505,28 +514,54 @@ static int acpi_pci_root_add(struct acpi_device *device, status = acpi_pci_osc_control_set(device->handle, &flags, OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); if (ACPI_SUCCESS(status)) { + is_osc_granted = true; dev_info(&device->dev, "ACPI _OSC control (0x%02x) granted\n", flags); - if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { - /* - * We have ASPM control, but the FADT indicates - * that it's unsupported. Clear it. - */ - pcie_clear_aspm(root->bus); - } } else { + is_osc_granted = false; dev_info(&device->dev, "ACPI _OSC request failed (%s), " "returned control mask: 0x%02x\n", acpi_format_exception(status), flags); - pr_info("ACPI _OSC control for PCIe not granted, " - "disabling ASPM\n"); - pcie_no_aspm(); } } else { dev_info(&device->dev, - "Unable to request _OSC control " - "(_OSC support mask: 0x%02x)\n", flags); + "Unable to request _OSC control " + "(_OSC support mask: 0x%02x)\n", flags); + } + + /* + * TBD: Need PCI interface for enumeration/configuration of roots. + */ + + mutex_lock(&acpi_pci_root_lock); + list_add_tail(&root->node, &acpi_pci_roots); + mutex_unlock(&acpi_pci_root_lock); + + /* + * Scan the Root Bridge + * -------------------- + * Must do this prior to any attempt to bind the root device, as the + * PCI namespace does not get created until this call is made (and + * thus the root bridge's pci_dev does not exist). + */ + root->bus = pci_acpi_scan_root(root); + if (!root->bus) { + printk(KERN_ERR PREFIX + "Bus %04x:%02x not present in PCI namespace\n", + root->segment, (unsigned int)root->secondary.start); + result = -ENODEV; + goto out_del_root; + } + + /* ASPM setting */ + if (is_osc_granted) { + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) + pcie_clear_aspm(root->bus); + } else { + pr_info("ACPI _OSC control for PCIe not granted, " + "disabling ASPM\n"); + pcie_no_aspm(); } pci_acpi_add_bus_pm_notifier(device, root->bus); @@ -538,6 +573,12 @@ static int acpi_pci_root_add(struct acpi_device *device, pci_assign_unassigned_bus_resources(root->bus); } + mutex_lock(&acpi_pci_root_lock); + list_for_each_entry(driver, &acpi_pci_drivers, node) + if (driver->add) + driver->add(root); + mutex_unlock(&acpi_pci_root_lock); + /* need to after hot-added ioapic is registered */ if (system_state != SYSTEM_BOOTING) pci_enable_bridges(root->bus); @@ -558,9 +599,16 @@ static int acpi_pci_root_add(struct acpi_device *device, static void acpi_pci_root_remove(struct acpi_device *device) { struct acpi_pci_root *root = acpi_driver_data(device); + struct acpi_pci_driver *driver; pci_stop_root_bus(root->bus); + mutex_lock(&acpi_pci_root_lock); + list_for_each_entry_reverse(driver, &acpi_pci_drivers, node) + if (driver->remove) + driver->remove(root); + mutex_unlock(&acpi_pci_root_lock); + device_set_run_wake(root->bus->bridge, false); pci_acpi_remove_bus_pm_notifier(device); @@ -598,7 +646,6 @@ static void handle_root_bridge_insertion(acpi_handle handle) static void handle_root_bridge_removal(struct acpi_device *device) { - acpi_status status; struct acpi_eject_event *ej_event; ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); @@ -614,9 +661,7 @@ static void handle_root_bridge_removal(struct acpi_device *device) ej_event->device = device; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; - status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); - if (ACPI_FAILURE(status)) - kfree(ej_event); + acpi_bus_hot_remove_device(ej_event); } static void _handle_hotplug_event_root(struct work_struct *work) @@ -631,9 +676,8 @@ static void _handle_hotplug_event_root(struct work_struct *work) handle = hp_work->handle; type = hp_work->type; - acpi_scan_lock_acquire(); - root = acpi_pci_find_root(handle); + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); switch (type) { @@ -667,7 +711,6 @@ static void _handle_hotplug_event_root(struct work_struct *work) break; } - acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ kfree(buffer.pointer); } diff --git a/trunk/drivers/acpi/pci_slot.c b/trunk/drivers/acpi/pci_slot.c index 033d1179bdb5..cd1434eb1de8 100644 --- a/trunk/drivers/acpi/pci_slot.c +++ b/trunk/drivers/acpi/pci_slot.c @@ -9,9 +9,6 @@ * Copyright (C) 2007-2008 Hewlett-Packard Development Company, L.P. * Alex Chiang * - * Copyright (C) 2013 Huawei Tech. Co., Ltd. - * Jiang Liu - * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. @@ -31,9 +28,10 @@ #include #include #include -#include #include #include +#include +#include #include static bool debug; @@ -63,12 +61,20 @@ ACPI_MODULE_NAME("pci_slot"); #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ struct acpi_pci_slot { + acpi_handle root_handle; /* handle of the root bridge */ struct pci_slot *pci_slot; /* corresponding pci_slot */ struct list_head list; /* node in the list of slots */ }; +static int acpi_pci_slot_add(struct acpi_pci_root *root); +static void acpi_pci_slot_remove(struct acpi_pci_root *root); + static LIST_HEAD(slot_list); static DEFINE_MUTEX(slot_list_lock); +static struct acpi_pci_driver acpi_pci_slot_driver = { + .add = acpi_pci_slot_add, + .remove = acpi_pci_slot_remove, +}; static int check_slot(acpi_handle handle, unsigned long long *sun) @@ -107,8 +113,21 @@ check_slot(acpi_handle handle, unsigned long long *sun) return device; } +struct callback_args { + acpi_walk_callback user_function; /* only for walk_p2p_bridge */ + struct pci_bus *pci_bus; + acpi_handle root_handle; +}; + /* - * Check whether handle has an associated slot and create PCI slot if it has. + * register_slot + * + * Called once for each SxFy object in the namespace. Don't worry about + * calling pci_create_slot multiple times for the same pci_bus:device, + * since each subsequent call simply bumps the refcount on the pci_slot. + * + * The number of calls to pci_destroy_slot from unregister_slot is + * symmetrical. */ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) @@ -118,22 +137,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) char name[SLOT_NAME_SIZE]; struct acpi_pci_slot *slot; struct pci_slot *pci_slot; - struct pci_bus *pci_bus = context; + struct callback_args *parent_context = context; + struct pci_bus *pci_bus = parent_context->pci_bus; device = check_slot(handle, &sun); if (device < 0) return AE_OK; - /* - * There may be multiple PCI functions associated with the same slot. - * Check whether PCI slot has already been created for this PCI device. - */ - list_for_each_entry(slot, &slot_list, list) { - pci_slot = slot->pci_slot; - if (pci_slot->bus == pci_bus && pci_slot->number == device) - return AE_OK; - } - slot = kmalloc(sizeof(*slot), GFP_KERNEL); if (!slot) { err("%s: cannot allocate memory\n", __func__); @@ -148,8 +158,12 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } + slot->root_handle = parent_context->root_handle; slot->pci_slot = pci_slot; + INIT_LIST_HEAD(&slot->list); + mutex_lock(&slot_list_lock); list_add(&slot->list, &slot_list); + mutex_unlock(&slot_list_lock); get_device(&pci_bus->dev); @@ -159,24 +173,131 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle) +/* + * walk_p2p_bridge - discover and walk p2p bridges + * @handle: points to an acpi_pci_root + * @context: p2p_bridge_context pointer + * + * Note that when we call ourselves recursively, we pass a different + * value of pci_bus in the child_context. + */ +static acpi_status +walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) { - mutex_lock(&slot_list_lock); - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, - register_slot, NULL, bus, NULL); - mutex_unlock(&slot_list_lock); + int device, function; + unsigned long long adr; + acpi_status status; + acpi_handle dummy_handle; + acpi_walk_callback user_function; + + struct pci_dev *dev; + struct pci_bus *pci_bus; + struct callback_args child_context; + struct callback_args *parent_context = context; + + pci_bus = parent_context->pci_bus; + user_function = parent_context->user_function; + + status = acpi_get_handle(handle, "_ADR", &dummy_handle); + if (ACPI_FAILURE(status)) + return AE_OK; + + status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); + if (ACPI_FAILURE(status)) + return AE_OK; + + device = (adr >> 16) & 0xffff; + function = adr & 0xffff; + + dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function)); + if (!dev || !dev->subordinate) + goto out; + + child_context.pci_bus = dev->subordinate; + child_context.user_function = user_function; + child_context.root_handle = parent_context->root_handle; + + dbg("p2p bridge walk, pci_bus = %x\n", dev->subordinate->number); + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + user_function, NULL, &child_context, NULL); + if (ACPI_FAILURE(status)) + goto out; + + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + walk_p2p_bridge, NULL, &child_context, NULL); +out: + pci_dev_put(dev); + return AE_OK; +} + +/* + * walk_root_bridge - generic root bridge walker + * @root: poiner of an acpi_pci_root + * @user_function: user callback for slot objects + * + * Call user_function for all objects underneath this root bridge. + * Walk p2p bridges underneath us and call user_function on those too. + */ +static int +walk_root_bridge(struct acpi_pci_root *root, acpi_walk_callback user_function) +{ + acpi_status status; + acpi_handle handle = root->device->handle; + struct pci_bus *pci_bus = root->bus; + struct callback_args context; + + context.pci_bus = pci_bus; + context.user_function = user_function; + context.root_handle = handle; + + dbg("root bridge walk, pci_bus = %x\n", pci_bus->number); + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + user_function, NULL, &context, NULL); + if (ACPI_FAILURE(status)) + return status; + + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + walk_p2p_bridge, NULL, &context, NULL); + if (ACPI_FAILURE(status)) + err("%s: walk_p2p_bridge failure - %d\n", __func__, status); + + return status; } -void acpi_pci_slot_remove(struct pci_bus *bus) +/* + * acpi_pci_slot_add + * @handle: points to an acpi_pci_root + */ +static int +acpi_pci_slot_add(struct acpi_pci_root *root) +{ + acpi_status status; + + status = walk_root_bridge(root, register_slot); + if (ACPI_FAILURE(status)) + err("%s: register_slot failure - %d\n", __func__, status); + + return status; +} + +/* + * acpi_pci_slot_remove + * @handle: points to an acpi_pci_root + */ +static void +acpi_pci_slot_remove(struct acpi_pci_root *root) { struct acpi_pci_slot *slot, *tmp; + struct pci_bus *pbus; + acpi_handle handle = root->device->handle; mutex_lock(&slot_list_lock); list_for_each_entry_safe(slot, tmp, &slot_list, list) { - if (slot->pci_slot->bus == bus) { + if (slot->root_handle == handle) { list_del(&slot->list); + pbus = slot->pci_slot->bus; pci_destroy_slot(slot->pci_slot); - put_device(&bus->dev); + put_device(&pbus->dev); kfree(slot); } } @@ -211,4 +332,5 @@ static struct dmi_system_id acpi_pci_slot_dmi_table[] __initdata = { void __init acpi_pci_slot_init(void) { dmi_check_system(acpi_pci_slot_dmi_table); + acpi_pci_register_driver(&acpi_pci_slot_driver); } diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 164d49569aeb..eff722278ff5 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -158,7 +158,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) } exit: - kfree(buffer.pointer); + if (buffer.pointer) + kfree(buffer.pointer); return apic_id; } diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index bec717ffd25f..df34bd04ae62 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -559,7 +559,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) return 0; #endif - BUG_ON(pr->id >= nr_cpu_ids); + BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); /* * Buggy BIOS check diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index ee255c60bdac..fc95308e9a11 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -66,8 +66,7 @@ module_param(latency_factor, uint, 0644); static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); -static DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], - acpi_cstate); +static struct acpi_processor_cx *acpi_cstate[CPUIDLE_STATE_MAX]; static int disabled_by_idle_boot_param(void) { @@ -723,7 +722,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); + struct acpi_processor_cx *cx = acpi_cstate[index]; pr = __this_cpu_read(processors); @@ -746,7 +745,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, */ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) { - struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); + struct acpi_processor_cx *cx = acpi_cstate[index]; ACPI_FLUSH_CPU_CACHE(); @@ -776,7 +775,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); + struct acpi_processor_cx *cx = acpi_cstate[index]; pr = __this_cpu_read(processors); @@ -834,7 +833,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); + struct acpi_processor_cx *cx = acpi_cstate[index]; pr = __this_cpu_read(processors); @@ -961,7 +960,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) continue; #endif - per_cpu(acpi_cstate[count], dev->cpu) = cx; + acpi_cstate[count] = cx; count++; if (count == CPUIDLE_STATE_MAX) diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index e854582f29a6..53e7ac9403a7 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -465,7 +465,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) return result; } -int acpi_processor_get_performance_info(struct acpi_processor *pr) +static int acpi_processor_get_performance_info(struct acpi_processor *pr) { int result = 0; acpi_status status = AE_OK; @@ -509,7 +509,7 @@ int acpi_processor_get_performance_info(struct acpi_processor *pr) #endif return result; } -EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info); + int acpi_processor_notify_smm(struct module *calling_module) { acpi_status status; diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index f54d1985e594..5e7e991717d7 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -1790,6 +1790,7 @@ int __init acpi_scan_init(void) acpi_platform_init(); acpi_csrt_init(); acpi_container_init(); + acpi_pci_slot_init(); mutex_lock(&acpi_scan_lock); /* diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index 9c1a435d10e6..6d3a06a629a1 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -193,14 +193,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, { .callback = init_nvs_nosave, - .ident = "Sony Vaio VGN-FW21M", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21M"), - }, - }, - { - .callback = init_nvs_nosave, .ident = "Sony Vaio VPCEB17FX", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), @@ -607,6 +599,7 @@ static void acpi_sleep_suspend_setup(void) status = acpi_get_sleep_type_data(i, &type_a, &type_b); if (ACPI_SUCCESS(status)) { sleep_states[i] = 1; + pr_cont(" S%d", i); } } @@ -749,6 +742,7 @@ static void acpi_sleep_hibernate_setup(void) hibernation_set_ops(old_suspend_ordering ? &acpi_hibernation_ops_old : &acpi_hibernation_ops); sleep_states[ACPI_STATE_S4] = 1; + pr_cont(KERN_CONT " S4"); if (nosigcheck) return; @@ -794,9 +788,6 @@ int __init acpi_sleep_init(void) { acpi_status status; u8 type_a, type_b; - char supported[ACPI_S_STATE_COUNT * 3 + 1]; - char *pos = supported; - int i; if (acpi_disabled) return 0; @@ -804,6 +795,7 @@ int __init acpi_sleep_init(void) acpi_sleep_dmi_check(); sleep_states[ACPI_STATE_S0] = 1; + pr_info(PREFIX "(supports S0"); acpi_sleep_suspend_setup(); acpi_sleep_hibernate_setup(); @@ -811,17 +803,11 @@ int __init acpi_sleep_init(void) status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); if (ACPI_SUCCESS(status)) { sleep_states[ACPI_STATE_S5] = 1; + pr_cont(" S5"); pm_power_off_prepare = acpi_power_off_prepare; pm_power_off = acpi_power_off; } - - supported[0] = 0; - for (i = 0; i < ACPI_S_STATE_COUNT; i++) { - if (sleep_states[i]) - pos += sprintf(pos, " S%d", i); - } - pr_info(PREFIX "(supports%s)\n", supported); - + pr_cont(")\n"); /* * Register the tts_notifier to reboot notifier list so that the _TTS * object can also be evaluated when the system enters S5. diff --git a/trunk/drivers/amba/tegra-ahb.c b/trunk/drivers/amba/tegra-ahb.c index 1f44e56cc65d..093c43554963 100644 --- a/trunk/drivers/amba/tegra-ahb.c +++ b/trunk/drivers/amba/tegra-ahb.c @@ -158,7 +158,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn) EXPORT_SYMBOL(tegra_ahb_enable_smmu); #endif -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int tegra_ahb_suspend(struct device *dev) { int i; diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index a5a3ebcbdd2c..3e751b74615e 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -59,16 +59,15 @@ config ATA_ACPI option libata.noacpi=1 config SATA_ZPODD - bool "SATA Zero Power Optical Disc Drive (ZPODD) support" + bool "SATA Zero Power ODD Support" depends on ATA_ACPI default n help - This option adds support for SATA Zero Power Optical Disc - Drive (ZPODD). It requires both the ODD and the platform - support, and if enabled, will automatically power on/off the - ODD when certain condition is satisfied. This does not impact - end user's experience of the ODD, only power is saved when - the ODD is not in use (i.e. no disc inside). + This option adds support for SATA ZPODD. It requires both + ODD and the platform support, and if enabled, will automatically + power on/off the ODD when certain condition is satisfied. This + does not impact user's experience of the ODD, only power is saved + when ODD is not in use(i.e. no disc inside). If unsure, say N. diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 251e57d38942..a99112cfd8b1 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -281,8 +281,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ - { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */ { PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */ @@ -415,17 +413,17 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* Marvell */ { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9123), + { PCI_DEVICE(0x1b4b, 0x9123), .class = PCI_CLASS_STORAGE_SATA_AHCI, .class_mask = 0xffffff, .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9125), + { PCI_DEVICE(0x1b4b, 0x9125), .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a), + { PCI_DEVICE(0x1b4b, 0x917a), .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192), + { PCI_DEVICE(0x1b4b, 0x9192), .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3), + { PCI_DEVICE(0x1b4b, 0x91a3), .driver_data = board_ahci_yes_fbs }, /* Promise */ diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 2f48123d74c4..d2ba439cfe54 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -150,7 +150,6 @@ enum piix_controller_ids { tolapai_sata, piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ ich8_sata_snb, - ich8_2port_sata_snb, }; struct piix_map_db { @@ -305,7 +304,7 @@ static const struct pci_device_id piix_pci_tbl[] = { /* SATA Controller IDE (Lynx Point) */ { 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, /* SATA Controller IDE (Lynx Point) */ - { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb }, + { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Lynx Point) */ { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Lynx Point-LP) */ @@ -440,7 +439,6 @@ static const struct piix_map_db *piix_map_db_table[] = { [ich8m_apple_sata] = &ich8m_apple_map_db, [tolapai_sata] = &tolapai_map_db, [ich8_sata_snb] = &ich8_map_db, - [ich8_2port_sata_snb] = &ich8_2port_map_db, }; static struct pci_bits piix_enable_bits[] = { @@ -1244,16 +1242,6 @@ static struct ata_port_info piix_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, - - [ich8_2port_sata_snb] = - { - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR - | PIIX_FLAG_PIO16, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, }; #define AHCI_PCI_BAR 5 @@ -1559,10 +1547,6 @@ static bool piix_broken_system_poweroff(struct pci_dev *pdev) static int prefer_ms_hyperv = 1; module_param(prefer_ms_hyperv, int, 0); -MODULE_PARM_DESC(prefer_ms_hyperv, - "Prefer Hyper-V paravirtualization drivers instead of ATA, " - "0 - Use ATA drivers, " - "1 (Default) - Use the paravirtualization drivers."); static void piix_ignore_devices_quirk(struct ata_host *host) { diff --git a/trunk/drivers/ata/libata-acpi.c b/trunk/drivers/ata/libata-acpi.c index 8a52dab412e2..0ea1018280bd 100644 --- a/trunk/drivers/ata/libata-acpi.c +++ b/trunk/drivers/ata/libata-acpi.c @@ -1027,7 +1027,7 @@ static void ata_acpi_register_power_resource(struct ata_device *dev) handle = ata_dev_acpi_handle(dev); if (handle) - acpi_dev_pm_add_dependent(handle, &sdev->sdev_gendev); + acpi_dev_pm_remove_dependent(handle, &sdev->sdev_gendev); } static void ata_acpi_unregister_power_resource(struct ata_device *dev) @@ -1144,8 +1144,13 @@ static int ata_acpi_find_device(struct device *dev, acpi_handle *handle) return -ENODEV; } +static int ata_acpi_find_dummy(struct device *dev, acpi_handle *handle) +{ + return -ENODEV; +} + static struct acpi_bus_type ata_acpi_bus = { - .name = "ATA", + .find_bridge = ata_acpi_find_dummy, .find_device = ata_acpi_find_device, }; diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 63c743baf920..497adea1f0d6 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -2329,7 +2329,7 @@ int ata_dev_configure(struct ata_device *dev) * from SATA Settings page of Identify Device Data Log. */ if (ata_id_has_devslp(dev->id)) { - u8 *sata_setting = ap->sector_buf; + u8 sata_setting[ATA_SECT_SIZE]; int i, j; dev->flags |= ATA_DFLAG_DEVSLP; @@ -2439,9 +2439,6 @@ int ata_dev_configure(struct ata_device *dev) dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, dev->max_sectors); - if (dev->horkage & ATA_HORKAGE_MAX_SEC_LBA48) - dev->max_sectors = ATA_MAX_SECTORS_LBA48; - if (ap->ops->dev_config) ap->ops->dev_config(dev); @@ -4103,7 +4100,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Weird ATAPI devices */ { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, { "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA }, - { "Slimtype DVD A DS8A8SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 }, /* Devices we expect to fail diagnostics */ diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index ff44787e5a45..318b41358187 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -532,8 +532,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) struct scsi_sense_hdr sshdr; scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sshdr); - if (sshdr.sense_key == RECOVERED_ERROR && - sshdr.asc == 0 && sshdr.ascq == 0x1d) + if (sshdr.sense_key == 0 && + sshdr.asc == 0 && sshdr.ascq == 0) cmd_result &= ~SAM_STAT_CHECK_CONDITION; } @@ -618,8 +618,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) struct scsi_sense_hdr sshdr; scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sshdr); - if (sshdr.sense_key == RECOVERED_ERROR && - sshdr.asc == 0 && sshdr.ascq == 0x1d) + if (sshdr.sense_key == 0 && + sshdr.asc == 0 && sshdr.ascq == 0) cmd_result &= ~SAM_STAT_CHECK_CONDITION; } diff --git a/trunk/drivers/ata/pata_pcmcia.c b/trunk/drivers/ata/pata_pcmcia.c index 40254f4df584..958238dda8fc 100644 --- a/trunk/drivers/ata/pata_pcmcia.c +++ b/trunk/drivers/ata/pata_pcmcia.c @@ -387,9 +387,21 @@ static struct pcmcia_driver pcmcia_driver = { .probe = pcmcia_init_one, .remove = pcmcia_remove_one, }; -module_pcmcia_driver(pcmcia_driver); + +static int __init pcmcia_init(void) +{ + return pcmcia_register_driver(&pcmcia_driver); +} + +static void __exit pcmcia_exit(void) +{ + pcmcia_unregister_driver(&pcmcia_driver); +} MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("low-level driver for PCMCIA ATA"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); + +module_init(pcmcia_init); +module_exit(pcmcia_exit); diff --git a/trunk/drivers/ata/pata_samsung_cf.c b/trunk/drivers/ata/pata_samsung_cf.c index 6ef27e98c508..70b0e01372b3 100644 --- a/trunk/drivers/ata/pata_samsung_cf.c +++ b/trunk/drivers/ata/pata_samsung_cf.c @@ -661,7 +661,18 @@ static struct platform_driver pata_s3c_driver = { }, }; -module_platform_driver_probe(pata_s3c_driver, pata_s3c_probe); +static int __init pata_s3c_init(void) +{ + return platform_driver_probe(&pata_s3c_driver, pata_s3c_probe); +} + +static void __exit pata_s3c_exit(void) +{ + platform_driver_unregister(&pata_s3c_driver); +} + +module_init(pata_s3c_init); +module_exit(pata_s3c_exit); MODULE_AUTHOR("Abhilash Kesavan, "); MODULE_DESCRIPTION("low-level driver for Samsung PATA controller"); diff --git a/trunk/drivers/ata/sata_fsl.c b/trunk/drivers/ata/sata_fsl.c index 608f82fed632..124b2c1d9c0b 100644 --- a/trunk/drivers/ata/sata_fsl.c +++ b/trunk/drivers/ata/sata_fsl.c @@ -1511,7 +1511,8 @@ static int sata_fsl_probe(struct platform_device *ofdev) if (hcr_base) iounmap(hcr_base); - kfree(host_priv); + if (host_priv) + kfree(host_priv); return retval; } diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index 8a00dec574d6..519865b53f76 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -898,18 +898,18 @@ static ssize_t bus_uevent_store(struct bus_type *bus, static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); /** - * bus_register - register a driver-core subsystem + * __bus_register - register a driver-core subsystem * @bus: bus to register + * @key: lockdep class key * * Once we have that, we register the bus with the kobject * infrastructure, then register the children subsystems it has: * the devices and drivers that belong to the subsystem. */ -int bus_register(struct bus_type *bus) +int __bus_register(struct bus_type *bus, struct lock_class_key *key) { int retval; struct subsys_private *priv; - struct lock_class_key *key = &bus->lock_key; priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL); if (!priv) @@ -981,7 +981,7 @@ int bus_register(struct bus_type *bus) bus->p = NULL; return retval; } -EXPORT_SYMBOL_GPL(bus_register); +EXPORT_SYMBOL_GPL(__bus_register); /** * bus_unregister - remove a bus from the system diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index f88d9e259a32..56536f4b0f6b 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -283,21 +283,15 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, const char *tmp; const char *name; umode_t mode = 0; - kuid_t uid = GLOBAL_ROOT_UID; - kgid_t gid = GLOBAL_ROOT_GID; add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); - name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); + name = device_get_devnode(dev, &mode, &tmp); if (name) { add_uevent_var(env, "DEVNAME=%s", name); + kfree(tmp); if (mode) add_uevent_var(env, "DEVMODE=%#o", mode & 0777); - if (!uid_eq(uid, GLOBAL_ROOT_UID)) - add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); - if (!gid_eq(gid, GLOBAL_ROOT_GID)) - add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); - kfree(tmp); } } @@ -569,15 +563,8 @@ int device_create_file(struct device *dev, const struct device_attribute *attr) { int error = 0; - - if (dev) { - WARN(((attr->attr.mode & S_IWUGO) && !attr->store), - "Write permission without 'store'\n"); - WARN(((attr->attr.mode & S_IRUGO) && !attr->show), - "Read permission without 'show'\n"); + if (dev) error = sysfs_create_file(&dev->kobj, &attr->attr); - } - return error; } @@ -1287,8 +1274,6 @@ static struct device *next_device(struct klist_iter *i) * device_get_devnode - path of device node file * @dev: device * @mode: returned file access mode - * @uid: returned file owner - * @gid: returned file group * @tmp: possibly allocated string * * Return the relative path of a possible device node. @@ -1297,8 +1282,7 @@ static struct device *next_device(struct klist_iter *i) * freed by the caller. */ const char *device_get_devnode(struct device *dev, - umode_t *mode, kuid_t *uid, kgid_t *gid, - const char **tmp) + umode_t *mode, const char **tmp) { char *s; @@ -1306,7 +1290,7 @@ const char *device_get_devnode(struct device *dev, /* the device type may provide a specific name */ if (dev->type && dev->type->devnode) - *tmp = dev->type->devnode(dev, mode, uid, gid); + *tmp = dev->type->devnode(dev, mode); if (*tmp) return *tmp; diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c index d8c7f3ee6e19..fb10728f6372 100644 --- a/trunk/drivers/base/cpu.c +++ b/trunk/drivers/base/cpu.c @@ -132,17 +132,6 @@ static ssize_t show_crash_notes(struct device *dev, struct device_attribute *att return rc; } static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL); - -static ssize_t show_crash_notes_size(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - ssize_t rc; - - rc = sprintf(buf, "%zu\n", sizeof(note_buf_t)); - return rc; -} -static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL); #endif /* @@ -270,9 +259,6 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) #ifdef CONFIG_KEXEC if (!error) error = device_create_file(&cpu->dev, &dev_attr_crash_notes); - if (!error) - error = device_create_file(&cpu->dev, - &dev_attr_crash_notes_size); #endif return error; } diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c index 35fa36898916..bb5645ea0282 100644 --- a/trunk/drivers/base/dd.c +++ b/trunk/drivers/base/dd.c @@ -380,7 +380,7 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) pm_runtime_barrier(dev); ret = really_probe(dev, drv); - pm_request_idle(dev); + pm_runtime_idle(dev); return ret; } @@ -428,7 +428,7 @@ int device_attach(struct device *dev) } } else { ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); - pm_request_idle(dev); + pm_runtime_idle(dev); } out_unlock: device_unlock(dev); @@ -499,7 +499,7 @@ static void __device_release_driver(struct device *dev) BUS_NOTIFY_UNBIND_DRIVER, dev); - pm_runtime_put(dev); + pm_runtime_put_sync(dev); if (dev->bus && dev->bus->remove) dev->bus->remove(dev); diff --git a/trunk/drivers/base/devtmpfs.c b/trunk/drivers/base/devtmpfs.c index 7413d065906b..01fc5b07f951 100644 --- a/trunk/drivers/base/devtmpfs.c +++ b/trunk/drivers/base/devtmpfs.c @@ -24,7 +24,6 @@ #include #include #include -#include "base.h" static struct task_struct *thread; @@ -42,8 +41,6 @@ static struct req { int err; const char *name; umode_t mode; /* 0 => delete */ - kuid_t uid; - kgid_t gid; struct device *dev; } *requests; @@ -88,9 +85,7 @@ int devtmpfs_create_node(struct device *dev) return 0; req.mode = 0; - req.uid = GLOBAL_ROOT_UID; - req.gid = GLOBAL_ROOT_GID; - req.name = device_get_devnode(dev, &req.mode, &req.uid, &req.gid, &tmp); + req.name = device_get_devnode(dev, &req.mode, &tmp); if (!req.name) return -ENOMEM; @@ -126,7 +121,7 @@ int devtmpfs_delete_node(struct device *dev) if (!thread) return 0; - req.name = device_get_devnode(dev, NULL, NULL, NULL, &tmp); + req.name = device_get_devnode(dev, NULL, &tmp); if (!req.name) return -ENOMEM; @@ -192,8 +187,7 @@ static int create_path(const char *nodepath) return err; } -static int handle_create(const char *nodename, umode_t mode, kuid_t uid, - kgid_t gid, struct device *dev) +static int handle_create(const char *nodename, umode_t mode, struct device *dev) { struct dentry *dentry; struct path path; @@ -207,14 +201,14 @@ static int handle_create(const char *nodename, umode_t mode, kuid_t uid, if (IS_ERR(dentry)) return PTR_ERR(dentry); - err = vfs_mknod(path.dentry->d_inode, dentry, mode, dev->devt); + err = vfs_mknod(path.dentry->d_inode, + dentry, mode, dev->devt); if (!err) { struct iattr newattrs; + /* fixup possibly umasked mode */ newattrs.ia_mode = mode; - newattrs.ia_uid = uid; - newattrs.ia_gid = gid; - newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID; + newattrs.ia_valid = ATTR_MODE; mutex_lock(&dentry->d_inode->i_mutex); notify_change(dentry, &newattrs); mutex_unlock(&dentry->d_inode->i_mutex); @@ -364,11 +358,10 @@ int devtmpfs_mount(const char *mntdir) static DECLARE_COMPLETION(setup_done); -static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, - struct device *dev) +static int handle(const char *name, umode_t mode, struct device *dev) { if (mode) - return handle_create(name, mode, uid, gid, dev); + return handle_create(name, mode, dev); else return handle_remove(name, dev); } @@ -394,8 +387,7 @@ static int devtmpfsd(void *p) spin_unlock(&req_lock); while (req) { struct req *next = req->next; - req->err = handle(req->name, req->mode, - req->uid, req->gid, req->dev); + req->err = handle(req->name, req->mode, req->dev); complete(&req->done); req = next; } diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 9eda84246ffd..c0b8df38402b 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -46,8 +46,8 @@ EXPORT_SYMBOL_GPL(platform_bus); * manipulate any relevant information in the pdev_archdata they can do: * * platform_device_alloc() - * ... manipulate ... - * platform_device_add() + * ... manipulate ... + * platform_device_add() * * And if they don't care they can just call platform_device_register() and * everything will just work out. @@ -326,7 +326,9 @@ int platform_device_add(struct platform_device *pdev) } if (p && insert_resource(p, r)) { - dev_err(&pdev->dev, "failed to claim resource %d\n", i); + printk(KERN_ERR + "%s: failed to claim resource %d\n", + dev_name(&pdev->dev), i); ret = -EBUSY; goto failed; } @@ -553,8 +555,7 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister); /** * platform_driver_probe - register driver for non-hotpluggable device * @drv: platform driver structure - * @probe: the driver probe routine, probably from an __init section, - * must not return -EPROBE_DEFER. + * @probe: the driver probe routine, probably from an __init section * * Use this instead of platform_driver_register() when you know the device * is not hotpluggable and has already been registered, and you want to @@ -565,9 +566,6 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister); * into system-on-chip processors, where the controller devices have been * configured as part of board setup. * - * This is incompatible with deferred probing so probe() must not - * return -EPROBE_DEFER. - * * Returns zero if the driver registered and bound to a device, else returns * a negative error code and with the driver not registered. */ @@ -684,7 +682,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) int rc; /* Some devices have extra OF data and an OF-style MODALIAS */ - rc = of_device_uevent_modalias(dev, env); + rc = of_device_uevent_modalias(dev,env); if (rc != -ENODEV) return rc; @@ -1128,8 +1126,8 @@ static int __init early_platform_driver_probe_id(char *class_str, switch (match_id) { case EARLY_PLATFORM_ID_ERROR: - pr_warn("%s: unable to parse %s parameter\n", - class_str, epdrv->pdrv->driver.name); + pr_warning("%s: unable to parse %s parameter\n", + class_str, epdrv->pdrv->driver.name); /* fall-through */ case EARLY_PLATFORM_ID_UNSET: match = NULL; @@ -1160,8 +1158,8 @@ static int __init early_platform_driver_probe_id(char *class_str, } if (epdrv->pdrv->probe(match)) - pr_warn("%s: unable to probe %s early.\n", - class_str, match->name); + pr_warning("%s: unable to probe %s early.\n", + class_str, match->name); else n++; } diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 15beb500a4e4..2b7f77d3fcb0 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -99,6 +99,7 @@ void device_pm_add(struct device *dev) dev_warn(dev, "parent %s should not be sleeping\n", dev_name(dev->parent)); list_add_tail(&dev->power.entry, &dpm_list); + dev_pm_qos_constraints_init(dev); mutex_unlock(&dpm_list_mtx); } @@ -112,6 +113,7 @@ void device_pm_remove(struct device *dev) dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); complete_all(&dev->power.completion); mutex_lock(&dpm_list_mtx); + dev_pm_qos_constraints_destroy(dev); list_del_init(&dev->power.entry); mutex_unlock(&dpm_list_mtx); device_wakeup_disable(dev); diff --git a/trunk/drivers/base/power/power.h b/trunk/drivers/base/power/power.h index cfc3226ec492..b16686a0a5a2 100644 --- a/trunk/drivers/base/power/power.h +++ b/trunk/drivers/base/power/power.h @@ -4,7 +4,7 @@ static inline void device_pm_init_common(struct device *dev) { if (!dev->power.early_init) { spin_lock_init(&dev->power.lock); - dev->power.qos = NULL; + dev->power.power_state = PMSG_INVALID; dev->power.early_init = true; } } @@ -56,10 +56,14 @@ extern void device_pm_move_last(struct device *); static inline void device_pm_sleep_init(struct device *dev) {} -static inline void device_pm_add(struct device *dev) {} +static inline void device_pm_add(struct device *dev) +{ + dev_pm_qos_constraints_init(dev); +} static inline void device_pm_remove(struct device *dev) { + dev_pm_qos_constraints_destroy(dev); pm_runtime_remove(dev); } diff --git a/trunk/drivers/base/power/qos.c b/trunk/drivers/base/power/qos.c index 71671c42ef45..3d4d1f8aac5c 100644 --- a/trunk/drivers/base/power/qos.c +++ b/trunk/drivers/base/power/qos.c @@ -41,12 +41,10 @@ #include #include #include -#include #include "power.h" static DEFINE_MUTEX(dev_pm_qos_mtx); -static DEFINE_MUTEX(dev_pm_qos_sysfs_mtx); static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); @@ -63,7 +61,7 @@ enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask) struct pm_qos_flags *pqf; s32 val; - if (IS_ERR_OR_NULL(qos)) + if (!qos) return PM_QOS_FLAGS_UNDEFINED; pqf = &qos->flags; @@ -103,8 +101,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_flags); */ s32 __dev_pm_qos_read_value(struct device *dev) { - return IS_ERR_OR_NULL(dev->power.qos) ? - 0 : pm_qos_read_value(&dev->power.qos->latency); + return dev->power.qos ? pm_qos_read_value(&dev->power.qos->latency) : 0; } /** @@ -201,8 +198,20 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) return 0; } -static void __dev_pm_qos_hide_latency_limit(struct device *dev); -static void __dev_pm_qos_hide_flags(struct device *dev); +/** + * dev_pm_qos_constraints_init - Initalize device's PM QoS constraints pointer. + * @dev: target device + * + * Called from the device PM subsystem during device insertion under + * device_pm_lock(). + */ +void dev_pm_qos_constraints_init(struct device *dev) +{ + mutex_lock(&dev_pm_qos_mtx); + dev->power.qos = NULL; + dev->power.power_state = PMSG_ON; + mutex_unlock(&dev_pm_qos_mtx); +} /** * dev_pm_qos_constraints_destroy @@ -217,20 +226,16 @@ void dev_pm_qos_constraints_destroy(struct device *dev) struct pm_qos_constraints *c; struct pm_qos_flags *f; - mutex_lock(&dev_pm_qos_sysfs_mtx); - /* * If the device's PM QoS resume latency limit or PM QoS flags have been * exposed to user space, they have to be hidden at this point. */ - pm_qos_sysfs_remove_latency(dev); - pm_qos_sysfs_remove_flags(dev); + dev_pm_qos_hide_latency_limit(dev); + dev_pm_qos_hide_flags(dev); mutex_lock(&dev_pm_qos_mtx); - __dev_pm_qos_hide_latency_limit(dev); - __dev_pm_qos_hide_flags(dev); - + dev->power.power_state = PMSG_INVALID; qos = dev->power.qos; if (!qos) goto out; @@ -252,7 +257,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) } spin_lock_irq(&dev->power.lock); - dev->power.qos = ERR_PTR(-ENODEV); + dev->power.qos = NULL; spin_unlock_irq(&dev->power.lock); kfree(c->notifiers); @@ -260,8 +265,6 @@ void dev_pm_qos_constraints_destroy(struct device *dev) out: mutex_unlock(&dev_pm_qos_mtx); - - mutex_unlock(&dev_pm_qos_sysfs_mtx); } /** @@ -298,19 +301,32 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, "%s() called for already added request\n", __func__)) return -EINVAL; + req->dev = dev; + mutex_lock(&dev_pm_qos_mtx); - if (IS_ERR(dev->power.qos)) - ret = -ENODEV; - else if (!dev->power.qos) - ret = dev_pm_qos_constraints_allocate(dev); + if (!dev->power.qos) { + if (dev->power.power_state.event == PM_EVENT_INVALID) { + /* The device has been removed from the system. */ + req->dev = NULL; + ret = -ENODEV; + goto out; + } else { + /* + * Allocate the constraints data on the first call to + * add_request, i.e. only if the data is not already + * allocated and if the device has not been removed. + */ + ret = dev_pm_qos_constraints_allocate(dev); + } + } if (!ret) { - req->dev = dev; req->type = type; ret = apply_constraint(req, PM_QOS_ADD_REQ, value); } + out: mutex_unlock(&dev_pm_qos_mtx); return ret; @@ -328,14 +344,7 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 curr_value; int ret = 0; - if (!req) /*guard against callers passing in null */ - return -EINVAL; - - if (WARN(!dev_pm_qos_request_active(req), - "%s() called for unknown object\n", __func__)) - return -EINVAL; - - if (IS_ERR_OR_NULL(req->dev->power.qos)) + if (!req->dev->power.qos) return -ENODEV; switch(req->type) { @@ -377,17 +386,6 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value) { int ret; - mutex_lock(&dev_pm_qos_mtx); - ret = __dev_pm_qos_update_request(req, new_value); - mutex_unlock(&dev_pm_qos_mtx); - return ret; -} -EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); - -static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req) -{ - int ret; - if (!req) /*guard against callers passing in null */ return -EINVAL; @@ -395,13 +393,13 @@ static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req) "%s() called for unknown object\n", __func__)) return -EINVAL; - if (IS_ERR_OR_NULL(req->dev->power.qos)) - return -ENODEV; + mutex_lock(&dev_pm_qos_mtx); + ret = __dev_pm_qos_update_request(req, new_value); + mutex_unlock(&dev_pm_qos_mtx); - ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); - memset(req, 0, sizeof(*req)); return ret; } +EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); /** * dev_pm_qos_remove_request - modifies an existing qos request @@ -420,10 +418,26 @@ static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req) */ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) { - int ret; + int ret = 0; + + if (!req) /*guard against callers passing in null */ + return -EINVAL; + + if (WARN(!dev_pm_qos_request_active(req), + "%s() called for unknown object\n", __func__)) + return -EINVAL; mutex_lock(&dev_pm_qos_mtx); - ret = __dev_pm_qos_remove_request(req); + + if (req->dev->power.qos) { + ret = apply_constraint(req, PM_QOS_REMOVE_REQ, + PM_QOS_DEFAULT_VALUE); + memset(req, 0, sizeof(*req)); + } else { + /* Return if the device has been removed */ + ret = -ENODEV; + } + mutex_unlock(&dev_pm_qos_mtx); return ret; } @@ -448,10 +462,9 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) mutex_lock(&dev_pm_qos_mtx); - if (IS_ERR(dev->power.qos)) - ret = -ENODEV; - else if (!dev->power.qos) - ret = dev_pm_qos_constraints_allocate(dev); + if (!dev->power.qos) + ret = dev->power.power_state.event != PM_EVENT_INVALID ? + dev_pm_qos_constraints_allocate(dev) : -ENODEV; if (!ret) ret = blocking_notifier_chain_register( @@ -480,7 +493,7 @@ int dev_pm_qos_remove_notifier(struct device *dev, mutex_lock(&dev_pm_qos_mtx); /* Silently return if the constraints object is not present. */ - if (!IS_ERR_OR_NULL(dev->power.qos)) + if (dev->power.qos) retval = blocking_notifier_chain_unregister( dev->power.qos->latency.notifiers, notifier); @@ -550,28 +563,16 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); static void __dev_pm_qos_drop_user_request(struct device *dev, enum dev_pm_qos_req_type type) { - struct dev_pm_qos_request *req = NULL; - switch(type) { case DEV_PM_QOS_LATENCY: - req = dev->power.qos->latency_req; + dev_pm_qos_remove_request(dev->power.qos->latency_req); dev->power.qos->latency_req = NULL; break; case DEV_PM_QOS_FLAGS: - req = dev->power.qos->flags_req; + dev_pm_qos_remove_request(dev->power.qos->flags_req); dev->power.qos->flags_req = NULL; break; } - __dev_pm_qos_remove_request(req); - kfree(req); -} - -static void dev_pm_qos_drop_user_request(struct device *dev, - enum dev_pm_qos_req_type type) -{ - mutex_lock(&dev_pm_qos_mtx); - __dev_pm_qos_drop_user_request(dev, type); - mutex_unlock(&dev_pm_qos_mtx); } /** @@ -587,66 +588,36 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (!device_is_registered(dev) || value < 0) return -EINVAL; + if (dev->power.qos && dev->power.qos->latency_req) + return -EEXIST; + req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value); - if (ret < 0) { - kfree(req); + if (ret < 0) return ret; - } - mutex_lock(&dev_pm_qos_sysfs_mtx); - - mutex_lock(&dev_pm_qos_mtx); - - if (IS_ERR_OR_NULL(dev->power.qos)) - ret = -ENODEV; - else if (dev->power.qos->latency_req) - ret = -EEXIST; - - if (ret < 0) { - __dev_pm_qos_remove_request(req); - kfree(req); - mutex_unlock(&dev_pm_qos_mtx); - goto out; - } dev->power.qos->latency_req = req; - - mutex_unlock(&dev_pm_qos_mtx); - ret = pm_qos_sysfs_add_latency(dev); if (ret) - dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); - out: - mutex_unlock(&dev_pm_qos_sysfs_mtx); return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); -static void __dev_pm_qos_hide_latency_limit(struct device *dev) -{ - if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) - __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); -} - /** * dev_pm_qos_hide_latency_limit - Hide PM QoS latency limit from user space. * @dev: Device whose PM QoS latency limit is to be hidden from user space. */ void dev_pm_qos_hide_latency_limit(struct device *dev) { - mutex_lock(&dev_pm_qos_sysfs_mtx); - - pm_qos_sysfs_remove_latency(dev); - - mutex_lock(&dev_pm_qos_mtx); - __dev_pm_qos_hide_latency_limit(dev); - mutex_unlock(&dev_pm_qos_mtx); - - mutex_unlock(&dev_pm_qos_sysfs_mtx); + if (dev->power.qos && dev->power.qos->latency_req) { + pm_qos_sysfs_remove_latency(dev); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + } } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); @@ -663,70 +634,41 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) if (!device_is_registered(dev)) return -EINVAL; + if (dev->power.qos && dev->power.qos->flags_req) + return -EEXIST; + req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; - ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val); - if (ret < 0) { - kfree(req); - return ret; - } - pm_runtime_get_sync(dev); - mutex_lock(&dev_pm_qos_sysfs_mtx); - - mutex_lock(&dev_pm_qos_mtx); - - if (IS_ERR_OR_NULL(dev->power.qos)) - ret = -ENODEV; - else if (dev->power.qos->flags_req) - ret = -EEXIST; + ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val); + if (ret < 0) + goto fail; - if (ret < 0) { - __dev_pm_qos_remove_request(req); - kfree(req); - mutex_unlock(&dev_pm_qos_mtx); - goto out; - } dev->power.qos->flags_req = req; - - mutex_unlock(&dev_pm_qos_mtx); - ret = pm_qos_sysfs_add_flags(dev); if (ret) - dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); - out: - mutex_unlock(&dev_pm_qos_sysfs_mtx); +fail: pm_runtime_put(dev); return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags); -static void __dev_pm_qos_hide_flags(struct device *dev) -{ - if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) - __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); -} - /** * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space. * @dev: Device whose PM QoS flags are to be hidden from user space. */ void dev_pm_qos_hide_flags(struct device *dev) { - pm_runtime_get_sync(dev); - mutex_lock(&dev_pm_qos_sysfs_mtx); - - pm_qos_sysfs_remove_flags(dev); - - mutex_lock(&dev_pm_qos_mtx); - __dev_pm_qos_hide_flags(dev); - mutex_unlock(&dev_pm_qos_mtx); - - mutex_unlock(&dev_pm_qos_sysfs_mtx); - pm_runtime_put(dev); + if (dev->power.qos && dev->power.qos->flags_req) { + pm_qos_sysfs_remove_flags(dev); + pm_runtime_get_sync(dev); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + pm_runtime_put(dev); + } } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags); @@ -741,14 +683,12 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) s32 value; int ret; + if (!dev->power.qos || !dev->power.qos->flags_req) + return -EINVAL; + pm_runtime_get_sync(dev); mutex_lock(&dev_pm_qos_mtx); - if (IS_ERR_OR_NULL(dev->power.qos) || !dev->power.qos->flags_req) { - ret = -EINVAL; - goto out; - } - value = dev_pm_qos_requested_flags(dev); if (set) value |= mask; @@ -757,12 +697,9 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value); - out: mutex_unlock(&dev_pm_qos_mtx); pm_runtime_put(dev); + return ret; } -#else /* !CONFIG_PM_RUNTIME */ -static void __dev_pm_qos_hide_latency_limit(struct device *dev) {} -static void __dev_pm_qos_hide_flags(struct device *dev) {} #endif /* CONFIG_PM_RUNTIME */ diff --git a/trunk/drivers/base/power/sysfs.c b/trunk/drivers/base/power/sysfs.c index a53ebd265701..50d16e3cb0a9 100644 --- a/trunk/drivers/base/power/sysfs.c +++ b/trunk/drivers/base/power/sysfs.c @@ -708,7 +708,6 @@ void rpm_sysfs_remove(struct device *dev) void dpm_sysfs_remove(struct device *dev) { - dev_pm_qos_constraints_destroy(dev); rpm_sysfs_remove(dev); sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); sysfs_remove_group(&dev->kobj, &pm_attr_group); diff --git a/trunk/drivers/base/regmap/regcache-rbtree.c b/trunk/drivers/base/regmap/regcache-rbtree.c index 79f4fca9877a..e6732cf7c06e 100644 --- a/trunk/drivers/base/regmap/regcache-rbtree.c +++ b/trunk/drivers/base/regmap/regcache-rbtree.c @@ -398,7 +398,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, base = 0; if (max < rbnode->base_reg + rbnode->blklen) - end = max - rbnode->base_reg + 1; + end = rbnode->base_reg + rbnode->blklen - max; else end = rbnode->blklen; diff --git a/trunk/drivers/base/regmap/regmap-irq.c b/trunk/drivers/base/regmap/regmap-irq.c index 020ea2b9fd2f..4706c63d0bc6 100644 --- a/trunk/drivers/base/regmap/regmap-irq.c +++ b/trunk/drivers/base/regmap/regmap-irq.c @@ -184,7 +184,6 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) if (ret < 0) { dev_err(map->dev, "IRQ thread failed to resume: %d\n", ret); - pm_runtime_put(map->dev); return IRQ_NONE; } } diff --git a/trunk/drivers/base/regmap/regmap.c b/trunk/drivers/base/regmap/regmap.c index 58cfb3232428..3d2367501fd0 100644 --- a/trunk/drivers/base/regmap/regmap.c +++ b/trunk/drivers/base/regmap/regmap.c @@ -710,12 +710,12 @@ struct regmap *regmap_init(struct device *dev, } } - regmap_debugfs_init(map, config->name); - ret = regcache_init(map, config); if (ret != 0) goto err_range; + regmap_debugfs_init(map, config->name); + /* Add a devres resource for dev_get_regmap() */ m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); if (!m) { @@ -1036,8 +1036,6 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, kfree(async->work_buf); kfree(async); } - - return ret; } trace_regmap_hw_write_start(map->dev, reg, diff --git a/trunk/drivers/bcma/driver_pci_host.c b/trunk/drivers/bcma/driver_pci_host.c index 30629a3d44cc..d3bde6cec927 100644 --- a/trunk/drivers/bcma/driver_pci_host.c +++ b/trunk/drivers/bcma/driver_pci_host.c @@ -404,8 +404,6 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) return; } - spin_lock_init(&pc_host->cfgspace_lock); - pc->host_controller = pc_host; pc_host->pci_controller.io_resource = &pc_host->io_resource; pc_host->pci_controller.mem_resource = &pc_host->mem_resource; diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index b81ddfea1da0..5dc0daed8fac 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -532,11 +532,11 @@ config BLK_DEV_RBD If unsure, say N. config BLK_DEV_RSXX - tristate "IBM FlashSystem 70/80 PCIe SSD Device Driver" + tristate "RamSam PCIe Flash SSD Device Driver" depends on PCI help Device driver for IBM's high speed PCIe SSD - storage devices: FlashSystem-70 and FlashSystem-80. + storage devices: RamSan-70 and RamSan-80. To compile this driver as a module, choose M here: the module will be called rsxx. diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 92b6d7c51e39..25ef5c014fca 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -51,9 +51,8 @@ new_skb(ulong len) { struct sk_buff *skb; - skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC); + skb = alloc_skb(len, GFP_ATOMIC); if (skb) { - skb_reserve(skb, MAX_HEADER); skb_reset_mac_header(skb); skb_reset_network_header(skb); skb->protocol = __constant_htons(ETH_P_AOE); diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 1c1b8e544aa2..ade58bc8f3c4 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -4206,7 +4206,7 @@ static int cciss_find_cfgtables(ctlr_info_t *h) if (rc) return rc; h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev, - cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable)); + cfg_base_addr_index) + cfg_offset, sizeof(h->cfgtable)); if (!h->cfgtable) return -ENOMEM; rc = write_driver_ver_to_cfgtable(h->cfgtable); diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index dfe758382eaf..747bb2af69dc 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -922,11 +922,6 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, lo->lo_flags |= LO_FLAGS_PARTSCAN; if (lo->lo_flags & LO_FLAGS_PARTSCAN) ioctl_by_bdev(bdev, BLKRRPART, 0); - - /* Grab the block_device to prevent its destruction after we - * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). - */ - bdgrab(bdev); return 0; out_clr: @@ -1036,10 +1031,8 @@ static int loop_clr_fd(struct loop_device *lo) memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); - if (bdev) { - bdput(bdev); + if (bdev) invalidate_bdev(bdev); - } set_capacity(lo->lo_disk, 0); loop_sysfs_exit(lo); if (bdev) { @@ -1630,7 +1623,6 @@ static int loop_add(struct loop_device **l, int i) goto out_free_dev; i = err; - err = -ENOMEM; lo->lo_queue = blk_alloc_queue(GFP_KERNEL); if (!lo->lo_queue) goto out_free_dev; diff --git a/trunk/drivers/block/mg_disk.c b/trunk/drivers/block/mg_disk.c index 076ae7f1b781..1788f491e0fb 100644 --- a/trunk/drivers/block/mg_disk.c +++ b/trunk/drivers/block/mg_disk.c @@ -890,10 +890,8 @@ static int mg_probe(struct platform_device *plat_dev) gpio_direction_output(host->rst, 1); /* reset out pin */ - if (!(prv_data->dev_attr & MG_DEV_MASK)) { - err = -EINVAL; + if (!(prv_data->dev_attr & MG_DEV_MASK)) goto probe_err_3a; - } if (prv_data->dev_attr != MG_BOOT_DEV) { rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO, diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index 32c678028e53..11cc9522cdd4 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -81,17 +81,12 @@ /* Device instance number, incremented each time a device is probed. */ static int instance; -struct list_head online_list; -struct list_head removing_list; -spinlock_t dev_lock; - /* * Global variable used to hold the major block device number * allocated in mtip_init(). */ static int mtip_major; static struct dentry *dfs_parent; -static struct dentry *dfs_device_status; static u32 cpu_use[NR_CPUS]; @@ -248,31 +243,40 @@ static inline void release_slot(struct mtip_port *port, int tag) /* * Reset the HBA (without sleeping) * + * Just like hba_reset, except does not call sleep, so can be + * run from interrupt/tasklet context. + * * @dd Pointer to the driver data structure. * * return value * 0 The reset was successful. * -1 The HBA Reset bit did not clear. */ -static int mtip_hba_reset(struct driver_data *dd) +static int hba_reset_nosleep(struct driver_data *dd) { unsigned long timeout; + /* Chip quirk: quiesce any chip function */ + mdelay(10); + /* Set the reset bit */ writel(HOST_RESET, dd->mmio + HOST_CTL); /* Flush */ readl(dd->mmio + HOST_CTL); - /* Spin for up to 2 seconds, waiting for reset acknowledgement */ - timeout = jiffies + msecs_to_jiffies(2000); - do { - mdelay(10); - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) - return -1; + /* + * Wait 10ms then spin for up to 1 second + * waiting for reset acknowledgement + */ + timeout = jiffies + msecs_to_jiffies(1000); + mdelay(10); + while ((readl(dd->mmio + HOST_CTL) & HOST_RESET) + && time_before(jiffies, timeout)) + mdelay(1); - } while ((readl(dd->mmio + HOST_CTL) & HOST_RESET) - && time_before(jiffies, timeout)); + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) + return -1; if (readl(dd->mmio + HOST_CTL) & HOST_RESET) return -1; @@ -477,7 +481,7 @@ static void mtip_restart_port(struct mtip_port *port) dev_warn(&port->dd->pdev->dev, "PxCMD.CR not clear, escalating reset\n"); - if (mtip_hba_reset(port->dd)) + if (hba_reset_nosleep(port->dd)) dev_err(&port->dd->pdev->dev, "HBA reset escalation failed.\n"); @@ -523,26 +527,6 @@ static void mtip_restart_port(struct mtip_port *port) } -static int mtip_device_reset(struct driver_data *dd) -{ - int rv = 0; - - if (mtip_check_surprise_removal(dd->pdev)) - return 0; - - if (mtip_hba_reset(dd) < 0) - rv = -EFAULT; - - mdelay(1); - mtip_init_port(dd->port); - mtip_start_port(dd->port); - - /* Enable interrupts on the HBA. */ - writel(readl(dd->mmio + HOST_CTL) | HOST_IRQ_EN, - dd->mmio + HOST_CTL); - return rv; -} - /* * Helper function for tag logging */ @@ -648,7 +632,7 @@ static void mtip_timeout_function(unsigned long int data) if (cmdto_cnt) { print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { - mtip_device_reset(port->dd); + mtip_restart_port(port); wake_up_interruptible(&port->svc_wait); } clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); @@ -1299,11 +1283,11 @@ static int mtip_exec_internal_command(struct mtip_port *port, int rv = 0, ready2go = 1; struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL]; unsigned long to; - struct driver_data *dd = port->dd; /* Make sure the buffer is 8 byte aligned. This is asic specific. */ if (buffer & 0x00000007) { - dev_err(&dd->pdev->dev, "SG buffer is not 8 byte aligned\n"); + dev_err(&port->dd->pdev->dev, + "SG buffer is not 8 byte aligned\n"); return -EFAULT; } @@ -1316,21 +1300,23 @@ static int mtip_exec_internal_command(struct mtip_port *port, mdelay(100); } while (time_before(jiffies, to)); if (!ready2go) { - dev_warn(&dd->pdev->dev, + dev_warn(&port->dd->pdev->dev, "Internal cmd active. new cmd [%02X]\n", fis->command); return -EBUSY; } set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); port->ic_pause_timer = 0; - clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); - clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); + if (fis->command == ATA_CMD_SEC_ERASE_UNIT) + clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); + else if (fis->command == ATA_CMD_DOWNLOAD_MICRO) + clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); if (atomic == GFP_KERNEL) { if (fis->command != ATA_CMD_STANDBYNOW1) { /* wait for io to complete if non atomic */ if (mtip_quiesce_io(port, 5000) < 0) { - dev_warn(&dd->pdev->dev, + dev_warn(&port->dd->pdev->dev, "Failed to quiesce IO\n"); release_slot(port, MTIP_TAG_INTERNAL); clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); @@ -1375,84 +1361,58 @@ static int mtip_exec_internal_command(struct mtip_port *port, /* Issue the command to the hardware */ mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL); + /* Poll if atomic, wait_for_completion otherwise */ if (atomic == GFP_KERNEL) { /* Wait for the command to complete or timeout. */ - if (wait_for_completion_interruptible_timeout( + if (wait_for_completion_timeout( &wait, - msecs_to_jiffies(timeout)) <= 0) { - if (rv == -ERESTARTSYS) { /* interrupted */ - dev_err(&dd->pdev->dev, - "Internal command [%02X] was interrupted after %lu ms\n", - fis->command, timeout); - rv = -EINTR; - goto exec_ic_exit; - } else if (rv == 0) /* timeout */ - dev_err(&dd->pdev->dev, - "Internal command did not complete [%02X] within timeout of %lu ms\n", - fis->command, timeout); - else - dev_err(&dd->pdev->dev, - "Internal command [%02X] wait returned code [%d] after %lu ms - unhandled\n", - fis->command, rv, timeout); - - if (mtip_check_surprise_removal(dd->pdev) || + msecs_to_jiffies(timeout)) == 0) { + dev_err(&port->dd->pdev->dev, + "Internal command did not complete [%d] " + "within timeout of %lu ms\n", + atomic, timeout); + if (mtip_check_surprise_removal(port->dd->pdev) || test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag)) { - dev_err(&dd->pdev->dev, - "Internal command [%02X] wait returned due to SR\n", - fis->command); + &port->dd->dd_flag)) { rv = -ENXIO; goto exec_ic_exit; } - mtip_device_reset(dd); /* recover from timeout issue */ rv = -EAGAIN; - goto exec_ic_exit; } } else { - u32 hba_stat, port_stat; - /* Spin for checking if command still outstanding */ timeout = jiffies + msecs_to_jiffies(timeout); while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) && time_before(jiffies, timeout)) { - if (mtip_check_surprise_removal(dd->pdev)) { + if (mtip_check_surprise_removal(port->dd->pdev)) { rv = -ENXIO; goto exec_ic_exit; } if ((fis->command != ATA_CMD_STANDBYNOW1) && test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag)) { + &port->dd->dd_flag)) { rv = -ENXIO; goto exec_ic_exit; } - port_stat = readl(port->mmio + PORT_IRQ_STAT); - if (!port_stat) - continue; - - if (port_stat & PORT_IRQ_ERR) { - dev_err(&dd->pdev->dev, - "Internal command [%02X] failed\n", - fis->command); - mtip_device_reset(dd); - rv = -EIO; - goto exec_ic_exit; - } else { - writel(port_stat, port->mmio + PORT_IRQ_STAT); - hba_stat = readl(dd->mmio + HOST_IRQ_STAT); - if (hba_stat) - writel(hba_stat, - dd->mmio + HOST_IRQ_STAT); + if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) { + atomic_inc(&int_cmd->active); /* error */ + break; } - break; } } + if (atomic_read(&int_cmd->active) > 1) { + dev_err(&port->dd->pdev->dev, + "Internal command [%02X] failed\n", fis->command); + rv = -EIO; + } if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) { rv = -ENXIO; - if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { - mtip_device_reset(dd); + if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) { + mtip_restart_port(port); rv = -EAGAIN; } } @@ -1764,8 +1724,7 @@ static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, * -EINVAL Invalid parameters passed in, trim not supported * -EIO Error submitting trim request to hw */ -static int mtip_send_trim(struct driver_data *dd, unsigned int lba, - unsigned int len) +static int mtip_send_trim(struct driver_data *dd, unsigned int lba, unsigned int len) { int i, rv = 0; u64 tlba, tlen, sect_left; @@ -1851,6 +1810,45 @@ static bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors) return (bool) !!port->identify_valid; } +/* + * Reset the HBA. + * + * Resets the HBA by setting the HBA Reset bit in the Global + * HBA Control register. After setting the HBA Reset bit the + * function waits for 1 second before reading the HBA Reset + * bit to make sure it has cleared. If HBA Reset is not clear + * an error is returned. Cannot be used in non-blockable + * context. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 The reset was successful. + * -1 The HBA Reset bit did not clear. + */ +static int mtip_hba_reset(struct driver_data *dd) +{ + mtip_deinit_port(dd->port); + + /* Set the reset bit */ + writel(HOST_RESET, dd->mmio + HOST_CTL); + + /* Flush */ + readl(dd->mmio + HOST_CTL); + + /* Wait for reset to clear */ + ssleep(1); + + /* Check the bit has cleared */ + if (readl(dd->mmio + HOST_CTL) & HOST_RESET) { + dev_err(&dd->pdev->dev, + "Reset bit did not clear.\n"); + return -1; + } + + return 0; +} + /* * Display the identify command data. * @@ -2712,100 +2710,6 @@ static ssize_t mtip_hw_show_status(struct device *dev, static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); -/* debugsfs entries */ - -static ssize_t show_device_status(struct device_driver *drv, char *buf) -{ - int size = 0; - struct driver_data *dd, *tmp; - unsigned long flags; - char id_buf[42]; - u16 status = 0; - - spin_lock_irqsave(&dev_lock, flags); - size += sprintf(&buf[size], "Devices Present:\n"); - list_for_each_entry_safe(dd, tmp, &online_list, online_list) { - if (dd->pdev) { - if (dd->port && - dd->port->identify && - dd->port->identify_valid) { - strlcpy(id_buf, - (char *) (dd->port->identify + 10), 21); - status = *(dd->port->identify + 141); - } else { - memset(id_buf, 0, 42); - status = 0; - } - - if (dd->port && - test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) { - size += sprintf(&buf[size], - " device %s %s (ftl rebuild %d %%)\n", - dev_name(&dd->pdev->dev), - id_buf, - status); - } else { - size += sprintf(&buf[size], - " device %s %s\n", - dev_name(&dd->pdev->dev), - id_buf); - } - } - } - - size += sprintf(&buf[size], "Devices Being Removed:\n"); - list_for_each_entry_safe(dd, tmp, &removing_list, remove_list) { - if (dd->pdev) { - if (dd->port && - dd->port->identify && - dd->port->identify_valid) { - strlcpy(id_buf, - (char *) (dd->port->identify+10), 21); - status = *(dd->port->identify + 141); - } else { - memset(id_buf, 0, 42); - status = 0; - } - - if (dd->port && - test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) { - size += sprintf(&buf[size], - " device %s %s (ftl rebuild %d %%)\n", - dev_name(&dd->pdev->dev), - id_buf, - status); - } else { - size += sprintf(&buf[size], - " device %s %s\n", - dev_name(&dd->pdev->dev), - id_buf); - } - } - } - spin_unlock_irqrestore(&dev_lock, flags); - - return size; -} - -static ssize_t mtip_hw_read_device_status(struct file *f, char __user *ubuf, - size_t len, loff_t *offset) -{ - int size = *offset; - char buf[MTIP_DFS_MAX_BUF_SIZE]; - - if (!len || *offset) - return 0; - - size += show_device_status(NULL, buf); - - *offset = size <= len ? size : len; - size = copy_to_user(ubuf, buf, *offset); - if (size) - return -EFAULT; - - return *offset; -} - static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, size_t len, loff_t *offset) { @@ -2900,13 +2804,6 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, return *offset; } -static const struct file_operations mtip_device_status_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = mtip_hw_read_device_status, - .llseek = no_llseek, -}; - static const struct file_operations mtip_regs_fops = { .owner = THIS_MODULE, .open = simple_open, @@ -4264,7 +4161,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, const struct cpumask *node_mask; int cpu, i = 0, j = 0; int my_node = NUMA_NO_NODE; - unsigned long flags; /* Allocate memory for this devices private data. */ my_node = pcibus_to_node(pdev->bus); @@ -4322,16 +4218,12 @@ static int mtip_pci_probe(struct pci_dev *pdev, dd->pdev = pdev; dd->numa_node = my_node; - INIT_LIST_HEAD(&dd->online_list); - INIT_LIST_HEAD(&dd->remove_list); - memset(dd->workq_name, 0, 32); snprintf(dd->workq_name, 31, "mtipq%d", dd->instance); dd->isr_workq = create_workqueue(dd->workq_name); if (!dd->isr_workq) { dev_warn(&pdev->dev, "Can't create wq %d\n", dd->instance); - rv = -ENOMEM; goto block_initialize_err; } @@ -4390,8 +4282,7 @@ static int mtip_pci_probe(struct pci_dev *pdev, INIT_WORK(&dd->work[7].work, mtip_workq_sdbf7); pci_set_master(pdev); - rv = pci_enable_msi(pdev); - if (rv) { + if (pci_enable_msi(pdev)) { dev_warn(&pdev->dev, "Unable to enable MSI interrupt.\n"); goto block_initialize_err; @@ -4412,14 +4303,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, instance++; if (rv != MTIP_FTL_REBUILD_MAGIC) set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); - else - rv = 0; /* device in rebuild state, return 0 from probe */ - - /* Add to online list even if in ftl rebuild */ - spin_lock_irqsave(&dev_lock, flags); - list_add(&dd->online_list, &online_list); - spin_unlock_irqrestore(&dev_lock, flags); - goto done; block_initialize_err: @@ -4453,15 +4336,9 @@ static void mtip_pci_remove(struct pci_dev *pdev) { struct driver_data *dd = pci_get_drvdata(pdev); int counter = 0; - unsigned long flags; set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); - spin_lock_irqsave(&dev_lock, flags); - list_del_init(&dd->online_list); - list_add(&dd->remove_list, &removing_list); - spin_unlock_irqrestore(&dev_lock, flags); - if (mtip_check_surprise_removal(pdev)) { while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { counter++; @@ -4487,10 +4364,6 @@ static void mtip_pci_remove(struct pci_dev *pdev) pci_disable_msi(pdev); - spin_lock_irqsave(&dev_lock, flags); - list_del_init(&dd->remove_list); - spin_unlock_irqrestore(&dev_lock, flags); - kfree(dd); pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); } @@ -4638,11 +4511,6 @@ static int __init mtip_init(void) pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); - spin_lock_init(&dev_lock); - - INIT_LIST_HEAD(&online_list); - INIT_LIST_HEAD(&removing_list); - /* Allocate a major block device number to use with this driver. */ error = register_blkdev(0, MTIP_DRV_NAME); if (error <= 0) { @@ -4652,18 +4520,11 @@ static int __init mtip_init(void) } mtip_major = error; - dfs_parent = debugfs_create_dir("rssd", NULL); - if (IS_ERR_OR_NULL(dfs_parent)) { - pr_warn("Error creating debugfs parent\n"); - dfs_parent = NULL; - } - if (dfs_parent) { - dfs_device_status = debugfs_create_file("device_status", - S_IRUGO, dfs_parent, NULL, - &mtip_device_status_fops); - if (IS_ERR_OR_NULL(dfs_device_status)) { - pr_err("Error creating device_status node\n"); - dfs_device_status = NULL; + if (!dfs_parent) { + dfs_parent = debugfs_create_dir("rssd", NULL); + if (IS_ERR_OR_NULL(dfs_parent)) { + pr_warn("Error creating debugfs parent\n"); + dfs_parent = NULL; } } diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index 8e8334c9dd0f..3bffff5f670c 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -129,9 +129,9 @@ enum { MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */ MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */ MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */ - MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | - (1 << MTIP_PF_EH_ACTIVE_BIT) | - (1 << MTIP_PF_SE_ACTIVE_BIT) | + MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ + (1 << MTIP_PF_EH_ACTIVE_BIT) | \ + (1 << MTIP_PF_SE_ACTIVE_BIT) | \ (1 << MTIP_PF_DM_ACTIVE_BIT)), MTIP_PF_SVC_THD_ACTIVE_BIT = 4, @@ -144,9 +144,9 @@ enum { MTIP_DDF_REMOVE_PENDING_BIT = 1, MTIP_DDF_OVER_TEMP_BIT = 2, MTIP_DDF_WRITE_PROTECT_BIT = 3, - MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | - (1 << MTIP_DDF_SEC_LOCK_BIT) | - (1 << MTIP_DDF_OVER_TEMP_BIT) | + MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ + (1 << MTIP_DDF_SEC_LOCK_BIT) | \ + (1 << MTIP_DDF_OVER_TEMP_BIT) | \ (1 << MTIP_DDF_WRITE_PROTECT_BIT)), MTIP_DDF_CLEANUP_BIT = 5, @@ -180,7 +180,7 @@ struct mtip_work { #define MTIP_TRIM_TIMEOUT_MS 240000 #define MTIP_MAX_TRIM_ENTRIES 8 -#define MTIP_MAX_TRIM_ENTRY_LEN 0xfff8 +#define MTIP_MAX_TRIM_ENTRY_LEN 0xfff8 struct mtip_trim_entry { u32 lba; /* starting lba of region */ @@ -501,10 +501,6 @@ struct driver_data { atomic_t irq_workers_active; int isr_binding; - - struct list_head online_list; /* linkage for online list */ - - struct list_head remove_list; /* linkage for removing list */ }; #endif diff --git a/trunk/drivers/block/nvme.c b/trunk/drivers/block/nvme.c index 9dcefe40380b..07fb2dfaae13 100644 --- a/trunk/drivers/block/nvme.c +++ b/trunk/drivers/block/nvme.c @@ -135,7 +135,6 @@ static inline void _nvme_check_size(void) BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096); BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096); BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64); - BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512); } typedef void (*nvme_completion_fn)(struct nvme_dev *, void *, @@ -238,8 +237,7 @@ static void *free_cmdid(struct nvme_queue *nvmeq, int cmdid, *fn = special_completion; return CMD_CTX_INVALID; } - if (fn) - *fn = info[cmdid].fn; + *fn = info[cmdid].fn; ctx = info[cmdid].ctx; info[cmdid].fn = special_completion; info[cmdid].ctx = CMD_CTX_COMPLETED; @@ -337,7 +335,6 @@ nvme_alloc_iod(unsigned nseg, unsigned nbytes, gfp_t gfp) iod->offset = offsetof(struct nvme_iod, sg[nseg]); iod->npages = -1; iod->length = nbytes; - iod->nents = 0; } return iod; @@ -378,8 +375,7 @@ static void bio_completion(struct nvme_dev *dev, void *ctx, struct bio *bio = iod->private; u16 status = le16_to_cpup(&cqe->status) >> 1; - if (iod->nents) - dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents, + dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents, bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); nvme_free_iod(dev, iod); if (status) { @@ -593,7 +589,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, result = nvme_map_bio(nvmeq->q_dmadev, iod, bio, dma_dir, psegs); if (result < 0) - goto free_cmdid; + goto free_iod; length = result; cmnd->rw.command_id = cmdid; @@ -613,8 +609,6 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, return 0; - free_cmdid: - free_cmdid(nvmeq, cmdid, NULL); free_iod: nvme_free_iod(nvmeq->dev, iod); nomem: @@ -841,8 +835,8 @@ static int nvme_identify(struct nvme_dev *dev, unsigned nsid, unsigned cns, return nvme_submit_admin_cmd(dev, &c, NULL); } -static int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, - dma_addr_t dma_addr, u32 *result) +static int nvme_get_features(struct nvme_dev *dev, unsigned fid, + unsigned nsid, dma_addr_t dma_addr) { struct nvme_command c; @@ -852,7 +846,7 @@ static int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, c.features.prp1 = cpu_to_le64(dma_addr); c.features.fid = cpu_to_le32(fid); - return nvme_submit_admin_cmd(dev, &c, result); + return nvme_submit_admin_cmd(dev, &c, NULL); } static int nvme_set_features(struct nvme_dev *dev, unsigned fid, @@ -912,10 +906,6 @@ static void nvme_free_queue(struct nvme_dev *dev, int qid) spin_lock_irq(&nvmeq->q_lock); nvme_cancel_ios(nvmeq, false); - while (bio_list_peek(&nvmeq->sq_cong)) { - struct bio *bio = bio_list_pop(&nvmeq->sq_cong); - bio_endio(bio, -EIO); - } spin_unlock_irq(&nvmeq->q_lock); irq_set_affinity_hint(vector, NULL); @@ -1240,17 +1230,12 @@ static int nvme_user_admin_cmd(struct nvme_dev *dev, if (length != cmd.data_len) status = -ENOMEM; else - status = nvme_submit_admin_cmd(dev, &c, &cmd.result); + status = nvme_submit_admin_cmd(dev, &c, NULL); if (cmd.data_len) { nvme_unmap_user_pages(dev, cmd.opcode & 1, iod); nvme_free_iod(dev, iod); } - - if (!status && copy_to_user(&ucmd->result, &cmd.result, - sizeof(cmd.result))) - status = -EFAULT; - return status; } @@ -1538,9 +1523,9 @@ static int nvme_dev_add(struct nvme_dev *dev) continue; res = nvme_get_features(dev, NVME_FEAT_LBA_RANGE, i, - dma_addr + 4096, NULL); + dma_addr + 4096); if (res) - memset(mem + 4096, 0, 4096); + continue; ns = nvme_alloc_ns(dev, i, mem, mem + 4096); if (ns) diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index b7b7a88d9f68..6c81a4c040b9 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -1264,32 +1264,6 @@ static bool obj_request_done_test(struct rbd_obj_request *obj_request) return atomic_read(&obj_request->done) != 0; } -static void -rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request) -{ - dout("%s: obj %p img %p result %d %llu/%llu\n", __func__, - obj_request, obj_request->img_request, obj_request->result, - obj_request->xferred, obj_request->length); - /* - * ENOENT means a hole in the image. We zero-fill the - * entire length of the request. A short read also implies - * zero-fill to the end of the request. Either way we - * update the xferred count to indicate the whole request - * was satisfied. - */ - BUG_ON(obj_request->type != OBJ_REQUEST_BIO); - if (obj_request->result == -ENOENT) { - zero_bio_chain(obj_request->bio_list, 0); - obj_request->result = 0; - obj_request->xferred = obj_request->length; - } else if (obj_request->xferred < obj_request->length && - !obj_request->result) { - zero_bio_chain(obj_request->bio_list, obj_request->xferred); - obj_request->xferred = obj_request->length; - } - obj_request_done_set(obj_request); -} - static void rbd_obj_request_complete(struct rbd_obj_request *obj_request) { dout("%s: obj %p cb %p\n", __func__, obj_request, @@ -1310,10 +1284,23 @@ static void rbd_osd_read_callback(struct rbd_obj_request *obj_request) { dout("%s: obj %p result %d %llu/%llu\n", __func__, obj_request, obj_request->result, obj_request->xferred, obj_request->length); - if (obj_request->img_request) - rbd_img_obj_request_read_callback(obj_request); - else - obj_request_done_set(obj_request); + /* + * ENOENT means a hole in the object. We zero-fill the + * entire length of the request. A short read also implies + * zero-fill to the end of the request. Either way we + * update the xferred count to indicate the whole request + * was satisfied. + */ + if (obj_request->result == -ENOENT) { + zero_bio_chain(obj_request->bio_list, 0); + obj_request->result = 0; + obj_request->xferred = obj_request->length; + } else if (obj_request->xferred < obj_request->length && + !obj_request->result) { + zero_bio_chain(obj_request->bio_list, obj_request->xferred); + obj_request->xferred = obj_request->length; + } + obj_request_done_set(obj_request); } static void rbd_osd_write_callback(struct rbd_obj_request *obj_request) @@ -1742,10 +1729,9 @@ static int rbd_img_request_submit(struct rbd_img_request *img_request) struct rbd_device *rbd_dev = img_request->rbd_dev; struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; struct rbd_obj_request *obj_request; - struct rbd_obj_request *next_obj_request; dout("%s: img %p\n", __func__, img_request); - for_each_obj_request_safe(img_request, obj_request, next_obj_request) { + for_each_obj_request(img_request, obj_request) { int ret; obj_request->callback = rbd_img_obj_callback; diff --git a/trunk/drivers/block/rsxx/Makefile b/trunk/drivers/block/rsxx/Makefile index b1c53c0aa450..f35cd0b71f7b 100644 --- a/trunk/drivers/block/rsxx/Makefile +++ b/trunk/drivers/block/rsxx/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_BLK_DEV_RSXX) += rsxx.o -rsxx-objs := config.o core.o cregs.o dev.o dma.o +rsxx-y := config.o core.o cregs.o dev.o dma.o diff --git a/trunk/drivers/block/rsxx/config.c b/trunk/drivers/block/rsxx/config.c index 10cd530d3e10..a295e7e9ee41 100644 --- a/trunk/drivers/block/rsxx/config.c +++ b/trunk/drivers/block/rsxx/config.c @@ -29,13 +29,15 @@ #include "rsxx_priv.h" #include "rsxx_cfg.h" -static void initialize_config(struct rsxx_card_cfg *cfg) +static void initialize_config(void *config) { + struct rsxx_card_cfg *cfg = config; + cfg->hdr.version = RSXX_CFG_VERSION; cfg->data.block_size = RSXX_HW_BLK_SIZE; cfg->data.stripe_size = RSXX_HW_BLK_SIZE; - cfg->data.vendor_id = RSXX_VENDOR_ID_IBM; + cfg->data.vendor_id = RSXX_VENDOR_ID_TMS_IBM; cfg->data.cache_order = (-1); cfg->data.intr_coal.mode = RSXX_INTR_COAL_DISABLED; cfg->data.intr_coal.count = 0; @@ -179,7 +181,7 @@ int rsxx_load_config(struct rsxx_cardinfo *card) } else { dev_info(CARD_TO_DEV(card), "Initializing card configuration.\n"); - initialize_config(&card->config); + initialize_config(card); st = rsxx_save_config(card); if (st) return st; diff --git a/trunk/drivers/block/rsxx/core.c b/trunk/drivers/block/rsxx/core.c index 5af21f2db29c..e5162487686a 100644 --- a/trunk/drivers/block/rsxx/core.c +++ b/trunk/drivers/block/rsxx/core.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -40,8 +39,8 @@ #define NO_LEGACY 0 -MODULE_DESCRIPTION("IBM FlashSystem 70/80 PCIe SSD Device Driver"); -MODULE_AUTHOR("Joshua Morris/Philip Kelleher, IBM"); +MODULE_DESCRIPTION("IBM RamSan PCIe Flash SSD Device Driver"); +MODULE_AUTHOR("IBM "); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); @@ -53,13 +52,6 @@ static DEFINE_IDA(rsxx_disk_ida); static DEFINE_SPINLOCK(rsxx_ida_lock); /*----------------- Interrupt Control & Handling -------------------*/ - -static void rsxx_mask_interrupts(struct rsxx_cardinfo *card) -{ - card->isr_mask = 0; - card->ier_mask = 0; -} - static void __enable_intr(unsigned int *mask, unsigned int intr) { *mask |= intr; @@ -79,8 +71,7 @@ static void __disable_intr(unsigned int *mask, unsigned int intr) */ void rsxx_enable_ier(struct rsxx_cardinfo *card, unsigned int intr) { - if (unlikely(card->halt) || - unlikely(card->eeh_state)) + if (unlikely(card->halt)) return; __enable_intr(&card->ier_mask, intr); @@ -89,9 +80,6 @@ void rsxx_enable_ier(struct rsxx_cardinfo *card, unsigned int intr) void rsxx_disable_ier(struct rsxx_cardinfo *card, unsigned int intr) { - if (unlikely(card->eeh_state)) - return; - __disable_intr(&card->ier_mask, intr); iowrite32(card->ier_mask, card->regmap + IER); } @@ -99,8 +87,7 @@ void rsxx_disable_ier(struct rsxx_cardinfo *card, unsigned int intr) void rsxx_enable_ier_and_isr(struct rsxx_cardinfo *card, unsigned int intr) { - if (unlikely(card->halt) || - unlikely(card->eeh_state)) + if (unlikely(card->halt)) return; __enable_intr(&card->isr_mask, intr); @@ -110,9 +97,6 @@ void rsxx_enable_ier_and_isr(struct rsxx_cardinfo *card, void rsxx_disable_ier_and_isr(struct rsxx_cardinfo *card, unsigned int intr) { - if (unlikely(card->eeh_state)) - return; - __disable_intr(&card->isr_mask, intr); __disable_intr(&card->ier_mask, intr); iowrite32(card->ier_mask, card->regmap + IER); @@ -131,9 +115,6 @@ static irqreturn_t rsxx_isr(int irq, void *pdata) do { reread_isr = 0; - if (unlikely(card->eeh_state)) - break; - isr = ioread32(card->regmap + ISR); if (isr == 0xffffffff) { /* @@ -180,9 +161,9 @@ static irqreturn_t rsxx_isr(int irq, void *pdata) } /*----------------- Card Event Handler -------------------*/ -static const char * const rsxx_card_state_to_str(unsigned int state) +static char *rsxx_card_state_to_str(unsigned int state) { - static const char * const state_strings[] = { + static char *state_strings[] = { "Unknown", "Shutdown", "Starting", "Formatting", "Uninitialized", "Good", "Shutting Down", "Fault", "Read Only Fault", "dStroying" @@ -323,192 +304,6 @@ static int card_shutdown(struct rsxx_cardinfo *card) return 0; } -static int rsxx_eeh_frozen(struct pci_dev *dev) -{ - struct rsxx_cardinfo *card = pci_get_drvdata(dev); - int i; - int st; - - dev_warn(&dev->dev, "IBM FlashSystem PCI: preparing for slot reset.\n"); - - card->eeh_state = 1; - rsxx_mask_interrupts(card); - - /* - * We need to guarantee that the write for eeh_state and masking - * interrupts does not become reordered. This will prevent a possible - * race condition with the EEH code. - */ - wmb(); - - pci_disable_device(dev); - - st = rsxx_eeh_save_issued_dmas(card); - if (st) - return st; - - rsxx_eeh_save_issued_creg(card); - - for (i = 0; i < card->n_targets; i++) { - if (card->ctrl[i].status.buf) - pci_free_consistent(card->dev, STATUS_BUFFER_SIZE8, - card->ctrl[i].status.buf, - card->ctrl[i].status.dma_addr); - if (card->ctrl[i].cmd.buf) - pci_free_consistent(card->dev, COMMAND_BUFFER_SIZE8, - card->ctrl[i].cmd.buf, - card->ctrl[i].cmd.dma_addr); - } - - return 0; -} - -static void rsxx_eeh_failure(struct pci_dev *dev) -{ - struct rsxx_cardinfo *card = pci_get_drvdata(dev); - int i; - - dev_err(&dev->dev, "IBM FlashSystem PCI: disabling failed card.\n"); - - card->eeh_state = 1; - - for (i = 0; i < card->n_targets; i++) - del_timer_sync(&card->ctrl[i].activity_timer); - - rsxx_eeh_cancel_dmas(card); -} - -static int rsxx_eeh_fifo_flush_poll(struct rsxx_cardinfo *card) -{ - unsigned int status; - int iter = 0; - - /* We need to wait for the hardware to reset */ - while (iter++ < 10) { - status = ioread32(card->regmap + PCI_RECONFIG); - - if (status & RSXX_FLUSH_BUSY) { - ssleep(1); - continue; - } - - if (status & RSXX_FLUSH_TIMEOUT) - dev_warn(CARD_TO_DEV(card), "HW: flash controller timeout\n"); - return 0; - } - - /* Hardware failed resetting itself. */ - return -1; -} - -static pci_ers_result_t rsxx_error_detected(struct pci_dev *dev, - enum pci_channel_state error) -{ - int st; - - if (dev->revision < RSXX_EEH_SUPPORT) - return PCI_ERS_RESULT_NONE; - - if (error == pci_channel_io_perm_failure) { - rsxx_eeh_failure(dev); - return PCI_ERS_RESULT_DISCONNECT; - } - - st = rsxx_eeh_frozen(dev); - if (st) { - dev_err(&dev->dev, "Slot reset setup failed\n"); - rsxx_eeh_failure(dev); - return PCI_ERS_RESULT_DISCONNECT; - } - - return PCI_ERS_RESULT_NEED_RESET; -} - -static pci_ers_result_t rsxx_slot_reset(struct pci_dev *dev) -{ - struct rsxx_cardinfo *card = pci_get_drvdata(dev); - unsigned long flags; - int i; - int st; - - dev_warn(&dev->dev, - "IBM FlashSystem PCI: recovering from slot reset.\n"); - - st = pci_enable_device(dev); - if (st) - goto failed_hw_setup; - - pci_set_master(dev); - - st = rsxx_eeh_fifo_flush_poll(card); - if (st) - goto failed_hw_setup; - - rsxx_dma_queue_reset(card); - - for (i = 0; i < card->n_targets; i++) { - st = rsxx_hw_buffers_init(dev, &card->ctrl[i]); - if (st) - goto failed_hw_buffers_init; - } - - if (card->config_valid) - rsxx_dma_configure(card); - - /* Clears the ISR register from spurious interrupts */ - st = ioread32(card->regmap + ISR); - - card->eeh_state = 0; - - st = rsxx_eeh_remap_dmas(card); - if (st) - goto failed_remap_dmas; - - spin_lock_irqsave(&card->irq_lock, flags); - if (card->n_targets & RSXX_MAX_TARGETS) - rsxx_enable_ier_and_isr(card, CR_INTR_ALL_G); - else - rsxx_enable_ier_and_isr(card, CR_INTR_ALL_C); - spin_unlock_irqrestore(&card->irq_lock, flags); - - rsxx_kick_creg_queue(card); - - for (i = 0; i < card->n_targets; i++) { - spin_lock(&card->ctrl[i].queue_lock); - if (list_empty(&card->ctrl[i].queue)) { - spin_unlock(&card->ctrl[i].queue_lock); - continue; - } - spin_unlock(&card->ctrl[i].queue_lock); - - queue_work(card->ctrl[i].issue_wq, - &card->ctrl[i].issue_dma_work); - } - - dev_info(&dev->dev, "IBM FlashSystem PCI: recovery complete.\n"); - - return PCI_ERS_RESULT_RECOVERED; - -failed_hw_buffers_init: -failed_remap_dmas: - for (i = 0; i < card->n_targets; i++) { - if (card->ctrl[i].status.buf) - pci_free_consistent(card->dev, - STATUS_BUFFER_SIZE8, - card->ctrl[i].status.buf, - card->ctrl[i].status.dma_addr); - if (card->ctrl[i].cmd.buf) - pci_free_consistent(card->dev, - COMMAND_BUFFER_SIZE8, - card->ctrl[i].cmd.buf, - card->ctrl[i].cmd.dma_addr); - } -failed_hw_setup: - rsxx_eeh_failure(dev); - return PCI_ERS_RESULT_DISCONNECT; - -} - /*----------------- Driver Initialization & Setup -------------------*/ /* Returns: 0 if the driver is compatible with the device -1 if the driver is NOT compatible with the device */ @@ -588,7 +383,6 @@ static int rsxx_pci_probe(struct pci_dev *dev, spin_lock_init(&card->irq_lock); card->halt = 0; - card->eeh_state = 0; spin_lock_irq(&card->irq_lock); rsxx_disable_ier_and_isr(card, CR_INTR_ALL); @@ -744,6 +538,9 @@ static void rsxx_pci_remove(struct pci_dev *dev) rsxx_disable_ier_and_isr(card, CR_INTR_EVENT); spin_unlock_irqrestore(&card->irq_lock, flags); + /* Prevent work_structs from re-queuing themselves. */ + card->halt = 1; + cancel_work_sync(&card->event_work); rsxx_destroy_dev(card); @@ -752,10 +549,6 @@ static void rsxx_pci_remove(struct pci_dev *dev) spin_lock_irqsave(&card->irq_lock, flags); rsxx_disable_ier_and_isr(card, CR_INTR_ALL); spin_unlock_irqrestore(&card->irq_lock, flags); - - /* Prevent work_structs from re-queuing themselves. */ - card->halt = 1; - free_irq(dev->irq, card); if (!force_legacy) @@ -799,14 +592,11 @@ static void rsxx_pci_shutdown(struct pci_dev *dev) card_shutdown(card); } -static const struct pci_error_handlers rsxx_err_handler = { - .error_detected = rsxx_error_detected, - .slot_reset = rsxx_slot_reset, -}; - static DEFINE_PCI_DEVICE_TABLE(rsxx_pci_ids) = { - {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS70_FLASH)}, - {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS80_FLASH)}, + {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS70_FLASH)}, + {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS70D_FLASH)}, + {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS80_FLASH)}, + {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS81_FLASH)}, {0,}, }; @@ -819,7 +609,6 @@ static struct pci_driver rsxx_pci_driver = { .remove = rsxx_pci_remove, .suspend = rsxx_pci_suspend, .shutdown = rsxx_pci_shutdown, - .err_handler = &rsxx_err_handler, }; static int __init rsxx_core_init(void) diff --git a/trunk/drivers/block/rsxx/cregs.c b/trunk/drivers/block/rsxx/cregs.c index 4b5c020a0a65..80bbe639fccd 100644 --- a/trunk/drivers/block/rsxx/cregs.c +++ b/trunk/drivers/block/rsxx/cregs.c @@ -58,7 +58,7 @@ static struct kmem_cache *creg_cmd_pool; #error Unknown endianess!!! Aborting... #endif -static int copy_to_creg_data(struct rsxx_cardinfo *card, +static void copy_to_creg_data(struct rsxx_cardinfo *card, int cnt8, void *buf, unsigned int stream) @@ -66,9 +66,6 @@ static int copy_to_creg_data(struct rsxx_cardinfo *card, int i = 0; u32 *data = buf; - if (unlikely(card->eeh_state)) - return -EIO; - for (i = 0; cnt8 > 0; i++, cnt8 -= 4) { /* * Firmware implementation makes it necessary to byte swap on @@ -79,12 +76,10 @@ static int copy_to_creg_data(struct rsxx_cardinfo *card, else iowrite32(data[i], card->regmap + CREG_DATA(i)); } - - return 0; } -static int copy_from_creg_data(struct rsxx_cardinfo *card, +static void copy_from_creg_data(struct rsxx_cardinfo *card, int cnt8, void *buf, unsigned int stream) @@ -92,9 +87,6 @@ static int copy_from_creg_data(struct rsxx_cardinfo *card, int i = 0; u32 *data = buf; - if (unlikely(card->eeh_state)) - return -EIO; - for (i = 0; cnt8 > 0; i++, cnt8 -= 4) { /* * Firmware implementation makes it necessary to byte swap on @@ -105,31 +97,41 @@ static int copy_from_creg_data(struct rsxx_cardinfo *card, else data[i] = ioread32(card->regmap + CREG_DATA(i)); } - - return 0; } -static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd) +static struct creg_cmd *pop_active_cmd(struct rsxx_cardinfo *card) { - int st; + struct creg_cmd *cmd; - if (unlikely(card->eeh_state)) - return; + /* + * Spin lock is needed because this can be called in atomic/interrupt + * context. + */ + spin_lock_bh(&card->creg_ctrl.lock); + cmd = card->creg_ctrl.active_cmd; + card->creg_ctrl.active_cmd = NULL; + spin_unlock_bh(&card->creg_ctrl.lock); + return cmd; +} + +static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd) +{ iowrite32(cmd->addr, card->regmap + CREG_ADD); iowrite32(cmd->cnt8, card->regmap + CREG_CNT); if (cmd->op == CREG_OP_WRITE) { - if (cmd->buf) { - st = copy_to_creg_data(card, cmd->cnt8, - cmd->buf, cmd->stream); - if (st) - return; - } + if (cmd->buf) + copy_to_creg_data(card, cmd->cnt8, + cmd->buf, cmd->stream); } - if (unlikely(card->eeh_state)) - return; + /* + * Data copy must complete before initiating the command. This is + * needed for weakly ordered processors (i.e. PowerPC), so that all + * neccessary registers are written before we kick the hardware. + */ + wmb(); /* Setting the valid bit will kick off the command. */ iowrite32(cmd->op, card->regmap + CREG_CMD); @@ -194,11 +196,11 @@ static int creg_queue_cmd(struct rsxx_cardinfo *card, cmd->cb_private = cb_private; cmd->status = 0; - spin_lock_bh(&card->creg_ctrl.lock); + spin_lock(&card->creg_ctrl.lock); list_add_tail(&cmd->list, &card->creg_ctrl.queue); card->creg_ctrl.q_depth++; creg_kick_queue(card); - spin_unlock_bh(&card->creg_ctrl.lock); + spin_unlock(&card->creg_ctrl.lock); return 0; } @@ -208,11 +210,7 @@ static void creg_cmd_timed_out(unsigned long data) struct rsxx_cardinfo *card = (struct rsxx_cardinfo *) data; struct creg_cmd *cmd; - spin_lock(&card->creg_ctrl.lock); - cmd = card->creg_ctrl.active_cmd; - card->creg_ctrl.active_cmd = NULL; - spin_unlock(&card->creg_ctrl.lock); - + cmd = pop_active_cmd(card); if (cmd == NULL) { card->creg_ctrl.creg_stats.creg_timeout++; dev_warn(CARD_TO_DEV(card), @@ -249,11 +247,7 @@ static void creg_cmd_done(struct work_struct *work) if (del_timer_sync(&card->creg_ctrl.cmd_timer) == 0) card->creg_ctrl.creg_stats.failed_cancel_timer++; - spin_lock_bh(&card->creg_ctrl.lock); - cmd = card->creg_ctrl.active_cmd; - card->creg_ctrl.active_cmd = NULL; - spin_unlock_bh(&card->creg_ctrl.lock); - + cmd = pop_active_cmd(card); if (cmd == NULL) { dev_err(CARD_TO_DEV(card), "Spurious creg interrupt!\n"); @@ -293,7 +287,7 @@ static void creg_cmd_done(struct work_struct *work) goto creg_done; } - st = copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream); + copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream); } creg_done: @@ -302,10 +296,10 @@ static void creg_cmd_done(struct work_struct *work) kmem_cache_free(creg_cmd_pool, cmd); - spin_lock_bh(&card->creg_ctrl.lock); + spin_lock(&card->creg_ctrl.lock); card->creg_ctrl.active = 0; creg_kick_queue(card); - spin_unlock_bh(&card->creg_ctrl.lock); + spin_unlock(&card->creg_ctrl.lock); } static void creg_reset(struct rsxx_cardinfo *card) @@ -330,7 +324,7 @@ static void creg_reset(struct rsxx_cardinfo *card) "Resetting creg interface for recovery\n"); /* Cancel outstanding commands */ - spin_lock_bh(&card->creg_ctrl.lock); + spin_lock(&card->creg_ctrl.lock); list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) { list_del(&cmd->list); card->creg_ctrl.q_depth--; @@ -351,7 +345,7 @@ static void creg_reset(struct rsxx_cardinfo *card) card->creg_ctrl.active = 0; } - spin_unlock_bh(&card->creg_ctrl.lock); + spin_unlock(&card->creg_ctrl.lock); card->creg_ctrl.reset = 0; spin_lock_irqsave(&card->irq_lock, flags); @@ -405,12 +399,12 @@ static int __issue_creg_rw(struct rsxx_cardinfo *card, return st; /* - * This timeout is necessary for unresponsive hardware. The additional + * This timeout is neccessary for unresponsive hardware. The additional * 20 seconds to used to guarantee that each cregs requests has time to * complete. */ - timeout = msecs_to_jiffies(CREG_TIMEOUT_MSEC * - card->creg_ctrl.q_depth + 20000); + timeout = msecs_to_jiffies((CREG_TIMEOUT_MSEC * + card->creg_ctrl.q_depth) + 20000); /* * The creg interface is guaranteed to complete. It has a timeout @@ -696,32 +690,6 @@ int rsxx_reg_access(struct rsxx_cardinfo *card, return 0; } -void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card) -{ - struct creg_cmd *cmd = NULL; - - cmd = card->creg_ctrl.active_cmd; - card->creg_ctrl.active_cmd = NULL; - - if (cmd) { - del_timer_sync(&card->creg_ctrl.cmd_timer); - - spin_lock_bh(&card->creg_ctrl.lock); - list_add(&cmd->list, &card->creg_ctrl.queue); - card->creg_ctrl.q_depth++; - card->creg_ctrl.active = 0; - spin_unlock_bh(&card->creg_ctrl.lock); - } -} - -void rsxx_kick_creg_queue(struct rsxx_cardinfo *card) -{ - spin_lock_bh(&card->creg_ctrl.lock); - if (!list_empty(&card->creg_ctrl.queue)) - creg_kick_queue(card); - spin_unlock_bh(&card->creg_ctrl.lock); -} - /*------------ Initialization & Setup --------------*/ int rsxx_creg_setup(struct rsxx_cardinfo *card) { @@ -744,7 +712,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card) int cnt = 0; /* Cancel outstanding commands */ - spin_lock_bh(&card->creg_ctrl.lock); + spin_lock(&card->creg_ctrl.lock); list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) { list_del(&cmd->list); if (cmd->cb) @@ -769,7 +737,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card) "Canceled active creg command\n"); kmem_cache_free(creg_cmd_pool, cmd); } - spin_unlock_bh(&card->creg_ctrl.lock); + spin_unlock(&card->creg_ctrl.lock); cancel_work_sync(&card->creg_ctrl.done_work); } diff --git a/trunk/drivers/block/rsxx/dma.c b/trunk/drivers/block/rsxx/dma.c index 0607513cfb41..63176e67662f 100644 --- a/trunk/drivers/block/rsxx/dma.c +++ b/trunk/drivers/block/rsxx/dma.c @@ -28,7 +28,7 @@ struct rsxx_dma { struct list_head list; u8 cmd; - unsigned int laddr; /* Logical address */ + unsigned int laddr; /* Logical address on the ramsan */ struct { u32 off; u32 cnt; @@ -81,6 +81,9 @@ enum rsxx_hw_status { HW_STATUS_FAULT = 0x08, }; +#define STATUS_BUFFER_SIZE8 4096 +#define COMMAND_BUFFER_SIZE8 4096 + static struct kmem_cache *rsxx_dma_pool; struct dma_tracker { @@ -119,7 +122,7 @@ static unsigned int rsxx_get_dma_tgt(struct rsxx_cardinfo *card, u64 addr8) return tgt; } -void rsxx_dma_queue_reset(struct rsxx_cardinfo *card) +static void rsxx_dma_queue_reset(struct rsxx_cardinfo *card) { /* Reset all DMA Command/Status Queues */ iowrite32(DMA_QUEUE_RESET, card->regmap + RESET); @@ -207,8 +210,7 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card) u32 q_depth = 0; u32 intr_coal; - if (card->config.data.intr_coal.mode != RSXX_INTR_COAL_AUTO_TUNE || - unlikely(card->eeh_state)) + if (card->config.data.intr_coal.mode != RSXX_INTR_COAL_AUTO_TUNE) return; for (i = 0; i < card->n_targets; i++) @@ -221,26 +223,31 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card) } /*----------------- RSXX DMA Handling -------------------*/ -static void rsxx_complete_dma(struct rsxx_dma_ctrl *ctrl, +static void rsxx_complete_dma(struct rsxx_cardinfo *card, struct rsxx_dma *dma, unsigned int status) { if (status & DMA_SW_ERR) - ctrl->stats.dma_sw_err++; + printk_ratelimited(KERN_ERR + "SW Error in DMA(cmd x%02x, laddr x%08x)\n", + dma->cmd, dma->laddr); if (status & DMA_HW_FAULT) - ctrl->stats.dma_hw_fault++; + printk_ratelimited(KERN_ERR + "HW Fault in DMA(cmd x%02x, laddr x%08x)\n", + dma->cmd, dma->laddr); if (status & DMA_CANCELLED) - ctrl->stats.dma_cancelled++; + printk_ratelimited(KERN_ERR + "DMA Cancelled(cmd x%02x, laddr x%08x)\n", + dma->cmd, dma->laddr); if (dma->dma_addr) - pci_unmap_page(ctrl->card->dev, dma->dma_addr, - get_dma_size(dma), + pci_unmap_page(card->dev, dma->dma_addr, get_dma_size(dma), dma->cmd == HW_CMD_BLK_WRITE ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); if (dma->cb) - dma->cb(ctrl->card, dma->cb_data, status ? 1 : 0); + dma->cb(card, dma->cb_data, status ? 1 : 0); kmem_cache_free(rsxx_dma_pool, dma); } @@ -323,15 +330,14 @@ static void rsxx_handle_dma_error(struct rsxx_dma_ctrl *ctrl, if (requeue_cmd) rsxx_requeue_dma(ctrl, dma); else - rsxx_complete_dma(ctrl, dma, status); + rsxx_complete_dma(ctrl->card, dma, status); } static void dma_engine_stalled(unsigned long data) { struct rsxx_dma_ctrl *ctrl = (struct rsxx_dma_ctrl *)data; - if (atomic_read(&ctrl->stats.hw_q_depth) == 0 || - unlikely(ctrl->card->eeh_state)) + if (atomic_read(&ctrl->stats.hw_q_depth) == 0) return; if (ctrl->cmd.idx != ioread32(ctrl->regmap + SW_CMD_IDX)) { @@ -363,8 +369,7 @@ static void rsxx_issue_dmas(struct work_struct *work) ctrl = container_of(work, struct rsxx_dma_ctrl, issue_dma_work); hw_cmd_buf = ctrl->cmd.buf; - if (unlikely(ctrl->card->halt) || - unlikely(ctrl->card->eeh_state)) + if (unlikely(ctrl->card->halt)) return; while (1) { @@ -392,7 +397,7 @@ static void rsxx_issue_dmas(struct work_struct *work) */ if (unlikely(ctrl->card->dma_fault)) { push_tracker(ctrl->trackers, tag); - rsxx_complete_dma(ctrl, dma, DMA_CANCELLED); + rsxx_complete_dma(ctrl->card, dma, DMA_CANCELLED); continue; } @@ -427,15 +432,19 @@ static void rsxx_issue_dmas(struct work_struct *work) /* Let HW know we've queued commands. */ if (cmds_pending) { + /* + * We must guarantee that the CPU writes to 'ctrl->cmd.buf' + * (which is in PCI-consistent system-memory) from the loop + * above make it into the coherency domain before the + * following PIO "trigger" updating the cmd.idx. A WMB is + * sufficient. We need not explicitly CPU cache-flush since + * the memory is a PCI-consistent (ie; coherent) mapping. + */ + wmb(); + atomic_add(cmds_pending, &ctrl->stats.hw_q_depth); mod_timer(&ctrl->activity_timer, jiffies + DMA_ACTIVITY_TIMEOUT); - - if (unlikely(ctrl->card->eeh_state)) { - del_timer_sync(&ctrl->activity_timer); - return; - } - iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); } } @@ -454,8 +463,7 @@ static void rsxx_dma_done(struct work_struct *work) hw_st_buf = ctrl->status.buf; if (unlikely(ctrl->card->halt) || - unlikely(ctrl->card->dma_fault) || - unlikely(ctrl->card->eeh_state)) + unlikely(ctrl->card->dma_fault)) return; count = le16_to_cpu(hw_st_buf[ctrl->status.idx].count); @@ -500,7 +508,7 @@ static void rsxx_dma_done(struct work_struct *work) if (status) rsxx_handle_dma_error(ctrl, dma, status); else - rsxx_complete_dma(ctrl, dma, 0); + rsxx_complete_dma(ctrl->card, dma, 0); push_tracker(ctrl->trackers, tag); @@ -719,54 +727,20 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card, /*----------------- DMA Engine Initialization & Setup -------------------*/ -int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl) -{ - ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8, - &ctrl->status.dma_addr); - ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8, - &ctrl->cmd.dma_addr); - if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL) - return -ENOMEM; - - memset(ctrl->status.buf, 0xac, STATUS_BUFFER_SIZE8); - iowrite32(lower_32_bits(ctrl->status.dma_addr), - ctrl->regmap + SB_ADD_LO); - iowrite32(upper_32_bits(ctrl->status.dma_addr), - ctrl->regmap + SB_ADD_HI); - - memset(ctrl->cmd.buf, 0x83, COMMAND_BUFFER_SIZE8); - iowrite32(lower_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_LO); - iowrite32(upper_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_HI); - - ctrl->status.idx = ioread32(ctrl->regmap + HW_STATUS_CNT); - if (ctrl->status.idx > RSXX_MAX_OUTSTANDING_CMDS) { - dev_crit(&dev->dev, "Failed reading status cnt x%x\n", - ctrl->status.idx); - return -EINVAL; - } - iowrite32(ctrl->status.idx, ctrl->regmap + HW_STATUS_CNT); - iowrite32(ctrl->status.idx, ctrl->regmap + SW_STATUS_CNT); - - ctrl->cmd.idx = ioread32(ctrl->regmap + HW_CMD_IDX); - if (ctrl->cmd.idx > RSXX_MAX_OUTSTANDING_CMDS) { - dev_crit(&dev->dev, "Failed reading cmd cnt x%x\n", - ctrl->status.idx); - return -EINVAL; - } - iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX); - iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); - - return 0; -} - static int rsxx_dma_ctrl_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl) { int i; - int st; memset(&ctrl->stats, 0, sizeof(ctrl->stats)); + ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8, + &ctrl->status.dma_addr); + ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8, + &ctrl->cmd.dma_addr); + if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL) + return -ENOMEM; + ctrl->trackers = vmalloc(DMA_TRACKER_LIST_SIZE8); if (!ctrl->trackers) return -ENOMEM; @@ -796,9 +770,35 @@ static int rsxx_dma_ctrl_init(struct pci_dev *dev, INIT_WORK(&ctrl->issue_dma_work, rsxx_issue_dmas); INIT_WORK(&ctrl->dma_done_work, rsxx_dma_done); - st = rsxx_hw_buffers_init(dev, ctrl); - if (st) - return st; + memset(ctrl->status.buf, 0xac, STATUS_BUFFER_SIZE8); + iowrite32(lower_32_bits(ctrl->status.dma_addr), + ctrl->regmap + SB_ADD_LO); + iowrite32(upper_32_bits(ctrl->status.dma_addr), + ctrl->regmap + SB_ADD_HI); + + memset(ctrl->cmd.buf, 0x83, COMMAND_BUFFER_SIZE8); + iowrite32(lower_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_LO); + iowrite32(upper_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_HI); + + ctrl->status.idx = ioread32(ctrl->regmap + HW_STATUS_CNT); + if (ctrl->status.idx > RSXX_MAX_OUTSTANDING_CMDS) { + dev_crit(&dev->dev, "Failed reading status cnt x%x\n", + ctrl->status.idx); + return -EINVAL; + } + iowrite32(ctrl->status.idx, ctrl->regmap + HW_STATUS_CNT); + iowrite32(ctrl->status.idx, ctrl->regmap + SW_STATUS_CNT); + + ctrl->cmd.idx = ioread32(ctrl->regmap + HW_CMD_IDX); + if (ctrl->cmd.idx > RSXX_MAX_OUTSTANDING_CMDS) { + dev_crit(&dev->dev, "Failed reading cmd cnt x%x\n", + ctrl->status.idx); + return -EINVAL; + } + iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX); + iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); + + wmb(); return 0; } @@ -834,7 +834,7 @@ static int rsxx_dma_stripe_setup(struct rsxx_cardinfo *card, return 0; } -int rsxx_dma_configure(struct rsxx_cardinfo *card) +static int rsxx_dma_configure(struct rsxx_cardinfo *card) { u32 intr_coal; @@ -980,103 +980,6 @@ void rsxx_dma_destroy(struct rsxx_cardinfo *card) } } -int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card) -{ - int i; - int j; - int cnt; - struct rsxx_dma *dma; - struct list_head *issued_dmas; - - issued_dmas = kzalloc(sizeof(*issued_dmas) * card->n_targets, - GFP_KERNEL); - if (!issued_dmas) - return -ENOMEM; - - for (i = 0; i < card->n_targets; i++) { - INIT_LIST_HEAD(&issued_dmas[i]); - cnt = 0; - for (j = 0; j < RSXX_MAX_OUTSTANDING_CMDS; j++) { - dma = get_tracker_dma(card->ctrl[i].trackers, j); - if (dma == NULL) - continue; - - if (dma->cmd == HW_CMD_BLK_WRITE) - card->ctrl[i].stats.writes_issued--; - else if (dma->cmd == HW_CMD_BLK_DISCARD) - card->ctrl[i].stats.discards_issued--; - else - card->ctrl[i].stats.reads_issued--; - - list_add_tail(&dma->list, &issued_dmas[i]); - push_tracker(card->ctrl[i].trackers, j); - cnt++; - } - - spin_lock(&card->ctrl[i].queue_lock); - list_splice(&issued_dmas[i], &card->ctrl[i].queue); - - atomic_sub(cnt, &card->ctrl[i].stats.hw_q_depth); - card->ctrl[i].stats.sw_q_depth += cnt; - card->ctrl[i].e_cnt = 0; - - list_for_each_entry(dma, &card->ctrl[i].queue, list) { - if (dma->dma_addr) - pci_unmap_page(card->dev, dma->dma_addr, - get_dma_size(dma), - dma->cmd == HW_CMD_BLK_WRITE ? - PCI_DMA_TODEVICE : - PCI_DMA_FROMDEVICE); - } - spin_unlock(&card->ctrl[i].queue_lock); - } - - kfree(issued_dmas); - - return 0; -} - -void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card) -{ - struct rsxx_dma *dma; - struct rsxx_dma *tmp; - int i; - - for (i = 0; i < card->n_targets; i++) { - spin_lock(&card->ctrl[i].queue_lock); - list_for_each_entry_safe(dma, tmp, &card->ctrl[i].queue, list) { - list_del(&dma->list); - - rsxx_complete_dma(&card->ctrl[i], dma, DMA_CANCELLED); - } - spin_unlock(&card->ctrl[i].queue_lock); - } -} - -int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card) -{ - struct rsxx_dma *dma; - int i; - - for (i = 0; i < card->n_targets; i++) { - spin_lock(&card->ctrl[i].queue_lock); - list_for_each_entry(dma, &card->ctrl[i].queue, list) { - dma->dma_addr = pci_map_page(card->dev, dma->page, - dma->pg_off, get_dma_size(dma), - dma->cmd == HW_CMD_BLK_WRITE ? - PCI_DMA_TODEVICE : - PCI_DMA_FROMDEVICE); - if (!dma->dma_addr) { - spin_unlock(&card->ctrl[i].queue_lock); - kmem_cache_free(rsxx_dma_pool, dma); - return -ENOMEM; - } - } - spin_unlock(&card->ctrl[i].queue_lock); - } - - return 0; -} int rsxx_dma_init(void) { diff --git a/trunk/drivers/block/rsxx/rsxx.h b/trunk/drivers/block/rsxx/rsxx.h index 24ba3642bd89..2e50b65902b7 100644 --- a/trunk/drivers/block/rsxx/rsxx.h +++ b/trunk/drivers/block/rsxx/rsxx.h @@ -27,17 +27,15 @@ /*----------------- IOCTL Definitions -------------------*/ -#define RSXX_MAX_DATA 8 - struct rsxx_reg_access { __u32 addr; __u32 cnt; __u32 stat; __u32 stream; - __u32 data[RSXX_MAX_DATA]; + __u32 data[8]; }; -#define RSXX_MAX_REG_CNT (RSXX_MAX_DATA * (sizeof(__u32))) +#define RSXX_MAX_REG_CNT (8 * (sizeof(__u32))) #define RSXX_IOC_MAGIC 'r' diff --git a/trunk/drivers/block/rsxx/rsxx_cfg.h b/trunk/drivers/block/rsxx/rsxx_cfg.h index f384c943846d..c025fe5fdb70 100644 --- a/trunk/drivers/block/rsxx/rsxx_cfg.h +++ b/trunk/drivers/block/rsxx/rsxx_cfg.h @@ -58,7 +58,7 @@ struct rsxx_card_cfg { }; /* Vendor ID Values */ -#define RSXX_VENDOR_ID_IBM 0 +#define RSXX_VENDOR_ID_TMS_IBM 0 #define RSXX_VENDOR_ID_DSI 1 #define RSXX_VENDOR_COUNT 2 diff --git a/trunk/drivers/block/rsxx/rsxx_priv.h b/trunk/drivers/block/rsxx/rsxx_priv.h index 382e8bf5c03b..a1ac907d8f4c 100644 --- a/trunk/drivers/block/rsxx/rsxx_priv.h +++ b/trunk/drivers/block/rsxx/rsxx_priv.h @@ -45,13 +45,16 @@ struct proc_cmd; -#define PCI_DEVICE_ID_FS70_FLASH 0x04A9 -#define PCI_DEVICE_ID_FS80_FLASH 0x04AA +#define PCI_VENDOR_ID_TMS_IBM 0x15B6 +#define PCI_DEVICE_ID_RS70_FLASH 0x0019 +#define PCI_DEVICE_ID_RS70D_FLASH 0x001A +#define PCI_DEVICE_ID_RS80_FLASH 0x001C +#define PCI_DEVICE_ID_RS81_FLASH 0x001E #define RS70_PCI_REV_SUPPORTED 4 #define DRIVER_NAME "rsxx" -#define DRIVER_VERSION "4.0" +#define DRIVER_VERSION "3.7" /* Block size is 4096 */ #define RSXX_HW_BLK_SHIFT 12 @@ -64,9 +67,6 @@ struct proc_cmd; #define RSXX_MAX_OUTSTANDING_CMDS 255 #define RSXX_CS_IDX_MASK 0xff -#define STATUS_BUFFER_SIZE8 4096 -#define COMMAND_BUFFER_SIZE8 4096 - #define RSXX_MAX_TARGETS 8 struct dma_tracker_list; @@ -91,9 +91,6 @@ struct rsxx_dma_stats { u32 discards_failed; u32 done_rescheduled; u32 issue_rescheduled; - u32 dma_sw_err; - u32 dma_hw_fault; - u32 dma_cancelled; u32 sw_q_depth; /* Number of DMAs on the SW queue. */ atomic_t hw_q_depth; /* Number of DMAs queued to HW. */ }; @@ -119,7 +116,6 @@ struct rsxx_dma_ctrl { struct rsxx_cardinfo { struct pci_dev *dev; unsigned int halt; - unsigned int eeh_state; void __iomem *regmap; spinlock_t irq_lock; @@ -228,7 +224,6 @@ enum rsxx_pci_regmap { PERF_RD512_HI = 0xac, PERF_WR512_LO = 0xb0, PERF_WR512_HI = 0xb4, - PCI_RECONFIG = 0xb8, }; enum rsxx_intr { @@ -242,8 +237,6 @@ enum rsxx_intr { CR_INTR_DMA5 = 0x00000080, CR_INTR_DMA6 = 0x00000100, CR_INTR_DMA7 = 0x00000200, - CR_INTR_ALL_C = 0x0000003f, - CR_INTR_ALL_G = 0x000003ff, CR_INTR_DMA_ALL = 0x000003f5, CR_INTR_ALL = 0xffffffff, }; @@ -260,14 +253,8 @@ enum rsxx_pci_reset { DMA_QUEUE_RESET = 0x00000001, }; -enum rsxx_hw_fifo_flush { - RSXX_FLUSH_BUSY = 0x00000002, - RSXX_FLUSH_TIMEOUT = 0x00000004, -}; - enum rsxx_pci_revision { RSXX_DISCARD_SUPPORT = 2, - RSXX_EEH_SUPPORT = 3, }; enum rsxx_creg_cmd { @@ -373,17 +360,11 @@ int rsxx_dma_setup(struct rsxx_cardinfo *card); void rsxx_dma_destroy(struct rsxx_cardinfo *card); int rsxx_dma_init(void); void rsxx_dma_cleanup(void); -void rsxx_dma_queue_reset(struct rsxx_cardinfo *card); -int rsxx_dma_configure(struct rsxx_cardinfo *card); int rsxx_dma_queue_bio(struct rsxx_cardinfo *card, struct bio *bio, atomic_t *n_dmas, rsxx_dma_cb cb, void *cb_data); -int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl); -int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card); -void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card); -int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card); /***** cregs.c *****/ int rsxx_creg_write(struct rsxx_cardinfo *card, u32 addr, @@ -408,11 +389,10 @@ int rsxx_creg_setup(struct rsxx_cardinfo *card); void rsxx_creg_destroy(struct rsxx_cardinfo *card); int rsxx_creg_init(void); void rsxx_creg_cleanup(void); + int rsxx_reg_access(struct rsxx_cardinfo *card, struct rsxx_reg_access __user *ucmd, int read); -void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card); -void rsxx_kick_creg_queue(struct rsxx_cardinfo *card); diff --git a/trunk/drivers/block/xen-blkback/blkback.c b/trunk/drivers/block/xen-blkback/blkback.c index dd5b2fed97e9..de1f319f7bd7 100644 --- a/trunk/drivers/block/xen-blkback/blkback.c +++ b/trunk/drivers/block/xen-blkback/blkback.c @@ -164,7 +164,7 @@ static void make_response(struct xen_blkif *blkif, u64 id, #define foreach_grant_safe(pos, n, rbtree, node) \ for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \ - (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL; \ + (n) = rb_next(&(pos)->node); \ &(pos)->node != NULL; \ (pos) = container_of(n, typeof(*(pos)), node), \ (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL) @@ -381,8 +381,8 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id) static void print_stats(struct xen_blkif *blkif) { - pr_info("xen-blkback (%s): oo %3llu | rd %4llu | wr %4llu | f %4llu" - " | ds %4llu\n", + pr_info("xen-blkback (%s): oo %3d | rd %4d | wr %4d | f %4d" + " | ds %4d\n", current->comm, blkif->st_oo_req, blkif->st_rd_req, blkif->st_wr_req, blkif->st_f_req, blkif->st_ds_req); @@ -442,7 +442,7 @@ int xen_blkif_schedule(void *arg) } struct seg_buf { - unsigned int offset; + unsigned long buf; unsigned int nsec; }; /* @@ -621,21 +621,30 @@ static int xen_blkbk_map(struct blkif_request *req, * If this is a new persistent grant * save the handler */ - persistent_gnts[i]->handle = map[j++].handle; + persistent_gnts[i]->handle = map[j].handle; + persistent_gnts[i]->dev_bus_addr = + map[j++].dev_bus_addr; } pending_handle(pending_req, i) = persistent_gnts[i]->handle; if (ret) continue; + + seg[i].buf = persistent_gnts[i]->dev_bus_addr | + (req->u.rw.seg[i].first_sect << 9); } else { - pending_handle(pending_req, i) = map[j++].handle; + pending_handle(pending_req, i) = map[j].handle; bitmap_set(pending_req->unmap_seg, i, 1); - if (ret) + if (ret) { + j++; continue; + } + + seg[i].buf = map[j++].dev_bus_addr | + (req->u.rw.seg[i].first_sect << 9); } - seg[i].offset = (req->u.rw.seg[i].first_sect << 9); } return ret; } @@ -670,16 +679,6 @@ static int dispatch_discard_io(struct xen_blkif *blkif, return err; } -static int dispatch_other_io(struct xen_blkif *blkif, - struct blkif_request *req, - struct pending_req *pending_req) -{ - free_req(pending_req); - make_response(blkif, req->u.other.id, req->operation, - BLKIF_RSP_EOPNOTSUPP); - return -EIO; -} - static void xen_blk_drain_io(struct xen_blkif *blkif) { atomic_set(&blkif->drain, 1); @@ -801,30 +800,17 @@ __do_block_io_op(struct xen_blkif *blkif) /* Apply all sanity checks to /private copy/ of request. */ barrier(); - - switch (req.operation) { - case BLKIF_OP_READ: - case BLKIF_OP_WRITE: - case BLKIF_OP_WRITE_BARRIER: - case BLKIF_OP_FLUSH_DISKCACHE: - if (dispatch_rw_block_io(blkif, &req, pending_req)) - goto done; - break; - case BLKIF_OP_DISCARD: + if (unlikely(req.operation == BLKIF_OP_DISCARD)) { free_req(pending_req); if (dispatch_discard_io(blkif, &req)) - goto done; + break; + } else if (dispatch_rw_block_io(blkif, &req, pending_req)) break; - default: - if (dispatch_other_io(blkif, &req, pending_req)) - goto done; - break; - } /* Yield point for this unbounded loop. */ cond_resched(); } -done: + return more_to_do; } @@ -918,8 +904,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n", operation == READ ? "read" : "write", preq.sector_number, - preq.sector_number + preq.nr_sects, - blkif->vbd.pdevice); + preq.sector_number + preq.nr_sects, preq.dev); goto fail_response; } @@ -962,7 +947,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, (bio_add_page(bio, pages[i], seg[i].nsec << 9, - seg[i].offset) == 0)) { + seg[i].buf & ~PAGE_MASK) == 0)) { bio = bio_alloc(GFP_KERNEL, nseg-i); if (unlikely(bio == NULL)) @@ -992,7 +977,13 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, bio->bi_end_io = end_block_io_op; } + /* + * We set it one so that the last submit_bio does not have to call + * atomic_inc. + */ atomic_set(&pending_req->pendcnt, nbio); + + /* Get a reference count for the disk queue and start sending I/O */ blk_start_plug(&plug); for (i = 0; i < nbio; i++) @@ -1020,7 +1011,6 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, fail_put_bio: for (i = 0; i < nbio; i++) bio_put(biolist[i]); - atomic_set(&pending_req->pendcnt, 1); __end_block_io_op(pending_req, -EINVAL); msleep(1); /* back off a bit */ return -EIO; diff --git a/trunk/drivers/block/xen-blkback/common.h b/trunk/drivers/block/xen-blkback/common.h index 60103e2517ba..6072390c7f57 100644 --- a/trunk/drivers/block/xen-blkback/common.h +++ b/trunk/drivers/block/xen-blkback/common.h @@ -77,18 +77,11 @@ struct blkif_x86_32_request_discard { uint64_t nr_sectors; } __attribute__((__packed__)); -struct blkif_x86_32_request_other { - uint8_t _pad1; - blkif_vdev_t _pad2; - uint64_t id; /* private guest value, echoed in resp */ -} __attribute__((__packed__)); - struct blkif_x86_32_request { uint8_t operation; /* BLKIF_OP_??? */ union { struct blkif_x86_32_request_rw rw; struct blkif_x86_32_request_discard discard; - struct blkif_x86_32_request_other other; } u; } __attribute__((__packed__)); @@ -120,19 +113,11 @@ struct blkif_x86_64_request_discard { uint64_t nr_sectors; } __attribute__((__packed__)); -struct blkif_x86_64_request_other { - uint8_t _pad1; - blkif_vdev_t _pad2; - uint32_t _pad3; /* offsetof(blkif_..,u.discard.id)==8 */ - uint64_t id; /* private guest value, echoed in resp */ -} __attribute__((__packed__)); - struct blkif_x86_64_request { uint8_t operation; /* BLKIF_OP_??? */ union { struct blkif_x86_64_request_rw rw; struct blkif_x86_64_request_discard discard; - struct blkif_x86_64_request_other other; } u; } __attribute__((__packed__)); @@ -187,6 +172,7 @@ struct persistent_gnt { struct page *page; grant_ref_t gnt; grant_handle_t handle; + uint64_t dev_bus_addr; struct rb_node node; }; @@ -222,13 +208,13 @@ struct xen_blkif { /* statistics */ unsigned long st_print; - unsigned long long st_rd_req; - unsigned long long st_wr_req; - unsigned long long st_oo_req; - unsigned long long st_f_req; - unsigned long long st_ds_req; - unsigned long long st_rd_sect; - unsigned long long st_wr_sect; + int st_rd_req; + int st_wr_req; + int st_oo_req; + int st_f_req; + int st_ds_req; + int st_rd_sect; + int st_wr_sect; wait_queue_head_t waiting_to_free; }; @@ -292,11 +278,6 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; default: - /* - * Don't know how to translate this op. Only get the - * ID so failure can be reported to the frontend. - */ - dst->u.other.id = src->u.other.id; break; } } @@ -328,11 +309,6 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; default: - /* - * Don't know how to translate this op. Only get the - * ID so failure can be reported to the frontend. - */ - dst->u.other.id = src->u.other.id; break; } } diff --git a/trunk/drivers/block/xen-blkback/xenbus.c b/trunk/drivers/block/xen-blkback/xenbus.c index 8bfd1bcf95ec..5e237f630c47 100644 --- a/trunk/drivers/block/xen-blkback/xenbus.c +++ b/trunk/drivers/block/xen-blkback/xenbus.c @@ -230,13 +230,13 @@ int __init xen_blkif_interface_init(void) } \ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) -VBD_SHOW(oo_req, "%llu\n", be->blkif->st_oo_req); -VBD_SHOW(rd_req, "%llu\n", be->blkif->st_rd_req); -VBD_SHOW(wr_req, "%llu\n", be->blkif->st_wr_req); -VBD_SHOW(f_req, "%llu\n", be->blkif->st_f_req); -VBD_SHOW(ds_req, "%llu\n", be->blkif->st_ds_req); -VBD_SHOW(rd_sect, "%llu\n", be->blkif->st_rd_sect); -VBD_SHOW(wr_sect, "%llu\n", be->blkif->st_wr_sect); +VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req); +VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req); +VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req); +VBD_SHOW(f_req, "%d\n", be->blkif->st_f_req); +VBD_SHOW(ds_req, "%d\n", be->blkif->st_ds_req); +VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect); +VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect); static struct attribute *xen_vbdstat_attrs[] = { &dev_attr_oo_req.attr, diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index a894f88762d8..c3dae2e0f290 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include @@ -68,12 +68,13 @@ enum blkif_state { struct grant { grant_ref_t gref; unsigned long pfn; - struct list_head node; + struct llist_node node; }; struct blk_shadow { struct blkif_request req; struct request *request; + unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct grant *grants_used[BLKIF_MAX_SEGMENTS_PER_REQUEST]; }; @@ -104,7 +105,7 @@ struct blkfront_info struct work_struct work; struct gnttab_free_callback callback; struct blk_shadow shadow[BLK_RING_SIZE]; - struct list_head persistent_gnts; + struct llist_head persistent_gnts; unsigned int persistent_gnts_c; unsigned long shadow_free; unsigned int feature_flush; @@ -164,69 +165,6 @@ static int add_id_to_freelist(struct blkfront_info *info, return 0; } -static int fill_grant_buffer(struct blkfront_info *info, int num) -{ - struct page *granted_page; - struct grant *gnt_list_entry, *n; - int i = 0; - - while(i < num) { - gnt_list_entry = kzalloc(sizeof(struct grant), GFP_NOIO); - if (!gnt_list_entry) - goto out_of_memory; - - granted_page = alloc_page(GFP_NOIO); - if (!granted_page) { - kfree(gnt_list_entry); - goto out_of_memory; - } - - gnt_list_entry->pfn = page_to_pfn(granted_page); - gnt_list_entry->gref = GRANT_INVALID_REF; - list_add(&gnt_list_entry->node, &info->persistent_gnts); - i++; - } - - return 0; - -out_of_memory: - list_for_each_entry_safe(gnt_list_entry, n, - &info->persistent_gnts, node) { - list_del(&gnt_list_entry->node); - __free_page(pfn_to_page(gnt_list_entry->pfn)); - kfree(gnt_list_entry); - i--; - } - BUG_ON(i != 0); - return -ENOMEM; -} - -static struct grant *get_grant(grant_ref_t *gref_head, - struct blkfront_info *info) -{ - struct grant *gnt_list_entry; - unsigned long buffer_mfn; - - BUG_ON(list_empty(&info->persistent_gnts)); - gnt_list_entry = list_first_entry(&info->persistent_gnts, struct grant, - node); - list_del(&gnt_list_entry->node); - - if (gnt_list_entry->gref != GRANT_INVALID_REF) { - info->persistent_gnts_c--; - return gnt_list_entry; - } - - /* Assign a gref to this page */ - gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); - BUG_ON(gnt_list_entry->gref == -ENOSPC); - buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); - gnttab_grant_foreign_access_ref(gnt_list_entry->gref, - info->xbdev->otherend_id, - buffer_mfn, 0); - return gnt_list_entry; -} - static const char *op_name(int op) { static const char *const names[] = { @@ -355,6 +293,7 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode, static int blkif_queue_request(struct request *req) { struct blkfront_info *info = req->rq_disk->private_data; + unsigned long buffer_mfn; struct blkif_request *ring_req; unsigned long id; unsigned int fsect, lsect; @@ -367,6 +306,7 @@ static int blkif_queue_request(struct request *req) */ bool new_persistent_gnts; grant_ref_t gref_head; + struct page *granted_page; struct grant *gnt_list_entry = NULL; struct scatterlist *sg; @@ -430,8 +370,41 @@ static int blkif_queue_request(struct request *req) fsect = sg->offset >> 9; lsect = fsect + (sg->length >> 9) - 1; - gnt_list_entry = get_grant(&gref_head, info); - ref = gnt_list_entry->gref; + if (info->persistent_gnts_c) { + BUG_ON(llist_empty(&info->persistent_gnts)); + gnt_list_entry = llist_entry( + llist_del_first(&info->persistent_gnts), + struct grant, node); + + ref = gnt_list_entry->gref; + buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); + info->persistent_gnts_c--; + } else { + ref = gnttab_claim_grant_reference(&gref_head); + BUG_ON(ref == -ENOSPC); + + gnt_list_entry = + kmalloc(sizeof(struct grant), + GFP_ATOMIC); + if (!gnt_list_entry) + return -ENOMEM; + + granted_page = alloc_page(GFP_ATOMIC); + if (!granted_page) { + kfree(gnt_list_entry); + return -ENOMEM; + } + + gnt_list_entry->pfn = + page_to_pfn(granted_page); + gnt_list_entry->gref = ref; + + buffer_mfn = pfn_to_mfn(page_to_pfn( + granted_page)); + gnttab_grant_foreign_access_ref(ref, + info->xbdev->otherend_id, + buffer_mfn, 0); + } info->shadow[id].grants_used[i] = gnt_list_entry; @@ -462,6 +435,7 @@ static int blkif_queue_request(struct request *req) kunmap_atomic(shared_data); } + info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); ring_req->u.rw.seg[i] = (struct blkif_request_segment) { .gref = ref, @@ -816,8 +790,9 @@ static void blkif_restart_queue(struct work_struct *work) static void blkif_free(struct blkfront_info *info, int suspend) { - struct grant *persistent_gnt; - struct grant *n; + struct llist_node *all_gnts; + struct grant *persistent_gnt, *tmp; + struct llist_node *n; /* Prevent new requests being issued until we fix things up. */ spin_lock_irq(&info->io_lock); @@ -828,20 +803,22 @@ static void blkif_free(struct blkfront_info *info, int suspend) blk_stop_queue(info->rq); /* Remove all persistent grants */ - if (!list_empty(&info->persistent_gnts)) { - list_for_each_entry_safe(persistent_gnt, n, - &info->persistent_gnts, node) { - list_del(&persistent_gnt->node); - if (persistent_gnt->gref != GRANT_INVALID_REF) { - gnttab_end_foreign_access(persistent_gnt->gref, - 0, 0UL); - info->persistent_gnts_c--; - } + if (info->persistent_gnts_c) { + all_gnts = llist_del_all(&info->persistent_gnts); + persistent_gnt = llist_entry(all_gnts, typeof(*(persistent_gnt)), node); + while (persistent_gnt) { + gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); __free_page(pfn_to_page(persistent_gnt->pfn)); - kfree(persistent_gnt); + tmp = persistent_gnt; + n = persistent_gnt->node.next; + if (n) + persistent_gnt = llist_entry(n, typeof(*(persistent_gnt)), node); + else + persistent_gnt = NULL; + kfree(tmp); } + info->persistent_gnts_c = 0; } - BUG_ON(info->persistent_gnts_c != 0); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); @@ -898,7 +875,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, } /* Add the persistent grant into the list of free grants */ for (i = 0; i < s->req.u.rw.nr_segments; i++) { - list_add(&s->grants_used[i]->node, &info->persistent_gnts); + llist_add(&s->grants_used[i]->node, &info->persistent_gnts); info->persistent_gnts_c++; } } @@ -1036,12 +1013,6 @@ static int setup_blkring(struct xenbus_device *dev, sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST); - /* Allocate memory for grants */ - err = fill_grant_buffer(info, BLK_RING_SIZE * - BLKIF_MAX_SEGMENTS_PER_REQUEST); - if (err) - goto fail; - err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); if (err < 0) { free_page((unsigned long)sring); @@ -1200,7 +1171,7 @@ static int blkfront_probe(struct xenbus_device *dev, spin_lock_init(&info->io_lock); info->xbdev = dev; info->vdevice = vdevice; - INIT_LIST_HEAD(&info->persistent_gnts); + init_llist_head(&info->persistent_gnts); info->persistent_gnts_c = 0; info->connected = BLKIF_STATE_DISCONNECTED; INIT_WORK(&info->work, blkif_restart_queue); @@ -1232,10 +1203,11 @@ static int blkif_recover(struct blkfront_info *info) int j; /* Stage 1: Make a safe copy of the shadow state. */ - copy = kmemdup(info->shadow, sizeof(info->shadow), + copy = kmalloc(sizeof(info->shadow), GFP_NOIO | __GFP_REPEAT | __GFP_HIGH); if (!copy) return -ENOMEM; + memcpy(copy, info->shadow, sizeof(info->shadow)); /* Stage 2: Set up free list. */ memset(&info->shadow, 0, sizeof(info->shadow)); @@ -1264,7 +1236,7 @@ static int blkif_recover(struct blkfront_info *info) gnttab_grant_foreign_access_ref( req->u.rw.seg[j].gref, info->xbdev->otherend_id, - pfn_to_mfn(copy[i].grants_used[j]->pfn), + pfn_to_mfn(info->shadow[req->u.rw.id].frame[j]), 0); } info->shadow[req->u.rw.id].req = *req; diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index 6aab00ef4379..a8a41e07a221 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -73,13 +73,9 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x03F0, 0x311D) }, /* Atheros AR3012 with sflash firmware*/ - { USB_DEVICE(0x0CF3, 0x0036) }, { USB_DEVICE(0x0CF3, 0x3004) }, - { USB_DEVICE(0x0CF3, 0x3008) }, { USB_DEVICE(0x0CF3, 0x311D) }, - { USB_DEVICE(0x0CF3, 0x817a) }, { USB_DEVICE(0x13d3, 0x3375) }, - { USB_DEVICE(0x04CA, 0x3004) }, { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3006) }, { USB_DEVICE(0x04CA, 0x3008) }, @@ -109,13 +105,9 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); static struct usb_device_id ath3k_blist_tbl[] = { /* Atheros AR3012 with sflash firmware*/ - { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, diff --git a/trunk/drivers/bluetooth/bluecard_cs.c b/trunk/drivers/bluetooth/bluecard_cs.c index 6c3e3d43c718..0d26851d6e49 100644 --- a/trunk/drivers/bluetooth/bluecard_cs.c +++ b/trunk/drivers/bluetooth/bluecard_cs.c @@ -934,4 +934,17 @@ static struct pcmcia_driver bluecard_driver = { .remove = bluecard_detach, .id_table = bluecard_ids, }; -module_pcmcia_driver(bluecard_driver); + +static int __init init_bluecard_cs(void) +{ + return pcmcia_register_driver(&bluecard_driver); +} + + +static void __exit exit_bluecard_cs(void) +{ + pcmcia_unregister_driver(&bluecard_driver); +} + +module_init(init_bluecard_cs); +module_exit(exit_bluecard_cs); diff --git a/trunk/drivers/bluetooth/bt3c_cs.c b/trunk/drivers/bluetooth/bt3c_cs.c index a1aaa3ba2a4b..7ffd3f407144 100644 --- a/trunk/drivers/bluetooth/bt3c_cs.c +++ b/trunk/drivers/bluetooth/bt3c_cs.c @@ -760,4 +760,17 @@ static struct pcmcia_driver bt3c_driver = { .remove = bt3c_detach, .id_table = bt3c_ids, }; -module_pcmcia_driver(bt3c_driver); + +static int __init init_bt3c_cs(void) +{ + return pcmcia_register_driver(&bt3c_driver); +} + + +static void __exit exit_bt3c_cs(void) +{ + pcmcia_unregister_driver(&bt3c_driver); +} + +module_init(init_bt3c_cs); +module_exit(exit_bt3c_cs); diff --git a/trunk/drivers/bluetooth/btuart_cs.c b/trunk/drivers/bluetooth/btuart_cs.c index beb262f2dc4d..35a553a90616 100644 --- a/trunk/drivers/bluetooth/btuart_cs.c +++ b/trunk/drivers/bluetooth/btuart_cs.c @@ -688,4 +688,17 @@ static struct pcmcia_driver btuart_driver = { .remove = btuart_detach, .id_table = btuart_ids, }; -module_pcmcia_driver(btuart_driver); + +static int __init init_btuart_cs(void) +{ + return pcmcia_register_driver(&btuart_driver); +} + + +static void __exit exit_btuart_cs(void) +{ + pcmcia_unregister_driver(&btuart_driver); +} + +module_init(init_btuart_cs); +module_exit(exit_btuart_cs); diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index 2cc5f774a29c..7e351e345476 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -131,13 +131,9 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, /* Atheros 3012 with sflash firmware */ - { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c index 33f3a6950c0e..036cb366fe6e 100644 --- a/trunk/drivers/bluetooth/dtl1_cs.c +++ b/trunk/drivers/bluetooth/dtl1_cs.c @@ -628,4 +628,17 @@ static struct pcmcia_driver dtl1_driver = { .remove = dtl1_detach, .id_table = dtl1_ids, }; -module_pcmcia_driver(dtl1_driver); + +static int __init init_dtl1_cs(void) +{ + return pcmcia_register_driver(&dtl1_driver); +} + + +static void __exit exit_dtl1_cs(void) +{ + pcmcia_unregister_driver(&dtl1_driver); +} + +module_init(init_dtl1_cs); +module_exit(exit_dtl1_cs); diff --git a/trunk/drivers/char/applicom.c b/trunk/drivers/char/applicom.c index 974321a2508d..25373df1dcf8 100644 --- a/trunk/drivers/char/applicom.c +++ b/trunk/drivers/char/applicom.c @@ -804,8 +804,8 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) printk(KERN_INFO "Prom version board %d ....... V%d.%d %s", i+1, - (int)(readb(apbs[i].RamIO + VERS) >> 4), - (int)(readb(apbs[i].RamIO + VERS) & 0xF), + (int)(readb(apbs[IndexCard].RamIO + VERS) >> 4), + (int)(readb(apbs[IndexCard].RamIO + VERS) & 0xF), boardname); diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index d784650d14f0..e3f9a99b8522 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -373,14 +373,26 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) struct hpet_dev *devp; unsigned long addr; + if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) + return -EINVAL; + devp = file->private_data; addr = devp->hd_hpets->hp_hpet_phys; if (addr & (PAGE_SIZE - 1)) return -ENOSYS; + vma->vm_flags |= VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - return vm_iomap_memory(vma, addr, PAGE_SIZE); + + if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, + PAGE_SIZE, vma->vm_page_prot)) { + printk(KERN_ERR "%s: io_remap_pfn_range failed\n", + __func__); + return -EAGAIN; + } + + return 0; #else return -ENOSYS; #endif diff --git a/trunk/drivers/char/hw_random/core.c b/trunk/drivers/char/hw_random/core.c index a0f7724852eb..1bafb40ec8a2 100644 --- a/trunk/drivers/char/hw_random/core.c +++ b/trunk/drivers/char/hw_random/core.c @@ -40,7 +40,6 @@ #include #include #include -#include #include @@ -53,12 +52,8 @@ static struct hwrng *current_rng; static LIST_HEAD(rng_list); static DEFINE_MUTEX(rng_mutex); static int data_avail; -static u8 *rng_buffer; - -static size_t rng_buffer_size(void) -{ - return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES; -} +static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES] + __cacheline_aligned; static inline int hwrng_init(struct hwrng *rng) { @@ -121,7 +116,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf, if (!data_avail) { bytes_read = rng_get_data(current_rng, rng_buffer, - rng_buffer_size(), + sizeof(rng_buffer), !(filp->f_flags & O_NONBLOCK)); if (bytes_read < 0) { err = bytes_read; @@ -312,14 +307,6 @@ int hwrng_register(struct hwrng *rng) mutex_lock(&rng_mutex); - /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */ - err = -ENOMEM; - if (!rng_buffer) { - rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL); - if (!rng_buffer) - goto out_unlock; - } - /* Must not register two RNGs with the same name. */ err = -EEXIST; list_for_each_entry(tmp, &rng_list, list) { @@ -380,15 +367,6 @@ void hwrng_unregister(struct hwrng *rng) } EXPORT_SYMBOL_GPL(hwrng_unregister); -static void __exit hwrng_exit(void) -{ - mutex_lock(&rng_mutex); - BUG_ON(current_rng); - kfree(rng_buffer); - mutex_unlock(&rng_mutex); -} - -module_exit(hwrng_exit); MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/hw_random/mxc-rnga.c b/trunk/drivers/char/hw_random/mxc-rnga.c index 895d0b8fb9ab..f05d85713fd3 100644 --- a/trunk/drivers/char/hw_random/mxc-rnga.c +++ b/trunk/drivers/char/hw_random/mxc-rnga.c @@ -228,7 +228,18 @@ static struct platform_driver mxc_rnga_driver = { .remove = __exit_p(mxc_rnga_remove), }; -module_platform_driver_probe(mxc_rnga_driver, mxc_rnga_probe); +static int __init mod_init(void) +{ + return platform_driver_probe(&mxc_rnga_driver, mxc_rnga_probe); +} + +static void __exit mod_exit(void) +{ + platform_driver_unregister(&mxc_rnga_driver); +} + +module_init(mod_init); +module_exit(mod_exit); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_DESCRIPTION("H/W RNGA driver for i.MX"); diff --git a/trunk/drivers/char/hw_random/tx4939-rng.c b/trunk/drivers/char/hw_random/tx4939-rng.c index d34a24a0d484..30991989d65b 100644 --- a/trunk/drivers/char/hw_random/tx4939-rng.c +++ b/trunk/drivers/char/hw_random/tx4939-rng.c @@ -166,7 +166,18 @@ static struct platform_driver tx4939_rng_driver = { .remove = tx4939_rng_remove, }; -module_platform_driver_probe(tx4939_rng_driver, tx4939_rng_probe); +static int __init tx4939rng_init(void) +{ + return platform_driver_probe(&tx4939_rng_driver, tx4939_rng_probe); +} + +static void __exit tx4939rng_exit(void) +{ + platform_driver_unregister(&tx4939_rng_driver); +} + +module_init(tx4939rng_init); +module_exit(tx4939rng_exit); MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for TX4939"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/hw_random/virtio-rng.c b/trunk/drivers/char/hw_random/virtio-rng.c index 6bf4d47324eb..10fd71ccf587 100644 --- a/trunk/drivers/char/hw_random/virtio-rng.c +++ b/trunk/drivers/char/hw_random/virtio-rng.c @@ -92,22 +92,14 @@ static int probe_common(struct virtio_device *vdev) { int err; - if (vq) { - /* We only support one device for now */ - return -EBUSY; - } /* We expect a single virtqueue. */ vq = virtio_find_single_vq(vdev, random_recv_done, "input"); - if (IS_ERR(vq)) { - err = PTR_ERR(vq); - vq = NULL; - return err; - } + if (IS_ERR(vq)) + return PTR_ERR(vq); err = hwrng_register(&virtio_hwrng); if (err) { vdev->config->del_vqs(vdev); - vq = NULL; return err; } @@ -120,7 +112,6 @@ static void remove_common(struct virtio_device *vdev) busy = false; hwrng_unregister(&virtio_hwrng); vdev->config->del_vqs(vdev); - vq = NULL; } static int virtrng_probe(struct virtio_device *vdev) diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 32a6c5764950..594bda9dcfc8 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -852,7 +852,6 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, int reserved) { unsigned long flags; - int wakeup_write = 0; /* Hold lock while accounting */ spin_lock_irqsave(&r->lock, flags); @@ -874,8 +873,10 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, else r->entropy_count = reserved; - if (r->entropy_count < random_write_wakeup_thresh) - wakeup_write = 1; + if (r->entropy_count < random_write_wakeup_thresh) { + wake_up_interruptible(&random_write_wait); + kill_fasync(&fasync, SIGIO, POLL_OUT); + } } DEBUG_ENT("debiting %zu entropy credits from %s%s\n", @@ -883,11 +884,6 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, spin_unlock_irqrestore(&r->lock, flags); - if (wakeup_write) { - wake_up_interruptible(&random_write_wait); - kill_fasync(&fasync, SIGIO, POLL_OUT); - } - return nbytes; } diff --git a/trunk/drivers/char/tile-srom.c b/trunk/drivers/char/tile-srom.c index 2e2036e940fc..3b22a606f79d 100644 --- a/trunk/drivers/char/tile-srom.c +++ b/trunk/drivers/char/tile-srom.c @@ -371,7 +371,7 @@ static int srom_setup_minor(struct srom_dev *srom, int index) dev = device_create(srom_class, &platform_bus, MKDEV(srom_major, index), srom, "%d", index); - return PTR_RET(dev); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; } /** srom_init() - Initialize the driver's module. */ diff --git a/trunk/drivers/char/virtio_console.c b/trunk/drivers/char/virtio_console.c index ce5f3fc25d6d..e905d5f53051 100644 --- a/trunk/drivers/char/virtio_console.c +++ b/trunk/drivers/char/virtio_console.c @@ -149,8 +149,7 @@ struct ports_device { spinlock_t ports_lock; /* To protect the vq operations for the control channel */ - spinlock_t c_ivq_lock; - spinlock_t c_ovq_lock; + spinlock_t cvq_lock; /* The current config space is stored here */ struct virtio_console_config config; @@ -570,14 +569,11 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, vq = portdev->c_ovq; sg_init_one(sg, &cpkt, sizeof(cpkt)); - - spin_lock(&portdev->c_ovq_lock); if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) == 0) { virtqueue_kick(vq); while (!virtqueue_get_buf(vq, &len)) cpu_relax(); } - spin_unlock(&portdev->c_ovq_lock); return 0; } @@ -1440,7 +1436,7 @@ static int add_port(struct ports_device *portdev, u32 id) * rproc_serial does not want the console port, only * the generic port implementation. */ - port->host_connected = true; + port->host_connected = port->guest_connected = true; else if (!use_multiport(port->portdev)) { /* * If we're not using multiport support, @@ -1713,23 +1709,23 @@ static void control_work_handler(struct work_struct *work) portdev = container_of(work, struct ports_device, control_work); vq = portdev->c_ivq; - spin_lock(&portdev->c_ivq_lock); + spin_lock(&portdev->cvq_lock); while ((buf = virtqueue_get_buf(vq, &len))) { - spin_unlock(&portdev->c_ivq_lock); + spin_unlock(&portdev->cvq_lock); buf->len = len; buf->offset = 0; handle_control_message(portdev, buf); - spin_lock(&portdev->c_ivq_lock); + spin_lock(&portdev->cvq_lock); if (add_inbuf(portdev->c_ivq, buf) < 0) { dev_warn(&portdev->vdev->dev, "Error adding buffer to queue\n"); free_buf(buf, false); } } - spin_unlock(&portdev->c_ivq_lock); + spin_unlock(&portdev->cvq_lock); } static void out_intr(struct virtqueue *vq) @@ -1756,23 +1752,13 @@ static void in_intr(struct virtqueue *vq) port->inbuf = get_inbuf(port); /* - * Normally the port should not accept data when the port is - * closed. For generic serial ports, the host won't (shouldn't) - * send data till the guest is connected. But this condition + * Don't queue up data when port is closed. This condition * can be reached when a console port is not yet connected (no - * tty is spawned) and the other side sends out data over the - * vring, or when a remote devices start sending data before - * the ports are opened. - * - * A generic serial port will discard data if not connected, - * while console ports and rproc-serial ports accepts data at - * any time. rproc-serial is initiated with guest_connected to - * false because port_fops_open expects this. Console ports are - * hooked up with an HVC console and is initialized with - * guest_connected to true. + * tty is spawned) and the host sends out data to console + * ports. For generic serial ports, the host won't + * (shouldn't) send data till the guest is connected. */ - - if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) + if (!port->guest_connected) discard_port_data(port); spin_unlock_irqrestore(&port->inbuf_lock, flags); @@ -2000,12 +1986,10 @@ static int virtcons_probe(struct virtio_device *vdev) if (multiport) { unsigned int nr_added_bufs; - spin_lock_init(&portdev->c_ivq_lock); - spin_lock_init(&portdev->c_ovq_lock); + spin_lock_init(&portdev->cvq_lock); INIT_WORK(&portdev->control_work, &control_work_handler); - nr_added_bufs = fill_queue(portdev->c_ivq, - &portdev->c_ivq_lock); + nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock); if (!nr_added_bufs) { dev_err(&vdev->dev, "Error allocating buffers for control queue\n"); @@ -2156,7 +2140,7 @@ static int virtcons_restore(struct virtio_device *vdev) return ret; if (use_multiport(portdev)) - fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); + fill_queue(portdev->c_ivq, &portdev->cvq_lock); list_for_each_entry(port, &portdev->ports, list) { port->in_vq = portdev->in_vqs[port->id]; diff --git a/trunk/drivers/clk/clk-vt8500.c b/trunk/drivers/clk/clk-vt8500.c index 09c63315e579..b5538bba7a10 100644 --- a/trunk/drivers/clk/clk-vt8500.c +++ b/trunk/drivers/clk/clk-vt8500.c @@ -157,7 +157,7 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, divisor = parent_rate / rate; /* If prate / rate would be decimal, incr the divisor */ - if (rate * divisor < parent_rate) + if (rate * divisor < *prate) divisor++; if (divisor == cdev->div_mask + 1) diff --git a/trunk/drivers/clk/tegra/clk-tegra20.c b/trunk/drivers/clk/tegra/clk-tegra20.c index f873dcefe0de..143ce1f899ad 100644 --- a/trunk/drivers/clk/tegra/clk-tegra20.c +++ b/trunk/drivers/clk/tegra/clk-tegra20.c @@ -703,7 +703,7 @@ static void tegra20_pll_init(void) clks[pll_a_out0] = clk; /* PLLE */ - clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base, + clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, NULL, 0, 100000000, &pll_e_params, 0, pll_e_freq_table, NULL); clk_register_clkdev(clk, "pll_e", NULL); @@ -1292,6 +1292,7 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), TEGRA_CLK_DUPLICATE(cclk, NULL, "cpu"), + TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL), TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */ }; diff --git a/trunk/drivers/clk/tegra/clk-tegra30.c b/trunk/drivers/clk/tegra/clk-tegra30.c index ba6f51bc9f3b..32c61cb6d0bb 100644 --- a/trunk/drivers/clk/tegra/clk-tegra30.c +++ b/trunk/drivers/clk/tegra/clk-tegra30.c @@ -1931,6 +1931,7 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL), TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"), TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"), + TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL), TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"), TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */ }; diff --git a/trunk/drivers/connector/cn_proc.c b/trunk/drivers/connector/cn_proc.c index 1110478dd0fd..fce2000eec31 100644 --- a/trunk/drivers/connector/cn_proc.c +++ b/trunk/drivers/connector/cn_proc.c @@ -313,12 +313,6 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, (task_active_pid_ns(current) != &init_pid_ns)) return; - /* Can only change if privileged. */ - if (!capable(CAP_NET_ADMIN)) { - err = EPERM; - goto out; - } - mc_op = (enum proc_cn_mcast_op *)msg->data; switch (*mc_op) { case PROC_CN_MCAST_LISTEN: @@ -331,8 +325,6 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, err = EINVAL; break; } - -out: cn_proc_ack(err, msg->seq, msg->ack); } diff --git a/trunk/drivers/cpufreq/acpi-cpufreq.c b/trunk/drivers/cpufreq/acpi-cpufreq.c index 57a8774f0b4e..937bc286591f 100644 --- a/trunk/drivers/cpufreq/acpi-cpufreq.c +++ b/trunk/drivers/cpufreq/acpi-cpufreq.c @@ -730,6 +730,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { cpumask_copy(policy->cpus, perf->shared_cpu_map); } + cpumask_copy(policy->related_cpus, perf->shared_cpu_map); #ifdef CONFIG_SMP dmi_check_system(sw_any_bug_dmi_table); @@ -741,6 +742,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) { cpumask_clear(policy->cpus); cpumask_set_cpu(cpu, policy->cpus); + cpumask_copy(policy->related_cpus, cpu_sibling_mask(cpu)); policy->shared_type = CPUFREQ_SHARED_TYPE_HW; pr_info_once(PFX "overriding BIOS provided _PSD data\n"); } diff --git a/trunk/drivers/cpufreq/cpufreq-cpu0.c b/trunk/drivers/cpufreq/cpufreq-cpu0.c index 37d23a0f8c56..4e5b7fb8927c 100644 --- a/trunk/drivers/cpufreq/cpufreq-cpu0.c +++ b/trunk/drivers/cpufreq/cpufreq-cpu0.c @@ -178,16 +178,10 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { static int cpu0_cpufreq_probe(struct platform_device *pdev) { - struct device_node *np, *parent; + struct device_node *np; int ret; - parent = of_find_node_by_path("/cpus"); - if (!parent) { - pr_err("failed to find OF /cpus\n"); - return -ENOENT; - } - - for_each_child_of_node(parent, np) { + for_each_child_of_node(of_find_node_by_path("/cpus"), np) { if (of_get_property(np, "operating-points", NULL)) break; } diff --git a/trunk/drivers/cpufreq/cpufreq_governor.h b/trunk/drivers/cpufreq/cpufreq_governor.h index cc4bd2f6838a..d2ac91150600 100644 --- a/trunk/drivers/cpufreq/cpufreq_governor.h +++ b/trunk/drivers/cpufreq/cpufreq_governor.h @@ -14,8 +14,8 @@ * published by the Free Software Foundation. */ -#ifndef _CPUFREQ_GOVERNOR_H -#define _CPUFREQ_GOVERNOR_H +#ifndef _CPUFREQ_GOVERNER_H +#define _CPUFREQ_GOVERNER_H #include #include @@ -64,7 +64,7 @@ static void *get_cpu_dbs_info_s(int cpu) \ * dbs: used as a shortform for demand based switching It helps to keep variable * names smaller, simpler * cdbs: common dbs - * od_*: On-demand governor + * on_*: On-demand governor * cs_*: Conservative governor */ @@ -175,4 +175,4 @@ bool need_load_eval(struct cpu_dbs_common_info *cdbs, unsigned int sampling_rate); int cpufreq_governor_dbs(struct dbs_data *dbs_data, struct cpufreq_policy *policy, unsigned int event); -#endif /* _CPUFREQ_GOVERNOR_H */ +#endif /* _CPUFREQ_GOVERNER_H */ diff --git a/trunk/drivers/cpufreq/cpufreq_stats.c b/trunk/drivers/cpufreq/cpufreq_stats.c index bfd6273fd873..2fd779eb1ed1 100644 --- a/trunk/drivers/cpufreq/cpufreq_stats.c +++ b/trunk/drivers/cpufreq/cpufreq_stats.c @@ -180,19 +180,15 @@ static void cpufreq_stats_free_sysfs(unsigned int cpu) { struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - if (!policy) - return; - if (!cpufreq_frequency_get_table(cpu)) - goto put_ref; + return; - if (!policy_is_shared(policy)) { + if (policy && !policy_is_shared(policy)) { pr_debug("%s: Free sysfs stat\n", __func__); sysfs_remove_group(&policy->kobj, &stats_attr_group); } - -put_ref: - cpufreq_cpu_put(policy); + if (policy) + cpufreq_cpu_put(policy); } static int cpufreq_stats_create_table(struct cpufreq_policy *policy, diff --git a/trunk/drivers/cpufreq/highbank-cpufreq.c b/trunk/drivers/cpufreq/highbank-cpufreq.c index b61b5a3fad64..66e3a71b81a3 100644 --- a/trunk/drivers/cpufreq/highbank-cpufreq.c +++ b/trunk/drivers/cpufreq/highbank-cpufreq.c @@ -28,7 +28,13 @@ static int hb_voltage_change(unsigned int freq) { - u32 msg[HB_CPUFREQ_IPC_LEN] = {HB_CPUFREQ_CHANGE_NOTE, freq / 1000000}; + int i; + u32 msg[HB_CPUFREQ_IPC_LEN]; + + msg[0] = HB_CPUFREQ_CHANGE_NOTE; + msg[1] = freq / 1000000; + for (i = 2; i < HB_CPUFREQ_IPC_LEN; i++) + msg[i] = 0; return pl320_ipc_transmit(msg); } diff --git a/trunk/drivers/cpufreq/intel_pstate.c b/trunk/drivers/cpufreq/intel_pstate.c index 6133ef5cf671..096fde0ebcb5 100644 --- a/trunk/drivers/cpufreq/intel_pstate.c +++ b/trunk/drivers/cpufreq/intel_pstate.c @@ -358,14 +358,14 @@ static void intel_pstate_sysfs_expose_params(void) static int intel_pstate_min_pstate(void) { u64 value; - rdmsrl(MSR_PLATFORM_INFO, value); + rdmsrl(0xCE, value); return (value >> 40) & 0xFF; } static int intel_pstate_max_pstate(void) { u64 value; - rdmsrl(MSR_PLATFORM_INFO, value); + rdmsrl(0xCE, value); return (value >> 8) & 0xFF; } @@ -373,7 +373,7 @@ static int intel_pstate_turbo_pstate(void) { u64 value; int nont, ret; - rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value); + rdmsrl(0x1AD, value); nont = intel_pstate_max_pstate(); ret = ((value) & 255); if (ret <= nont) @@ -454,7 +454,7 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu, sample->idletime_us * 100, sample->duration_us); core_pct = div64_u64(sample->aperf * 100, sample->mperf); - sample->freq = cpu->pstate.max_pstate * core_pct * 1000; + sample->freq = cpu->pstate.turbo_pstate * core_pct * 1000; sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct), 100); @@ -502,6 +502,7 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu) sample_time = cpu->pstate_policy->sample_rate_ms; delay = msecs_to_jiffies(sample_time); + delay -= jiffies % delay; mod_timer_pinned(&cpu->timer, jiffies + delay); } @@ -661,9 +662,6 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) cpu = all_cpu_data[policy->cpu]; - if (!policy->cpuinfo.max_freq) - return -ENODEV; - intel_pstate_get_min_max(cpu, &min, &max); limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; @@ -749,34 +747,37 @@ static struct cpufreq_driver intel_pstate_driver = { .owner = THIS_MODULE, }; -static int __initdata no_load; - -static int intel_pstate_msrs_not_valid(void) +static void intel_pstate_exit(void) { - /* Check that all the msr's we are using are valid. */ - u64 aperf, mperf, tmp; + int cpu; - rdmsrl(MSR_IA32_APERF, aperf); - rdmsrl(MSR_IA32_MPERF, mperf); + sysfs_remove_group(intel_pstate_kobject, + &intel_pstate_attr_group); + debugfs_remove_recursive(debugfs_parent); - if (!intel_pstate_min_pstate() || - !intel_pstate_max_pstate() || - !intel_pstate_turbo_pstate()) - return -ENODEV; + cpufreq_unregister_driver(&intel_pstate_driver); - rdmsrl(MSR_IA32_APERF, tmp); - if (!(tmp - aperf)) - return -ENODEV; + if (!all_cpu_data) + return; - rdmsrl(MSR_IA32_MPERF, tmp); - if (!(tmp - mperf)) - return -ENODEV; + get_online_cpus(); + for_each_online_cpu(cpu) { + if (all_cpu_data[cpu]) { + del_timer_sync(&all_cpu_data[cpu]->timer); + kfree(all_cpu_data[cpu]); + } + } - return 0; + put_online_cpus(); + vfree(all_cpu_data); } +module_exit(intel_pstate_exit); + +static int __initdata no_load; + static int __init intel_pstate_init(void) { - int cpu, rc = 0; + int rc = 0; const struct x86_cpu_id *id; if (no_load) @@ -786,9 +787,6 @@ static int __init intel_pstate_init(void) if (!id) return -ENODEV; - if (intel_pstate_msrs_not_valid()) - return -ENODEV; - pr_info("Intel P-state driver initializing.\n"); all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus()); @@ -804,16 +802,7 @@ static int __init intel_pstate_init(void) intel_pstate_sysfs_expose_params(); return rc; out: - get_online_cpus(); - for_each_online_cpu(cpu) { - if (all_cpu_data[cpu]) { - del_timer_sync(&all_cpu_data[cpu]->timer); - kfree(all_cpu_data[cpu]); - } - } - - put_online_cpus(); - vfree(all_cpu_data); + intel_pstate_exit(); return -ENODEV; } device_initcall(intel_pstate_init); diff --git a/trunk/drivers/crypto/caam/caamalg.c b/trunk/drivers/crypto/caam/caamalg.c index cf268b14ae9a..b2a0a0726a54 100644 --- a/trunk/drivers/crypto/caam/caamalg.c +++ b/trunk/drivers/crypto/caam/caamalg.c @@ -1650,7 +1650,11 @@ struct caam_alg_template { }; static struct caam_alg_template driver_algs[] = { - /* single-pass ipsec_esp descriptor */ + /* + * single-pass ipsec_esp descriptor + * authencesn(*,*) is also registered, although not present + * explicitly here. + */ { .name = "authenc(hmac(md5),cbc(aes))", .driver_name = "authenc-hmac-md5-cbc-aes-caam", @@ -2213,7 +2217,9 @@ static int __init caam_algapi_init(void) for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { /* TODO: check if h/w supports alg */ struct caam_crypto_alg *t_alg; + bool done = false; +authencesn: t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]); if (IS_ERR(t_alg)) { err = PTR_ERR(t_alg); @@ -2227,8 +2233,25 @@ static int __init caam_algapi_init(void) dev_warn(ctrldev, "%s alg registration failed\n", t_alg->crypto_alg.cra_driver_name); kfree(t_alg); - } else + } else { list_add_tail(&t_alg->entry, &priv->alg_list); + if (driver_algs[i].type == CRYPTO_ALG_TYPE_AEAD && + !memcmp(driver_algs[i].name, "authenc", 7) && + !done) { + char *name; + + name = driver_algs[i].name; + memmove(name + 10, name + 7, strlen(name) - 7); + memcpy(name + 7, "esn", 3); + + name = driver_algs[i].driver_name; + memmove(name + 10, name + 7, strlen(name) - 7); + memcpy(name + 7, "esn", 3); + + done = true; + goto authencesn; + } + } } if (!list_empty(&priv->alg_list)) dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n", diff --git a/trunk/drivers/crypto/caam/compat.h b/trunk/drivers/crypto/caam/compat.h index 762aeff626ac..cf15e7813801 100644 --- a/trunk/drivers/crypto/caam/compat.h +++ b/trunk/drivers/crypto/caam/compat.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/crypto/talitos.c b/trunk/drivers/crypto/talitos.c index 5b2b5e61e4f9..09b184adf31b 100644 --- a/trunk/drivers/crypto/talitos.c +++ b/trunk/drivers/crypto/talitos.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -1973,7 +1974,11 @@ struct talitos_alg_template { }; static struct talitos_alg_template driver_algs[] = { - /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */ + /* + * AEAD algorithms. These use a single-pass ipsec_esp descriptor. + * authencesn(*,*) is also registered, although not present + * explicitly here. + */ { .type = CRYPTO_ALG_TYPE_AEAD, .alg.crypto = { .cra_name = "authenc(hmac(sha1),cbc(aes))", @@ -2815,7 +2820,9 @@ static int talitos_probe(struct platform_device *ofdev) if (hw_supports(dev, driver_algs[i].desc_hdr_template)) { struct talitos_crypto_alg *t_alg; char *name = NULL; + bool authenc = false; +authencesn: t_alg = talitos_alg_alloc(dev, &driver_algs[i]); if (IS_ERR(t_alg)) { err = PTR_ERR(t_alg); @@ -2830,6 +2837,8 @@ static int talitos_probe(struct platform_device *ofdev) err = crypto_register_alg( &t_alg->algt.alg.crypto); name = t_alg->algt.alg.crypto.cra_driver_name; + authenc = authenc ? !authenc : + !(bool)memcmp(name, "authenc", 7); break; case CRYPTO_ALG_TYPE_AHASH: err = crypto_register_ahash( @@ -2842,8 +2851,25 @@ static int talitos_probe(struct platform_device *ofdev) dev_err(dev, "%s alg registration failed\n", name); kfree(t_alg); - } else + } else { list_add_tail(&t_alg->entry, &priv->alg_list); + if (authenc) { + struct crypto_alg *alg = + &driver_algs[i].alg.crypto; + + name = alg->cra_name; + memmove(name + 10, name + 7, + strlen(name) - 7); + memcpy(name + 7, "esn", 3); + + name = alg->cra_driver_name; + memmove(name + 10, name + 7, + strlen(name) - 7); + memcpy(name + 7, "esn", 3); + + goto authencesn; + } + } } } if (!list_empty(&priv->alg_list)) diff --git a/trunk/drivers/crypto/ux500/cryp/cryp_core.c b/trunk/drivers/crypto/ux500/cryp/cryp_core.c index 22c9063e0120..8bc5fef07e7a 100644 --- a/trunk/drivers/crypto/ux500/cryp/cryp_core.c +++ b/trunk/drivers/crypto/ux500/cryp/cryp_core.c @@ -1750,7 +1750,7 @@ static struct platform_driver cryp_driver = { .shutdown = ux500_cryp_shutdown, .driver = { .owner = THIS_MODULE, - .name = "cryp1", + .name = "cryp1" .pm = &ux500_cryp_pm, } }; diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig index aeaea32bcfda..80b69971cf28 100644 --- a/trunk/drivers/dma/Kconfig +++ b/trunk/drivers/dma/Kconfig @@ -83,7 +83,6 @@ config INTEL_IOP_ADMA config DW_DMAC tristate "Synopsys DesignWare AHB DMA support" - depends on GENERIC_HARDIRQS select DMA_ENGINE default y if CPU_AT32AP7000 help diff --git a/trunk/drivers/dma/at_hdmac.c b/trunk/drivers/dma/at_hdmac.c index 88cfc61329d2..6e13f262139a 100644 --- a/trunk/drivers/dma/at_hdmac.c +++ b/trunk/drivers/dma/at_hdmac.c @@ -310,6 +310,8 @@ static void atc_complete_all(struct at_dma_chan *atchan) dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n"); + BUG_ON(atc_chan_is_enabled(atchan)); + /* * Submit queued descriptors ASAP, i.e. before we go through * the completed ones. @@ -366,9 +368,6 @@ static void atc_advance_work(struct at_dma_chan *atchan) { dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n"); - if (atc_chan_is_enabled(atchan)) - return; - if (list_empty(&atchan->active_list) || list_is_singular(&atchan->active_list)) { atc_complete_all(atchan); @@ -1079,7 +1078,9 @@ static void atc_issue_pending(struct dma_chan *chan) return; spin_lock_irqsave(&atchan->lock, flags); - atc_advance_work(atchan); + if (!atc_chan_is_enabled(atchan)) { + atc_advance_work(atchan); + } spin_unlock_irqrestore(&atchan->lock, flags); } diff --git a/trunk/drivers/dma/dw_dmac.c b/trunk/drivers/dma/dw_dmac.c index 43a5329d4483..c599558faeda 100644 --- a/trunk/drivers/dma/dw_dmac.c +++ b/trunk/drivers/dma/dw_dmac.c @@ -1001,13 +1001,6 @@ static inline void convert_burst(u32 *maxburst) *maxburst = 0; } -static inline void convert_slave_id(struct dw_dma_chan *dwc) -{ - struct dw_dma *dw = to_dw_dma(dwc->chan.device); - - dwc->dma_sconfig.slave_id -= dw->request_line_base; -} - static int set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) { @@ -1022,7 +1015,6 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) convert_burst(&dwc->dma_sconfig.src_maxburst); convert_burst(&dwc->dma_sconfig.dst_maxburst); - convert_slave_id(dwc); return 0; } @@ -1284,9 +1276,9 @@ static struct dma_chan *dw_dma_xlate(struct of_phandle_args *dma_spec, if (dma_spec->args_count != 3) return NULL; - fargs.req = dma_spec->args[0]; - fargs.src = dma_spec->args[1]; - fargs.dst = dma_spec->args[2]; + fargs.req = be32_to_cpup(dma_spec->args+0); + fargs.src = be32_to_cpup(dma_spec->args+1); + fargs.dst = be32_to_cpup(dma_spec->args+2); if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS || fargs.src >= dw->nr_masters || @@ -1636,7 +1628,6 @@ dw_dma_parse_dt(struct platform_device *pdev) static int dw_probe(struct platform_device *pdev) { - const struct platform_device_id *match; struct dw_dma_platform_data *pdata; struct resource *io; struct dw_dma *dw; @@ -1720,11 +1711,6 @@ static int dw_probe(struct platform_device *pdev) memcpy(dw->data_width, pdata->data_width, 4); } - /* Get the base request line if set */ - match = platform_get_device_id(pdev); - if (match) - dw->request_line_base = (unsigned int)match->driver_data; - /* Calculate all channel mask before DMA setup */ dw->all_chan_mask = (1 << nr_channels) - 1; @@ -1920,8 +1906,7 @@ MODULE_DEVICE_TABLE(of, dw_dma_id_table); #endif static const struct platform_device_id dw_dma_ids[] = { - /* Name, Request Line Base */ - { "INTL9C60", (kernel_ulong_t)16 }, + { "INTL9C60", 0 }, { } }; diff --git a/trunk/drivers/dma/dw_dmac_regs.h b/trunk/drivers/dma/dw_dmac_regs.h index 4d02c3669b75..cf0ce5c77d60 100644 --- a/trunk/drivers/dma/dw_dmac_regs.h +++ b/trunk/drivers/dma/dw_dmac_regs.h @@ -247,7 +247,6 @@ struct dw_dma { /* hardware configuration */ unsigned char nr_masters; unsigned char data_width[4]; - unsigned int request_line_base; struct dw_dma_chan chan[0]; }; diff --git a/trunk/drivers/dma/omap-dma.c b/trunk/drivers/dma/omap-dma.c index 08b43bf37158..c4b4fd2acc42 100644 --- a/trunk/drivers/dma/omap-dma.c +++ b/trunk/drivers/dma/omap-dma.c @@ -276,20 +276,12 @@ static void omap_dma_issue_pending(struct dma_chan *chan) spin_lock_irqsave(&c->vc.lock, flags); if (vchan_issue_pending(&c->vc) && !c->desc) { - /* - * c->cyclic is used only by audio and in this case the DMA need - * to be started without delay. - */ - if (!c->cyclic) { - struct omap_dmadev *d = to_omap_dma_dev(chan->device); - spin_lock(&d->lock); - if (list_empty(&c->node)) - list_add_tail(&c->node, &d->pending); - spin_unlock(&d->lock); - tasklet_schedule(&d->task); - } else { - omap_dma_start_desc(c); - } + struct omap_dmadev *d = to_omap_dma_dev(chan->device); + spin_lock(&d->lock); + if (list_empty(&c->node)) + list_add_tail(&c->node, &d->pending); + spin_unlock(&d->lock); + tasklet_schedule(&d->task); } spin_unlock_irqrestore(&c->vc.lock, flags); } diff --git a/trunk/drivers/dma/pl330.c b/trunk/drivers/dma/pl330.c index 5dbc5946c4c3..718153122759 100644 --- a/trunk/drivers/dma/pl330.c +++ b/trunk/drivers/dma/pl330.c @@ -2882,7 +2882,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) { struct dma_pl330_platdata *pdat; struct dma_pl330_dmac *pdmac; - struct dma_pl330_chan *pch, *_p; + struct dma_pl330_chan *pch; struct pl330_info *pi; struct dma_device *pd; struct resource *res; @@ -2984,16 +2984,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) ret = dma_async_device_register(pd); if (ret) { dev_err(&adev->dev, "unable to register DMAC\n"); - goto probe_err3; - } - - if (adev->dev.of_node) { - ret = of_dma_controller_register(adev->dev.of_node, - of_dma_pl330_xlate, pdmac); - if (ret) { - dev_err(&adev->dev, - "unable to register DMA to the generic DT DMA helpers\n"); - } + goto probe_err2; } dev_info(&adev->dev, @@ -3004,21 +2995,16 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan, pi->pcfg.num_peri, pi->pcfg.num_events); - return 0; -probe_err3: - amba_set_drvdata(adev, NULL); - - /* Idle the DMAC */ - list_for_each_entry_safe(pch, _p, &pdmac->ddma.channels, - chan.device_node) { + ret = of_dma_controller_register(adev->dev.of_node, + of_dma_pl330_xlate, pdmac); + if (ret) { + dev_err(&adev->dev, + "unable to register DMA to the generic DT DMA helpers\n"); + goto probe_err2; + } - /* Remove the channel */ - list_del(&pch->chan.device_node); + return 0; - /* Flush the channel */ - pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0); - pl330_free_chan_resources(&pch->chan); - } probe_err2: pl330_del(pi); probe_err1: @@ -3037,10 +3023,8 @@ static int pl330_remove(struct amba_device *adev) if (!pdmac) return 0; - if (adev->dev.of_node) - of_dma_controller_free(adev->dev.of_node); + of_dma_controller_free(adev->dev.of_node); - dma_async_device_unregister(&pdmac->ddma); amba_set_drvdata(adev, NULL); /* Idle the DMAC */ diff --git a/trunk/drivers/edac/amd64_edac.c b/trunk/drivers/edac/amd64_edac.c index e1d13c463c90..910b0116c128 100644 --- a/trunk/drivers/edac/amd64_edac.c +++ b/trunk/drivers/edac/amd64_edac.c @@ -2048,18 +2048,12 @@ static int init_csrows(struct mem_ctl_info *mci) edac_dbg(1, "MC node: %d, csrow: %d\n", pvt->mc_node_id, i); - if (row_dct0) { + if (row_dct0) nr_pages = amd64_csrow_nr_pages(pvt, 0, i); - csrow->channels[0]->dimm->nr_pages = nr_pages; - } /* K8 has only one DCT */ - if (boot_cpu_data.x86 != 0xf && row_dct1) { - int row_dct1_pages = amd64_csrow_nr_pages(pvt, 1, i); - - csrow->channels[1]->dimm->nr_pages = row_dct1_pages; - nr_pages += row_dct1_pages; - } + if (boot_cpu_data.x86 != 0xf && row_dct1) + nr_pages += amd64_csrow_nr_pages(pvt, 1, i); mtype = amd64_determine_memory_type(pvt, i); @@ -2078,7 +2072,9 @@ static int init_csrows(struct mem_ctl_info *mci) dimm = csrow->channels[j]->dimm; dimm->mtype = mtype; dimm->edac_mode = edac_mode; + dimm->nr_pages = nr_pages; } + csrow->nr_pages = nr_pages; } return empty; @@ -2423,6 +2419,7 @@ static int amd64_init_one_instance(struct pci_dev *F2) mci->pvt_info = pvt; mci->pdev = &pvt->F2->dev; + mci->csbased = 1; setup_mci_misc_attrs(mci, fam_type); diff --git a/trunk/drivers/edac/edac_mc.c b/trunk/drivers/edac/edac_mc.c index 27e86d938262..cdb81aa73ab7 100644 --- a/trunk/drivers/edac/edac_mc.c +++ b/trunk/drivers/edac/edac_mc.c @@ -86,7 +86,7 @@ static void edac_mc_dump_dimm(struct dimm_info *dimm, int number) edac_dimm_info_location(dimm, location, sizeof(location)); edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n", - dimm->mci->csbased ? "rank" : "dimm", + dimm->mci->mem_is_per_rank ? "rank" : "dimm", number, location, dimm->csrow, dimm->cschannel); edac_dbg(4, " dimm = %p\n", dimm); edac_dbg(4, " dimm->label = '%s'\n", dimm->label); @@ -341,7 +341,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, memcpy(mci->layers, layers, sizeof(*layer) * n_layers); mci->nr_csrows = tot_csrows; mci->num_cschannel = tot_channels; - mci->csbased = per_rank; + mci->mem_is_per_rank = per_rank; /* * Alocate and fill the csrow/channels structs @@ -1235,7 +1235,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, * incrementing the compat API counters */ edac_dbg(4, "%s csrows map: (%d,%d)\n", - mci->csbased ? "rank" : "dimm", + mci->mem_is_per_rank ? "rank" : "dimm", dimm->csrow, dimm->cschannel); if (row == -1) row = dimm->csrow; diff --git a/trunk/drivers/edac/edac_mc_sysfs.c b/trunk/drivers/edac/edac_mc_sysfs.c index 5899a76eec3b..4f4b6137d74e 100644 --- a/trunk/drivers/edac/edac_mc_sysfs.c +++ b/trunk/drivers/edac/edac_mc_sysfs.c @@ -143,7 +143,7 @@ static const char *edac_caps[] = { * and the per-dimm/per-rank one */ #define DEVICE_ATTR_LEGACY(_name, _mode, _show, _store) \ - static struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store) + struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store) struct dev_ch_attribute { struct device_attribute attr; @@ -180,6 +180,9 @@ static ssize_t csrow_size_show(struct device *dev, int i; u32 nr_pages = 0; + if (csrow->mci->csbased) + return sprintf(data, "%u\n", PAGES_TO_MiB(csrow->nr_pages)); + for (i = 0; i < csrow->nr_channels; i++) nr_pages += csrow->channels[i]->dimm->nr_pages; return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages)); @@ -609,7 +612,7 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci, device_initialize(&dimm->dev); dimm->dev.parent = &mci->dev; - if (mci->csbased) + if (mci->mem_is_per_rank) dev_set_name(&dimm->dev, "rank%d", index); else dev_set_name(&dimm->dev, "dimm%d", index); @@ -775,10 +778,14 @@ static ssize_t mci_size_mb_show(struct device *dev, for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) { struct csrow_info *csrow = mci->csrows[csrow_idx]; - for (j = 0; j < csrow->nr_channels; j++) { - struct dimm_info *dimm = csrow->channels[j]->dimm; + if (csrow->mci->csbased) { + total_pages += csrow->nr_pages; + } else { + for (j = 0; j < csrow->nr_channels; j++) { + struct dimm_info *dimm = csrow->channels[j]->dimm; - total_pages += dimm->nr_pages; + total_pages += dimm->nr_pages; + } } } diff --git a/trunk/drivers/eisa/eisa-bus.c b/trunk/drivers/eisa/eisa-bus.c index 272a3ec35957..806c77bfd434 100644 --- a/trunk/drivers/eisa/eisa-bus.c +++ b/trunk/drivers/eisa/eisa-bus.c @@ -275,18 +275,19 @@ static int __init eisa_request_resources(struct eisa_root_device *root, } if (slot) { + edev->res[i].name = NULL; edev->res[i].start = SLOT_ADDRESS(root, slot) + (i * 0x400); edev->res[i].end = edev->res[i].start + 0xff; edev->res[i].flags = IORESOURCE_IO; } else { + edev->res[i].name = NULL; edev->res[i].start = SLOT_ADDRESS(root, slot) + EISA_VENDOR_ID_OFFSET; edev->res[i].end = edev->res[i].start + 3; - edev->res[i].flags = IORESOURCE_IO | IORESOURCE_BUSY; + edev->res[i].flags = IORESOURCE_BUSY; } - dev_printk(KERN_DEBUG, &edev->dev, "%pR\n", &edev->res[i]); if (request_resource(root->res, &edev->res[i])) goto failed; } @@ -313,40 +314,41 @@ static int __init eisa_probe(struct eisa_root_device *root) { int i, c; struct eisa_device *edev; - char *enabled_str; - dev_info(root->dev, "Probing EISA bus %d\n", root->bus_nr); + printk(KERN_INFO "EISA: Probing bus %d at %s\n", + root->bus_nr, dev_name(root->dev)); /* First try to get hold of slot 0. If there is no device * here, simply fail, unless root->force_probe is set. */ edev = kzalloc(sizeof(*edev), GFP_KERNEL); if (!edev) { - dev_err(root->dev, "EISA: Couldn't allocate mainboard slot\n"); + printk(KERN_ERR "EISA: Couldn't allocate mainboard slot\n"); return -ENOMEM; } - if (eisa_init_device(root, edev, 0)) { + if (eisa_request_resources(root, edev, 0)) { + printk(KERN_WARNING \ + "EISA: Cannot allocate resource for mainboard\n"); kfree(edev); if (!root->force_probe) - return -ENODEV; + return -EBUSY; goto force_probe; } - if (eisa_request_resources(root, edev, 0)) { - dev_warn(root->dev, - "EISA: Cannot allocate resource for mainboard\n"); + if (eisa_init_device(root, edev, 0)) { + eisa_release_resources(edev); kfree(edev); if (!root->force_probe) - return -EBUSY; + return -ENODEV; goto force_probe; } - dev_info(&edev->dev, "EISA: Mainboard %s detected\n", edev->id.sig); + printk(KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig); if (eisa_register_device(edev)) { - dev_err(&edev->dev, "EISA: Failed to register %s\n", - edev->id.sig); + printk(KERN_ERR "EISA: Failed to register %s\n", + edev->id.sig); eisa_release_resources(edev); kfree(edev); } @@ -356,47 +358,55 @@ static int __init eisa_probe(struct eisa_root_device *root) for (c = 0, i = 1; i <= root->slots; i++) { edev = kzalloc(sizeof(*edev), GFP_KERNEL); if (!edev) { - dev_err(root->dev, "EISA: Out of memory for slot %d\n", - i); + printk(KERN_ERR "EISA: Out of memory for slot %d\n", i); continue; } - if (eisa_init_device(root, edev, i)) { + if (eisa_request_resources(root, edev, i)) { + printk(KERN_WARNING \ + "Cannot allocate resource for EISA slot %d\n", + i); kfree(edev); continue; } - if (eisa_request_resources(root, edev, i)) { - dev_warn(root->dev, - "Cannot allocate resource for EISA slot %d\n", - i); + if (eisa_init_device(root, edev, i)) { + eisa_release_resources(edev); kfree(edev); continue; } - - if (edev->state == (EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED)) - enabled_str = " (forced enabled)"; - else if (edev->state == EISA_CONFIG_FORCED) - enabled_str = " (forced disabled)"; - else if (edev->state == 0) - enabled_str = " (disabled)"; - else - enabled_str = ""; - - dev_info(&edev->dev, "EISA: slot %d: %s detected%s\n", i, - edev->id.sig, enabled_str); + + printk(KERN_INFO "EISA: slot %d : %s detected", + i, edev->id.sig); + + switch (edev->state) { + case EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED: + printk(" (forced enabled)"); + break; + + case EISA_CONFIG_FORCED: + printk(" (forced disabled)"); + break; + + case 0: + printk(" (disabled)"); + break; + } + + printk (".\n"); c++; if (eisa_register_device(edev)) { - dev_err(&edev->dev, "EISA: Failed to register %s\n", - edev->id.sig); + printk(KERN_ERR "EISA: Failed to register %s\n", + edev->id.sig); eisa_release_resources(edev); kfree(edev); } } - dev_info(root->dev, "EISA: Detected %d card%s\n", c, c == 1 ? "" : "s"); + printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s"); + return 0; } diff --git a/trunk/drivers/eisa/pci_eisa.c b/trunk/drivers/eisa/pci_eisa.c index a333bf3517de..cdae207028a7 100644 --- a/trunk/drivers/eisa/pci_eisa.c +++ b/trunk/drivers/eisa/pci_eisa.c @@ -19,72 +19,48 @@ /* There is only *one* pci_eisa device per machine, right ? */ static struct eisa_root_device pci_eisa_root; -static int __init pci_eisa_init(struct pci_dev *pdev) +static int __init pci_eisa_init(struct pci_dev *pdev, + const struct pci_device_id *ent) { - int rc, i; - struct resource *res, *bus_res = NULL; + int rc; if ((rc = pci_enable_device (pdev))) { - dev_err(&pdev->dev, "Could not enable device\n"); + printk (KERN_ERR "pci_eisa : Could not enable device %s\n", + pci_name(pdev)); return rc; } - /* - * The Intel 82375 PCI-EISA bridge is a subtractive-decode PCI - * device, so the resources available on EISA are the same as those - * available on the 82375 bus. This works the same as a PCI-PCI - * bridge in subtractive-decode mode (see pci_read_bridge_bases()). - * We assume other PCI-EISA bridges are similar. - * - * eisa_root_register() can only deal with a single io port resource, - * so we use the first valid io port resource. - */ - pci_bus_for_each_resource(pdev->bus, res, i) - if (res && (res->flags & IORESOURCE_IO)) { - bus_res = res; - break; - } - - if (!bus_res) { - dev_err(&pdev->dev, "No resources available\n"); - return -1; - } - pci_eisa_root.dev = &pdev->dev; - pci_eisa_root.res = bus_res; - pci_eisa_root.bus_base_addr = bus_res->start; + pci_eisa_root.res = pdev->bus->resource[0]; + pci_eisa_root.bus_base_addr = pdev->bus->resource[0]->start; pci_eisa_root.slots = EISA_MAX_SLOTS; pci_eisa_root.dma_mask = pdev->dma_mask; dev_set_drvdata(pci_eisa_root.dev, &pci_eisa_root); if (eisa_root_register (&pci_eisa_root)) { - dev_err(&pdev->dev, "Could not register EISA root\n"); + printk (KERN_ERR "pci_eisa : Could not register EISA root\n"); return -1; } return 0; } -/* - * We have to call pci_eisa_init_early() before pnpacpi_init()/isapnp_init(). - * Otherwise pnp resource will get enabled early and could prevent eisa - * to be initialized. - * Also need to make sure pci_eisa_init_early() is called after - * x86/pci_subsys_init(). - * So need to use subsys_initcall_sync with it. - */ -static int __init pci_eisa_init_early(void) -{ - struct pci_dev *dev = NULL; - int ret; +static struct pci_device_id pci_eisa_pci_tbl[] = { + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_BRIDGE_EISA << 8, 0xffff00, 0 }, + { 0, } +}; - for_each_pci_dev(dev) - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_EISA) { - ret = pci_eisa_init(dev); - if (ret) - return ret; - } +static struct pci_driver __refdata pci_eisa_driver = { + .name = "pci_eisa", + .id_table = pci_eisa_pci_tbl, + .probe = pci_eisa_init, +}; - return 0; +static int __init pci_eisa_init_module (void) +{ + return pci_register_driver (&pci_eisa_driver); } -subsys_initcall_sync(pci_eisa_init_early); + +device_initcall(pci_eisa_init_module); +MODULE_DEVICE_TABLE(pci, pci_eisa_pci_tbl); diff --git a/trunk/drivers/extcon/extcon-arizona.c b/trunk/drivers/extcon/extcon-arizona.c index 7a1b4a7791ba..dc357a4051f6 100644 --- a/trunk/drivers/extcon/extcon-arizona.c +++ b/trunk/drivers/extcon/extcon-arizona.c @@ -33,17 +33,12 @@ #include #include -#define ARIZONA_MAX_MICD_RANGE 8 +#define ARIZONA_NUM_BUTTONS 6 #define ARIZONA_ACCDET_MODE_MIC 0 #define ARIZONA_ACCDET_MODE_HPL 1 #define ARIZONA_ACCDET_MODE_HPR 2 -#define ARIZONA_HPDET_MAX 10000 - -#define HPDET_DEBOUNCE 500 -#define DEFAULT_MICD_TIMEOUT 2000 - struct arizona_extcon_info { struct device *dev; struct arizona *arizona; @@ -51,27 +46,17 @@ struct arizona_extcon_info { struct regulator *micvdd; struct input_dev *input; - u16 last_jackdet; - int micd_mode; const struct arizona_micd_config *micd_modes; int micd_num_modes; - const struct arizona_micd_range *micd_ranges; - int num_micd_ranges; - - int micd_timeout; - bool micd_reva; bool micd_clamp; struct delayed_work hpdet_work; - struct delayed_work micd_detect_work; - struct delayed_work micd_timeout_work; bool hpdet_active; bool hpdet_done; - bool hpdet_retried; int num_hpdet_res; unsigned int hpdet_res[3]; @@ -86,25 +71,20 @@ struct arizona_extcon_info { }; static const struct arizona_micd_config micd_default_modes[] = { - { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 }, { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 }, + { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 }, }; -static const struct arizona_micd_range micd_default_ranges[] = { - { .max = 11, .key = BTN_0 }, - { .max = 28, .key = BTN_1 }, - { .max = 54, .key = BTN_2 }, - { .max = 100, .key = BTN_3 }, - { .max = 186, .key = BTN_4 }, - { .max = 430, .key = BTN_5 }, -}; - -static const int arizona_micd_levels[] = { - 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46, - 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100, - 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245, - 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071, - 1257, +static struct { + u16 status; + int report; +} arizona_lvl_to_key[ARIZONA_NUM_BUTTONS] = { + { 0x1, BTN_0 }, + { 0x2, BTN_1 }, + { 0x4, BTN_2 }, + { 0x8, BTN_3 }, + { 0x10, BTN_4 }, + { 0x20, BTN_5 }, }; #define ARIZONA_CABLE_MECHANICAL 0 @@ -120,63 +100,10 @@ static const char *arizona_cable[] = { NULL, }; -static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info); - -static void arizona_extcon_do_magic(struct arizona_extcon_info *info, - unsigned int magic) -{ - struct arizona *arizona = info->arizona; - int ret; - - mutex_lock(&arizona->dapm->card->dapm_mutex); - - arizona->hpdet_magic = magic; - - /* Keep the HP output stages disabled while doing the magic */ - if (magic) { - ret = regmap_update_bits(arizona->regmap, - ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT1L_ENA | - ARIZONA_OUT1R_ENA, 0); - if (ret != 0) - dev_warn(arizona->dev, - "Failed to disable headphone outputs: %d\n", - ret); - } - - ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, - magic); - if (ret != 0) - dev_warn(arizona->dev, "Failed to do magic: %d\n", - ret); - - ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, - magic); - if (ret != 0) - dev_warn(arizona->dev, "Failed to do magic: %d\n", - ret); - - /* Restore the desired state while not doing the magic */ - if (!magic) { - ret = regmap_update_bits(arizona->regmap, - ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT1L_ENA | - ARIZONA_OUT1R_ENA, arizona->hp_ena); - if (ret != 0) - dev_warn(arizona->dev, - "Failed to restore headphone outputs: %d\n", - ret); - } - - mutex_unlock(&arizona->dapm->card->dapm_mutex); -} - static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) { struct arizona *arizona = info->arizona; - mode %= info->micd_num_modes; - if (arizona->pdata.micd_pol_gpio > 0) gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio, info->micd_modes[mode].gpio); @@ -403,7 +330,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info) /* If we go out of range report top of range */ if (val < 100 || val > 0x3fb) { dev_dbg(arizona->dev, "Measurement out of range\n"); - return ARIZONA_HPDET_MAX; + return 10000; } dev_dbg(arizona->dev, "HPDET read %d in range %d\n", @@ -464,8 +391,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info) return val; } -static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading, - bool *mic) +static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading) { struct arizona *arizona = info->arizona; int id_gpio = arizona->pdata.hpdet_id_gpio; @@ -477,8 +403,32 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading, if (arizona->pdata.hpdet_acc_id) { info->hpdet_res[info->num_hpdet_res++] = *reading; + /* + * If the impedence is too high don't measure the + * second ground. + */ + if (info->num_hpdet_res == 1 && *reading >= 45) { + dev_dbg(arizona->dev, "Skipping ground flip\n"); + info->hpdet_res[info->num_hpdet_res++] = *reading; + } + + if (info->num_hpdet_res == 1) { + dev_dbg(arizona->dev, "Flipping ground\n"); + + regmap_update_bits(arizona->regmap, + ARIZONA_ACCESSORY_DETECT_MODE_1, + ARIZONA_ACCDET_SRC, + ~info->micd_modes[0].src); + + regmap_update_bits(arizona->regmap, + ARIZONA_HEADPHONE_DETECT_1, + ARIZONA_HP_POLL, ARIZONA_HP_POLL); + return -EAGAIN; + } + /* Only check the mic directly if we didn't already ID it */ - if (id_gpio && info->num_hpdet_res == 1) { + if (id_gpio && info->num_hpdet_res == 2 && + !((info->hpdet_res[0] > info->hpdet_res[1] * 2))) { dev_dbg(arizona->dev, "Measuring mic\n"); regmap_update_bits(arizona->regmap, @@ -497,28 +447,22 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading, } /* OK, got both. Now, compare... */ - dev_dbg(arizona->dev, "HPDET measured %d %d\n", - info->hpdet_res[0], info->hpdet_res[1]); + dev_dbg(arizona->dev, "HPDET measured %d %d %d\n", + info->hpdet_res[0], info->hpdet_res[1], + info->hpdet_res[2]); + /* Take the headphone impedance for the main report */ *reading = info->hpdet_res[0]; - /* Sometimes we get false readings due to slow insert */ - if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) { - dev_dbg(arizona->dev, "Retrying high impedance\n"); - info->num_hpdet_res = 0; - info->hpdet_retried = true; - arizona_start_hpdet_acc_id(info); - pm_runtime_put(info->dev); - return -EAGAIN; - } - /* - * If we measure the mic as + * Either the two grounds measure differently or we + * measure the mic as high impedance. */ - if (!id_gpio || info->hpdet_res[1] > 50) { + if ((info->hpdet_res[0] > info->hpdet_res[1] * 2) || + (id_gpio && info->hpdet_res[2] > 10)) { dev_dbg(arizona->dev, "Detected mic\n"); - *mic = true; + info->mic = true; info->detecting = true; } else { dev_dbg(arizona->dev, "Detected headphone\n"); @@ -540,8 +484,8 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) struct arizona *arizona = info->arizona; int id_gpio = arizona->pdata.hpdet_id_gpio; int report = ARIZONA_CABLE_HEADPHONE; + unsigned int val; int ret, reading; - bool mic = false; mutex_lock(&info->lock); @@ -577,7 +521,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL, 0); - ret = arizona_hpdet_do_id(info, &reading, &mic); + ret = arizona_hpdet_do_id(info, &reading); if (ret == -EAGAIN) { goto out; } else if (ret < 0) { @@ -595,7 +539,28 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) dev_err(arizona->dev, "Failed to report HP/line: %d\n", ret); - arizona_extcon_do_magic(info, 0); + mutex_lock(&arizona->dapm->card->dapm_mutex); + + ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read output enables: %d\n", + ret); + val = 0; + } + + if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { + ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0); + if (ret != 0) + dev_warn(arizona->dev, "Failed to undo magic: %d\n", + ret); + + ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0); + if (ret != 0) + dev_warn(arizona->dev, "Failed to undo magic: %d\n", + ret); + } + + mutex_unlock(&arizona->dapm->card->dapm_mutex); done: if (id_gpio) @@ -607,7 +572,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); /* If we have a mic then reenable MICDET */ - if (mic || info->mic) + if (info->mic) arizona_start_mic(info); if (info->hpdet_active) { @@ -641,7 +606,13 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info) if (info->mic) arizona_stop_mic(info); - arizona_extcon_do_magic(info, 0x4000); + ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000); + if (ret != 0) + dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); + + ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000); + if (ret != 0) + dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); ret = regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, @@ -682,8 +653,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info) static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) { struct arizona *arizona = info->arizona; - int hp_reading = 32; - bool mic; + unsigned int val; int ret; dev_dbg(arizona->dev, "Starting identification via HPDET\n"); @@ -693,7 +663,32 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) info->hpdet_active = true; - arizona_extcon_do_magic(info, 0x4000); + arizona_extcon_pulse_micbias(info); + + mutex_lock(&arizona->dapm->card->dapm_mutex); + + ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read output enables: %d\n", + ret); + val = 0; + } + + if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { + ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, + 0x4000); + if (ret != 0) + dev_warn(arizona->dev, "Failed to do magic: %d\n", + ret); + + ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, + 0x4000); + if (ret != 0) + dev_warn(arizona->dev, "Failed to do magic: %d\n", + ret); + } + + mutex_unlock(&arizona->dapm->card->dapm_mutex); ret = regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, @@ -705,18 +700,12 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) goto err; } - if (arizona->pdata.hpdet_acc_id_line) { - ret = regmap_update_bits(arizona->regmap, - ARIZONA_HEADPHONE_DETECT_1, - ARIZONA_HP_POLL, ARIZONA_HP_POLL); - if (ret != 0) { - dev_err(arizona->dev, - "Can't start HPDETL measurement: %d\n", - ret); - goto err; - } - } else { - arizona_hpdet_do_id(info, &hp_reading, &mic); + ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, + ARIZONA_HP_POLL, ARIZONA_HP_POLL); + if (ret != 0) { + dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n", + ret); + goto err; } return; @@ -735,58 +724,28 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) info->hpdet_active = false; } -static void arizona_micd_timeout_work(struct work_struct *work) -{ - struct arizona_extcon_info *info = container_of(work, - struct arizona_extcon_info, - micd_timeout_work.work); - - mutex_lock(&info->lock); - - dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n"); - arizona_identify_headphone(info); - - info->detecting = false; - - arizona_stop_mic(info); - - mutex_unlock(&info->lock); -} - -static void arizona_micd_detect(struct work_struct *work) +static irqreturn_t arizona_micdet(int irq, void *data) { - struct arizona_extcon_info *info = container_of(work, - struct arizona_extcon_info, - micd_detect_work.work); + struct arizona_extcon_info *info = data; struct arizona *arizona = info->arizona; - unsigned int val = 0, lvl; - int ret, i, key; - - cancel_delayed_work_sync(&info->micd_timeout_work); + unsigned int val, lvl; + int ret, i; mutex_lock(&info->lock); - for (i = 0; i < 10 && !(val & 0x7fc); i++) { - ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); - if (ret != 0) { - dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); - mutex_unlock(&info->lock); - return; - } - - dev_dbg(arizona->dev, "MICDET: %x\n", val); - - if (!(val & ARIZONA_MICD_VALID)) { - dev_warn(arizona->dev, "Microphone detection state invalid\n"); - mutex_unlock(&info->lock); - return; - } + ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); + mutex_unlock(&info->lock); + return IRQ_NONE; } - if (i == 10 && !(val & 0x7fc)) { - dev_err(arizona->dev, "Failed to get valid MICDET value\n"); + dev_dbg(arizona->dev, "MICDET: %x\n", val); + + if (!(val & ARIZONA_MICD_VALID)) { + dev_warn(arizona->dev, "Microphone detection state invalid\n"); mutex_unlock(&info->lock); - return; + return IRQ_NONE; } /* Due to jack detect this should never happen */ @@ -827,7 +786,7 @@ static void arizona_micd_detect(struct work_struct *work) * impedence then give up and report headphones. */ if (info->detecting && (val & 0x3f8)) { - if (info->jack_flips >= info->micd_num_modes * 10) { + if (info->jack_flips >= info->micd_num_modes) { dev_dbg(arizona->dev, "Detected HP/line\n"); arizona_identify_headphone(info); @@ -857,17 +816,12 @@ static void arizona_micd_detect(struct work_struct *work) lvl = val & ARIZONA_MICD_LVL_MASK; lvl >>= ARIZONA_MICD_LVL_SHIFT; - for (i = 0; i < info->num_micd_ranges; i++) - input_report_key(info->input, - info->micd_ranges[i].key, 0); - - WARN_ON(!lvl); - WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges); - if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) { - key = info->micd_ranges[ffs(lvl) - 1].key; - input_report_key(info->input, key, 1); - input_sync(info->input); - } + for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) + if (lvl & arizona_lvl_to_key[i].status) + input_report_key(info->input, + arizona_lvl_to_key[i].report, + 1); + input_sync(info->input); } else if (info->detecting) { dev_dbg(arizona->dev, "Headphone detected\n"); @@ -881,41 +835,16 @@ static void arizona_micd_detect(struct work_struct *work) } } else { dev_dbg(arizona->dev, "Mic button released\n"); - for (i = 0; i < info->num_micd_ranges; i++) + for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) input_report_key(info->input, - info->micd_ranges[i].key, 0); + arizona_lvl_to_key[i].report, 0); input_sync(info->input); arizona_extcon_pulse_micbias(info); } handled: - if (info->detecting) - schedule_delayed_work(&info->micd_timeout_work, - msecs_to_jiffies(info->micd_timeout)); - pm_runtime_mark_last_busy(info->dev); mutex_unlock(&info->lock); -} - -static irqreturn_t arizona_micdet(int irq, void *data) -{ - struct arizona_extcon_info *info = data; - struct arizona *arizona = info->arizona; - int debounce = arizona->pdata.micd_detect_debounce; - - cancel_delayed_work_sync(&info->micd_detect_work); - cancel_delayed_work_sync(&info->micd_timeout_work); - - mutex_lock(&info->lock); - if (!info->detecting) - debounce = 0; - mutex_unlock(&info->lock); - - if (debounce) - schedule_delayed_work(&info->micd_detect_work, - msecs_to_jiffies(debounce)); - else - arizona_micd_detect(&info->micd_detect_work.work); return IRQ_HANDLED; } @@ -936,14 +865,12 @@ static irqreturn_t arizona_jackdet(int irq, void *data) struct arizona_extcon_info *info = data; struct arizona *arizona = info->arizona; unsigned int val, present, mask; - bool cancelled_hp, cancelled_mic; int ret, i; - cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work); - cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work); - pm_runtime_get_sync(info->dev); + cancel_delayed_work_sync(&info->hpdet_work); + mutex_lock(&info->lock); if (arizona->pdata.jd_gpio5) { @@ -963,22 +890,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data) return IRQ_NONE; } - val &= mask; - if (val == info->last_jackdet) { - dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n"); - if (cancelled_hp) - schedule_delayed_work(&info->hpdet_work, - msecs_to_jiffies(HPDET_DEBOUNCE)); - - if (cancelled_mic) - schedule_delayed_work(&info->micd_timeout_work, - msecs_to_jiffies(info->micd_timeout)); - - goto out; - } - info->last_jackdet = val; - - if (info->last_jackdet == present) { + if ((val & mask) == present) { dev_dbg(arizona->dev, "Detected jack\n"); ret = extcon_set_cable_state_(&info->edev, ARIZONA_CABLE_MECHANICAL, true); @@ -995,7 +907,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data) arizona_start_mic(info); } else { schedule_delayed_work(&info->hpdet_work, - msecs_to_jiffies(HPDET_DEBOUNCE)); + msecs_to_jiffies(250)); } regmap_update_bits(arizona->regmap, @@ -1011,11 +923,10 @@ static irqreturn_t arizona_jackdet(int irq, void *data) info->hpdet_res[i] = 0; info->mic = false; info->hpdet_done = false; - info->hpdet_retried = false; - for (i = 0; i < info->num_micd_ranges; i++) + for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) input_report_key(info->input, - info->micd_ranges[i].key, 0); + arizona_lvl_to_key[i].report, 0); input_sync(info->input); ret = extcon_update_state(&info->edev, 0xffffffff, 0); @@ -1029,11 +940,6 @@ static irqreturn_t arizona_jackdet(int irq, void *data) ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB); } - if (arizona->pdata.micd_timeout) - info->micd_timeout = arizona->pdata.micd_timeout; - else - info->micd_timeout = DEFAULT_MICD_TIMEOUT; - /* Clear trig_sts to make sure DCVDD is not forced up */ regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG, ARIZONA_MICD_CLAMP_FALL_TRIG_STS | @@ -1041,7 +947,6 @@ static irqreturn_t arizona_jackdet(int irq, void *data) ARIZONA_JD1_FALL_TRIG_STS | ARIZONA_JD1_RISE_TRIG_STS); -out: mutex_unlock(&info->lock); pm_runtime_mark_last_busy(info->dev); @@ -1050,34 +955,13 @@ static irqreturn_t arizona_jackdet(int irq, void *data) return IRQ_HANDLED; } -/* Map a level onto a slot in the register bank */ -static void arizona_micd_set_level(struct arizona *arizona, int index, - unsigned int level) -{ - int reg; - unsigned int mask; - - reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2); - - if (!(index % 2)) { - mask = 0x3f00; - level <<= 8; - } else { - mask = 0x3f; - } - - /* Program the level itself */ - regmap_update_bits(arizona->regmap, reg, mask, level); -} - static int arizona_extcon_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct arizona_pdata *pdata; struct arizona_extcon_info *info; - unsigned int val; int jack_irq_fall, jack_irq_rise; - int ret, mode, i, j; + int ret, mode, i; if (!arizona->dapm || !arizona->dapm->card) return -EPROBE_DEFER; @@ -1101,10 +985,7 @@ static int arizona_extcon_probe(struct platform_device *pdev) mutex_init(&info->lock); info->arizona = arizona; info->dev = &pdev->dev; - info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS); INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work); - INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect); - INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work); platform_set_drvdata(pdev, info); switch (arizona->type) { @@ -1133,17 +1014,6 @@ static int arizona_extcon_probe(struct platform_device *pdev) goto err; } - info->input = devm_input_allocate_device(&pdev->dev); - if (!info->input) { - dev_err(arizona->dev, "Can't allocate input dev\n"); - ret = -ENOMEM; - goto err_register; - } - - info->input->name = "Headset"; - info->input->phys = "arizona/extcon"; - info->input->dev.parent = &pdev->dev; - if (pdata->num_micd_configs) { info->micd_modes = pdata->micd_configs; info->micd_num_modes = pdata->num_micd_configs; @@ -1199,79 +1069,15 @@ static int arizona_extcon_probe(struct platform_device *pdev) arizona->pdata.micd_dbtime << ARIZONA_MICD_DBTIME_SHIFT); - BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40); - - if (arizona->pdata.num_micd_ranges) { - info->micd_ranges = pdata->micd_ranges; - info->num_micd_ranges = pdata->num_micd_ranges; - } else { - info->micd_ranges = micd_default_ranges; - info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges); - } - - if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) { - dev_err(arizona->dev, "Too many MICD ranges: %d\n", - arizona->pdata.num_micd_ranges); - } - - if (info->num_micd_ranges > 1) { - for (i = 1; i < info->num_micd_ranges; i++) { - if (info->micd_ranges[i - 1].max > - info->micd_ranges[i].max) { - dev_err(arizona->dev, - "MICD ranges must be sorted\n"); - ret = -EINVAL; - goto err_input; - } - } - } - - /* Disable all buttons by default */ - regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2, - ARIZONA_MICD_LVL_SEL_MASK, 0x81); - - /* Set up all the buttons the user specified */ - for (i = 0; i < info->num_micd_ranges; i++) { - for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++) - if (arizona_micd_levels[j] >= info->micd_ranges[i].max) - break; - - if (j == ARRAY_SIZE(arizona_micd_levels)) { - dev_err(arizona->dev, "Unsupported MICD level %d\n", - info->micd_ranges[i].max); - ret = -EINVAL; - goto err_input; - } - - dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n", - arizona_micd_levels[j], i); - - arizona_micd_set_level(arizona, i, j); - input_set_capability(info->input, EV_KEY, - info->micd_ranges[i].key); - - /* Enable reporting of that range */ - regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2, - 1 << i, 1 << i); - } - - /* Set all the remaining keys to a maximum */ - for (; i < ARIZONA_MAX_MICD_RANGE; i++) - arizona_micd_set_level(arizona, i, 0x3f); - /* * If we have a clamp use it, activating in conjunction with * GPIO5 if that is connected for jack detect operation. */ if (info->micd_clamp) { if (arizona->pdata.jd_gpio5) { - /* Put the GPIO into input mode with optional pull */ - val = 0xc101; - if (arizona->pdata.jd_gpio5_nopull) - val &= ~ARIZONA_GPN_PU; - + /* Put the GPIO into input mode */ regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL, - val); + 0xc101); regmap_update_bits(arizona->regmap, ARIZONA_MICD_CLAMP_CONTROL, @@ -1290,6 +1096,20 @@ static int arizona_extcon_probe(struct platform_device *pdev) arizona_extcon_set_mode(info, 0); + info->input = devm_input_allocate_device(&pdev->dev); + if (!info->input) { + dev_err(arizona->dev, "Can't allocate input dev\n"); + ret = -ENOMEM; + goto err_register; + } + + for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) + input_set_capability(info->input, EV_KEY, + arizona_lvl_to_key[i].report); + info->input->name = "Headset"; + info->input->phys = "arizona/extcon"; + info->input->dev.parent = &pdev->dev; + pm_runtime_enable(&pdev->dev); pm_runtime_idle(&pdev->dev); pm_runtime_get_sync(&pdev->dev); diff --git a/trunk/drivers/extcon/extcon-max77693.c b/trunk/drivers/extcon/extcon-max77693.c index b56bdaa27d4b..b70e3815c459 100644 --- a/trunk/drivers/extcon/extcon-max77693.c +++ b/trunk/drivers/extcon/extcon-max77693.c @@ -32,38 +32,6 @@ #define DEV_NAME "max77693-muic" #define DELAY_MS_DEFAULT 20000 /* unit: millisecond */ -/* - * Default value of MAX77693 register to bring up MUIC device. - * If user don't set some initial value for MUIC device through platform data, - * extcon-max77693 driver use 'default_init_data' to bring up base operation - * of MAX77693 MUIC device. - */ -static struct max77693_reg_data default_init_data[] = { - { - /* STATUS2 - [3]ChgDetRun */ - .addr = MAX77693_MUIC_REG_STATUS2, - .data = STATUS2_CHGDETRUN_MASK, - }, { - /* INTMASK1 - Unmask [3]ADC1KM,[0]ADCM */ - .addr = MAX77693_MUIC_REG_INTMASK1, - .data = INTMASK1_ADC1K_MASK - | INTMASK1_ADC_MASK, - }, { - /* INTMASK2 - Unmask [0]ChgTypM */ - .addr = MAX77693_MUIC_REG_INTMASK2, - .data = INTMASK2_CHGTYP_MASK, - }, { - /* INTMASK3 - Mask all of interrupts */ - .addr = MAX77693_MUIC_REG_INTMASK3, - .data = 0x0, - }, { - /* CDETCTRL2 */ - .addr = MAX77693_MUIC_REG_CDETCTRL2, - .data = CDETCTRL2_VIDRMEN_MASK - | CDETCTRL2_DXOVPEN_MASK, - }, -}; - enum max77693_muic_adc_debounce_time { ADC_DEBOUNCE_TIME_5MS = 0, ADC_DEBOUNCE_TIME_10MS, @@ -258,7 +226,7 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, CONTROL3_ADCDBSET_MASK); if (ret) { dev_err(info->dev, "failed to set ADC debounce time\n"); - return ret; + return -EAGAIN; } break; default: @@ -294,7 +262,7 @@ static int max77693_muic_set_path(struct max77693_muic_info *info, MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK); if (ret < 0) { dev_err(info->dev, "failed to update MUIC register\n"); - return ret; + return -EAGAIN; } if (attached) @@ -307,7 +275,7 @@ static int max77693_muic_set_path(struct max77693_muic_info *info, CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK); if (ret < 0) { dev_err(info->dev, "failed to update MUIC register\n"); - return ret; + return -EAGAIN; } dev_info(info->dev, @@ -1035,7 +1003,7 @@ static int max77693_muic_detect_accessory(struct max77693_muic_info *info) if (ret) { dev_err(info->dev, "failed to read MUIC register\n"); mutex_unlock(&info->mutex); - return ret; + return -EINVAL; } adc = max77693_muic_get_cable_type(info, MAX77693_CABLE_GROUP_ADC, @@ -1077,9 +1045,8 @@ static int max77693_muic_probe(struct platform_device *pdev) { struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev); + struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; struct max77693_muic_info *info; - struct max77693_reg_data *init_data; - int num_init_data; int delay_jiffies; int ret; int i; @@ -1178,25 +1145,15 @@ static int max77693_muic_probe(struct platform_device *pdev) goto err_irq; } - - /* Initialize MUIC register by using platform data or default data */ - if (pdata->muic_data) { - init_data = pdata->muic_data->init_data; - num_init_data = pdata->muic_data->num_init_data; - } else { - init_data = default_init_data; - num_init_data = ARRAY_SIZE(default_init_data); - } - - for (i = 0 ; i < num_init_data ; i++) { - enum max77693_irq_source irq_src - = MAX77693_IRQ_GROUP_NR; + /* Initialize MUIC register by using platform data */ + for (i = 0 ; i < muic_pdata->num_init_data ; i++) { + enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR; max77693_write_reg(info->max77693->regmap_muic, - init_data[i].addr, - init_data[i].data); + muic_pdata->init_data[i].addr, + muic_pdata->init_data[i].data); - switch (init_data[i].addr) { + switch (muic_pdata->init_data[i].addr) { case MAX77693_MUIC_REG_INTMASK1: irq_src = MUIC_INT1; break; @@ -1210,40 +1167,22 @@ static int max77693_muic_probe(struct platform_device *pdev) if (irq_src < MAX77693_IRQ_GROUP_NR) info->max77693->irq_masks_cur[irq_src] - = init_data[i].data; + = muic_pdata->init_data[i].data; } - if (pdata->muic_data) { - struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; - - /* - * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB - * h/w path of COMP2/COMN1 on CONTROL1 register. - */ - if (muic_pdata->path_uart) - info->path_uart = muic_pdata->path_uart; - else - info->path_uart = CONTROL1_SW_UART; - - if (muic_pdata->path_usb) - info->path_usb = muic_pdata->path_usb; - else - info->path_usb = CONTROL1_SW_USB; + /* + * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB + * h/w path of COMP2/COMN1 on CONTROL1 register. + */ + if (muic_pdata->path_uart) + info->path_uart = muic_pdata->path_uart; + else + info->path_uart = CONTROL1_SW_UART; - /* - * Default delay time for detecting cable state - * after certain time. - */ - if (muic_pdata->detcable_delay_ms) - delay_jiffies = - msecs_to_jiffies(muic_pdata->detcable_delay_ms); - else - delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); - } else { + if (muic_pdata->path_usb) + info->path_usb = muic_pdata->path_usb; + else info->path_usb = CONTROL1_SW_USB; - info->path_uart = CONTROL1_SW_UART; - delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); - } /* Set initial path for UART */ max77693_muic_set_path(info, info->path_uart, true); @@ -1269,6 +1208,10 @@ static int max77693_muic_probe(struct platform_device *pdev) * driver should notify cable state to upper layer. */ INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq); + if (muic_pdata->detcable_delay_ms) + delay_jiffies = msecs_to_jiffies(muic_pdata->detcable_delay_ms); + else + delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); schedule_delayed_work(&info->wq_detcable, delay_jiffies); return ret; diff --git a/trunk/drivers/extcon/extcon-max8997.c b/trunk/drivers/extcon/extcon-max8997.c index 67d6738d85a0..e636d950ad6c 100644 --- a/trunk/drivers/extcon/extcon-max8997.c +++ b/trunk/drivers/extcon/extcon-max8997.c @@ -196,7 +196,7 @@ static int max8997_muic_set_debounce_time(struct max8997_muic_info *info, CONTROL3_ADCDBSET_MASK); if (ret) { dev_err(info->dev, "failed to set ADC debounce time\n"); - return ret; + return -EAGAIN; } break; default: @@ -232,7 +232,7 @@ static int max8997_muic_set_path(struct max8997_muic_info *info, MAX8997_MUIC_REG_CONTROL1, ctrl1, COMP_SW_MASK); if (ret < 0) { dev_err(info->dev, "failed to update MUIC register\n"); - return ret; + return -EAGAIN; } if (attached) @@ -245,7 +245,7 @@ static int max8997_muic_set_path(struct max8997_muic_info *info, CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK); if (ret < 0) { dev_err(info->dev, "failed to update MUIC register\n"); - return ret; + return -EAGAIN; } dev_info(info->dev, @@ -397,7 +397,7 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, ret = max8997_muic_set_path(info, info->path_uart, attached); if (ret) { dev_err(info->dev, "failed to update muic register\n"); - return ret; + return -EINVAL; } extcon_set_cable_state(info->edev, "JIG", attached); @@ -608,7 +608,7 @@ static int max8997_muic_detect_dev(struct max8997_muic_info *info) if (ret) { dev_err(info->dev, "failed to read MUIC register\n"); mutex_unlock(&info->mutex); - return ret; + return -EINVAL; } adc = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_ADC, @@ -646,7 +646,7 @@ static void max8997_muic_detect_cable_wq(struct work_struct *work) ret = max8997_muic_detect_dev(info); if (ret < 0) - dev_err(info->dev, "failed to detect cable type\n"); + pr_err("failed to detect cable type\n"); } static int max8997_muic_probe(struct platform_device *pdev) @@ -712,45 +712,29 @@ static int max8997_muic_probe(struct platform_device *pdev) goto err_irq; } + /* Initialize registers according to platform data */ if (pdata->muic_pdata) { - struct max8997_muic_platform_data *muic_pdata - = pdata->muic_pdata; - - /* Initialize registers according to platform data */ - for (i = 0; i < muic_pdata->num_init_data; i++) { - max8997_write_reg(info->muic, - muic_pdata->init_data[i].addr, - muic_pdata->init_data[i].data); - } + struct max8997_muic_platform_data *mdata = info->muic_pdata; - /* - * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB - * h/w path of COMP2/COMN1 on CONTROL1 register. - */ - if (muic_pdata->path_uart) - info->path_uart = muic_pdata->path_uart; - else - info->path_uart = CONTROL1_SW_UART; - - if (muic_pdata->path_usb) - info->path_usb = muic_pdata->path_usb; - else - info->path_usb = CONTROL1_SW_USB; + for (i = 0; i < mdata->num_init_data; i++) { + max8997_write_reg(info->muic, mdata->init_data[i].addr, + mdata->init_data[i].data); + } + } - /* - * Default delay time for detecting cable state - * after certain time. - */ - if (muic_pdata->detcable_delay_ms) - delay_jiffies = - msecs_to_jiffies(muic_pdata->detcable_delay_ms); - else - delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); - } else { + /* + * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB + * h/w path of COMP2/COMN1 on CONTROL1 register. + */ + if (pdata->muic_pdata->path_uart) + info->path_uart = pdata->muic_pdata->path_uart; + else info->path_uart = CONTROL1_SW_UART; + + if (pdata->muic_pdata->path_usb) + info->path_usb = pdata->muic_pdata->path_usb; + else info->path_usb = CONTROL1_SW_USB; - delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); - } /* Set initial path for UART */ max8997_muic_set_path(info, info->path_uart, true); @@ -767,6 +751,10 @@ static int max8997_muic_probe(struct platform_device *pdev) * driver should notify cable state to upper layer. */ INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq); + if (pdata->muic_pdata->detcable_delay_ms) + delay_jiffies = msecs_to_jiffies(pdata->muic_pdata->detcable_delay_ms); + else + delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); schedule_delayed_work(&info->wq_detcable, delay_jiffies); return 0; diff --git a/trunk/drivers/firmware/Kconfig b/trunk/drivers/firmware/Kconfig index 3e532002e4d1..9b00072a020f 100644 --- a/trunk/drivers/firmware/Kconfig +++ b/trunk/drivers/firmware/Kconfig @@ -39,7 +39,6 @@ config FIRMWARE_MEMMAP config EFI_VARS tristate "EFI Variable Support via sysfs" depends on EFI - select UCS2_STRING default n help If you say Y here, you are able to get EFI (Extensible Firmware @@ -54,24 +53,6 @@ config EFI_VARS Subsequent efibootmgr releases may be found at: -config EFI_VARS_PSTORE - bool "Register efivars backend for pstore" - depends on EFI_VARS && PSTORE - default y - help - Say Y here to enable use efivars as a backend to pstore. This - will allow writing console messages, crash dumps, or anything - else supported by pstore to EFI variables. - -config EFI_VARS_PSTORE_DEFAULT_DISABLE - bool "Disable using efivars as a pstore backend by default" - depends on EFI_VARS_PSTORE - default n - help - Saying Y here will disable the use of efivars as a storage - backend for pstore by default. This setting can be overridden - using the efivars module's pstore_disable parameter. - config EFI_PCDP bool "Console device selection via EFI PCDP or HCDP table" depends on ACPI && EFI && IA64 diff --git a/trunk/drivers/firmware/dmi_scan.c b/trunk/drivers/firmware/dmi_scan.c index 4cd392dbf115..982f1f5f5742 100644 --- a/trunk/drivers/firmware/dmi_scan.c +++ b/trunk/drivers/firmware/dmi_scan.c @@ -442,6 +442,7 @@ static int __init dmi_present(const char __iomem *p) static int __init smbios_present(const char __iomem *p) { u8 buf[32]; + int offset = 0; memcpy_fromio(buf, p, 32); if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) { @@ -460,9 +461,9 @@ static int __init smbios_present(const char __iomem *p) dmi_ver = 0x0206; break; } - return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16); + offset = 16; } - return 1; + return dmi_present(buf + offset); } void __init dmi_scan_machine(void) diff --git a/trunk/drivers/firmware/efivars.c b/trunk/drivers/firmware/efivars.c index f4baa11d3644..7320bf891706 100644 --- a/trunk/drivers/firmware/efivars.c +++ b/trunk/drivers/firmware/efivars.c @@ -80,7 +80,6 @@ #include #include #include -#include #include #include @@ -104,11 +103,6 @@ MODULE_VERSION(EFIVARS_VERSION); */ #define GUID_LEN 36 -static bool efivars_pstore_disable = - IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE); - -module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644); - /* * The maximum size of VariableName + Data = 1024 * Therefore, it's reasonable to save that much @@ -171,7 +165,51 @@ efivar_create_sysfs_entry(struct efivars *efivars, static void efivar_update_sysfs_entries(struct work_struct *); static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries); -static bool efivar_wq_enabled = true; + +/* Return the number of unicode characters in data */ +static unsigned long +utf16_strnlen(efi_char16_t *s, size_t maxlength) +{ + unsigned long length = 0; + + while (*s++ != 0 && length < maxlength) + length++; + return length; +} + +static inline unsigned long +utf16_strlen(efi_char16_t *s) +{ + return utf16_strnlen(s, ~0UL); +} + +/* + * Return the number of bytes is the length of this string + * Note: this is NOT the same as the number of unicode characters + */ +static inline unsigned long +utf16_strsize(efi_char16_t *data, unsigned long maxlength) +{ + return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t); +} + +static inline int +utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len) +{ + while (1) { + if (len == 0) + return 0; + if (*a < *b) + return -1; + if (*a > *b) + return 1; + if (*a == 0) /* implies *b == 0 */ + return 0; + a++; + b++; + len--; + } +} static bool validate_device_path(struct efi_variable *var, int match, u8 *buffer, @@ -224,7 +262,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, u16 filepathlength; int i, desclength = 0, namelen; - namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName)); + namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); /* Either "Boot" or "Driver" followed by four digits of hex */ for (i = match; i < match+4; i++) { @@ -247,7 +285,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, * There's no stored length for the description, so it has to be * found by hand */ - desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; + desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; /* Each boot entry must have a descriptor */ if (!desclength) @@ -388,32 +426,6 @@ get_var_data(struct efivars *efivars, struct efi_variable *var) return status; } -static efi_status_t -check_var_size_locked(struct efivars *efivars, u32 attributes, - unsigned long size) -{ - const struct efivar_operations *fops = efivars->ops; - - if (!efivars->ops->query_variable_store) - return EFI_UNSUPPORTED; - - return fops->query_variable_store(attributes, size); -} - - -static efi_status_t -check_var_size(struct efivars *efivars, u32 attributes, unsigned long size) -{ - efi_status_t status; - unsigned long flags; - - spin_lock_irqsave(&efivars->lock, flags); - status = check_var_size_locked(efivars, attributes, size); - spin_unlock_irqrestore(&efivars->lock, flags); - - return status; -} - static ssize_t efivar_guid_read(struct efivar_entry *entry, char *buf) { @@ -535,16 +547,11 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) } spin_lock_irq(&efivars->lock); - - status = check_var_size_locked(efivars, new_var->Attributes, - new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024)); - - if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED) - status = efivars->ops->set_variable(new_var->VariableName, - &new_var->VendorGuid, - new_var->Attributes, - new_var->DataSize, - new_var->Data); + status = efivars->ops->set_variable(new_var->VariableName, + &new_var->VendorGuid, + new_var->Attributes, + new_var->DataSize, + new_var->Data); spin_unlock_irq(&efivars->lock); @@ -695,7 +702,8 @@ static ssize_t efivarfs_file_write(struct file *file, u32 attributes; struct inode *inode = file->f_mapping->host; unsigned long datasize = count - sizeof(attributes); - unsigned long newdatasize, varsize; + unsigned long newdatasize; + u64 storage_size, remaining_size, max_size; ssize_t bytes = 0; if (count < sizeof(attributes)) @@ -714,18 +722,28 @@ static ssize_t efivarfs_file_write(struct file *file, * amounts of memory. Pick a default size of 64K if * QueryVariableInfo() isn't supported by the firmware. */ + spin_lock_irq(&efivars->lock); - varsize = datasize + ucs2_strsize(var->var.VariableName, 1024); - status = check_var_size(efivars, attributes, varsize); + if (!efivars->ops->query_variable_info) + status = EFI_UNSUPPORTED; + else { + const struct efivar_operations *fops = efivars->ops; + status = fops->query_variable_info(attributes, &storage_size, + &remaining_size, &max_size); + } + + spin_unlock_irq(&efivars->lock); if (status != EFI_SUCCESS) { if (status != EFI_UNSUPPORTED) return efi_status_to_err(status); - if (datasize > 65536) - return -ENOSPC; + remaining_size = 65536; } + if (datasize > remaining_size) + return -ENOSPC; + data = kmalloc(datasize, GFP_KERNEL); if (!data) return -ENOMEM; @@ -747,19 +765,6 @@ static ssize_t efivarfs_file_write(struct file *file, */ spin_lock_irq(&efivars->lock); - /* - * Ensure that the available space hasn't shrunk below the safe level - */ - - status = check_var_size_locked(efivars, attributes, varsize); - - if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) { - spin_unlock_irq(&efivars->lock); - kfree(data); - - return efi_status_to_err(status); - } - status = efivars->ops->set_variable(var->var.VariableName, &var->var.VendorGuid, attributes, datasize, @@ -924,8 +929,8 @@ static bool efivarfs_valid_name(const char *str, int len) if (len < GUID_LEN + 2) return false; - /* GUID must be preceded by a '-' */ - if (*(s - 1) != '-') + /* GUID should be right after the first '-' */ + if (s - 1 != strchr(str, '-')) return false; /* @@ -1113,22 +1118,15 @@ static struct dentry_operations efivarfs_d_ops = { static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name) { - struct dentry *d; struct qstr q; - int err; q.name = name; q.len = strlen(name); - err = efivarfs_d_hash(NULL, NULL, &q); - if (err) - return ERR_PTR(err); - - d = d_alloc(parent, &q); - if (d) - return d; + if (efivarfs_d_hash(NULL, NULL, &q)) + return NULL; - return ERR_PTR(-ENOMEM); + return d_alloc(parent, &q); } static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) @@ -1138,7 +1136,6 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) struct efivar_entry *entry, *n; struct efivars *efivars = &__efivars; char *name; - int err = -ENOMEM; efivarfs_sb = sb; @@ -1167,7 +1164,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) inode = NULL; - len = ucs2_strlen(entry->var.VariableName); + len = utf16_strlen(entry->var.VariableName); /* name, plus '-', plus GUID, plus NUL*/ name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC); @@ -1189,10 +1186,8 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) goto fail_name; dentry = efivarfs_alloc_dentry(root, name); - if (IS_ERR(dentry)) { - err = PTR_ERR(dentry); + if (!dentry) goto fail_inode; - } /* copied by the above to local storage in the dentry. */ kfree(name); @@ -1219,7 +1214,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) fail_name: kfree(name); fail: - return err; + return -ENOMEM; } static struct dentry *efivarfs_mount(struct file_system_type *fs_type, @@ -1239,7 +1234,6 @@ static struct file_system_type efivarfs_type = { .mount = efivarfs_mount, .kill_sb = efivarfs_kill_sb, }; -MODULE_ALIAS_FS("efivarfs"); /* * Handle negative dentry. @@ -1259,7 +1253,9 @@ static const struct inode_operations efivarfs_dir_inode_operations = { .create = efivarfs_create, }; -#ifdef CONFIG_EFI_VARS_PSTORE +static struct pstore_info efi_pstore_info; + +#ifdef CONFIG_PSTORE static int efi_pstore_open(struct pstore_info *psi) { @@ -1349,6 +1345,7 @@ static int efi_pstore_write(enum pstore_type_id type, efi_guid_t vendor = LINUX_EFI_CRASH_GUID; struct efivars *efivars = psi->data; int i, ret = 0; + u64 storage_space, remaining_space, max_variable_size; efi_status_t status = EFI_NOT_FOUND; unsigned long flags; @@ -1368,11 +1365,11 @@ static int efi_pstore_write(enum pstore_type_id type, * size: a size of logging data * DUMP_NAME_LEN * 2: a maximum size of variable name */ - - status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES, - size + DUMP_NAME_LEN * 2); - - if (status) { + status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES, + &storage_space, + &remaining_space, + &max_variable_size); + if (status || remaining_space < size + DUMP_NAME_LEN * 2) { spin_unlock_irqrestore(&efivars->lock, flags); *id = part; return -ENOSPC; @@ -1389,7 +1386,7 @@ static int efi_pstore_write(enum pstore_type_id type, spin_unlock_irqrestore(&efivars->lock, flags); - if (reason == KMSG_DUMP_OOPS && efivar_wq_enabled) + if (reason == KMSG_DUMP_OOPS) schedule_work(&efivar_work); *id = part; @@ -1425,8 +1422,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, if (efi_guidcmp(entry->var.VendorGuid, vendor)) continue; - if (ucs2_strncmp(entry->var.VariableName, efi_name, - ucs2_strlen(efi_name))) { + if (utf16_strncmp(entry->var.VariableName, efi_name, + utf16_strlen(efi_name))) { /* * Check if an old format, * which doesn't support holding @@ -1438,8 +1435,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, for (i = 0; i < DUMP_NAME_LEN; i++) efi_name_old[i] = name_old[i]; - if (ucs2_strncmp(entry->var.VariableName, efi_name_old, - ucs2_strlen(efi_name_old))) + if (utf16_strncmp(entry->var.VariableName, efi_name_old, + utf16_strlen(efi_name_old))) continue; } @@ -1462,6 +1459,38 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, return 0; } +#else +static int efi_pstore_open(struct pstore_info *psi) +{ + return 0; +} + +static int efi_pstore_close(struct pstore_info *psi) +{ + return 0; +} + +static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count, + struct timespec *timespec, + char **buf, struct pstore_info *psi) +{ + return -1; +} + +static int efi_pstore_write(enum pstore_type_id type, + enum kmsg_dump_reason reason, u64 *id, + unsigned int part, int count, size_t size, + struct pstore_info *psi) +{ + return 0; +} + +static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, + struct timespec time, struct pstore_info *psi) +{ + return 0; +} +#endif static struct pstore_info efi_pstore_info = { .owner = THIS_MODULE, @@ -1473,24 +1502,6 @@ static struct pstore_info efi_pstore_info = { .erase = efi_pstore_erase, }; -static void efivar_pstore_register(struct efivars *efivars) -{ - efivars->efi_pstore_info = efi_pstore_info; - efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL); - if (efivars->efi_pstore_info.buf) { - efivars->efi_pstore_info.bufsize = 1024; - efivars->efi_pstore_info.data = efivars; - spin_lock_init(&efivars->efi_pstore_info.buf_lock); - pstore_register(&efivars->efi_pstore_info); - } -} -#else -static void efivar_pstore_register(struct efivars *efivars) -{ - return; -} -#endif - static ssize_t efivar_create(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) @@ -1517,8 +1528,8 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, * Does this variable already exist? */ list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { - strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024); - strsize2 = ucs2_strsize(new_var->VariableName, 1024); + strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); + strsize2 = utf16_strsize(new_var->VariableName, 1024); if (strsize1 == strsize2 && !memcmp(&(search_efivar->var.VariableName), new_var->VariableName, strsize1) && @@ -1533,14 +1544,6 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, return -EINVAL; } - status = check_var_size_locked(efivars, new_var->Attributes, - new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024)); - - if (status && status != EFI_UNSUPPORTED) { - spin_unlock_irq(&efivars->lock); - return efi_status_to_err(status); - } - /* now *really* create the variable via EFI */ status = efivars->ops->set_variable(new_var->VariableName, &new_var->VendorGuid, @@ -1558,7 +1561,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, /* Create the entry in sysfs. Locking is not required here */ status = efivar_create_sysfs_entry(efivars, - ucs2_strsize(new_var->VariableName, + utf16_strsize(new_var->VariableName, 1024), new_var->VariableName, &new_var->VendorGuid); @@ -1588,8 +1591,8 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, * Does this variable already exist? */ list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { - strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024); - strsize2 = ucs2_strsize(del_var->VariableName, 1024); + strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); + strsize2 = utf16_strsize(del_var->VariableName, 1024); if (strsize1 == strsize2 && !memcmp(&(search_efivar->var.VariableName), del_var->VariableName, strsize1) && @@ -1628,17 +1631,16 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, return count; } -static bool variable_is_present(struct efivars *efivars, - efi_char16_t *variable_name, - efi_guid_t *vendor) +static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor) { struct efivar_entry *entry, *n; + struct efivars *efivars = &__efivars; unsigned long strsize1, strsize2; bool found = false; - strsize1 = ucs2_strsize(variable_name, 1024); + strsize1 = utf16_strsize(variable_name, 1024); list_for_each_entry_safe(entry, n, &efivars->list, list) { - strsize2 = ucs2_strsize(entry->var.VariableName, 1024); + strsize2 = utf16_strsize(entry->var.VariableName, 1024); if (strsize1 == strsize2 && !memcmp(variable_name, &(entry->var.VariableName), strsize2) && @@ -1651,31 +1653,6 @@ static bool variable_is_present(struct efivars *efivars, return found; } -/* - * Returns the size of variable_name, in bytes, including the - * terminating NULL character, or variable_name_size if no NULL - * character is found among the first variable_name_size bytes. - */ -static unsigned long var_name_strnsize(efi_char16_t *variable_name, - unsigned long variable_name_size) -{ - unsigned long len; - efi_char16_t c; - - /* - * The variable name is, by definition, a NULL-terminated - * string, so make absolutely sure that variable_name_size is - * the value we expect it to be. If not, return the real size. - */ - for (len = 2; len <= variable_name_size; len += sizeof(c)) { - c = variable_name[(len / sizeof(c)) - 1]; - if (!c) - break; - } - - return min(len, variable_name_size); -} - static void efivar_update_sysfs_entries(struct work_struct *work) { struct efivars *efivars = &__efivars; @@ -1704,8 +1681,8 @@ static void efivar_update_sysfs_entries(struct work_struct *work) if (status != EFI_SUCCESS) { break; } else { - if (!variable_is_present(efivars, - variable_name, &vendor)) { + if (!variable_is_present(variable_name, + &vendor)) { found = true; break; } @@ -1716,13 +1693,10 @@ static void efivar_update_sysfs_entries(struct work_struct *work) if (!found) { kfree(variable_name); break; - } else { - variable_name_size = var_name_strnsize(variable_name, - variable_name_size); + } else efivar_create_sysfs_entry(efivars, variable_name_size, variable_name, &vendor); - } } } @@ -1921,35 +1895,6 @@ void unregister_efivars(struct efivars *efivars) } EXPORT_SYMBOL_GPL(unregister_efivars); -/* - * Print a warning when duplicate EFI variables are encountered and - * disable the sysfs workqueue since the firmware is buggy. - */ -static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid, - unsigned long len16) -{ - size_t i, len8 = len16 / sizeof(efi_char16_t); - char *s8; - - /* - * Disable the workqueue since the algorithm it uses for - * detecting new variables won't work with this buggy - * implementation of GetNextVariableName(). - */ - efivar_wq_enabled = false; - - s8 = kzalloc(len8, GFP_KERNEL); - if (!s8) - return; - - for (i = 0; i < len8; i++) - s8[i] = s16[i]; - - printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n", - s8, vendor_guid); - kfree(s8); -} - int register_efivars(struct efivars *efivars, const struct efivar_operations *ops, struct kobject *parent_kobj) @@ -1998,25 +1943,6 @@ int register_efivars(struct efivars *efivars, &vendor_guid); switch (status) { case EFI_SUCCESS: - variable_name_size = var_name_strnsize(variable_name, - variable_name_size); - - /* - * Some firmware implementations return the - * same variable name on multiple calls to - * get_next_variable(). Terminate the loop - * immediately as there is no guarantee that - * we'll ever see a different variable name, - * and may end up looping here forever. - */ - if (variable_is_present(efivars, variable_name, - &vendor_guid)) { - dup_variable_bug(variable_name, &vendor_guid, - variable_name_size); - status = EFI_NOT_FOUND; - break; - } - efivar_create_sysfs_entry(efivars, variable_name_size, variable_name, @@ -2036,8 +1962,15 @@ int register_efivars(struct efivars *efivars, if (error) unregister_efivars(efivars); - if (!efivars_pstore_disable) - efivar_pstore_register(efivars); + efivars->efi_pstore_info = efi_pstore_info; + + efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL); + if (efivars->efi_pstore_info.buf) { + efivars->efi_pstore_info.bufsize = 1024; + efivars->efi_pstore_info.data = efivars; + spin_lock_init(&efivars->efi_pstore_info.buf_lock); + pstore_register(&efivars->efi_pstore_info); + } register_filesystem(&efivarfs_type); @@ -2077,7 +2010,7 @@ efivars_init(void) ops.get_variable = efi.get_variable; ops.set_variable = efi.set_variable; ops.get_next_variable = efi.get_next_variable; - ops.query_variable_store = efi_query_variable_store; + ops.query_variable_info = efi.query_variable_info; error = register_efivars(&__efivars, &ops, efi_kobj); if (error) diff --git a/trunk/drivers/gpio/gpio-ich.c b/trunk/drivers/gpio/gpio-ich.c index de3c317bd3e2..6f2306db8591 100644 --- a/trunk/drivers/gpio/gpio-ich.c +++ b/trunk/drivers/gpio/gpio-ich.c @@ -128,9 +128,9 @@ static int ichx_read_bit(int reg, unsigned nr) return data & (1 << bit) ? 1 : 0; } -static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) +static int ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) { - return ichx_priv.use_gpio & (1 << (nr / 32)); + return (ichx_priv.use_gpio & (1 << (nr / 32))) ? 0 : -ENXIO; } static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) @@ -214,7 +214,7 @@ static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) * If it can't be trusted, assume that the pin can be used as a GPIO. */ if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) - return 0; + return 1; return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; } diff --git a/trunk/drivers/gpio/gpio-mvebu.c b/trunk/drivers/gpio/gpio-mvebu.c index 61a6fde6c089..7472182967ce 100644 --- a/trunk/drivers/gpio/gpio-mvebu.c +++ b/trunk/drivers/gpio/gpio-mvebu.c @@ -42,7 +42,6 @@ #include #include #include -#include #include /* @@ -497,7 +496,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) struct resource *res; struct irq_chip_generic *gc; struct irq_chip_type *ct; - struct clk *clk; unsigned int ngpios; int soc_variant; int i, cpu, id; @@ -531,11 +529,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) return id; } - clk = devm_clk_get(&pdev->dev, NULL); - /* Not all SoCs require a clock.*/ - if (!IS_ERR(clk)) - clk_prepare_enable(clk); - mvchip->soc_variant = soc_variant; mvchip->chip.label = dev_name(&pdev->dev); mvchip->chip.dev = &pdev->dev; diff --git a/trunk/drivers/gpio/gpio-pca953x.c b/trunk/drivers/gpio/gpio-pca953x.c index 9391cf16e990..24059462c87f 100644 --- a/trunk/drivers/gpio/gpio-pca953x.c +++ b/trunk/drivers/gpio/gpio-pca953x.c @@ -575,7 +575,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, chip->gpio_chip.ngpio, irq_base, &pca953x_irq_simple_ops, - chip); + NULL); if (!chip->domain) return -ENODEV; diff --git a/trunk/drivers/gpio/gpio-pl061.c b/trunk/drivers/gpio/gpio-pl061.c index d7008dfdd6f0..b820869ca93c 100644 --- a/trunk/drivers/gpio/gpio-pl061.c +++ b/trunk/drivers/gpio/gpio-pl061.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -23,7 +22,6 @@ #include #include #include -#include #include #include @@ -53,7 +51,8 @@ struct pl061_gpio { spinlock_t lock; void __iomem *base; - struct irq_domain *domain; + int irq_base; + struct irq_chip_generic *irq_gc; struct gpio_chip gc; #ifdef CONFIG_PM @@ -61,24 +60,6 @@ struct pl061_gpio { #endif }; -static int pl061_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - /* - * Map back to global GPIO space and request muxing, the direction - * parameter does not matter for this controller. - */ - int gpio = chip->base + offset; - - return pinctrl_request_gpio(gpio); -} - -static void pl061_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - int gpio = chip->base + offset; - - pinctrl_free_gpio(gpio); -} - static int pl061_direction_input(struct gpio_chip *gc, unsigned offset) { struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); @@ -141,20 +122,24 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) { struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); - return irq_create_mapping(chip->domain, offset); + if (chip->irq_base <= 0) + return -EINVAL; + + return chip->irq_base + offset; } static int pl061_irq_type(struct irq_data *d, unsigned trigger) { - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); - int offset = irqd_to_hwirq(d); + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct pl061_gpio *chip = gc->private; + int offset = d->irq - chip->irq_base; unsigned long flags; u8 gpiois, gpioibe, gpioiev; if (offset < 0 || offset >= PL061_GPIO_NR) return -EINVAL; - spin_lock_irqsave(&chip->lock, flags); + raw_spin_lock_irqsave(&gc->lock, flags); gpioiev = readb(chip->base + GPIOIEV); @@ -183,7 +168,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) writeb(gpioiev, chip->base + GPIOIEV); - spin_unlock_irqrestore(&chip->lock, flags); + raw_spin_unlock_irqrestore(&gc->lock, flags); return 0; } @@ -207,61 +192,31 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) chained_irq_exit(irqchip, desc); } -static void pl061_irq_mask(struct irq_data *d) -{ - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); - u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); - u8 gpioie; - - spin_lock(&chip->lock); - gpioie = readb(chip->base + GPIOIE) & ~mask; - writeb(gpioie, chip->base + GPIOIE); - spin_unlock(&chip->lock); -} - -static void pl061_irq_unmask(struct irq_data *d) +static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base) { - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); - u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); - u8 gpioie; - - spin_lock(&chip->lock); - gpioie = readb(chip->base + GPIOIE) | mask; - writeb(gpioie, chip->base + GPIOIE); - spin_unlock(&chip->lock); -} - -static struct irq_chip pl061_irqchip = { - .name = "pl061 gpio", - .irq_mask = pl061_irq_mask, - .irq_unmask = pl061_irq_unmask, - .irq_set_type = pl061_irq_type, -}; + struct irq_chip_type *ct; -static int pl061_irq_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) -{ - struct pl061_gpio *chip = d->host_data; + chip->irq_gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base, + chip->base, handle_simple_irq); + chip->irq_gc->private = chip; - irq_set_chip_and_handler_name(virq, &pl061_irqchip, handle_simple_irq, - "pl061"); - irq_set_chip_data(virq, chip); - irq_set_irq_type(virq, IRQ_TYPE_NONE); + ct = chip->irq_gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_clr_bit; + ct->chip.irq_unmask = irq_gc_mask_set_bit; + ct->chip.irq_set_type = pl061_irq_type; + ct->chip.irq_set_wake = irq_gc_set_wake; + ct->regs.mask = GPIOIE; - return 0; + irq_setup_generic_chip(chip->irq_gc, IRQ_MSK(PL061_GPIO_NR), + IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); } -static const struct irq_domain_ops pl061_domain_ops = { - .map = pl061_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - static int pl061_probe(struct amba_device *adev, const struct amba_id *id) { struct device *dev = &adev->dev; struct pl061_platform_data *pdata = dev->platform_data; struct pl061_gpio *chip; - int ret, irq, i, irq_base; + int ret, irq, i; chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) @@ -269,32 +224,24 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) if (pdata) { chip->gc.base = pdata->gpio_base; - irq_base = pdata->irq_base; - if (irq_base <= 0) - return -ENODEV; - } else { + chip->irq_base = pdata->irq_base; + } else if (adev->dev.of_node) { chip->gc.base = -1; - irq_base = 0; - } + chip->irq_base = 0; + } else + return -ENODEV; if (!devm_request_mem_region(dev, adev->res.start, - resource_size(&adev->res), "pl061")) + resource_size(&adev->res), "pl061")) return -EBUSY; chip->base = devm_ioremap(dev, adev->res.start, - resource_size(&adev->res)); - if (!chip->base) + resource_size(&adev->res)); + if (chip->base == NULL) return -ENOMEM; - chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR, - irq_base, &pl061_domain_ops, chip); - if (!chip->domain) - return -ENODEV; - spin_lock_init(&chip->lock); - chip->gc.request = pl061_gpio_request; - chip->gc.free = pl061_gpio_free; chip->gc.direction_input = pl061_direction_input; chip->gc.direction_output = pl061_direction_output; chip->gc.get = pl061_get_value; @@ -312,6 +259,12 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) /* * irq_chip support */ + + if (chip->irq_base <= 0) + return 0; + + pl061_init_gc(chip, chip->irq_base); + writeb(0, chip->base + GPIOIE); /* disable irqs */ irq = adev->irq[0]; if (irq < 0) diff --git a/trunk/drivers/gpio/gpio-pxa.c b/trunk/drivers/gpio/gpio-pxa.c index 8325f580c0f1..9cc108d2b770 100644 --- a/trunk/drivers/gpio/gpio-pxa.c +++ b/trunk/drivers/gpio/gpio-pxa.c @@ -642,12 +642,7 @@ static struct platform_driver pxa_gpio_driver = { .of_match_table = of_match_ptr(pxa_gpio_dt_ids), }, }; - -static int __init pxa_gpio_init(void) -{ - return platform_driver_register(&pxa_gpio_driver); -} -postcore_initcall(pxa_gpio_init); +module_platform_driver(pxa_gpio_driver); #ifdef CONFIG_PM static int pxa_gpio_suspend(void) diff --git a/trunk/drivers/gpio/gpio-stmpe.c b/trunk/drivers/gpio/gpio-stmpe.c index 3ce5bc38ac31..770476a9da87 100644 --- a/trunk/drivers/gpio/gpio-stmpe.c +++ b/trunk/drivers/gpio/gpio-stmpe.c @@ -307,15 +307,11 @@ static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = { .xlate = irq_domain_xlate_twocell, }; -static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio, - struct device_node *np) +static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) { - int base = 0; + int base = stmpe_gpio->irq_base; - if (!np) - base = stmpe_gpio->irq_base; - - stmpe_gpio->domain = irq_domain_add_simple(np, + stmpe_gpio->domain = irq_domain_add_simple(NULL, stmpe_gpio->chip.ngpio, base, &stmpe_gpio_irq_simple_ops, stmpe_gpio); if (!stmpe_gpio->domain) { @@ -350,9 +346,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev) stmpe_gpio->chip = template_chip; stmpe_gpio->chip.ngpio = stmpe->num_gpios; stmpe_gpio->chip.dev = &pdev->dev; -#ifdef CONFIG_OF - stmpe_gpio->chip.of_node = np; -#endif stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1; if (pdata) @@ -373,7 +366,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) goto out_free; if (irq >= 0) { - ret = stmpe_gpio_irq_init(stmpe_gpio, np); + ret = stmpe_gpio_irq_init(stmpe_gpio); if (ret) goto out_disable; diff --git a/trunk/drivers/gpio/gpiolib-of.c b/trunk/drivers/gpio/gpiolib-of.c index 465f4ca57e80..a71a54a3e3f7 100644 --- a/trunk/drivers/gpio/gpiolib-of.c +++ b/trunk/drivers/gpio/gpiolib-of.c @@ -193,7 +193,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (!np) return; - for (;; index++) { + do { ret = of_parse_phandle_with_args(np, "gpio-ranges", "#gpio-range-cells", index, &pinspec); if (ret) @@ -203,15 +203,27 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (!pctldev) break; + /* + * This assumes that the n GPIO pins are consecutive in the + * GPIO number space, and that the pins are also consecutive + * in their local number space. Currently it is not possible + * to add different ranges for one and the same GPIO chip, + * as the code assumes that we have one consecutive range + * on both, mapping 1-to-1. + * + * TODO: make the OF bindings handle multiple sparse ranges + * on the same GPIO chip. + */ ret = gpiochip_add_pin_range(chip, pinctrl_dev_get_devname(pctldev), + 0, /* offset in gpiochip */ pinspec.args[0], - pinspec.args[1], - pinspec.args[2]); + pinspec.args[1]); if (ret) break; - } + + } while (index++); } #else diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c index c2534d62911c..fff9786cdc64 100644 --- a/trunk/drivers/gpio/gpiolib.c +++ b/trunk/drivers/gpio/gpiolib.c @@ -88,14 +88,13 @@ static int gpiod_request(struct gpio_desc *desc, const char *label); static void gpiod_free(struct gpio_desc *desc); static int gpiod_direction_input(struct gpio_desc *desc); static int gpiod_direction_output(struct gpio_desc *desc, int value); -static int gpiod_get_direction(const struct gpio_desc *desc); static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce); -static int gpiod_get_value_cansleep(const struct gpio_desc *desc); +static int gpiod_get_value_cansleep(struct gpio_desc *desc); static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value); -static int gpiod_get_value(const struct gpio_desc *desc); +static int gpiod_get_value(struct gpio_desc *desc); static void gpiod_set_value(struct gpio_desc *desc, int value); -static int gpiod_cansleep(const struct gpio_desc *desc); -static int gpiod_to_irq(const struct gpio_desc *desc); +static int gpiod_cansleep(struct gpio_desc *desc); +static int gpiod_to_irq(struct gpio_desc *desc); static int gpiod_export(struct gpio_desc *desc, bool direction_may_change); static int gpiod_export_link(struct device *dev, const char *name, struct gpio_desc *desc); @@ -172,12 +171,12 @@ static int gpio_ensure_requested(struct gpio_desc *desc) return 0; } -static struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc) +/* caller holds gpio_lock *OR* gpio is marked as requested */ +static struct gpio_chip *gpiod_to_chip(struct gpio_desc *desc) { - return desc ? desc->chip : NULL; + return desc->chip; } -/* caller holds gpio_lock *OR* gpio is marked as requested */ struct gpio_chip *gpio_to_chip(unsigned gpio) { return gpiod_to_chip(gpio_to_desc(gpio)); @@ -208,7 +207,7 @@ static int gpiochip_find_base(int ngpio) } /* caller ensures gpio is valid and requested, chip->get_direction may sleep */ -static int gpiod_get_direction(const struct gpio_desc *desc) +static int gpiod_get_direction(struct gpio_desc *desc) { struct gpio_chip *chip; unsigned offset; @@ -224,13 +223,11 @@ static int gpiod_get_direction(const struct gpio_desc *desc) if (status > 0) { /* GPIOF_DIR_IN, or other positive */ status = 1; - /* FLAG_IS_OUT is just a cache of the result of get_direction(), - * so it does not affect constness per se */ - clear_bit(FLAG_IS_OUT, &((struct gpio_desc *)desc)->flags); + clear_bit(FLAG_IS_OUT, &desc->flags); } if (status == 0) { /* GPIOF_DIR_OUT */ - set_bit(FLAG_IS_OUT, &((struct gpio_desc *)desc)->flags); + set_bit(FLAG_IS_OUT, &desc->flags); } return status; } @@ -266,7 +263,7 @@ static DEFINE_MUTEX(sysfs_lock); static ssize_t gpio_direction_show(struct device *dev, struct device_attribute *attr, char *buf) { - const struct gpio_desc *desc = dev_get_drvdata(dev); + struct gpio_desc *desc = dev_get_drvdata(dev); ssize_t status; mutex_lock(&sysfs_lock); @@ -657,11 +654,6 @@ static ssize_t export_store(struct class *class, goto done; desc = gpio_to_desc(gpio); - /* reject invalid GPIOs */ - if (!desc) { - pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); - return -EINVAL; - } /* No extra locking here; FLAG_SYSFS just signifies that the * request and export were done by on behalf of userspace, so @@ -698,14 +690,12 @@ static ssize_t unexport_store(struct class *class, if (status < 0) goto done; + status = -EINVAL; + desc = gpio_to_desc(gpio); /* reject bogus commands (gpio_unexport ignores them) */ - if (!desc) { - pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); - return -EINVAL; - } - - status = -EINVAL; + if (!desc) + goto done; /* No extra locking here; FLAG_SYSFS just signifies that the * request and export were done by on behalf of userspace, so @@ -856,10 +846,8 @@ static int gpiod_export_link(struct device *dev, const char *name, { int status = -EINVAL; - if (!desc) { - pr_warn("%s: invalid GPIO\n", __func__); - return -EINVAL; - } + if (!desc) + goto done; mutex_lock(&sysfs_lock); @@ -877,6 +865,7 @@ static int gpiod_export_link(struct device *dev, const char *name, mutex_unlock(&sysfs_lock); +done: if (status) pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), status); @@ -907,10 +896,8 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value) struct device *dev = NULL; int status = -EINVAL; - if (!desc) { - pr_warn("%s: invalid GPIO\n", __func__); - return -EINVAL; - } + if (!desc) + goto done; mutex_lock(&sysfs_lock); @@ -927,6 +914,7 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value) unlock: mutex_unlock(&sysfs_lock); +done: if (status) pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), status); @@ -952,8 +940,8 @@ static void gpiod_unexport(struct gpio_desc *desc) struct device *dev = NULL; if (!desc) { - pr_warn("%s: invalid GPIO\n", __func__); - return; + status = -EINVAL; + goto done; } mutex_lock(&sysfs_lock); @@ -974,7 +962,7 @@ static void gpiod_unexport(struct gpio_desc *desc) device_unregister(dev); put_device(dev); } - +done: if (status) pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), status); @@ -1396,13 +1384,12 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) int status = -EPROBE_DEFER; unsigned long flags; - if (!desc) { - pr_warn("%s: invalid GPIO\n", __func__); - return -EINVAL; - } - spin_lock_irqsave(&gpio_lock, flags); + if (!desc) { + status = -EINVAL; + goto done; + } chip = desc->chip; if (chip == NULL) goto done; @@ -1445,7 +1432,8 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) done: if (status) pr_debug("_gpio_request: gpio-%d (%s) status %d\n", - desc_to_gpio(desc), label ? : "?", status); + desc ? desc_to_gpio(desc) : -1, + label ? : "?", status); spin_unlock_irqrestore(&gpio_lock, flags); return status; } @@ -1628,13 +1616,10 @@ static int gpiod_direction_input(struct gpio_desc *desc) int status = -EINVAL; int offset; - if (!desc) { - pr_warn("%s: invalid GPIO\n", __func__); - return -EINVAL; - } - spin_lock_irqsave(&gpio_lock, flags); + if (!desc) + goto fail; chip = desc->chip; if (!chip || !chip->get || !chip->direction_input) goto fail; @@ -1670,9 +1655,13 @@ static int gpiod_direction_input(struct gpio_desc *desc) return status; fail: spin_unlock_irqrestore(&gpio_lock, flags); - if (status) - pr_debug("%s: gpio-%d status %d\n", __func__, - desc_to_gpio(desc), status); + if (status) { + int gpio = -1; + if (desc) + gpio = desc_to_gpio(desc); + pr_debug("%s: gpio-%d status %d\n", + __func__, gpio, status); + } return status; } @@ -1689,11 +1678,6 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) int status = -EINVAL; int offset; - if (!desc) { - pr_warn("%s: invalid GPIO\n", __func__); - return -EINVAL; - } - /* Open drain pin should not be driven to 1 */ if (value && test_bit(FLAG_OPEN_DRAIN, &desc->flags)) return gpiod_direction_input(desc); @@ -1704,6 +1688,8 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) spin_lock_irqsave(&gpio_lock, flags); + if (!desc) + goto fail; chip = desc->chip; if (!chip || !chip->set || !chip->direction_output) goto fail; @@ -1739,9 +1725,13 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) return status; fail: spin_unlock_irqrestore(&gpio_lock, flags); - if (status) - pr_debug("%s: gpio-%d status %d\n", __func__, - desc_to_gpio(desc), status); + if (status) { + int gpio = -1; + if (desc) + gpio = desc_to_gpio(desc); + pr_debug("%s: gpio-%d status %d\n", + __func__, gpio, status); + } return status; } @@ -1763,13 +1753,10 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) int status = -EINVAL; int offset; - if (!desc) { - pr_warn("%s: invalid GPIO\n", __func__); - return -EINVAL; - } - spin_lock_irqsave(&gpio_lock, flags); + if (!desc) + goto fail; chip = desc->chip; if (!chip || !chip->set || !chip->set_debounce) goto fail; @@ -1789,9 +1776,13 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) fail: spin_unlock_irqrestore(&gpio_lock, flags); - if (status) - pr_debug("%s: gpio-%d status %d\n", __func__, - desc_to_gpio(desc), status); + if (status) { + int gpio = -1; + if (desc) + gpio = desc_to_gpio(desc); + pr_debug("%s: gpio-%d status %d\n", + __func__, gpio, status); + } return status; } @@ -1833,14 +1824,12 @@ EXPORT_SYMBOL_GPL(gpio_set_debounce); * It returns the zero or nonzero value provided by the associated * gpio_chip.get() method; or zero if no such method is provided. */ -static int gpiod_get_value(const struct gpio_desc *desc) +static int gpiod_get_value(struct gpio_desc *desc) { struct gpio_chip *chip; int value; int offset; - if (!desc) - return 0; chip = desc->chip; offset = gpio_chip_hwgpio(desc); /* Should be using gpio_get_value_cansleep() */ @@ -1923,8 +1912,6 @@ static void gpiod_set_value(struct gpio_desc *desc, int value) { struct gpio_chip *chip; - if (!desc) - return; chip = desc->chip; /* Should be using gpio_set_value_cansleep() */ WARN_ON(chip->can_sleep); @@ -1951,10 +1938,8 @@ EXPORT_SYMBOL_GPL(__gpio_set_value); * This is used directly or indirectly to implement gpio_cansleep(). It * returns nonzero if access reading or writing the GPIO value can sleep. */ -static int gpiod_cansleep(const struct gpio_desc *desc) +static int gpiod_cansleep(struct gpio_desc *desc) { - if (!desc) - return 0; /* only call this on GPIOs that are valid! */ return desc->chip->can_sleep; } @@ -1974,13 +1959,11 @@ EXPORT_SYMBOL_GPL(__gpio_cansleep); * It returns the number of the IRQ signaled by this (input) GPIO, * or a negative errno. */ -static int gpiod_to_irq(const struct gpio_desc *desc) +static int gpiod_to_irq(struct gpio_desc *desc) { struct gpio_chip *chip; int offset; - if (!desc) - return -EINVAL; chip = desc->chip; offset = gpio_chip_hwgpio(desc); return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO; @@ -1997,15 +1980,13 @@ EXPORT_SYMBOL_GPL(__gpio_to_irq); * Common examples include ones connected to I2C or SPI chips. */ -static int gpiod_get_value_cansleep(const struct gpio_desc *desc) +static int gpiod_get_value_cansleep(struct gpio_desc *desc) { struct gpio_chip *chip; int value; int offset; might_sleep_if(extra_checks); - if (!desc) - return 0; chip = desc->chip; offset = gpio_chip_hwgpio(desc); value = chip->get ? chip->get(chip, offset) : 0; @@ -2024,8 +2005,6 @@ static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value) struct gpio_chip *chip; might_sleep_if(extra_checks); - if (!desc) - return; chip = desc->chip; trace_gpio_value(desc_to_gpio(desc), 0, value); if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index dd64a06dc5b4..792c3e3795ca 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -2326,6 +2326,7 @@ int drm_mode_addfb(struct drm_device *dev, fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); if (IS_ERR(fb)) { DRM_DEBUG_KMS("could not create framebuffer\n"); + drm_modeset_unlock_all(dev); return PTR_ERR(fb); } @@ -2505,6 +2506,7 @@ int drm_mode_addfb2(struct drm_device *dev, fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); if (IS_ERR(fb)) { DRM_DEBUG_KMS("could not create framebuffer\n"); + drm_modeset_unlock_all(dev); return PTR_ERR(fb); } diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index e2acfdbf7d3c..c194f4e680ad 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -1634,7 +1634,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo; unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo; - unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4; + unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf); /* ignore tiny modes */ @@ -1715,7 +1715,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, } mode->type = DRM_MODE_TYPE_DRIVER; - mode->vrefresh = drm_mode_vrefresh(mode); drm_mode_set_name(mode); return mode; diff --git a/trunk/drivers/gpu/drm/drm_fb_helper.c b/trunk/drivers/gpu/drm/drm_fb_helper.c index 892ff9f95975..59d6b9bf204b 100644 --- a/trunk/drivers/gpu/drm/drm_fb_helper.c +++ b/trunk/drivers/gpu/drm/drm_fb_helper.c @@ -1544,10 +1544,10 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) if (!fb_helper->fb) return 0; - mutex_lock(&fb_helper->dev->mode_config.mutex); + drm_modeset_lock_all(dev); if (!drm_fb_helper_is_bound(fb_helper)) { fb_helper->delayed_hotplug = true; - mutex_unlock(&fb_helper->dev->mode_config.mutex); + drm_modeset_unlock_all(dev); return 0; } DRM_DEBUG_KMS("\n"); @@ -1558,11 +1558,9 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, max_height); - mutex_unlock(&fb_helper->dev->mode_config.mutex); - - drm_modeset_lock_all(dev); drm_setup_crtcs(fb_helper); drm_modeset_unlock_all(dev); + drm_fb_helper_set_par(fb_helper->fbdev); return 0; diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 429e07d0b0f1..13fdcd10a605 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -123,7 +123,6 @@ int drm_open(struct inode *inode, struct file *filp) int retcode = 0; int need_setup = 0; struct address_space *old_mapping; - struct address_space *old_imapping; minor = idr_find(&drm_minors_idr, minor_id); if (!minor) @@ -138,7 +137,6 @@ int drm_open(struct inode *inode, struct file *filp) if (!dev->open_count++) need_setup = 1; mutex_lock(&dev->struct_mutex); - old_imapping = inode->i_mapping; old_mapping = dev->dev_mapping; if (old_mapping == NULL) dev->dev_mapping = &inode->i_data; @@ -161,8 +159,8 @@ int drm_open(struct inode *inode, struct file *filp) err_undo: mutex_lock(&dev->struct_mutex); - filp->f_mapping = old_imapping; - inode->i_mapping = old_imapping; + filp->f_mapping = old_mapping; + inode->i_mapping = old_mapping; iput(container_of(dev->dev_mapping, struct inode, i_data)); dev->dev_mapping = old_mapping; mutex_unlock(&dev->struct_mutex); diff --git a/trunk/drivers/gpu/drm/drm_modes.c b/trunk/drivers/gpu/drm/drm_modes.c index f83f0719922e..04fa6f1808d1 100644 --- a/trunk/drivers/gpu/drm/drm_modes.c +++ b/trunk/drivers/gpu/drm/drm_modes.c @@ -506,7 +506,7 @@ drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, } EXPORT_SYMBOL(drm_gtf_mode); -#ifdef CONFIG_VIDEOMODE_HELPERS +#if IS_ENABLED(CONFIG_VIDEOMODE) int drm_display_mode_from_videomode(const struct videomode *vm, struct drm_display_mode *dmode) { @@ -523,25 +523,26 @@ int drm_display_mode_from_videomode(const struct videomode *vm, dmode->clock = vm->pixelclock / 1000; dmode->flags = 0; - if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH) + if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH) dmode->flags |= DRM_MODE_FLAG_PHSYNC; - else if (vm->flags & DISPLAY_FLAGS_HSYNC_LOW) + else if (vm->dmt_flags & VESA_DMT_HSYNC_LOW) dmode->flags |= DRM_MODE_FLAG_NHSYNC; - if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH) + if (vm->dmt_flags & VESA_DMT_VSYNC_HIGH) dmode->flags |= DRM_MODE_FLAG_PVSYNC; - else if (vm->flags & DISPLAY_FLAGS_VSYNC_LOW) + else if (vm->dmt_flags & VESA_DMT_VSYNC_LOW) dmode->flags |= DRM_MODE_FLAG_NVSYNC; - if (vm->flags & DISPLAY_FLAGS_INTERLACED) + if (vm->data_flags & DISPLAY_FLAGS_INTERLACED) dmode->flags |= DRM_MODE_FLAG_INTERLACE; - if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN) + if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN) dmode->flags |= DRM_MODE_FLAG_DBLSCAN; drm_mode_set_name(dmode); return 0; } EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode); +#endif -#ifdef CONFIG_OF +#if IS_ENABLED(CONFIG_OF_VIDEOMODE) /** * of_get_drm_display_mode - get a drm_display_mode from devicetree * @np: device_node with the timing specification @@ -571,8 +572,7 @@ int of_get_drm_display_mode(struct device_node *np, return 0; } EXPORT_SYMBOL_GPL(of_get_drm_display_mode); -#endif /* CONFIG_OF */ -#endif /* CONFIG_VIDEOMODE_HELPERS */ +#endif /** * drm_mode_set_name - set the name on a mode diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 98cc14725ba9..36493ce71f9a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -38,12 +38,11 @@ /* position control register for hardware window 0, 2 ~ 4.*/ #define VIDOSD_A(win) (VIDOSD_BASE + 0x00 + (win) * 16) #define VIDOSD_B(win) (VIDOSD_BASE + 0x04 + (win) * 16) -/* - * size control register for hardware windows 0 and alpha control register - * for hardware windows 1 ~ 4 - */ -#define VIDOSD_C(win) (VIDOSD_BASE + 0x08 + (win) * 16) -/* size control register for hardware windows 1 ~ 2. */ +/* size control register for hardware window 0. */ +#define VIDOSD_C_SIZE_W0 (VIDOSD_BASE + 0x08) +/* alpha control register for hardware window 1 ~ 4. */ +#define VIDOSD_C(win) (VIDOSD_BASE + 0x18 + (win) * 16) +/* size control register for hardware window 1 ~ 4. */ #define VIDOSD_D(win) (VIDOSD_BASE + 0x0C + (win) * 16) #define VIDWx_BUF_START(win, buf) (VIDW_BUF_START(buf) + (win) * 8) @@ -51,9 +50,9 @@ #define VIDWx_BUF_SIZE(win, buf) (VIDW_BUF_SIZE(buf) + (win) * 4) /* color key control register for hardware window 1 ~ 4. */ -#define WKEYCON0_BASE(x) ((WKEYCON0 + 0x140) + ((x - 1) * 8)) +#define WKEYCON0_BASE(x) ((WKEYCON0 + 0x140) + (x * 8)) /* color key value register for hardware window 1 ~ 4. */ -#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + ((x - 1) * 8)) +#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + (x * 8)) /* FIMD has totally five hardware windows. */ #define WINDOWS_NR 5 @@ -110,9 +109,9 @@ struct fimd_context { #ifdef CONFIG_OF static const struct of_device_id fimd_driver_dt_match[] = { - { .compatible = "samsung,exynos4210-fimd", + { .compatible = "samsung,exynos4-fimd", .data = &exynos4_fimd_driver_data }, - { .compatible = "samsung,exynos5250-fimd", + { .compatible = "samsung,exynos5-fimd", .data = &exynos5_fimd_driver_data }, {}, }; @@ -582,7 +581,7 @@ static void fimd_win_commit(struct device *dev, int zpos) if (win != 3 && win != 4) { u32 offset = VIDOSD_D(win); if (win == 0) - offset = VIDOSD_C(win); + offset = VIDOSD_C_SIZE_W0; val = win_data->ovl_width * win_data->ovl_height; writel(val, ctx->regs + offset); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 47a493c8a71f..3b0da0378acf 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -48,14 +48,8 @@ /* registers for base address */ #define G2D_SRC_BASE_ADDR 0x0304 -#define G2D_SRC_COLOR_MODE 0x030C -#define G2D_SRC_LEFT_TOP 0x0310 -#define G2D_SRC_RIGHT_BOTTOM 0x0314 #define G2D_SRC_PLANE2_BASE_ADDR 0x0318 #define G2D_DST_BASE_ADDR 0x0404 -#define G2D_DST_COLOR_MODE 0x040C -#define G2D_DST_LEFT_TOP 0x0410 -#define G2D_DST_RIGHT_BOTTOM 0x0414 #define G2D_DST_PLANE2_BASE_ADDR 0x0418 #define G2D_PAT_BASE_ADDR 0x0500 #define G2D_MSK_BASE_ADDR 0x0520 @@ -88,7 +82,7 @@ #define G2D_DMA_LIST_DONE_COUNT_OFFSET 17 /* G2D_DMA_HOLD_CMD */ -#define G2D_USER_HOLD (1 << 2) +#define G2D_USET_HOLD (1 << 2) #define G2D_LIST_HOLD (1 << 1) #define G2D_BITBLT_HOLD (1 << 0) @@ -97,27 +91,13 @@ #define G2D_START_NHOLT (1 << 1) #define G2D_START_BITBLT (1 << 0) -/* buffer color format */ -#define G2D_FMT_XRGB8888 0 -#define G2D_FMT_ARGB8888 1 -#define G2D_FMT_RGB565 2 -#define G2D_FMT_XRGB1555 3 -#define G2D_FMT_ARGB1555 4 -#define G2D_FMT_XRGB4444 5 -#define G2D_FMT_ARGB4444 6 -#define G2D_FMT_PACKED_RGB888 7 -#define G2D_FMT_A8 11 -#define G2D_FMT_L8 12 - -/* buffer valid length */ -#define G2D_LEN_MIN 1 -#define G2D_LEN_MAX 8000 - #define G2D_CMDLIST_SIZE (PAGE_SIZE / 4) #define G2D_CMDLIST_NUM 64 #define G2D_CMDLIST_POOL_SIZE (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM) #define G2D_CMDLIST_DATA_NUM (G2D_CMDLIST_SIZE / sizeof(u32) - 2) +#define MAX_BUF_ADDR_NR 6 + /* maximum buffer pool size of userptr is 64MB as default */ #define MAX_POOL (64 * 1024 * 1024) @@ -126,17 +106,6 @@ enum { BUF_TYPE_USERPTR, }; -enum g2d_reg_type { - REG_TYPE_NONE = -1, - REG_TYPE_SRC, - REG_TYPE_SRC_PLANE2, - REG_TYPE_DST, - REG_TYPE_DST_PLANE2, - REG_TYPE_PAT, - REG_TYPE_MSK, - MAX_REG_TYPE_NR -}; - /* cmdlist data structure */ struct g2d_cmdlist { u32 head; @@ -144,42 +113,6 @@ struct g2d_cmdlist { u32 last; /* last data offset */ }; -/* - * A structure of buffer description - * - * @format: color format - * @left_x: the x coordinates of left top corner - * @top_y: the y coordinates of left top corner - * @right_x: the x coordinates of right bottom corner - * @bottom_y: the y coordinates of right bottom corner - * - */ -struct g2d_buf_desc { - unsigned int format; - unsigned int left_x; - unsigned int top_y; - unsigned int right_x; - unsigned int bottom_y; -}; - -/* - * A structure of buffer information - * - * @map_nr: manages the number of mapped buffers - * @reg_types: stores regitster type in the order of requested command - * @handles: stores buffer handle in its reg_type position - * @types: stores buffer type in its reg_type position - * @descs: stores buffer description in its reg_type position - * - */ -struct g2d_buf_info { - unsigned int map_nr; - enum g2d_reg_type reg_types[MAX_REG_TYPE_NR]; - unsigned long handles[MAX_REG_TYPE_NR]; - unsigned int types[MAX_REG_TYPE_NR]; - struct g2d_buf_desc descs[MAX_REG_TYPE_NR]; -}; - struct drm_exynos_pending_g2d_event { struct drm_pending_event base; struct drm_exynos_g2d_event event; @@ -198,11 +131,14 @@ struct g2d_cmdlist_userptr { bool in_pool; bool out_of_list; }; + struct g2d_cmdlist_node { struct list_head list; struct g2d_cmdlist *cmdlist; + unsigned int map_nr; + unsigned long handles[MAX_BUF_ADDR_NR]; + unsigned int obj_type[MAX_BUF_ADDR_NR]; dma_addr_t dma_addr; - struct g2d_buf_info buf_info; struct drm_exynos_pending_g2d_event *event; }; @@ -252,7 +188,6 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) struct exynos_drm_subdrv *subdrv = &g2d->subdrv; int nr; int ret; - struct g2d_buf_info *buf_info; init_dma_attrs(&g2d->cmdlist_dma_attrs); dma_set_attr(DMA_ATTR_WRITE_COMBINE, &g2d->cmdlist_dma_attrs); @@ -274,17 +209,11 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) } for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) { - unsigned int i; - node[nr].cmdlist = g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE; node[nr].dma_addr = g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE; - buf_info = &node[nr].buf_info; - for (i = 0; i < MAX_REG_TYPE_NR; i++) - buf_info->reg_types[i] = REG_TYPE_NONE; - list_add_tail(&node[nr].list, &g2d->free_cmdlist); } @@ -521,7 +450,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, DMA_BIDIRECTIONAL); if (ret < 0) { DRM_ERROR("failed to map sgt with dma region.\n"); - goto err_sg_free_table; + goto err_free_sgt; } g2d_userptr->dma_addr = sgt->sgl[0].dma_address; @@ -538,10 +467,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, return &g2d_userptr->dma_addr; -err_sg_free_table: - sg_free_table(sgt); - err_free_sgt: + sg_free_table(sgt); kfree(sgt); sgt = NULL; @@ -579,172 +506,36 @@ static void g2d_userptr_free_all(struct drm_device *drm_dev, g2d->current_pool = 0; } -static enum g2d_reg_type g2d_get_reg_type(int reg_offset) -{ - enum g2d_reg_type reg_type; - - switch (reg_offset) { - case G2D_SRC_BASE_ADDR: - case G2D_SRC_COLOR_MODE: - case G2D_SRC_LEFT_TOP: - case G2D_SRC_RIGHT_BOTTOM: - reg_type = REG_TYPE_SRC; - break; - case G2D_SRC_PLANE2_BASE_ADDR: - reg_type = REG_TYPE_SRC_PLANE2; - break; - case G2D_DST_BASE_ADDR: - case G2D_DST_COLOR_MODE: - case G2D_DST_LEFT_TOP: - case G2D_DST_RIGHT_BOTTOM: - reg_type = REG_TYPE_DST; - break; - case G2D_DST_PLANE2_BASE_ADDR: - reg_type = REG_TYPE_DST_PLANE2; - break; - case G2D_PAT_BASE_ADDR: - reg_type = REG_TYPE_PAT; - break; - case G2D_MSK_BASE_ADDR: - reg_type = REG_TYPE_MSK; - break; - default: - reg_type = REG_TYPE_NONE; - DRM_ERROR("Unknown register offset![%d]\n", reg_offset); - break; - }; - - return reg_type; -} - -static unsigned long g2d_get_buf_bpp(unsigned int format) -{ - unsigned long bpp; - - switch (format) { - case G2D_FMT_XRGB8888: - case G2D_FMT_ARGB8888: - bpp = 4; - break; - case G2D_FMT_RGB565: - case G2D_FMT_XRGB1555: - case G2D_FMT_ARGB1555: - case G2D_FMT_XRGB4444: - case G2D_FMT_ARGB4444: - bpp = 2; - break; - case G2D_FMT_PACKED_RGB888: - bpp = 3; - break; - default: - bpp = 1; - break; - } - - return bpp; -} - -static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc, - enum g2d_reg_type reg_type, - unsigned long size) -{ - unsigned int width, height; - unsigned long area; - - /* - * check source and destination buffers only. - * so the others are always valid. - */ - if (reg_type != REG_TYPE_SRC && reg_type != REG_TYPE_DST) - return true; - - width = buf_desc->right_x - buf_desc->left_x; - if (width < G2D_LEN_MIN || width > G2D_LEN_MAX) { - DRM_ERROR("width[%u] is out of range!\n", width); - return false; - } - - height = buf_desc->bottom_y - buf_desc->top_y; - if (height < G2D_LEN_MIN || height > G2D_LEN_MAX) { - DRM_ERROR("height[%u] is out of range!\n", height); - return false; - } - - area = (unsigned long)width * (unsigned long)height * - g2d_get_buf_bpp(buf_desc->format); - if (area > size) { - DRM_ERROR("area[%lu] is out of range[%lu]!\n", area, size); - return false; - } - - return true; -} - static int g2d_map_cmdlist_gem(struct g2d_data *g2d, struct g2d_cmdlist_node *node, struct drm_device *drm_dev, struct drm_file *file) { struct g2d_cmdlist *cmdlist = node->cmdlist; - struct g2d_buf_info *buf_info = &node->buf_info; int offset; - int ret; int i; - for (i = 0; i < buf_info->map_nr; i++) { - struct g2d_buf_desc *buf_desc; - enum g2d_reg_type reg_type; - int reg_pos; + for (i = 0; i < node->map_nr; i++) { unsigned long handle; dma_addr_t *addr; - reg_pos = cmdlist->last - 2 * (i + 1); - - offset = cmdlist->data[reg_pos]; - handle = cmdlist->data[reg_pos + 1]; - - reg_type = g2d_get_reg_type(offset); - if (reg_type == REG_TYPE_NONE) { - ret = -EFAULT; - goto err; - } - - buf_desc = &buf_info->descs[reg_type]; - - if (buf_info->types[reg_type] == BUF_TYPE_GEM) { - unsigned long size; - - size = exynos_drm_gem_get_size(drm_dev, handle, file); - if (!size) { - ret = -EFAULT; - goto err; - } - - if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type, - size)) { - ret = -EFAULT; - goto err; - } + offset = cmdlist->last - (i * 2 + 1); + handle = cmdlist->data[offset]; + if (node->obj_type[i] == BUF_TYPE_GEM) { addr = exynos_drm_gem_get_dma_addr(drm_dev, handle, file); if (IS_ERR(addr)) { - ret = -EFAULT; - goto err; + node->map_nr = i; + return -EFAULT; } } else { struct drm_exynos_g2d_userptr g2d_userptr; if (copy_from_user(&g2d_userptr, (void __user *)handle, sizeof(struct drm_exynos_g2d_userptr))) { - ret = -EFAULT; - goto err; - } - - if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type, - g2d_userptr.size)) { - ret = -EFAULT; - goto err; + node->map_nr = i; + return -EFAULT; } addr = g2d_userptr_get_dma_addr(drm_dev, @@ -753,21 +544,16 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, file, &handle); if (IS_ERR(addr)) { - ret = -EFAULT; - goto err; + node->map_nr = i; + return -EFAULT; } } - cmdlist->data[reg_pos + 1] = *addr; - buf_info->reg_types[i] = reg_type; - buf_info->handles[reg_type] = handle; + cmdlist->data[offset] = *addr; + node->handles[i] = handle; } return 0; - -err: - buf_info->map_nr = i; - return ret; } static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, @@ -775,33 +561,22 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, struct drm_file *filp) { struct exynos_drm_subdrv *subdrv = &g2d->subdrv; - struct g2d_buf_info *buf_info = &node->buf_info; int i; - for (i = 0; i < buf_info->map_nr; i++) { - struct g2d_buf_desc *buf_desc; - enum g2d_reg_type reg_type; - unsigned long handle; - - reg_type = buf_info->reg_types[i]; - - buf_desc = &buf_info->descs[reg_type]; - handle = buf_info->handles[reg_type]; + for (i = 0; i < node->map_nr; i++) { + unsigned long handle = node->handles[i]; - if (buf_info->types[reg_type] == BUF_TYPE_GEM) + if (node->obj_type[i] == BUF_TYPE_GEM) exynos_drm_gem_put_dma_addr(subdrv->drm_dev, handle, filp); else g2d_userptr_put_dma_addr(subdrv->drm_dev, handle, false); - buf_info->reg_types[i] = REG_TYPE_NONE; - buf_info->handles[reg_type] = 0; - buf_info->types[reg_type] = 0; - memset(buf_desc, 0x00, sizeof(*buf_desc)); + node->handles[i] = 0; } - buf_info->map_nr = 0; + node->map_nr = 0; } static void g2d_dma_start(struct g2d_data *g2d, @@ -814,6 +589,10 @@ static void g2d_dma_start(struct g2d_data *g2d, pm_runtime_get_sync(g2d->dev); clk_enable(g2d->gate_clk); + /* interrupt enable */ + writel_relaxed(G2D_INTEN_ACF | G2D_INTEN_UCF | G2D_INTEN_GCF, + g2d->regs + G2D_INTEN); + writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); } @@ -864,6 +643,7 @@ static void g2d_runqueue_worker(struct work_struct *work) struct g2d_data *g2d = container_of(work, struct g2d_data, runqueue_work); + mutex_lock(&g2d->runqueue_mutex); clk_disable(g2d->gate_clk); pm_runtime_put_sync(g2d->dev); @@ -944,14 +724,20 @@ static int g2d_check_reg_offset(struct device *dev, int i; for (i = 0; i < nr; i++) { - struct g2d_buf_info *buf_info = &node->buf_info; - struct g2d_buf_desc *buf_desc; - enum g2d_reg_type reg_type; - unsigned long value; - index = cmdlist->last - 2 * (i + 1); + if (for_addr) { + /* check userptr buffer type. */ + reg_offset = (cmdlist->data[index] & + ~0x7fffffff) >> 31; + if (reg_offset) { + node->obj_type[i] = BUF_TYPE_USERPTR; + cmdlist->data[index] &= ~G2D_BUF_USERPTR; + } + } + reg_offset = cmdlist->data[index] & ~0xfffff000; + if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END) goto err; if (reg_offset % 4) @@ -967,60 +753,8 @@ static int g2d_check_reg_offset(struct device *dev, if (!for_addr) goto err; - reg_type = g2d_get_reg_type(reg_offset); - if (reg_type == REG_TYPE_NONE) - goto err; - - /* check userptr buffer type. */ - if ((cmdlist->data[index] & ~0x7fffffff) >> 31) { - buf_info->types[reg_type] = BUF_TYPE_USERPTR; - cmdlist->data[index] &= ~G2D_BUF_USERPTR; - } else - buf_info->types[reg_type] = BUF_TYPE_GEM; - break; - case G2D_SRC_COLOR_MODE: - case G2D_DST_COLOR_MODE: - if (for_addr) - goto err; - - reg_type = g2d_get_reg_type(reg_offset); - if (reg_type == REG_TYPE_NONE) - goto err; - - buf_desc = &buf_info->descs[reg_type]; - value = cmdlist->data[index + 1]; - - buf_desc->format = value & 0xf; - break; - case G2D_SRC_LEFT_TOP: - case G2D_DST_LEFT_TOP: - if (for_addr) - goto err; - - reg_type = g2d_get_reg_type(reg_offset); - if (reg_type == REG_TYPE_NONE) - goto err; - - buf_desc = &buf_info->descs[reg_type]; - value = cmdlist->data[index + 1]; - - buf_desc->left_x = value & 0x1fff; - buf_desc->top_y = (value & 0x1fff0000) >> 16; - break; - case G2D_SRC_RIGHT_BOTTOM: - case G2D_DST_RIGHT_BOTTOM: - if (for_addr) - goto err; - - reg_type = g2d_get_reg_type(reg_offset); - if (reg_type == REG_TYPE_NONE) - goto err; - - buf_desc = &buf_info->descs[reg_type]; - value = cmdlist->data[index + 1]; - - buf_desc->right_x = value & 0x1fff; - buf_desc->bottom_y = (value & 0x1fff0000) >> 16; + if (node->obj_type[i] != BUF_TYPE_USERPTR) + node->obj_type[i] = BUF_TYPE_GEM; break; default: if (for_addr) @@ -1126,23 +860,9 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR; cmdlist->data[cmdlist->last++] = 0; - /* - * 'LIST_HOLD' command should be set to the DMA_HOLD_CMD_REG - * and GCF bit should be set to INTEN register if user wants - * G2D interrupt event once current command list execution is - * finished. - * Otherwise only ACF bit should be set to INTEN register so - * that one interrupt is occured after all command lists - * have been completed. - */ if (node->event) { - cmdlist->data[cmdlist->last++] = G2D_INTEN; - cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF | G2D_INTEN_GCF; cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD; cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD; - } else { - cmdlist->data[cmdlist->last++] = G2D_INTEN; - cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF; } /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */ @@ -1167,7 +887,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, if (ret < 0) goto err_free_event; - node->buf_info.map_nr = req->cmd_buf_nr; + node->map_nr = req->cmd_buf_nr; if (req->cmd_buf_nr) { struct drm_exynos_g2d_cmd *cmd_buf; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c index 0e6fe000578c..67e17ce112b6 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -164,27 +164,6 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj) exynos_gem_obj = NULL; } -unsigned long exynos_drm_gem_get_size(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - - obj = drm_gem_object_lookup(dev, file_priv, gem_handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return 0; - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - drm_gem_object_unreference_unlocked(obj); - - return exynos_gem_obj->buffer->size; -} - - struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, unsigned long size) { diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h index 468766bee450..35ebac47dc2b 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -130,11 +130,6 @@ int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data, int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -/* get buffer size to gem handle. */ -unsigned long exynos_drm_gem_get_size(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv); - /* initialize gem object. */ int exynos_drm_gem_init_object(struct drm_gem_object *obj); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 9504b0cd825a..13ccbd4bcfaa 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -117,12 +117,13 @@ static struct edid *vidi_get_edid(struct device *dev, } edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; - edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); + edid = kzalloc(edid_len, GFP_KERNEL); if (!edid) { DRM_DEBUG_KMS("failed to allocate edid\n"); return ERR_PTR(-ENOMEM); } + memcpy(edid, ctx->raw_edid, edid_len); return edid; } @@ -562,11 +563,12 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, return -EINVAL; } edid_len = (1 + raw_edid->extensions) * EDID_LENGTH; - ctx->raw_edid = kmemdup(raw_edid, edid_len, GFP_KERNEL); + ctx->raw_edid = kzalloc(edid_len, GFP_KERNEL); if (!ctx->raw_edid) { DRM_DEBUG_KMS("failed to allocate raw_edid.\n"); return -ENOMEM; } + memcpy(ctx->raw_edid, raw_edid, edid_len); } else { /* * with connection = 0, free raw_edid diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index 2f4f72f07047..e919aba29b3d 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -818,7 +818,7 @@ static void mixer_win_disable(void *ctx, int win) mixer_ctx->win_data[win].enabled = false; } -static int mixer_check_timing(void *ctx, struct fb_videomode *timing) +int mixer_check_timing(void *ctx, struct fb_videomode *timing) { struct mixer_context *mixer_ctx = ctx; u32 w, h; diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index 7299ea45dd03..aae31489c893 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -103,7 +103,7 @@ static const char *cache_level_str(int type) static void describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) { - seq_printf(m, "%pK: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s", + seq_printf(m, "%p: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s", &obj->base, get_pin_flag(obj), get_tiling_flag(obj), diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index e9b57893db2b..c5b8c81b9440 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -125,11 +125,6 @@ MODULE_PARM_DESC(preliminary_hw_support, "Enable Haswell and ValleyView Support. " "(default: false)"); -int i915_disable_power_well __read_mostly = 0; -module_param_named(disable_power_well, i915_disable_power_well, int, 0600); -MODULE_PARM_DESC(disable_power_well, - "Disable the power well when possible (default: false)"); - static struct drm_driver driver; extern int intel_agp_enabled; @@ -384,15 +379,15 @@ static const struct pci_device_id pciidlist[] = { /* aka */ 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(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */ - INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */ + 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(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */ - INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */ + 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(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */ - INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */ + INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ + INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ + INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */ INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), @@ -500,7 +495,6 @@ static int i915_drm_freeze(struct drm_device *dev) intel_modeset_disable(dev); drm_irq_uninstall(dev); - dev_priv->enable_hotplug_processing = false; } i915_save_state(dev); @@ -574,20 +568,10 @@ static int __i915_drm_thaw(struct drm_device *dev) error = i915_gem_init_hw(dev); mutex_unlock(&dev->struct_mutex); - /* We need working interrupts for modeset enabling ... */ - drm_irq_install(dev); - intel_modeset_init_hw(dev); intel_modeset_setup_hw_state(dev, false); - - /* - * ... but also need to make sure that hotplug processing - * doesn't cause havoc. Like in the driver load code we don't - * bother with the tiny race here where we might loose hotplug - * notifications. - * */ + drm_irq_install(dev); intel_hpd_init(dev); - dev_priv->enable_hotplug_processing = true; } intel_opregion_init(dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 01769e2a9953..e95337c97459 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -1398,7 +1398,6 @@ extern int i915_enable_fbc __read_mostly; extern bool i915_enable_hangcheck __read_mostly; extern int i915_enable_ppgtt __read_mostly; extern unsigned int i915_preliminary_hw_support __read_mostly; -extern int i915_disable_power_well __read_mostly; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 9a48e1a2d417..2f2daebd0eef 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -57,7 +57,7 @@ eb_create(struct drm_i915_gem_execbuffer2 *args) if (eb == NULL) { int size = args->buffer_count; int count = PAGE_SIZE / sizeof(struct hlist_head) / 2; - BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head)); + BUILD_BUG_ON(!is_power_of_2(PAGE_SIZE / sizeof(struct hlist_head))); while (count > 2*size) count >>= 1; eb = kzalloc(count*sizeof(struct hlist_head) + @@ -732,8 +732,6 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, int count) { int i; - int relocs_total = 0; - int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry); for (i = 0; i < count; i++) { char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; @@ -742,13 +740,10 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, if (exec[i].flags & __EXEC_OBJECT_UNKNOWN_FLAGS) return -EINVAL; - /* First check for malicious input causing overflow in - * the worst case where we need to allocate the entire - * relocation tree as a single array. - */ - if (exec[i].relocation_count > relocs_max - relocs_total) + /* First check for malicious input causing overflow */ + if (exec[i].relocation_count > + INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) return -EINVAL; - relocs_total += exec[i].relocation_count; length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry); diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 3c7bb0410b51..2cd97d1cc920 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -701,7 +701,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier; + u32 de_iir, gt_iir, de_ier, pm_iir; irqreturn_t ret = IRQ_NONE; int i; @@ -711,15 +711,6 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) de_ier = I915_READ(DEIER); I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); - /* Disable south interrupts. We'll only write to SDEIIR once, so further - * interrupts will will be stored on its back queue, and then we'll be - * able to process them after we restore SDEIER (as soon as we restore - * it, we'll get an interrupt if SDEIIR still has something to process - * due to its back queue). */ - sde_ier = I915_READ(SDEIER); - I915_WRITE(SDEIER, 0); - POSTING_READ(SDEIER); - gt_iir = I915_READ(GTIIR); if (gt_iir) { snb_gt_irq_handler(dev, dev_priv, gt_iir); @@ -768,8 +759,6 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) I915_WRITE(DEIER, de_ier); POSTING_READ(DEIER); - I915_WRITE(SDEIER, sde_ier); - POSTING_READ(SDEIER); return ret; } @@ -789,7 +778,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = IRQ_NONE; - u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier; + u32 de_iir, gt_iir, de_ier, pm_iir; atomic_inc(&dev_priv->irq_received); @@ -798,15 +787,6 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); POSTING_READ(DEIER); - /* Disable south interrupts. We'll only write to SDEIIR once, so further - * interrupts will will be stored on its back queue, and then we'll be - * able to process them after we restore SDEIER (as soon as we restore - * it, we'll get an interrupt if SDEIIR still has something to process - * due to its back queue). */ - sde_ier = I915_READ(SDEIER); - I915_WRITE(SDEIER, 0); - POSTING_READ(SDEIER); - de_iir = I915_READ(DEIIR); gt_iir = I915_READ(GTIIR); pm_iir = I915_READ(GEN6_PMIIR); @@ -869,8 +849,6 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) done: I915_WRITE(DEIER, de_ier); POSTING_READ(DEIER); - I915_WRITE(SDEIER, sde_ier); - POSTING_READ(SDEIER); return ret; } diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 848992f67d56..527b664d3434 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -1613,9 +1613,9 @@ #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) #define ADPA_USE_VGA_HVPOLARITY (1<<15) #define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1<<10) +#define ADPA_VSYNC_CNTL_DISABLE (1<<11) #define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1<<11) +#define ADPA_HSYNC_CNTL_DISABLE (1<<10) #define ADPA_HSYNC_CNTL_ENABLE 0 #define ADPA_VSYNC_ACTIVE_HIGH (1<<4) #define ADPA_VSYNC_ACTIVE_LOW 0 diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 1ce45a0a2d3e..969d08c72d10 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -45,9 +45,6 @@ struct intel_crt { struct intel_encoder base; - /* DPMS state is stored in the connector, which we need in the - * encoder's enable/disable callbacks */ - struct intel_connector *connector; bool force_hotplug_required; u32 adpa_reg; }; @@ -84,6 +81,29 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, return true; } +static void intel_disable_crt(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crt *crt = intel_encoder_to_crt(encoder); + u32 temp; + + temp = I915_READ(crt->adpa_reg); + temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); + temp &= ~ADPA_DAC_ENABLE; + I915_WRITE(crt->adpa_reg, temp); +} + +static void intel_enable_crt(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crt *crt = intel_encoder_to_crt(encoder); + u32 temp; + + temp = I915_READ(crt->adpa_reg); + temp |= ADPA_DAC_ENABLE; + I915_WRITE(crt->adpa_reg, temp); +} + /* Note: The caller is required to filter out dpms modes not supported by the * platform. */ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) @@ -115,19 +135,6 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) I915_WRITE(crt->adpa_reg, temp); } -static void intel_disable_crt(struct intel_encoder *encoder) -{ - intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void intel_enable_crt(struct intel_encoder *encoder) -{ - struct intel_crt *crt = intel_encoder_to_crt(encoder); - - intel_crt_set_dpms(encoder, crt->connector->base.dpms); -} - - static void intel_crt_dpms(struct drm_connector *connector, int mode) { struct drm_device *dev = connector->dev; @@ -739,7 +746,6 @@ void intel_crt_init(struct drm_device *dev) } connector = &intel_connector->base; - crt->connector = intel_connector; drm_connector_init(dev, &intel_connector->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); diff --git a/trunk/drivers/gpu/drm/i915/intel_ddi.c b/trunk/drivers/gpu/drm/i915/intel_ddi.c index 8d0bac3c35d7..d64af5aa4a1c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ddi.c +++ b/trunk/drivers/gpu/drm/i915/intel_ddi.c @@ -1391,8 +1391,8 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) struct intel_dp *intel_dp = &intel_dig_port->dp; struct drm_i915_private *dev_priv = encoder->dev->dev_private; enum port port = intel_dig_port->port; + bool wait; uint32_t val; - bool wait = false; if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { val = I915_READ(DDI_BUF_CTL(port)); diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index b20d50192fcc..a05ac2c91ba2 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -3604,30 +3604,6 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) */ } -/** - * i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware - * cursor plane briefly if not already running after enabling the display - * plane. - * This workaround avoids occasional blank screens when self refresh is - * enabled. - */ -static void -g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe) -{ - u32 cntl = I915_READ(CURCNTR(pipe)); - - if ((cntl & CURSOR_MODE) == 0) { - u32 fw_bcl_self = I915_READ(FW_BLC_SELF); - - I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN); - I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX); - intel_wait_for_vblank(dev_priv->dev, pipe); - I915_WRITE(CURCNTR(pipe), cntl); - I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); - I915_WRITE(FW_BLC_SELF, fw_bcl_self); - } -} - static void i9xx_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -3653,8 +3629,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_enable_pipe(dev_priv, pipe, false); intel_enable_plane(dev_priv, plane, pipe); - if (IS_G4X(dev)) - g4x_fixup_plane(dev_priv, pipe); intel_crtc_load_lut(crtc); intel_update_fbc(dev); @@ -5771,11 +5745,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, num_connectors++; } - if (is_cpu_edp) - intel_crtc->cpu_transcoder = TRANSCODER_EDP; - else - intel_crtc->cpu_transcoder = pipe; - /* We are not sure yet this won't happen. */ WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); @@ -5842,6 +5811,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int pipe = intel_crtc->pipe; int ret; + if (IS_HASWELL(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) + intel_crtc->cpu_transcoder = TRANSCODER_EDP; + else + intel_crtc->cpu_transcoder = pipe; + drm_vblank_pre_modeset(dev, pipe); ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode, @@ -7282,8 +7256,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *old_fb = crtc->fb; - struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; + struct intel_framebuffer *intel_fb; + struct drm_i915_gem_object *obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; unsigned long flags; @@ -7308,7 +7282,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->event = event; work->crtc = crtc; - work->old_fb_obj = to_intel_framebuffer(old_fb)->obj; + intel_fb = to_intel_framebuffer(crtc->fb); + work->old_fb_obj = intel_fb->obj; INIT_WORK(&work->work, intel_unpin_work_fn); ret = drm_vblank_get(dev, intel_crtc->pipe); @@ -7328,6 +7303,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_crtc->unpin_work = work; spin_unlock_irqrestore(&dev->event_lock, flags); + intel_fb = to_intel_framebuffer(fb); + obj = intel_fb->obj; + if (atomic_read(&intel_crtc->unpin_work_count) >= 2) flush_workqueue(dev_priv->wq); @@ -7362,7 +7340,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, cleanup_pending: atomic_dec(&intel_crtc->unpin_work_count); - crtc->fb = old_fb; drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 8fc93f90a7cd..f61cb7998c72 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -353,8 +353,7 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0) if (has_aux_irq) - done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, - msecs_to_jiffies(10)); + done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, 10); else done = wait_for_atomic(C, 10) == 0; if (!done) @@ -820,7 +819,6 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct intel_link_m_n m_n; int pipe = intel_crtc->pipe; enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; - int target_clock; /* * Find the lane count in the intel_encoder private @@ -836,22 +834,13 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, } } - target_clock = mode->clock; - for_each_encoder_on_crtc(dev, crtc, intel_encoder) { - if (intel_encoder->type == INTEL_OUTPUT_EDP) { - target_clock = intel_edp_target_clock(intel_encoder, - mode); - break; - } - } - /* * Compute the GMCH and Link ratios. The '3' here is * the number of bytes_per_pixel post-LUT, which we always * set up for 8-bits of R/G/B, or 3 bytes total. */ intel_link_compute_m_n(intel_crtc->bpp, lane_count, - target_clock, adjusted_mode->clock, &m_n); + mode->clock, adjusted_mode->clock, &m_n); if (IS_HASWELL(dev)) { I915_WRITE(PIPE_DATA_M1(cpu_transcoder), @@ -1940,7 +1929,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) for (i = 0; i < intel_dp->lane_count; i++) if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) break; - if (i == intel_dp->lane_count) { + if (i == intel_dp->lane_count && voltage_tries == 5) { ++loop_tries; if (loop_tries == 5) { DRM_DEBUG_KMS("too many full retries, give up\n"); @@ -2559,15 +2548,12 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) { struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); struct intel_dp *intel_dp = &intel_dig_port->dp; - struct drm_device *dev = intel_dp_to_dev(intel_dp); i2c_del_adapter(&intel_dp->adapter); drm_encoder_cleanup(encoder); if (is_edp(intel_dp)) { cancel_delayed_work_sync(&intel_dp->panel_vdd_work); - mutex_lock(&dev->mode_config.mutex); ironlake_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev->mode_config.mutex); } kfree(intel_dig_port); } diff --git a/trunk/drivers/gpu/drm/i915/intel_i2c.c b/trunk/drivers/gpu/drm/i915/intel_i2c.c index ef4744e1bf0b..acf8aec9ada7 100644 --- a/trunk/drivers/gpu/drm/i915/intel_i2c.c +++ b/trunk/drivers/gpu/drm/i915/intel_i2c.c @@ -203,13 +203,7 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin) algo->data = bus; } -/* - * gmbus on gen4 seems to be able to generate legacy interrupts even when in MSI - * mode. This results in spurious interrupt warnings if the legacy irq no. is - * shared with another device. The kernel then disables that interrupt source - * and so prevents the other device from working properly. - */ -#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) +#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 4) static int gmbus_wait_hw_status(struct drm_i915_private *dev_priv, u32 gmbus2_status, @@ -220,9 +214,6 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv, u32 gmbus2 = 0; DEFINE_WAIT(wait); - if (!HAS_GMBUS_IRQ(dev_priv->dev)) - gmbus4_irq_en = 0; - /* Important: The hw handles only the first bit, so set only one! Since * we also need to check for NAKs besides the hw ready/idle signal, we * need to wake up periodically and check that ourselves. */ diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index bee8cb6108a7..a3730e0289e5 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -321,6 +321,9 @@ void intel_panel_enable_backlight(struct drm_device *dev, if (dev_priv->backlight_level == 0) dev_priv->backlight_level = intel_panel_get_max_backlight(dev); + dev_priv->backlight_enabled = true; + intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); + if (INTEL_INFO(dev)->gen >= 4) { uint32_t reg, tmp; @@ -356,12 +359,12 @@ void intel_panel_enable_backlight(struct drm_device *dev, } set_level: - /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. - * BLC_PWM_CPU_CTL may be cleared to zero automatically when these - * registers are set. + /* Check the current backlight level and try to set again if it's zero. + * On some machines, BLC_PWM_CPU_CTL is cleared to zero automatically + * when BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1 are written. */ - dev_priv->backlight_enabled = true; - intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); + if (!intel_panel_get_backlight(dev)) + intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); } static void intel_panel_init_backlight(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index adca00783e61..61fee7fcdc2c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -2574,7 +2574,7 @@ static void gen6_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_SLEEP, 0); I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); I915_WRITE(GEN6_RC6_THRESHOLD, 50000); - I915_WRITE(GEN6_RC6p_THRESHOLD, 150000); + I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ /* Check if we are enabling RC6 */ @@ -4079,9 +4079,6 @@ void intel_set_power_well(struct drm_device *dev, bool enable) if (!IS_HASWELL(dev)) return; - if (!i915_disable_power_well && !enable) - return; - tmp = I915_READ(HSW_PWR_WELL_DRIVER); is_enabled = tmp & HSW_PWR_WELL_STATE; enable_requested = tmp & HSW_PWR_WELL_ENABLE; diff --git a/trunk/drivers/gpu/drm/mgag200/mgag200_drv.h b/trunk/drivers/gpu/drm/mgag200/mgag200_drv.h index 4d932c46725d..5ea5033eae0a 100644 --- a/trunk/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/trunk/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -112,6 +112,7 @@ struct mga_framebuffer { struct mga_fbdev { struct drm_fb_helper helper; struct mga_framebuffer mfb; + struct list_head fbdev_list; void *sysram; int size; struct ttm_bo_kmap_obj mapping; diff --git a/trunk/drivers/gpu/drm/mgag200/mgag200_i2c.c b/trunk/drivers/gpu/drm/mgag200/mgag200_i2c.c index d3dcf54e6233..5a88ec51b513 100644 --- a/trunk/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/trunk/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -92,7 +92,6 @@ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev) int ret; int data, clock; - WREG_DAC(MGA1064_GEN_IO_CTL2, 1); WREG_DAC(MGA1064_GEN_IO_DATA, 0xff); WREG_DAC(MGA1064_GEN_IO_CTL, 0); diff --git a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c index 78d8e919509f..d3d99a28ddef 100644 --- a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -382,19 +382,19 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) m = n = p = 0; vcomax = 800000; vcomin = 400000; - pllreffreq = 33333; + pllreffreq = 3333; delta = 0xffffffff; permitteddelta = clock * 5 / 1000; - for (testp = 16; testp > 0; testp >>= 1) { + for (testp = 16; testp > 0; testp--) { if (clock * testp > vcomax) continue; if (clock * testp < vcomin) continue; for (testm = 1; testm < 33; testm++) { - for (testn = 17; testn < 257; testn++) { + for (testn = 1; testn < 257; testn++) { computed = (pllreffreq * testn) / (testm * testp); if (computed > clock) @@ -404,11 +404,11 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) if (tmpdelta < delta) { delta = tmpdelta; n = testn - 1; - m = (testm - 1); + m = (testm - 1) | ((n >> 1) & 0x80); p = testp - 1; } if ((clock * testp) >= 600000) - p |= 0x80; + p |= 80; } } } @@ -751,6 +751,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, int i; unsigned char misc = 0; unsigned char ext_vga[6]; + unsigned char ext_vga_index24; + unsigned char dac_index90 = 0; u8 bppshift; static unsigned char dacvalue[] = { @@ -801,6 +803,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, option2 = 0x0000b000; break; case G200_ER: + dac_index90 = 0; break; } @@ -849,8 +852,10 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_DAC(i, dacvalue[i]); } - if (mdev->type == G200_ER) - WREG_DAC(0x90, 0); + if (mdev->type == G200_ER) { + WREG_DAC(0x90, dac_index90); + } + if (option) pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option); @@ -947,6 +952,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, if (mdev->type == G200_WB) ext_vga[1] |= 0x88; + ext_vga_index24 = 0x05; + /* Set pixel clocks */ misc = 0x2d; WREG8(MGA_MISC_OUT, misc); @@ -958,7 +965,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, } if (mdev->type == G200_ER) - WREG_ECRT(0x24, 0x5); + WREG_ECRT(24, ext_vga_index24); if (mdev->type == G200_EV) { WREG_ECRT(6, 0); @@ -1399,14 +1406,6 @@ static int mga_vga_get_modes(struct drm_connector *connector) static int mga_vga_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct drm_device *dev = connector->dev; - struct mga_device *mdev = (struct mga_device*)dev->dev_private; - struct mga_fbdev *mfbdev = mdev->mfbdev; - struct drm_fb_helper *fb_helper = &mfbdev->helper; - struct drm_fb_helper_connector *fb_helper_conn = NULL; - int bpp = 32; - int i = 0; - /* FIXME: Add bandwidth and g200se limitations */ if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 || @@ -1416,25 +1415,6 @@ static int mga_vga_mode_valid(struct drm_connector *connector, return MODE_BAD; } - /* Validate the mode input by the user */ - for (i = 0; i < fb_helper->connector_count; i++) { - if (fb_helper->connector_info[i]->connector == connector) { - /* Found the helper for this connector */ - fb_helper_conn = fb_helper->connector_info[i]; - if (fb_helper_conn->cmdline_mode.specified) { - if (fb_helper_conn->cmdline_mode.bpp_specified) { - bpp = fb_helper_conn->cmdline_mode.bpp; - } - } - } - } - - if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) { - if (fb_helper_conn) - fb_helper_conn->cmdline_mode.specified = false; - return MODE_BAD; - } - return MODE_OK; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/object.c b/trunk/drivers/gpu/drm/nouveau/core/core/object.c index 3b2e7b6304d3..0daab62ea14c 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/object.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/object.c @@ -278,6 +278,7 @@ nouveau_object_del(struct nouveau_object *client, u32 _parent, u32 _handle) struct nouveau_object *parent = NULL; struct nouveau_object *namedb = NULL; struct nouveau_handle *handle = NULL; + int ret = -EINVAL; parent = nouveau_handle_ref(client, _parent); if (!parent) @@ -294,7 +295,7 @@ nouveau_object_del(struct nouveau_object *client, u32 _parent, u32 _handle) } nouveau_object_ref(NULL, &parent); - return handle ? 0 : -EINVAL; + return ret; } int diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 02e369f80449..5fa13267bd9f 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -544,13 +544,13 @@ nv50_disp_curs_ofuncs = { static void nv50_disp_base_vblank_enable(struct nouveau_event *event, int head) { - nv_mask(event->priv, 0x61002c, (4 << head), (4 << head)); + nv_mask(event->priv, 0x61002c, (1 << head), (1 << head)); } static void nv50_disp_base_vblank_disable(struct nouveau_event *event, int head) { - nv_mask(event->priv, 0x61002c, (4 << head), 0); + nv_mask(event->priv, 0x61002c, (1 << head), (0 << head)); } static int diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c index 4857f913efdd..61cec0f6ff1c 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c @@ -350,7 +350,7 @@ nve0_graph_init_gpc_0(struct nvc0_graph_priv *priv) nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918); } - nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918); + nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918); nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800)); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/therm.h index 0b20fc0d19c1..6b17b614629f 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/therm.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/therm.h @@ -4,7 +4,7 @@ #include #include -enum nouveau_therm_fan_mode { +enum nouveau_therm_mode { NOUVEAU_THERM_CTRL_NONE = 0, NOUVEAU_THERM_CTRL_MANUAL = 1, NOUVEAU_THERM_CTRL_AUTO = 2, diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index 0e2c1a4f1659..e816f06637a7 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c @@ -248,22 +248,6 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios) } } -static void -nouveau_bios_shadow_platform(struct nouveau_bios *bios) -{ - struct pci_dev *pdev = nv_device(bios)->pdev; - size_t size; - - void __iomem *rom = pci_platform_rom(pdev, &size); - if (rom && size) { - bios->data = kmalloc(size, GFP_KERNEL); - if (bios->data) { - memcpy_fromio(bios->data, rom, size); - bios->size = size; - } - } -} - static int nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) { @@ -304,7 +288,6 @@ nouveau_bios_shadow(struct nouveau_bios *bios) { "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL }, { "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL }, { "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL }, - { "PLATFORM", nouveau_bios_shadow_platform, true, 0, 0, NULL }, {} }; struct methods *mthd, *best; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index 9c41b58d57e2..2cc1e6a5eb6a 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -869,7 +869,7 @@ init_idx_addr_latched(struct nvbios_init *init) init->offset += 2; init_wr32(init, dreg, idata); - init_mask(init, creg, ~mask, data | iaddr); + init_mask(init, creg, ~mask, data | idata); } } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index 2e98e8a3f1aa..a114a0ed7e98 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -142,7 +142,6 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, /* drop port's i2c subdev refcount, i2c handles this itself */ if (ret == 0) { list_add_tail(&port->head, &i2c->ports); - atomic_dec(&parent->refcount); atomic_dec(&engine->refcount); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index a00a5a76e2d6..f794dc89a3b2 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -134,7 +134,7 @@ nouveau_therm_alarm(struct nouveau_alarm *alarm) } int -nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode) +nouveau_therm_mode(struct nouveau_therm *therm, int mode) { struct nouveau_therm_priv *priv = (void *)therm; struct nouveau_device *device = nv_device(therm); @@ -149,15 +149,10 @@ nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode) (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0)) return -EINVAL; - /* do not allow automatic fan management if the thermal sensor is - * not available */ - if (priv->mode == 2 && therm->temp_get(therm) < 0) - return -EINVAL; - if (priv->mode == mode) return 0; - nv_info(therm, "fan management: %s\n", name[mode]); + nv_info(therm, "Thermal management: %s\n", name[mode]); nouveau_therm_update(therm, mode); return 0; } @@ -218,7 +213,7 @@ nouveau_therm_attr_set(struct nouveau_therm *therm, priv->fan->bios.max_duty = value; return 0; case NOUVEAU_THERM_ATTR_FAN_MODE: - return nouveau_therm_fan_mode(therm, value); + return nouveau_therm_mode(therm, value); case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST: priv->bios_sensor.thrs_fan_boost.temp = value; priv->sensor.program_alarms(therm); @@ -268,7 +263,7 @@ _nouveau_therm_init(struct nouveau_object *object) return ret; if (priv->suspend >= 0) - nouveau_therm_fan_mode(therm, priv->mode); + nouveau_therm_mode(therm, priv->mode); priv->sensor.program_alarms(therm); return 0; } @@ -318,12 +313,11 @@ nouveau_therm_create_(struct nouveau_object *parent, int nouveau_therm_preinit(struct nouveau_therm *therm) { - nouveau_therm_sensor_ctor(therm); nouveau_therm_ic_ctor(therm); + nouveau_therm_sensor_ctor(therm); nouveau_therm_fan_ctor(therm); - nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE); - nouveau_therm_sensor_preinit(therm); + nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_NONE); return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c index 8b3adec5fbb1..e24090bac195 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c @@ -32,7 +32,6 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c, struct i2c_board_info *info) { struct nouveau_therm_priv *priv = (void *)nouveau_therm(i2c); - struct nvbios_therm_sensor *sensor = &priv->bios_sensor; struct i2c_client *client; request_module("%s%s", I2C_MODULE_PREFIX, info->type); @@ -47,9 +46,8 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c, } nv_info(priv, - "Found an %s at address 0x%x (controlled by lm_sensors, " - "temp offset %+i C)\n", - info->type, info->addr, sensor->offset_constant); + "Found an %s at address 0x%x (controlled by lm_sensors)\n", + info->type, info->addr); priv->ic = client; return true; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index a70d1b7e397b..0f5363edb964 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c @@ -29,83 +29,54 @@ struct nv40_therm_priv { struct nouveau_therm_priv base; }; -enum nv40_sensor_style { INVALID_STYLE = -1, OLD_STYLE = 0, NEW_STYLE = 1 }; - -static enum nv40_sensor_style -nv40_sensor_style(struct nouveau_therm *therm) -{ - struct nouveau_device *device = nv_device(therm); - - switch (device->chipset) { - case 0x43: - case 0x44: - case 0x4a: - case 0x47: - return OLD_STYLE; - - case 0x46: - case 0x49: - case 0x4b: - case 0x4e: - case 0x4c: - case 0x67: - case 0x68: - case 0x63: - return NEW_STYLE; - default: - return INVALID_STYLE; - } -} - static int nv40_sensor_setup(struct nouveau_therm *therm) { - enum nv40_sensor_style style = nv40_sensor_style(therm); + struct nouveau_device *device = nv_device(therm); /* enable ADC readout and disable the ALARM threshold */ - if (style == NEW_STYLE) { + if (device->chipset >= 0x46) { nv_mask(therm, 0x15b8, 0x80000000, 0); nv_wr32(therm, 0x15b0, 0x80003fff); - mdelay(20); /* wait for the temperature to stabilize */ + mdelay(10); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0x3fff; - } else if (style == OLD_STYLE) { + } else { nv_wr32(therm, 0x15b0, 0xff); - mdelay(20); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0xff; - } else - return -ENODEV; + } } static int nv40_temp_get(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; + struct nouveau_device *device = nv_device(therm); struct nvbios_therm_sensor *sensor = &priv->bios_sensor; - enum nv40_sensor_style style = nv40_sensor_style(therm); int core_temp; - if (style == NEW_STYLE) { + if (device->chipset >= 0x46) { nv_wr32(therm, 0x15b0, 0x80003fff); core_temp = nv_rd32(therm, 0x15b4) & 0x3fff; - } else if (style == OLD_STYLE) { + } else { nv_wr32(therm, 0x15b0, 0xff); core_temp = nv_rd32(therm, 0x15b4) & 0xff; - } else - return -ENODEV; + } - /* if the slope or the offset is unset, do no use the sensor */ - if (!sensor->slope_div || !sensor->slope_mult || - !sensor->offset_num || !sensor->offset_den) - return -ENODEV; + /* Setup the sensor if the temperature is 0 */ + if (core_temp == 0) + core_temp = nv40_sensor_setup(therm); + + if (sensor->slope_div == 0) + sensor->slope_div = 1; + if (sensor->offset_den == 0) + sensor->offset_den = 1; + if (sensor->slope_mult < 1) + sensor->slope_mult = 1; core_temp = core_temp * sensor->slope_mult / sensor->slope_div; core_temp = core_temp + sensor->offset_num / sensor->offset_den; core_temp = core_temp + sensor->offset_constant - 8; - /* reserve negative temperatures for errors */ - if (core_temp < 0) - core_temp = 0; - return core_temp; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index 438d9824b774..06b98706b3fc 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -102,7 +102,7 @@ struct nouveau_therm_priv { struct i2c_client *ic; }; -int nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode); +int nouveau_therm_mode(struct nouveau_therm *therm, int mode); int nouveau_therm_attr_get(struct nouveau_therm *therm, enum nouveau_therm_attr_type type); int nouveau_therm_attr_set(struct nouveau_therm *therm, @@ -122,7 +122,6 @@ int nouveau_therm_fan_sense(struct nouveau_therm *therm); int nouveau_therm_preinit(struct nouveau_therm *); -void nouveau_therm_sensor_preinit(struct nouveau_therm *); void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm, enum nouveau_therm_thrs thrs, enum nouveau_therm_thrs_state st); diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index 470f6a47b656..b37624af8297 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -34,6 +34,10 @@ nouveau_therm_temp_set_defaults(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; + priv->bios_sensor.slope_mult = 1; + priv->bios_sensor.slope_div = 1; + priv->bios_sensor.offset_num = 0; + priv->bios_sensor.offset_den = 1; priv->bios_sensor.offset_constant = 0; priv->bios_sensor.thrs_fan_boost.temp = 90; @@ -56,6 +60,11 @@ nouveau_therm_temp_safety_checks(struct nouveau_therm *therm) struct nouveau_therm_priv *priv = (void *)therm; struct nvbios_therm_sensor *s = &priv->bios_sensor; + if (!priv->bios_sensor.slope_div) + priv->bios_sensor.slope_div = 1; + if (!priv->bios_sensor.offset_den) + priv->bios_sensor.offset_den = 1; + /* enforce a minimum hysteresis on thresholds */ s->thrs_fan_boost.hysteresis = max_t(u8, s->thrs_fan_boost.hysteresis, 2); s->thrs_down_clock.hysteresis = max_t(u8, s->thrs_down_clock.hysteresis, 2); @@ -97,16 +106,16 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm, const char *thresolds[] = { "fanboost", "downclock", "critical", "shutdown" }; - int temperature = therm->temp_get(therm); + uint8_t temperature = therm->temp_get(therm); if (thrs < 0 || thrs > 3) return; if (dir == NOUVEAU_THERM_THRS_FALLING) - nv_info(therm, "temperature (%i C) went below the '%s' threshold\n", + nv_info(therm, "temperature (%u C) went below the '%s' threshold\n", temperature, thresolds[thrs]); else - nv_info(therm, "temperature (%i C) hit the '%s' threshold\n", + nv_info(therm, "temperature (%u C) hit the '%s' threshold\n", temperature, thresolds[thrs]); active = (dir == NOUVEAU_THERM_THRS_RISING); @@ -114,7 +123,7 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm, case NOUVEAU_THERM_THRS_FANBOOST: if (active) { nouveau_therm_fan_set(therm, true, 100); - nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO); + nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_AUTO); } break; case NOUVEAU_THERM_THRS_DOWNCLOCK: @@ -193,7 +202,7 @@ alarm_timer_callback(struct nouveau_alarm *alarm) NOUVEAU_THERM_THRS_SHUTDOWN); /* schedule the next poll in one second */ - if (therm->temp_get(therm) >= 0 && list_empty(&alarm->head)) + if (list_empty(&alarm->head)) ptimer->alarm(ptimer, 1000 * 1000 * 1000, alarm); spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); @@ -216,17 +225,6 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm) alarm_timer_callback(&priv->sensor.therm_poll_alarm); } -void -nouveau_therm_sensor_preinit(struct nouveau_therm *therm) -{ - const char *sensor_avail = "yes"; - - if (therm->temp_get(therm) < 0) - sensor_avail = "no"; - - nv_info(therm, "internal sensor: %s\n", sensor_avail); -} - int nouveau_therm_sensor_ctor(struct nouveau_therm *therm) { diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c b/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c index 5eb3e0da7c6e..41241922263f 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -116,11 +116,6 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, { struct nouveau_abi16_ntfy *ntfy, *temp; - /* wait for all activity to stop before releasing notify object, which - * may be still in use */ - if (chan->chan && chan->ntfy) - nouveau_channel_idle(chan->chan); - /* cleanup notifier state */ list_for_each_entry_safe(ntfy, temp, &chan->notifiers, head) { nouveau_abi16_ntfy_fini(chan, ntfy); @@ -391,7 +386,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_device *device = nv_device(drm->device); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); - struct nouveau_abi16_chan *chan = NULL, *temp; + struct nouveau_abi16_chan *chan, *temp; struct nouveau_abi16_ntfy *ntfy; struct nouveau_object *object; struct nv_dma_class args = {}; @@ -404,11 +399,10 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) if (unlikely(nv_device(abi16->device)->card_type >= NV_C0)) return nouveau_abi16_put(abi16, -EINVAL); - list_for_each_entry(temp, &abi16->channels, head) { - if (temp->chan->handle == (NVDRM_CHAN | info->channel)) { - chan = temp; + list_for_each_entry_safe(chan, temp, &abi16->channels, head) { + if (chan->chan->handle == (NVDRM_CHAN | info->channel)) break; - } + chan = NULL; } if (!chan) @@ -460,18 +454,17 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) { struct drm_nouveau_gpuobj_free *fini = data; struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); - struct nouveau_abi16_chan *chan = NULL, *temp; + struct nouveau_abi16_chan *chan, *temp; struct nouveau_abi16_ntfy *ntfy; int ret; if (unlikely(!abi16)) return -ENOMEM; - list_for_each_entry(temp, &abi16->channels, head) { - if (temp->chan->handle == (NVDRM_CHAN | fini->channel)) { - chan = temp; + list_for_each_entry_safe(chan, temp, &abi16->channels, head) { + if (chan->chan->handle == (NVDRM_CHAN | fini->channel)) break; - } + chan = NULL; } if (!chan) diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_agp.c b/trunk/drivers/gpu/drm/nouveau/nouveau_agp.c index 6e7a55f93a85..d28430cd2ba6 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_agp.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_agp.c @@ -47,18 +47,6 @@ nouveau_agp_enabled(struct nouveau_drm *drm) if (drm->agp.stat == UNKNOWN) { if (!nouveau_agpmode) return false; -#ifdef __powerpc__ - /* Disable AGP by default on all PowerPC machines for - * now -- At least some UniNorth-2 AGP bridges are - * known to be broken: DMA from the host to the card - * works just fine, but writeback from the card to the - * host goes straight to memory untranslated bypassing - * the GATT somehow, making them quite painful to deal - * with... - */ - if (nouveau_agpmode == -1) - return false; -#endif return true; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c index 7ff10711a4d0..11ca82148edc 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -801,7 +801,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, stride = 16 * 4; height = amount / stride; - if (old_mem->mem_type == TTM_PL_VRAM && + if (new_mem->mem_type == TTM_PL_VRAM && nouveau_bo_tile_layout(nvbo)) { ret = RING_SPACE(chan, 8); if (ret) @@ -823,7 +823,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, BEGIN_NV04(chan, NvSubCopy, 0x0200, 1); OUT_RING (chan, 1); } - if (new_mem->mem_type == TTM_PL_VRAM && + if (old_mem->mem_type == TTM_PL_VRAM && nouveau_bo_tile_layout(nvbo)) { ret = RING_SPACE(chan, 8); if (ret) diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c index c95decf543e9..d1099365bfc1 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -71,26 +71,12 @@ module_param_named(modeset, nouveau_modeset, int, 0400); static struct drm_driver driver; -static int -nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) -{ - struct nouveau_drm *drm = - container_of(event, struct nouveau_drm, vblank[head]); - drm_handle_vblank(drm->dev, head); - return NVKM_EVENT_KEEP; -} - static int nouveau_drm_vblank_enable(struct drm_device *dev, int head) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); - - if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank))) - return -EIO; - WARN_ON_ONCE(drm->vblank[head].func); - drm->vblank[head].func = nouveau_drm_vblank_handler; - nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]); + nouveau_event_get(pdisp->vblank, head, &drm->vblank); return 0; } @@ -99,11 +85,16 @@ nouveau_drm_vblank_disable(struct drm_device *dev, int head) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); - if (drm->vblank[head].func) - nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]); - else - WARN_ON_ONCE(1); - drm->vblank[head].func = NULL; + nouveau_event_put(pdisp->vblank, head, &drm->vblank); +} + +static int +nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) +{ + struct nouveau_drm *drm = + container_of(event, struct nouveau_drm, vblank); + drm_handle_vblank(drm->dev, head); + return NVKM_EVENT_KEEP; } static u64 @@ -301,6 +292,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) dev->dev_private = drm; drm->dev = dev; + drm->vblank.func = nouveau_drm_vblank_handler; INIT_LIST_HEAD(&drm->clients); spin_lock_init(&drm->tile.lock); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h index 9c39bafbef2c..b25df374c901 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -113,7 +113,7 @@ struct nouveau_drm { struct nvbios vbios; struct nouveau_display *display; struct backlight_device *backlight; - struct nouveau_eventh vblank[4]; + struct nouveau_eventh vblank; /* power management */ struct nouveau_pm *pm; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c index 936b442a6ab7..bb54098c6d97 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -402,12 +402,8 @@ nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) struct drm_device *dev = dev_get_drvdata(d); struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_therm *therm = nouveau_therm(drm->device); - int temp = therm->temp_get(therm); - if (temp < 0) - return temp; - - return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000); + return snprintf(buf, PAGE_SIZE, "%d\n", therm->temp_get(therm) * 1000); } static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp, NULL, 0); @@ -875,12 +871,7 @@ static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_get_pwm1_max, nouveau_hwmon_set_pwm1_max, 0); -static struct attribute *hwmon_default_attributes[] = { - &sensor_dev_attr_name.dev_attr.attr, - &sensor_dev_attr_update_rate.dev_attr.attr, - NULL -}; -static struct attribute *hwmon_temp_attributes[] = { +static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr, &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, @@ -891,6 +882,8 @@ static struct attribute *hwmon_temp_attributes[] = { &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, &sensor_dev_attr_temp1_emergency.dev_attr.attr, &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr, + &sensor_dev_attr_name.dev_attr.attr, + &sensor_dev_attr_update_rate.dev_attr.attr, NULL }; static struct attribute *hwmon_fan_rpm_attributes[] = { @@ -905,11 +898,8 @@ static struct attribute *hwmon_pwm_fan_attributes[] = { NULL }; -static const struct attribute_group hwmon_default_attrgroup = { - .attrs = hwmon_default_attributes, -}; -static const struct attribute_group hwmon_temp_attrgroup = { - .attrs = hwmon_temp_attributes, +static const struct attribute_group hwmon_attrgroup = { + .attrs = hwmon_attributes, }; static const struct attribute_group hwmon_fan_rpm_attrgroup = { .attrs = hwmon_fan_rpm_attributes, @@ -941,22 +931,13 @@ nouveau_hwmon_init(struct drm_device *dev) } dev_set_drvdata(hwmon_dev, dev); - /* set the default attributes */ - ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_default_attrgroup); + /* default sysfs entries */ + ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_attrgroup); if (ret) { if (ret) goto error; } - /* if the card has a working thermal sensor */ - if (therm->temp_get(therm) >= 0) { - ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_temp_attrgroup); - if (ret) { - if (ret) - goto error; - } - } - /* if the card has a pwm fan */ /*XXX: incorrect, need better detection for this, some boards have * the gpio entries for pwm fan control even when there's no @@ -998,10 +979,11 @@ nouveau_hwmon_fini(struct drm_device *dev) struct nouveau_pm *pm = nouveau_pm(dev); if (pm->hwmon) { - sysfs_remove_group(&pm->hwmon->kobj, &hwmon_default_attrgroup); - sysfs_remove_group(&pm->hwmon->kobj, &hwmon_temp_attrgroup); - sysfs_remove_group(&pm->hwmon->kobj, &hwmon_pwm_fan_attrgroup); - sysfs_remove_group(&pm->hwmon->kobj, &hwmon_fan_rpm_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, + &hwmon_pwm_fan_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, + &hwmon_fan_rpm_attrgroup); hwmon_device_unregister(pm->hwmon); } diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_display.c b/trunk/drivers/gpu/drm/nouveau/nv50_display.c index 1ddc03e51bf4..a6237c9cbbc3 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_display.c @@ -55,9 +55,9 @@ /* offsets in shared sync bo of various structures */ #define EVO_SYNC(c, o) ((c) * 0x0100 + (o)) -#define EVO_MAST_NTFY EVO_SYNC( 0, 0x00) -#define EVO_FLIP_SEM0(c) EVO_SYNC((c) + 1, 0x00) -#define EVO_FLIP_SEM1(c) EVO_SYNC((c) + 1, 0x10) +#define EVO_MAST_NTFY EVO_SYNC( 0, 0x00) +#define EVO_FLIP_SEM0(c) EVO_SYNC((c), 0x00) +#define EVO_FLIP_SEM1(c) EVO_SYNC((c), 0x10) #define EVO_CORE_HANDLE (0xd1500000) #define EVO_CHAN_HANDLE(t,i) (0xd15c0000 | (((t) & 0x00ff) << 8) | (i)) @@ -341,8 +341,10 @@ struct nv50_curs { struct nv50_sync { struct nv50_dmac base; - u32 addr; - u32 data; + struct { + u32 offset; + u16 value; + } sem; }; struct nv50_ovly { @@ -469,33 +471,13 @@ nv50_display_crtc_sema(struct drm_device *dev, int crtc) return nv50_disp(dev)->sync; } -struct nv50_display_flip { - struct nv50_disp *disp; - struct nv50_sync *chan; -}; - -static bool -nv50_display_flip_wait(void *data) -{ - struct nv50_display_flip *flip = data; - if (nouveau_bo_rd32(flip->disp->sync, flip->chan->addr / 4) == - flip->chan->data) - return true; - usleep_range(1, 2); - return false; -} - void nv50_display_flip_stop(struct drm_crtc *crtc) { - struct nouveau_device *device = nouveau_dev(crtc->dev); - struct nv50_display_flip flip = { - .disp = nv50_disp(crtc->dev), - .chan = nv50_sync(crtc), - }; + struct nv50_sync *sync = nv50_sync(crtc); u32 *push; - push = evo_wait(flip.chan, 8); + push = evo_wait(sync, 8); if (push) { evo_mthd(push, 0x0084, 1); evo_data(push, 0x00000000); @@ -505,10 +487,8 @@ nv50_display_flip_stop(struct drm_crtc *crtc) evo_data(push, 0x00000000); evo_mthd(push, 0x0080, 1); evo_data(push, 0x00000000); - evo_kick(push, flip.chan); + evo_kick(push, sync); } - - nv_wait_cb(device, nv50_display_flip_wait, &flip); } int @@ -516,78 +496,73 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct nouveau_channel *chan, u32 swap_interval) { struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); + struct nv50_disp *disp = nv50_disp(crtc->dev); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nv50_sync *sync = nv50_sync(crtc); - int head = nv_crtc->index, ret; u32 *push; + int ret; swap_interval <<= 4; if (swap_interval == 0) swap_interval |= 0x100; - if (chan == NULL) - evo_sync(crtc->dev); push = evo_wait(sync, 128); if (unlikely(push == NULL)) return -EBUSY; - if (chan && nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) { - ret = RING_SPACE(chan, 8); - if (ret) - return ret; - - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); - OUT_RING (chan, NvEvoSema0 + head); - OUT_RING (chan, sync->addr ^ 0x10); - BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1); - OUT_RING (chan, sync->data + 1); - BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2); - OUT_RING (chan, sync->addr); - OUT_RING (chan, sync->data); - } else - if (chan && nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { - u64 addr = nv84_fence_crtc(chan, head) + sync->addr; - ret = RING_SPACE(chan, 12); - if (ret) - return ret; - - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram); - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr ^ 0x10)); - OUT_RING (chan, lower_32_bits(addr ^ 0x10)); - OUT_RING (chan, sync->data + 1); - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr)); - OUT_RING (chan, lower_32_bits(addr)); - OUT_RING (chan, sync->data); - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); - } else - if (chan) { - u64 addr = nv84_fence_crtc(chan, head) + sync->addr; + /* synchronise with the rendering channel, if necessary */ + if (likely(chan)) { ret = RING_SPACE(chan, 10); if (ret) return ret; - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr ^ 0x10)); - OUT_RING (chan, lower_32_bits(addr ^ 0x10)); - OUT_RING (chan, sync->data + 1); - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG | - NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr)); - OUT_RING (chan, lower_32_bits(addr)); - OUT_RING (chan, sync->data); - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL | - NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); - } + if (nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) { + BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); + OUT_RING (chan, NvEvoSema0 + nv_crtc->index); + OUT_RING (chan, sync->sem.offset); + BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1); + OUT_RING (chan, 0xf00d0000 | sync->sem.value); + BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2); + OUT_RING (chan, sync->sem.offset ^ 0x10); + OUT_RING (chan, 0x74b1e000); + BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); + OUT_RING (chan, NvSema); + } else + if (nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { + u64 offset = nv84_fence_crtc(chan, nv_crtc->index); + offset += sync->sem.offset; + + BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(offset)); + OUT_RING (chan, lower_32_bits(offset)); + OUT_RING (chan, 0xf00d0000 | sync->sem.value); + OUT_RING (chan, 0x00000002); + BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(offset)); + OUT_RING (chan, lower_32_bits(offset ^ 0x10)); + OUT_RING (chan, 0x74b1e000); + OUT_RING (chan, 0x00000001); + } else { + u64 offset = nv84_fence_crtc(chan, nv_crtc->index); + offset += sync->sem.offset; + + BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(offset)); + OUT_RING (chan, lower_32_bits(offset)); + OUT_RING (chan, 0xf00d0000 | sync->sem.value); + OUT_RING (chan, 0x00001002); + BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(offset)); + OUT_RING (chan, lower_32_bits(offset ^ 0x10)); + OUT_RING (chan, 0x74b1e000); + OUT_RING (chan, 0x00001001); + } - if (chan) { - sync->addr ^= 0x10; - sync->data++; FIRE_RING (chan); + } else { + nouveau_bo_wr32(disp->sync, sync->sem.offset / 4, + 0xf00d0000 | sync->sem.value); + evo_sync(crtc->dev); } /* queue the flip */ @@ -600,9 +575,9 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, evo_data(push, 0x40000000); } evo_mthd(push, 0x0088, 4); - evo_data(push, sync->addr); - evo_data(push, sync->data++); - evo_data(push, sync->data); + evo_data(push, sync->sem.offset); + evo_data(push, 0xf00d0000 | sync->sem.value); + evo_data(push, 0x74b1e000); evo_data(push, NvEvoSync); evo_mthd(push, 0x00a0, 2); evo_data(push, 0x00000000); @@ -630,6 +605,9 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, evo_mthd(push, 0x0080, 1); evo_data(push, 0x00000000); evo_kick(push, sync); + + sync->sem.offset ^= 0x10; + sync->sem.value++; return 0; } @@ -1401,8 +1379,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) if (ret) goto out; - head->sync.addr = EVO_FLIP_SEM0(index); - head->sync.data = 0x00000000; + head->sync.sem.offset = EVO_SYNC(1 + index, 0x00); /* allocate overlay resources */ ret = nv50_pioc_create(disp->core, NV50_DISP_OIMM_CLASS, index, @@ -2135,23 +2112,15 @@ nv50_display_fini(struct drm_device *dev) int nv50_display_init(struct drm_device *dev) { - struct nv50_disp *disp = nv50_disp(dev); - struct drm_crtc *crtc; - u32 *push; - - push = evo_wait(nv50_mast(dev), 32); - if (!push) - return -EBUSY; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nv50_sync *sync = nv50_sync(crtc); - nouveau_bo_wr32(disp->sync, sync->addr / 4, sync->data); + u32 *push = evo_wait(nv50_mast(dev), 32); + if (push) { + evo_mthd(push, 0x0088, 1); + evo_data(push, NvEvoSync); + evo_kick(push, nv50_mast(dev)); + return 0; } - evo_mthd(push, 0x0088, 1); - evo_data(push, NvEvoSync); - evo_kick(push, nv50_mast(dev)); - return 0; + return -EBUSY; } void @@ -2276,7 +2245,6 @@ nv50_display_create(struct drm_device *dev) NV_WARN(drm, "failed to create encoder %d/%d/%d: %d\n", dcbe->location, dcbe->type, ffs(dcbe->or) - 1, ret); - ret = 0; } } diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 305a657bf215..3c38ea46531c 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -2438,12 +2438,6 @@ static u32 evergreen_gpu_check_soft_reset(struct radeon_device *rdev) if (tmp & L2_BUSY) reset_mask |= RADEON_RESET_VMC; - /* Skip MC reset as it's mostly likely not hung, just busy */ - if (reset_mask & RADEON_RESET_MC) { - DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); - reset_mask &= ~RADEON_RESET_MC; - } - return reset_mask; } diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index eb8ac315f92f..99fb13286fd0 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -834,7 +834,7 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, __func__, __LINE__, toffset, surf.base_align); return -EINVAL; } - if (surf.nsamples <= 1 && moffset & (surf.base_align - 1)) { + if (moffset & (surf.base_align - 1)) { dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n", __func__, __LINE__, moffset, surf.base_align); return -EINVAL; diff --git a/trunk/drivers/gpu/drm/radeon/ni.c b/trunk/drivers/gpu/drm/radeon/ni.c index 27769e724b6d..7cead763be9e 100644 --- a/trunk/drivers/gpu/drm/radeon/ni.c +++ b/trunk/drivers/gpu/drm/radeon/ni.c @@ -468,19 +468,13 @@ static void cayman_gpu_init(struct radeon_device *rdev) (rdev->pdev->device == 0x9907) || (rdev->pdev->device == 0x9908) || (rdev->pdev->device == 0x9909) || - (rdev->pdev->device == 0x990B) || - (rdev->pdev->device == 0x990C) || - (rdev->pdev->device == 0x990F) || (rdev->pdev->device == 0x9910) || - (rdev->pdev->device == 0x9917) || - (rdev->pdev->device == 0x9999)) { + (rdev->pdev->device == 0x9917)) { rdev->config.cayman.max_simds_per_se = 6; rdev->config.cayman.max_backends_per_se = 2; } else if ((rdev->pdev->device == 0x9903) || (rdev->pdev->device == 0x9904) || (rdev->pdev->device == 0x990A) || - (rdev->pdev->device == 0x990D) || - (rdev->pdev->device == 0x990E) || (rdev->pdev->device == 0x9913) || (rdev->pdev->device == 0x9918)) { rdev->config.cayman.max_simds_per_se = 4; @@ -489,9 +483,6 @@ static void cayman_gpu_init(struct radeon_device *rdev) (rdev->pdev->device == 0x9990) || (rdev->pdev->device == 0x9991) || (rdev->pdev->device == 0x9994) || - (rdev->pdev->device == 0x9995) || - (rdev->pdev->device == 0x9996) || - (rdev->pdev->device == 0x999A) || (rdev->pdev->device == 0x99A0)) { rdev->config.cayman.max_simds_per_se = 3; rdev->config.cayman.max_backends_per_se = 1; @@ -625,22 +616,11 @@ static void cayman_gpu_init(struct radeon_device *rdev) WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config); WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config); - if ((rdev->config.cayman.max_backends_per_se == 1) && - (rdev->flags & RADEON_IS_IGP)) { - if ((disabled_rb_mask & 3) == 1) { - /* RB0 disabled, RB1 enabled */ - tmp = 0x11111111; - } else { - /* RB1 disabled, RB0 enabled */ - tmp = 0x00000000; - } - } else { - tmp = gb_addr_config & NUM_PIPES_MASK; - tmp = r6xx_remap_render_backend(rdev, tmp, - rdev->config.cayman.max_backends_per_se * - rdev->config.cayman.max_shader_engines, - CAYMAN_MAX_BACKENDS, disabled_rb_mask); - } + tmp = gb_addr_config & NUM_PIPES_MASK; + tmp = r6xx_remap_render_backend(rdev, tmp, + rdev->config.cayman.max_backends_per_se * + rdev->config.cayman.max_shader_engines, + CAYMAN_MAX_BACKENDS, disabled_rb_mask); WREG32(GB_BACKEND_MAP, tmp); cgts_tcc_disable = 0xffff0000; @@ -1401,12 +1381,6 @@ static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev) if (tmp & L2_BUSY) reset_mask |= RADEON_RESET_VMC; - /* Skip MC reset as it's mostly likely not hung, just busy */ - if (reset_mask & RADEON_RESET_MC) { - DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); - reset_mask &= ~RADEON_RESET_MC; - } - return reset_mask; } @@ -1791,7 +1765,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); - radeon_vm_manager_fini(rdev); cayman_cp_enable(rdev, false); cayman_dma_stop(rdev); evergreen_irq_suspend(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index 0740db3fcd22..6d4b5611daf4 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -1394,12 +1394,6 @@ static u32 r600_gpu_check_soft_reset(struct radeon_device *rdev) if (r600_is_display_hung(rdev)) reset_mask |= RADEON_RESET_DISPLAY; - /* Skip MC reset as it's mostly likely not hung, just busy */ - if (reset_mask & RADEON_RESET_MC) { - DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); - reset_mask &= ~RADEON_RESET_MC; - } - return reset_mask; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_benchmark.c b/trunk/drivers/gpu/drm/radeon/radeon_benchmark.c index 6e05a2e75a46..bedda9caadd9 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_benchmark.c @@ -122,7 +122,10 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, goto out_cleanup; } - if (rdev->asic->copy.dma) { + /* r100 doesn't have dma engine so skip the test */ + /* also, VRAM-to-VRAM test doesn't make much sense for DMA */ + /* skip it as well if domains are the same */ + if ((rdev->asic->copy.dma) && (sdomain != ddomain)) { time = radeon_benchmark_do_move(rdev, size, saddr, daddr, RADEON_BENCHMARK_COPY_DMA, n); if (time < 0) @@ -132,15 +135,13 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, sdomain, ddomain, "dma"); } - if (rdev->asic->copy.blit) { - time = radeon_benchmark_do_move(rdev, size, saddr, daddr, - RADEON_BENCHMARK_COPY_BLIT, n); - if (time < 0) - goto out_cleanup; - if (time > 0) - radeon_benchmark_log_results(n, size, time, - sdomain, ddomain, "blit"); - } + time = radeon_benchmark_do_move(rdev, size, saddr, daddr, + RADEON_BENCHMARK_COPY_BLIT, n); + if (time < 0) + goto out_cleanup; + if (time > 0) + radeon_benchmark_log_results(n, size, time, + sdomain, ddomain, "blit"); out_cleanup: if (sobj) { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_bios.c b/trunk/drivers/gpu/drm/radeon/radeon_bios.c index fa3c56fba294..b8015913d382 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_bios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_bios.c @@ -99,29 +99,6 @@ static bool radeon_read_bios(struct radeon_device *rdev) return true; } -static bool radeon_read_platform_bios(struct radeon_device *rdev) -{ - uint8_t __iomem *bios; - size_t size; - - rdev->bios = NULL; - - bios = pci_platform_rom(rdev->pdev, &size); - if (!bios) { - return false; - } - - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { - return false; - } - rdev->bios = kmemdup(bios, size, GFP_KERNEL); - if (rdev->bios == NULL) { - return false; - } - - return true; -} - #ifdef CONFIG_ACPI /* ATRM is used to get the BIOS on the discrete cards in * dual-gpu systems. @@ -643,9 +620,6 @@ bool radeon_get_bios(struct radeon_device *rdev) if (r == false) { r = radeon_read_disabled_bios(rdev); } - if (r == false) { - r = radeon_read_platform_bios(rdev); - } if (r == false || rdev->bios == NULL) { DRM_ERROR("Unable to locate a BIOS ROM\n"); rdev->bios = NULL; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index 78edadc9e86b..3e403bdda58f 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -970,15 +970,6 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct found = 1; } - /* quirks */ - /* Radeon 9100 (R200) */ - if ((dev->pdev->device == 0x514D) && - (dev->pdev->subsystem_vendor == 0x174B) && - (dev->pdev->subsystem_device == 0x7149)) { - /* vbios value is bad, use the default */ - found = 0; - } - if (!found) /* fallback to defaults */ radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 66a7f0fd9620..167758488ed6 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -70,10 +70,9 @@ * 2.27.0 - r600-SI: Add CS ioctl support for async DMA * 2.28.0 - r600-eg: Add MEM_WRITE packet support * 2.29.0 - R500 FP16 color clear registers - * 2.30.0 - fix for FMASK texturing */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 30 +#define KMS_DRIVER_MINOR 29 #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_irq_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c index 48f80cd42d8f..90374dd77960 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -400,9 +400,6 @@ void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block) { unsigned long irqflags; - if (!rdev->ddev->irq_enabled) - return; - spin_lock_irqsave(&rdev->irq.lock, irqflags); rdev->irq.afmt[block] = true; radeon_irq_set(rdev); @@ -422,9 +419,6 @@ void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block) { unsigned long irqflags; - if (!rdev->ddev->irq_enabled) - return; - spin_lock_irqsave(&rdev->irq.lock, irqflags); rdev->irq.afmt[block] = false; radeon_irq_set(rdev); @@ -444,9 +438,6 @@ void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask) unsigned long irqflags; int i; - if (!rdev->ddev->irq_enabled) - return; - spin_lock_irqsave(&rdev->irq.lock, irqflags); for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i)); @@ -467,9 +458,6 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) unsigned long irqflags; int i; - if (!rdev->ddev->irq_enabled) - return; - spin_lock_irqsave(&rdev->irq.lock, irqflags); for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) rdev->irq.hpd[i] &= !(hpd_mask & (1 << i)); diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index bafbe3216952..80979ed951eb 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -2284,12 +2284,6 @@ static u32 si_gpu_check_soft_reset(struct radeon_device *rdev) if (tmp & L2_BUSY) reset_mask |= RADEON_RESET_VMC; - /* Skip MC reset as it's mostly likely not hung, just busy */ - if (reset_mask & RADEON_RESET_MC) { - DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); - reset_mask &= ~RADEON_RESET_MC; - } - return reset_mask; } @@ -4469,7 +4463,6 @@ int si_resume(struct radeon_device *rdev) int si_suspend(struct radeon_device *rdev) { - radeon_vm_manager_fini(rdev); si_cp_enable(rdev, false); cayman_dma_stop(rdev); si_irq_suspend(rdev); diff --git a/trunk/drivers/gpu/drm/tegra/Kconfig b/trunk/drivers/gpu/drm/tegra/Kconfig index be1daf7344d3..c92955df0658 100644 --- a/trunk/drivers/gpu/drm/tegra/Kconfig +++ b/trunk/drivers/gpu/drm/tegra/Kconfig @@ -4,6 +4,7 @@ config DRM_TEGRA select DRM_KMS_HELPER select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER + select DRM_HDMI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/trunk/drivers/gpu/drm/tilcdc/Kconfig b/trunk/drivers/gpu/drm/tilcdc/Kconfig index e461e9972455..d24d04013476 100644 --- a/trunk/drivers/gpu/drm/tilcdc/Kconfig +++ b/trunk/drivers/gpu/drm/tilcdc/Kconfig @@ -4,7 +4,8 @@ config DRM_TILCDC select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER - select VIDEOMODE_HELPERS + select OF_VIDEOMODE + select OF_DISPLAY_TIMING select BACKLIGHT_CLASS_DEVICE help Choose this option if you have an TI SoC with LCDC display diff --git a/trunk/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/trunk/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 90ee49786372..580b74e2022b 100644 --- a/trunk/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/trunk/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -173,7 +173,7 @@ static int panel_connector_get_modes(struct drm_connector *connector) struct drm_display_mode *mode = drm_mode_create(dev); struct videomode vm; - if (videomode_from_timings(timings, &vm, i)) + if (videomode_from_timing(timings, &vm, i)) break; drm_display_mode_from_videomode(&vm, mode); diff --git a/trunk/drivers/gpu/drm/udl/udl_connector.c b/trunk/drivers/gpu/drm/udl/udl_connector.c index b44d548c56f8..fe5cdbcf2636 100644 --- a/trunk/drivers/gpu/drm/udl/udl_connector.c +++ b/trunk/drivers/gpu/drm/udl/udl_connector.c @@ -61,10 +61,6 @@ static int udl_get_modes(struct drm_connector *connector) int ret; edid = (struct edid *)udl_get_edid(udl); - if (!edid) { - drm_mode_connector_update_edid_property(connector, NULL); - return 0; - } /* * We only read the main block, but if the monitor reports extension diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index aa341d135867..512b01c04ea7 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -2077,6 +2077,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) }, { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MASTERKIT, USB_DEVICE_ID_MASTERKIT_MA901RADIO) }, { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, @@ -2243,18 +2244,6 @@ bool hid_ignore(struct hid_device *hdev) hdev->product <= USB_DEVICE_ID_VELLEMAN_K8061_LAST)) return true; break; - case USB_VENDOR_ID_ATMEL_V_USB: - /* Masterkit MA901 usb radio based on Atmel tiny85 chip and - * it has the same USB ID as many Atmel V-USB devices. This - * usb radio is handled by radio-ma901.c driver so we want - * ignore the hid. Check the name, bus, product and ignore - * if we have MA901 usb radio. - */ - if (hdev->product == USB_DEVICE_ID_ATMEL_V_USB && - hdev->bus == BUS_USB && - strncmp(hdev->name, "www.masterkit.ru MA901", 22) == 0) - return true; - break; } if (hdev->type == HID_TYPE_USBMOUSE && diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index 5309fd5eb0eb..92e47e5c9564 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -158,8 +158,6 @@ #define USB_VENDOR_ID_ATMEL 0x03eb #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c #define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118 -#define USB_VENDOR_ID_ATMEL_V_USB 0x16c0 -#define USB_DEVICE_ID_ATMEL_V_USB 0x05df #define USB_VENDOR_ID_AUREAL 0x0755 #define USB_DEVICE_ID_AUREAL_W01RN 0x2626 @@ -559,6 +557,9 @@ #define USB_VENDOR_ID_MADCATZ 0x0738 #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 +#define USB_VENDOR_ID_MASTERKIT 0x16c0 +#define USB_DEVICE_ID_MASTERKIT_MA901RADIO 0x05df + #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a @@ -589,9 +590,6 @@ #define USB_VENDOR_ID_MONTEREY 0x0566 #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 -#define USB_VENDOR_ID_MSI 0x1770 -#define USB_DEVICE_ID_MSI_GX680R_LED_PANEL 0xff00 - #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 #define USB_DEVICE_ID_N_S_HARMONY 0xc359 @@ -686,9 +684,6 @@ #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 -#define USB_VENDOR_ID_REALTEK 0x0bda -#define USB_DEVICE_ID_REALTEK_READER 0x0152 - #define USB_VENDOR_ID_ROCCAT 0x1e7d #define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4 #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c diff --git a/trunk/drivers/hid/hid-logitech-dj.c b/trunk/drivers/hid/hid-logitech-dj.c index 8758f38c948c..9500f2f3f8fe 100644 --- a/trunk/drivers/hid/hid-logitech-dj.c +++ b/trunk/drivers/hid/hid-logitech-dj.c @@ -459,25 +459,19 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, struct dj_report *dj_report) { struct hid_device *hdev = djrcv_dev->hdev; - struct hid_report *report; - struct hid_report_enum *output_report_enum; - u8 *data = (u8 *)(&dj_report->device_index); - int i; + int sent_bytes; - output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT]; - report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT]; - - if (!report) { - dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__); + if (!hdev->hid_output_raw_report) { + dev_err(&hdev->dev, "%s:" + "hid_output_raw_report is null\n", __func__); return -ENODEV; } - for (i = 0; i < report->field[0]->report_count; i++) - report->field[0]->value[i] = data[i]; - - usbhid_submit_report(hdev, report, USB_DIR_OUT); + sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report, + sizeof(struct dj_report), + HID_OUTPUT_REPORT); - return 0; + return (sent_bytes < 0) ? sent_bytes : 0; } static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) diff --git a/trunk/drivers/hid/hid-magicmouse.c b/trunk/drivers/hid/hid-magicmouse.c index a8ce44296cfd..f7f113ba083e 100644 --- a/trunk/drivers/hid/hid-magicmouse.c +++ b/trunk/drivers/hid/hid-magicmouse.c @@ -462,21 +462,6 @@ static int magicmouse_input_mapping(struct hid_device *hdev, return 0; } -static void magicmouse_input_configured(struct hid_device *hdev, - struct hid_input *hi) - -{ - struct magicmouse_sc *msc = hid_get_drvdata(hdev); - - int ret = magicmouse_setup_input(msc->input, hdev); - if (ret) { - hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); - /* clean msc->input to notify probe() of the failure */ - msc->input = NULL; - } -} - - static int magicmouse_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -508,10 +493,15 @@ static int magicmouse_probe(struct hid_device *hdev, goto err_free; } - if (!msc->input) { - hid_err(hdev, "magicmouse input not registered\n"); - ret = -ENOMEM; - goto err_stop_hw; + /* We do this after hid-input is done parsing reports so that + * hid-input uses the most natural button and axis IDs. + */ + if (msc->input) { + ret = magicmouse_setup_input(msc->input, hdev); + if (ret) { + hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); + goto err_stop_hw; + } } if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) @@ -578,7 +568,6 @@ static struct hid_driver magicmouse_driver = { .remove = magicmouse_remove, .raw_event = magicmouse_raw_event, .input_mapping = magicmouse_input_mapping, - .input_configured = magicmouse_input_configured, }; module_hid_driver(magicmouse_driver); diff --git a/trunk/drivers/hid/hid-multitouch.c b/trunk/drivers/hid/hid-multitouch.c index 82e9211b3ca9..7a1ebb867cf4 100644 --- a/trunk/drivers/hid/hid-multitouch.c +++ b/trunk/drivers/hid/hid-multitouch.c @@ -621,7 +621,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, { struct mt_device *td = hid_get_drvdata(hid); __s32 quirks = td->mtclass.quirks; - struct input_dev *input = field->hidinput->input; if (hid->claimed & HID_CLAIMED_INPUT) { switch (usage->hid) { @@ -671,16 +670,13 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, break; default: - if (usage->type) - input_event(input, usage->type, usage->code, - value); return; } if (usage->usage_index + 1 == field->report_count) { /* we only take into account the last report. */ if (usage->hid == td->last_slot_field) - mt_complete_slot(td, input); + mt_complete_slot(td, field->hidinput->input); if (field->index == td->last_field_index && td->num_received >= td->num_expected) diff --git a/trunk/drivers/hid/usbhid/hid-quirks.c b/trunk/drivers/hid/usbhid/hid-quirks.c index 19b8360f2330..e0e6abf1cd3b 100644 --- a/trunk/drivers/hid/usbhid/hid-quirks.c +++ b/trunk/drivers/hid/usbhid/hid-quirks.c @@ -73,7 +73,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, @@ -81,7 +80,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, diff --git a/trunk/drivers/hv/Makefile b/trunk/drivers/hv/Makefile index 0a74b5661186..e6abfa02d8b7 100644 --- a/trunk/drivers/hv/Makefile +++ b/trunk/drivers/hv/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o hv_vmbus-y := vmbus_drv.o \ hv.o connection.o channel.o \ channel_mgmt.o ring_buffer.o -hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o +hv_utils-y := hv_util.o hv_kvp.o diff --git a/trunk/drivers/hv/channel_mgmt.c b/trunk/drivers/hv/channel_mgmt.c index bad8128b283a..ff1be167eb04 100644 --- a/trunk/drivers/hv/channel_mgmt.c +++ b/trunk/drivers/hv/channel_mgmt.c @@ -165,19 +165,8 @@ static void vmbus_process_rescind_offer(struct work_struct *work) struct vmbus_channel *channel = container_of(work, struct vmbus_channel, work); - unsigned long flags; - struct vmbus_channel_relid_released msg; vmbus_device_unregister(channel->device_obj); - memset(&msg, 0, sizeof(struct vmbus_channel_relid_released)); - msg.child_relid = channel->offermsg.child_relid; - msg.header.msgtype = CHANNELMSG_RELID_RELEASED; - vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released)); - - spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_del(&channel->listentry); - spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); - free_channel(channel); } void vmbus_free_channels(void) diff --git a/trunk/drivers/hv/hv.c b/trunk/drivers/hv/hv.c index ae4923756d98..731158910c1e 100644 --- a/trunk/drivers/hv/hv.c +++ b/trunk/drivers/hv/hv.c @@ -289,8 +289,9 @@ void hv_synic_init(void *arg) /* Check the version */ rdmsrl(HV_X64_MSR_SVERSION, version); - hv_context.event_dpc[cpu] = kmalloc(sizeof(struct tasklet_struct), - GFP_ATOMIC); + hv_context.event_dpc[cpu] = (struct tasklet_struct *) + kmalloc(sizeof(struct tasklet_struct), + GFP_ATOMIC); if (hv_context.event_dpc[cpu] == NULL) { pr_err("Unable to allocate event dpc\n"); goto cleanup; diff --git a/trunk/drivers/hv/hv_balloon.c b/trunk/drivers/hv/hv_balloon.c index 4c605c70ebf9..37873213e24f 100644 --- a/trunk/drivers/hv/hv_balloon.c +++ b/trunk/drivers/hv/hv_balloon.c @@ -117,14 +117,7 @@ union dm_caps { struct { __u64 balloon:1; __u64 hot_add:1; - /* - * To support guests that may have alignment - * limitations on hot-add, the guest can specify - * its alignment requirements; a value of n - * represents an alignment of 2^n in mega bytes. - */ - __u64 hot_add_alignment:4; - __u64 reservedz:58; + __u64 reservedz:62; } cap_bits; __u64 caps; } __packed; @@ -419,45 +412,13 @@ struct dm_info_msg { * End protocol definitions. */ -/* - * State to manage hot adding memory into the guest. - * The range start_pfn : end_pfn specifies the range - * that the host has asked us to hot add. The range - * start_pfn : ha_end_pfn specifies the range that we have - * currently hot added. We hot add in multiples of 128M - * chunks; it is possible that we may not be able to bring - * online all the pages in the region. The range - * covered_start_pfn : covered_end_pfn defines the pages that can - * be brough online. - */ - -struct hv_hotadd_state { - struct list_head list; - unsigned long start_pfn; - unsigned long covered_start_pfn; - unsigned long covered_end_pfn; - unsigned long ha_end_pfn; - unsigned long end_pfn; -}; - -struct balloon_state { - __u32 num_pages; - struct work_struct wrk; -}; - -struct hot_add_wrk { - union dm_mem_page_range ha_page_range; - union dm_mem_page_range ha_region_range; - struct work_struct wrk; -}; - -static bool hot_add = true; +static bool hot_add; static bool do_hot_add; /* * Delay reporting memory pressure by * the specified number of seconds. */ -static uint pressure_report_delay = 45; +static uint pressure_report_delay = 30; module_param(hot_add, bool, (S_IRUGO | S_IWUSR)); MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add"); @@ -485,7 +446,6 @@ enum hv_dm_state { static __u8 recv_buffer[PAGE_SIZE]; static __u8 *send_buffer; #define PAGES_IN_2M 512 -#define HA_CHUNK (32 * 1024) struct hv_dynmem_device { struct hv_device *dev; @@ -499,39 +459,13 @@ struct hv_dynmem_device { unsigned int num_pages_ballooned; /* - * State to manage the ballooning (up) operation. - */ - struct balloon_state balloon_wrk; - - /* - * State to execute the "hot-add" operation. - */ - struct hot_add_wrk ha_wrk; - - /* - * This state tracks if the host has specified a hot-add - * region. - */ - bool host_specified_ha_region; - - /* - * State to synchronize hot-add. - */ - struct completion ol_waitevent; - bool ha_waiting; - /* - * This thread handles hot-add + * This thread handles both balloon/hot-add * requests from the host as well as notifying * the host with regards to memory pressure in * the guest. */ struct task_struct *thread; - /* - * A list of hot-add regions. - */ - struct list_head ha_region_list; - /* * We start with the highest version we can support * and downgrade based on the host; we save here the @@ -542,358 +476,35 @@ struct hv_dynmem_device { static struct hv_dynmem_device dm_device; -#ifdef CONFIG_MEMORY_HOTPLUG - -static void hv_bring_pgs_online(unsigned long start_pfn, unsigned long size) -{ - int i; - - for (i = 0; i < size; i++) { - struct page *pg; - pg = pfn_to_page(start_pfn + i); - __online_page_set_limits(pg); - __online_page_increment_counters(pg); - __online_page_free(pg); - } -} - -static void hv_mem_hot_add(unsigned long start, unsigned long size, - unsigned long pfn_count, - struct hv_hotadd_state *has) +static void hot_add_req(struct hv_dynmem_device *dm, struct dm_hot_add *msg) { - int ret = 0; - int i, nid, t; - unsigned long start_pfn; - unsigned long processed_pfn; - unsigned long total_pfn = pfn_count; - - for (i = 0; i < (size/HA_CHUNK); i++) { - start_pfn = start + (i * HA_CHUNK); - has->ha_end_pfn += HA_CHUNK; - - if (total_pfn > HA_CHUNK) { - processed_pfn = HA_CHUNK; - total_pfn -= HA_CHUNK; - } else { - processed_pfn = total_pfn; - total_pfn = 0; - } - - has->covered_end_pfn += processed_pfn; - - init_completion(&dm_device.ol_waitevent); - dm_device.ha_waiting = true; - - nid = memory_add_physaddr_to_nid(PFN_PHYS(start_pfn)); - ret = add_memory(nid, PFN_PHYS((start_pfn)), - (HA_CHUNK << PAGE_SHIFT)); - - if (ret) { - pr_info("hot_add memory failed error is %d\n", ret); - if (ret == -EEXIST) { - /* - * This error indicates that the error - * is not a transient failure. This is the - * case where the guest's physical address map - * precludes hot adding memory. Stop all further - * memory hot-add. - */ - do_hot_add = false; - } - has->ha_end_pfn -= HA_CHUNK; - has->covered_end_pfn -= processed_pfn; - break; - } - - /* - * Wait for the memory block to be onlined. - */ - t = wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ); - if (t == 0) { - pr_info("hot_add memory timedout\n"); - has->ha_end_pfn -= HA_CHUNK; - has->covered_end_pfn -= processed_pfn; - break; - } - - } - - return; -} - -static void hv_online_page(struct page *pg) -{ - struct list_head *cur; - struct hv_hotadd_state *has; - unsigned long cur_start_pgp; - unsigned long cur_end_pgp; - - if (dm_device.ha_waiting) { - dm_device.ha_waiting = false; - complete(&dm_device.ol_waitevent); - } - - list_for_each(cur, &dm_device.ha_region_list) { - has = list_entry(cur, struct hv_hotadd_state, list); - cur_start_pgp = (unsigned long) - pfn_to_page(has->covered_start_pfn); - cur_end_pgp = (unsigned long)pfn_to_page(has->covered_end_pfn); - - if (((unsigned long)pg >= cur_start_pgp) && - ((unsigned long)pg < cur_end_pgp)) { - /* - * This frame is currently backed; online the - * page. - */ - __online_page_set_limits(pg); - __online_page_increment_counters(pg); - __online_page_free(pg); - has->covered_start_pfn++; - } - } -} - -static bool pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt) -{ - struct list_head *cur; - struct hv_hotadd_state *has; - unsigned long residual, new_inc; - - if (list_empty(&dm_device.ha_region_list)) - return false; - - list_for_each(cur, &dm_device.ha_region_list) { - has = list_entry(cur, struct hv_hotadd_state, list); - - /* - * If the pfn range we are dealing with is not in the current - * "hot add block", move on. - */ - if ((start_pfn >= has->end_pfn)) - continue; - /* - * If the current hot add-request extends beyond - * our current limit; extend it. - */ - if ((start_pfn + pfn_cnt) > has->end_pfn) { - residual = (start_pfn + pfn_cnt - has->end_pfn); - /* - * Extend the region by multiples of HA_CHUNK. - */ - new_inc = (residual / HA_CHUNK) * HA_CHUNK; - if (residual % HA_CHUNK) - new_inc += HA_CHUNK; - - has->end_pfn += new_inc; - } - - /* - * If the current start pfn is not where the covered_end - * is, update it. - */ - - if (has->covered_end_pfn != start_pfn) { - has->covered_end_pfn = start_pfn; - has->covered_start_pfn = start_pfn; - } - return true; - - } - return false; -} - -static unsigned long handle_pg_range(unsigned long pg_start, - unsigned long pg_count) -{ - unsigned long start_pfn = pg_start; - unsigned long pfn_cnt = pg_count; - unsigned long size; - struct list_head *cur; - struct hv_hotadd_state *has; - unsigned long pgs_ol = 0; - unsigned long old_covered_state; - - if (list_empty(&dm_device.ha_region_list)) - return 0; - - list_for_each(cur, &dm_device.ha_region_list) { - has = list_entry(cur, struct hv_hotadd_state, list); - - /* - * If the pfn range we are dealing with is not in the current - * "hot add block", move on. - */ - if ((start_pfn >= has->end_pfn)) - continue; + struct dm_hot_add_response resp; - old_covered_state = has->covered_end_pfn; + if (do_hot_add) { - if (start_pfn < has->ha_end_pfn) { - /* - * This is the case where we are backing pages - * in an already hot added region. Bring - * these pages online first. - */ - pgs_ol = has->ha_end_pfn - start_pfn; - if (pgs_ol > pfn_cnt) - pgs_ol = pfn_cnt; - hv_bring_pgs_online(start_pfn, pgs_ol); - has->covered_end_pfn += pgs_ol; - has->covered_start_pfn += pgs_ol; - pfn_cnt -= pgs_ol; - } + pr_info("Memory hot add not supported\n"); - if ((has->ha_end_pfn < has->end_pfn) && (pfn_cnt > 0)) { - /* - * We have some residual hot add range - * that needs to be hot added; hot add - * it now. Hot add a multiple of - * of HA_CHUNK that fully covers the pages - * we have. - */ - size = (has->end_pfn - has->ha_end_pfn); - if (pfn_cnt <= size) { - size = ((pfn_cnt / HA_CHUNK) * HA_CHUNK); - if (pfn_cnt % HA_CHUNK) - size += HA_CHUNK; - } else { - pfn_cnt = size; - } - hv_mem_hot_add(has->ha_end_pfn, size, pfn_cnt, has); - } /* - * If we managed to online any pages that were given to us, - * we declare success. + * Currently we do not support hot add. + * Just fail the request. */ - return has->covered_end_pfn - old_covered_state; - - } - - return 0; -} - -static unsigned long process_hot_add(unsigned long pg_start, - unsigned long pfn_cnt, - unsigned long rg_start, - unsigned long rg_size) -{ - struct hv_hotadd_state *ha_region = NULL; - - if (pfn_cnt == 0) - return 0; - - if (!dm_device.host_specified_ha_region) - if (pfn_covered(pg_start, pfn_cnt)) - goto do_pg_range; - - /* - * If the host has specified a hot-add range; deal with it first. - */ - - if (rg_size != 0) { - ha_region = kzalloc(sizeof(struct hv_hotadd_state), GFP_KERNEL); - if (!ha_region) - return 0; - - INIT_LIST_HEAD(&ha_region->list); - - list_add_tail(&ha_region->list, &dm_device.ha_region_list); - ha_region->start_pfn = rg_start; - ha_region->ha_end_pfn = rg_start; - ha_region->covered_start_pfn = pg_start; - ha_region->covered_end_pfn = pg_start; - ha_region->end_pfn = rg_start + rg_size; } -do_pg_range: - /* - * Process the page range specified; bringing them - * online if possible. - */ - return handle_pg_range(pg_start, pfn_cnt); -} - -#endif - -static void hot_add_req(struct work_struct *dummy) -{ - struct dm_hot_add_response resp; -#ifdef CONFIG_MEMORY_HOTPLUG - unsigned long pg_start, pfn_cnt; - unsigned long rg_start, rg_sz; -#endif - struct hv_dynmem_device *dm = &dm_device; - memset(&resp, 0, sizeof(struct dm_hot_add_response)); resp.hdr.type = DM_MEM_HOT_ADD_RESPONSE; resp.hdr.size = sizeof(struct dm_hot_add_response); resp.hdr.trans_id = atomic_inc_return(&trans_id); -#ifdef CONFIG_MEMORY_HOTPLUG - pg_start = dm->ha_wrk.ha_page_range.finfo.start_page; - pfn_cnt = dm->ha_wrk.ha_page_range.finfo.page_cnt; - - rg_start = dm->ha_wrk.ha_region_range.finfo.start_page; - rg_sz = dm->ha_wrk.ha_region_range.finfo.page_cnt; - - if ((rg_start == 0) && (!dm->host_specified_ha_region)) { - unsigned long region_size; - unsigned long region_start; - - /* - * The host has not specified the hot-add region. - * Based on the hot-add page range being specified, - * compute a hot-add region that can cover the pages - * that need to be hot-added while ensuring the alignment - * and size requirements of Linux as it relates to hot-add. - */ - region_start = pg_start; - region_size = (pfn_cnt / HA_CHUNK) * HA_CHUNK; - if (pfn_cnt % HA_CHUNK) - region_size += HA_CHUNK; - - region_start = (pg_start / HA_CHUNK) * HA_CHUNK; - - rg_start = region_start; - rg_sz = region_size; - } - - if (do_hot_add) - resp.page_count = process_hot_add(pg_start, pfn_cnt, - rg_start, rg_sz); -#endif - /* - * The result field of the response structure has the - * following semantics: - * - * 1. If all or some pages hot-added: Guest should return success. - * - * 2. If no pages could be hot-added: - * - * If the guest returns success, then the host - * will not attempt any further hot-add operations. This - * signifies a permanent failure. - * - * If the guest returns failure, then this failure will be - * treated as a transient failure and the host may retry the - * hot-add operation after some delay. - */ - if (resp.page_count > 0) - resp.result = 1; - else if (!do_hot_add) - resp.result = 1; - else - resp.result = 0; - - if (!do_hot_add || (resp.page_count == 0)) - pr_info("Memory hot add failed\n"); + resp.page_count = 0; + resp.result = 0; dm->state = DM_INITIALIZED; vmbus_sendpacket(dm->dev->channel, &resp, sizeof(struct dm_hot_add_response), (unsigned long)NULL, VM_PKT_DATA_INBAND, 0); + } static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg) @@ -912,7 +523,7 @@ static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg) } } -static unsigned long compute_balloon_floor(void) +unsigned long compute_balloon_floor(void) { unsigned long min_pages; #define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) @@ -1033,14 +644,6 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages, dm->num_pages_ballooned += alloc_unit; - /* - * If we allocatted 2M pages; split them so we - * can free them in any order we get. - */ - - if (alloc_unit != 1) - split_page(pg, get_order(alloc_unit << PAGE_SHIFT)); - bl_resp->range_count++; bl_resp->range_array[i].finfo.start_page = page_to_pfn(pg); @@ -1054,9 +657,9 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages, -static void balloon_up(struct work_struct *dummy) +static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req) { - int num_pages = dm_device.balloon_wrk.num_pages; + int num_pages = req->num_pages; int num_ballooned = 0; struct dm_balloon_response *bl_resp; int alloc_unit; @@ -1067,10 +670,9 @@ static void balloon_up(struct work_struct *dummy) /* - * We will attempt 2M allocations. However, if we fail to - * allocate 2M chunks, we will go back to 4k allocations. + * Currently, we only support 4k allocations. */ - alloc_unit = 512; + alloc_unit = 1; while (!done) { bl_resp = (struct dm_balloon_response *)send_buffer; @@ -1082,19 +684,14 @@ static void balloon_up(struct work_struct *dummy) num_pages -= num_ballooned; - num_ballooned = alloc_balloon_pages(&dm_device, num_pages, + num_ballooned = alloc_balloon_pages(dm, num_pages, bl_resp, alloc_unit, &alloc_error); - if ((alloc_error) && (alloc_unit != 1)) { - alloc_unit = 1; - continue; - } - if ((alloc_error) || (num_ballooned == num_pages)) { bl_resp->more_pages = 0; done = true; - dm_device.state = DM_INITIALIZED; + dm->state = DM_INITIALIZED; } /* @@ -1122,7 +719,7 @@ static void balloon_up(struct work_struct *dummy) pr_info("Balloon response failed\n"); for (i = 0; i < bl_resp->range_count; i++) - free_balloon_pages(&dm_device, + free_balloon_pages(dm, &bl_resp->range_array[i]); done = true; @@ -1164,6 +761,7 @@ static int dm_thread_func(void *dm_dev) { struct hv_dynmem_device *dm = dm_dev; int t; + unsigned long scan_start; while (!kthread_should_stop()) { t = wait_for_completion_timeout(&dm_device.config_event, 1*HZ); @@ -1175,6 +773,22 @@ static int dm_thread_func(void *dm_dev) if (t == 0) post_status(dm); + scan_start = jiffies; + switch (dm->state) { + case DM_BALLOON_UP: + balloon_up(dm, (struct dm_balloon *)recv_buffer); + break; + + case DM_HOT_ADD: + hot_add_req(dm, (struct dm_hot_add *)recv_buffer); + break; + default: + break; + } + + if (!time_in_range(jiffies, scan_start, scan_start + HZ)) + post_status(dm); + } return 0; @@ -1247,10 +861,6 @@ static void balloon_onchannelcallback(void *context) struct dm_message *dm_msg; struct dm_header *dm_hdr; struct hv_dynmem_device *dm = hv_get_drvdata(dev); - struct dm_balloon *bal_msg; - struct dm_hot_add *ha_msg; - union dm_mem_page_range *ha_pg_range; - union dm_mem_page_range *ha_region; memset(recv_buffer, 0, sizeof(recv_buffer)); vmbus_recvpacket(dev->channel, recv_buffer, @@ -1272,12 +882,8 @@ static void balloon_onchannelcallback(void *context) break; case DM_BALLOON_REQUEST: - if (dm->state == DM_BALLOON_UP) - pr_warn("Currently ballooning\n"); - bal_msg = (struct dm_balloon *)recv_buffer; dm->state = DM_BALLOON_UP; - dm_device.balloon_wrk.num_pages = bal_msg->num_pages; - schedule_work(&dm_device.balloon_wrk.wrk); + complete(&dm->config_event); break; case DM_UNBALLOON_REQUEST: @@ -1287,31 +893,8 @@ static void balloon_onchannelcallback(void *context) break; case DM_MEM_HOT_ADD_REQUEST: - if (dm->state == DM_HOT_ADD) - pr_warn("Currently hot-adding\n"); dm->state = DM_HOT_ADD; - ha_msg = (struct dm_hot_add *)recv_buffer; - if (ha_msg->hdr.size == sizeof(struct dm_hot_add)) { - /* - * This is a normal hot-add request specifying - * hot-add memory. - */ - ha_pg_range = &ha_msg->range; - dm->ha_wrk.ha_page_range = *ha_pg_range; - dm->ha_wrk.ha_region_range.page_range = 0; - } else { - /* - * Host is specifying that we first hot-add - * a region and then partially populate this - * region. - */ - dm->host_specified_ha_region = true; - ha_pg_range = &ha_msg->range; - ha_region = &ha_pg_range[1]; - dm->ha_wrk.ha_page_range = *ha_pg_range; - dm->ha_wrk.ha_region_range = *ha_region; - } - schedule_work(&dm_device.ha_wrk.wrk); + complete(&dm->config_event); break; case DM_INFO_MESSAGE: @@ -1354,10 +937,6 @@ static int balloon_probe(struct hv_device *dev, dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7; init_completion(&dm_device.host_event); init_completion(&dm_device.config_event); - INIT_LIST_HEAD(&dm_device.ha_region_list); - INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up); - INIT_WORK(&dm_device.ha_wrk.wrk, hot_add_req); - dm_device.host_specified_ha_region = false; dm_device.thread = kthread_run(dm_thread_func, &dm_device, "hv_balloon"); @@ -1366,10 +945,6 @@ static int balloon_probe(struct hv_device *dev, goto probe_error1; } -#ifdef CONFIG_MEMORY_HOTPLUG - set_online_page_callback(&hv_online_page); -#endif - hv_set_drvdata(dev, &dm_device); /* * Initiate the hand shake with the host and negotiate @@ -1387,7 +962,8 @@ static int balloon_probe(struct hv_device *dev, ret = vmbus_sendpacket(dev->channel, &version_req, sizeof(struct dm_version_request), (unsigned long)NULL, - VM_PKT_DATA_INBAND, 0); + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret) goto probe_error2; @@ -1414,13 +990,13 @@ static int balloon_probe(struct hv_device *dev, cap_msg.hdr.trans_id = atomic_inc_return(&trans_id); cap_msg.caps.cap_bits.balloon = 1; - cap_msg.caps.cap_bits.hot_add = 1; - /* - * Specify our alignment requirements as it relates - * memory hot-add. Specify 128MB alignment. + * While we currently don't support hot-add, + * we still advertise this capability since the + * host requires that guests partcipating in the + * dynamic memory protocol support hot add. */ - cap_msg.caps.cap_bits.hot_add_alignment = 7; + cap_msg.caps.cap_bits.hot_add = 1; /* * Currently the host does not use these @@ -1433,7 +1009,8 @@ static int balloon_probe(struct hv_device *dev, ret = vmbus_sendpacket(dev->channel, &cap_msg, sizeof(struct dm_capabilities), (unsigned long)NULL, - VM_PKT_DATA_INBAND, 0); + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret) goto probe_error2; @@ -1457,9 +1034,6 @@ static int balloon_probe(struct hv_device *dev, return 0; probe_error2: -#ifdef CONFIG_MEMORY_HOTPLUG - restore_online_page_callback(&hv_online_page); -#endif kthread_stop(dm_device.thread); probe_error1: @@ -1472,26 +1046,13 @@ static int balloon_probe(struct hv_device *dev, static int balloon_remove(struct hv_device *dev) { struct hv_dynmem_device *dm = hv_get_drvdata(dev); - struct list_head *cur, *tmp; - struct hv_hotadd_state *has; if (dm->num_pages_ballooned != 0) pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned); - cancel_work_sync(&dm->balloon_wrk.wrk); - cancel_work_sync(&dm->ha_wrk.wrk); - vmbus_close(dev->channel); kthread_stop(dm->thread); kfree(send_buffer); -#ifdef CONFIG_MEMORY_HOTPLUG - restore_online_page_callback(&hv_online_page); -#endif - list_for_each_safe(cur, tmp, &dm->ha_region_list) { - has = list_entry(cur, struct hv_hotadd_state, list); - list_del(&has->list); - kfree(has); - } return 0; } @@ -1518,7 +1079,14 @@ static int __init init_balloon_drv(void) return vmbus_driver_register(&balloon_drv); } +static void exit_balloon_drv(void) +{ + + vmbus_driver_unregister(&balloon_drv); +} + module_init(init_balloon_drv); +module_exit(exit_balloon_drv); MODULE_DESCRIPTION("Hyper-V Balloon"); MODULE_VERSION(HV_DRV_VERSION); diff --git a/trunk/drivers/hv/hv_snapshot.c b/trunk/drivers/hv/hv_snapshot.c deleted file mode 100644 index 8ad5653ce447..000000000000 --- a/trunk/drivers/hv/hv_snapshot.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * An implementation of host initiated guest snapshot. - * - * - * Copyright (C) 2013, Microsoft, Inc. - * Author : K. Y. Srinivasan - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include - - - -/* - * Global state maintained for transaction that is being processed. - * Note that only one transaction can be active at any point in time. - * - * This state is set when we receive a request from the host; we - * cleanup this state when the transaction is completed - when we respond - * to the host with the key value. - */ - -static struct { - bool active; /* transaction status - active or not */ - int recv_len; /* number of bytes received. */ - struct vmbus_channel *recv_channel; /* chn we got the request */ - u64 recv_req_id; /* request ID. */ - struct hv_vss_msg *msg; /* current message */ -} vss_transaction; - - -static void vss_respond_to_host(int error); - -static struct cb_id vss_id = { CN_VSS_IDX, CN_VSS_VAL }; -static const char vss_name[] = "vss_kernel_module"; -static __u8 *recv_buffer; - -static void vss_send_op(struct work_struct *dummy); -static DECLARE_WORK(vss_send_op_work, vss_send_op); - -/* - * Callback when data is received from user mode. - */ - -static void -vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) -{ - struct hv_vss_msg *vss_msg; - - vss_msg = (struct hv_vss_msg *)msg->data; - - if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER) { - pr_info("VSS daemon registered\n"); - vss_transaction.active = false; - if (vss_transaction.recv_channel != NULL) - hv_vss_onchannelcallback(vss_transaction.recv_channel); - return; - - } - vss_respond_to_host(vss_msg->error); -} - - -static void vss_send_op(struct work_struct *dummy) -{ - int op = vss_transaction.msg->vss_hdr.operation; - struct cn_msg *msg; - struct hv_vss_msg *vss_msg; - - msg = kzalloc(sizeof(*msg) + sizeof(*vss_msg), GFP_ATOMIC); - if (!msg) - return; - - vss_msg = (struct hv_vss_msg *)msg->data; - - msg->id.idx = CN_VSS_IDX; - msg->id.val = CN_VSS_VAL; - - vss_msg->vss_hdr.operation = op; - msg->len = sizeof(struct hv_vss_msg); - - cn_netlink_send(msg, 0, GFP_ATOMIC); - kfree(msg); - - return; -} - -/* - * Send a response back to the host. - */ - -static void -vss_respond_to_host(int error) -{ - struct icmsg_hdr *icmsghdrp; - u32 buf_len; - struct vmbus_channel *channel; - u64 req_id; - - /* - * If a transaction is not active; log and return. - */ - - if (!vss_transaction.active) { - /* - * This is a spurious call! - */ - pr_warn("VSS: Transaction not active\n"); - return; - } - /* - * Copy the global state for completing the transaction. Note that - * only one transaction can be active at a time. - */ - - buf_len = vss_transaction.recv_len; - channel = vss_transaction.recv_channel; - req_id = vss_transaction.recv_req_id; - vss_transaction.active = false; - - icmsghdrp = (struct icmsg_hdr *) - &recv_buffer[sizeof(struct vmbuspipe_hdr)]; - - if (channel->onchannel_callback == NULL) - /* - * We have raced with util driver being unloaded; - * silently return. - */ - return; - - icmsghdrp->status = error; - - icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; - - vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, - VM_PKT_DATA_INBAND, 0); - -} - -/* - * This callback is invoked when we get a VSS message from the host. - * The host ensures that only one VSS transaction can be active at a time. - */ - -void hv_vss_onchannelcallback(void *context) -{ - struct vmbus_channel *channel = context; - u32 recvlen; - u64 requestid; - struct hv_vss_msg *vss_msg; - - - struct icmsg_hdr *icmsghdrp; - struct icmsg_negotiate *negop = NULL; - - if (vss_transaction.active) { - /* - * We will defer processing this callback once - * the current transaction is complete. - */ - vss_transaction.recv_channel = channel; - return; - } - - vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen, - &requestid); - - if (recvlen > 0) { - icmsghdrp = (struct icmsg_hdr *)&recv_buffer[ - sizeof(struct vmbuspipe_hdr)]; - - if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - vmbus_prep_negotiate_resp(icmsghdrp, negop, - recv_buffer, MAX_SRV_VER, MAX_SRV_VER); - /* - * We currently negotiate the highest number the - * host has presented. If this version is not - * atleast 5.0, reject. - */ - negop = (struct icmsg_negotiate *)&recv_buffer[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; - - if (negop->icversion_data[1].major < 5) - negop->icframe_vercnt = 0; - } else { - vss_msg = (struct hv_vss_msg *)&recv_buffer[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; - - /* - * Stash away this global state for completing the - * transaction; note transactions are serialized. - */ - - vss_transaction.recv_len = recvlen; - vss_transaction.recv_channel = channel; - vss_transaction.recv_req_id = requestid; - vss_transaction.active = true; - vss_transaction.msg = (struct hv_vss_msg *)vss_msg; - - switch (vss_msg->vss_hdr.operation) { - /* - * Initiate a "freeze/thaw" - * operation in the guest. - * We respond to the host once - * the operation is complete. - * - * We send the message to the - * user space daemon and the - * operation is performed in - * the daemon. - */ - case VSS_OP_FREEZE: - case VSS_OP_THAW: - schedule_work(&vss_send_op_work); - return; - - case VSS_OP_HOT_BACKUP: - vss_msg->vss_cf.flags = - VSS_HBU_NO_AUTO_RECOVERY; - vss_respond_to_host(0); - return; - - case VSS_OP_GET_DM_INFO: - vss_msg->dm_info.flags = 0; - vss_respond_to_host(0); - return; - - default: - vss_respond_to_host(0); - return; - - } - - } - - icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION - | ICMSGHDRFLAG_RESPONSE; - - vmbus_sendpacket(channel, recv_buffer, - recvlen, requestid, - VM_PKT_DATA_INBAND, 0); - } - -} - -int -hv_vss_init(struct hv_util_service *srv) -{ - int err; - - err = cn_add_callback(&vss_id, vss_name, vss_cn_callback); - if (err) - return err; - recv_buffer = srv->recv_buffer; - - /* - * When this driver loads, the user level daemon that - * processes the host requests may not yet be running. - * Defer processing channel callbacks until the daemon - * has registered. - */ - vss_transaction.active = true; - return 0; -} - -void hv_vss_deinit(void) -{ - cn_del_callback(&vss_id); - cancel_work_sync(&vss_send_op_work); -} diff --git a/trunk/drivers/hv/hv_util.c b/trunk/drivers/hv/hv_util.c index 2f561c5dfe24..1d4cbd8e8261 100644 --- a/trunk/drivers/hv/hv_util.c +++ b/trunk/drivers/hv/hv_util.c @@ -49,12 +49,6 @@ static struct hv_util_service util_kvp = { .util_deinit = hv_kvp_deinit, }; -static struct hv_util_service util_vss = { - .util_cb = hv_vss_onchannelcallback, - .util_init = hv_vss_init, - .util_deinit = hv_vss_deinit, -}; - static void perform_shutdown(struct work_struct *dummy) { orderly_poweroff(true); @@ -345,10 +339,6 @@ static const struct hv_vmbus_device_id id_table[] = { { HV_KVP_GUID, .driver_data = (unsigned long)&util_kvp }, - /* VSS GUID */ - { HV_VSS_GUID, - .driver_data = (unsigned long)&util_vss - }, { }, }; diff --git a/trunk/drivers/hv/ring_buffer.c b/trunk/drivers/hv/ring_buffer.c index d6fbb5772b8d..cafa72ffdc30 100644 --- a/trunk/drivers/hv/ring_buffer.c +++ b/trunk/drivers/hv/ring_buffer.c @@ -71,7 +71,6 @@ u32 hv_end_read(struct hv_ring_buffer_info *rbi) static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi) { - smp_mb(); if (rbi->ring_buffer->interrupt_mask) return false; diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index 4f29117651b6..89ac1cb26f24 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -179,29 +179,9 @@ config SENSORS_ADM9240 This driver can also be built as a module. If so, the module will be called adm9240. -config SENSORS_ADT7X10 - tristate - help - This module contains common code shared by the ADT7310/ADT7320 and - ADT7410/ADT7420 temperature monitoring chip drivers. - - If build as a module, the module will be called adt7x10. - -config SENSORS_ADT7310 - tristate "Analog Devices ADT7310/ADT7320" - depends on SPI_MASTER - select SENSORS_ADT7X10 - help - If you say yes here you get support for the Analog Devices - ADT7310 and ADT7320 temperature monitoring chips. - - This driver can also be built as a module. If so, the module - will be called adt7310. - config SENSORS_ADT7410 tristate "Analog Devices ADT7410/ADT7420" depends on I2C - select SENSORS_ADT7X10 help If you say yes here you get support for the Analog Devices ADT7410 and ADT7420 temperature monitoring chips. @@ -771,16 +751,6 @@ config SENSORS_LTC4261 This driver can also be built as a module. If so, the module will be called ltc4261. -config SENSORS_LM95234 - tristate "National Semiconductor LM95234" - depends on I2C - help - If you say yes here you get support for the LM95234 temperature - sensor. - - This driver can also be built as a module. If so, the module - will be called lm95234. - config SENSORS_LM95241 tristate "National Semiconductor LM95241 and compatibles" depends on I2C @@ -907,22 +877,8 @@ config SENSORS_MCP3021 This driver can also be built as a module. If so, the module will be called mcp3021. -config SENSORS_NCT6775 - tristate "Nuvoton NCT6775F and compatibles" - depends on !PPC - select HWMON_VID - help - If you say yes here you get support for the hardware monitoring - functionality of the Nuvoton NCT6775F, NCT6776F, NCT6779D - and compatible Super-I/O chips. This driver replaces the - w83627ehf driver for NCT6775F and NCT6776F. - - This driver can also be built as a module. If so, the module - will be called nct6775. - config SENSORS_NTC_THERMISTOR tristate "NTC thermistor support" - depends on (!OF && !IIO) || (OF && IIO) help This driver supports NTC thermistors sensor reading and its interpretation. The driver can also monitor the temperature and @@ -1248,8 +1204,8 @@ config SENSORS_TMP401 tristate "Texas Instruments TMP401 and compatibles" depends on I2C help - If you say yes here you get support for Texas Instruments TMP401, - TMP411, TMP431, and TMP432 temperature sensor chips. + If you say yes here you get support for Texas Instruments TMP401 and + TMP411 temperature sensor chips. This driver can also be built as a module. If so, the module will be called tmp401. diff --git a/trunk/drivers/hwmon/Makefile b/trunk/drivers/hwmon/Makefile index 5c71fe6a9c79..8d6d97ea7c1e 100644 --- a/trunk/drivers/hwmon/Makefile +++ b/trunk/drivers/hwmon/Makefile @@ -34,8 +34,6 @@ obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o -obj-$(CONFIG_SENSORS_ADT7X10) += adt7x10.o -obj-$(CONFIG_SENSORS_ADT7310) += adt7310.o obj-$(CONFIG_SENSORS_ADT7410) += adt7410.o obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o @@ -88,7 +86,6 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_LM92) += lm92.o obj-$(CONFIG_SENSORS_LM93) += lm93.o -obj-$(CONFIG_SENSORS_LM95234) += lm95234.o obj-$(CONFIG_SENSORS_LM95241) += lm95241.o obj-$(CONFIG_SENSORS_LM95245) += lm95245.o obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o @@ -106,7 +103,6 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o obj-$(CONFIG_SENSORS_MAX6697) += max6697.o obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o -obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_PC87427) += pc87427.o diff --git a/trunk/drivers/hwmon/abituguru.c b/trunk/drivers/hwmon/abituguru.c index df0b69987914..6119ff8e8c87 100644 --- a/trunk/drivers/hwmon/abituguru.c +++ b/trunk/drivers/hwmon/abituguru.c @@ -96,12 +96,9 @@ #define ABIT_UGURU_MAX_TIMEOUTS 2 /* utility macros */ #define ABIT_UGURU_NAME "abituguru" -#define ABIT_UGURU_DEBUG(level, format, arg...) \ - do { \ - if (level <= verbose) \ - pr_debug(format , ## arg); \ - } while (0) - +#define ABIT_UGURU_DEBUG(level, format, arg...) \ + if (level <= verbose) \ + printk(KERN_DEBUG ABIT_UGURU_NAME ": " format , ## arg) /* Macros to help calculate the sysfs_names array length */ /* * sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, @@ -1536,7 +1533,7 @@ static int abituguru_resume(struct device *dev) } static SIMPLE_DEV_PM_OPS(abituguru_pm, abituguru_suspend, abituguru_resume); -#define ABIT_UGURU_PM (&abituguru_pm) +#define ABIT_UGURU_PM &abituguru_pm #else #define ABIT_UGURU_PM NULL #endif /* CONFIG_PM */ diff --git a/trunk/drivers/hwmon/abituguru3.c b/trunk/drivers/hwmon/abituguru3.c index 1d2da31c27c6..205327d33c4d 100644 --- a/trunk/drivers/hwmon/abituguru3.c +++ b/trunk/drivers/hwmon/abituguru3.c @@ -76,11 +76,9 @@ #define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT 5 /* utility macros */ #define ABIT_UGURU3_NAME "abituguru3" -#define ABIT_UGURU3_DEBUG(format, arg...) \ - do { \ - if (verbose) \ - pr_debug(format , ## arg); \ - } while (0) +#define ABIT_UGURU3_DEBUG(format, arg...) \ + if (verbose) \ + printk(KERN_DEBUG ABIT_UGURU3_NAME ": " format , ## arg) /* Macros to help calculate the sysfs_names array length */ #define ABIT_UGURU3_MAX_NO_SENSORS 26 @@ -1161,7 +1159,7 @@ static int abituguru3_resume(struct device *dev) } static SIMPLE_DEV_PM_OPS(abituguru3_pm, abituguru3_suspend, abituguru3_resume); -#define ABIT_UGURU3_PM (&abituguru3_pm) +#define ABIT_UGURU3_PM &abituguru3_pm #else #define ABIT_UGURU3_PM NULL #endif /* CONFIG_PM */ diff --git a/trunk/drivers/hwmon/ad7314.c b/trunk/drivers/hwmon/ad7314.c index f4f9b219bf16..a57584d28a40 100644 --- a/trunk/drivers/hwmon/ad7314.c +++ b/trunk/drivers/hwmon/ad7314.c @@ -116,7 +116,7 @@ static int ad7314_probe(struct spi_device *spi_dev) if (chip == NULL) return -ENOMEM; - spi_set_drvdata(spi_dev, chip); + dev_set_drvdata(&spi_dev->dev, chip); ret = sysfs_create_group(&spi_dev->dev.kobj, &ad7314_group); if (ret < 0) @@ -137,7 +137,7 @@ static int ad7314_probe(struct spi_device *spi_dev) static int ad7314_remove(struct spi_device *spi_dev) { - struct ad7314_data *chip = spi_get_drvdata(spi_dev); + struct ad7314_data *chip = dev_get_drvdata(&spi_dev->dev); hwmon_device_unregister(chip->hwmon_dev); sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group); @@ -166,5 +166,6 @@ static struct spi_driver ad7314_driver = { module_spi_driver(ad7314_driver); MODULE_AUTHOR("Sonic Zhang "); -MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital temperature sensor driver"); +MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital" + " temperature sensor driver"); MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/hwmon/adm1021.c b/trunk/drivers/hwmon/adm1021.c index 7e76922a4ba9..71bcba8abfc0 100644 --- a/trunk/drivers/hwmon/adm1021.c +++ b/trunk/drivers/hwmon/adm1021.c @@ -312,7 +312,8 @@ static int adm1021_detect(struct i2c_client *client, int conv_rate, status, config, man_id, dev_id; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - pr_debug("detect failed, smbus byte data not supported!\n"); + pr_debug("adm1021: detect failed, " + "smbus byte data not supported!\n"); return -ENODEV; } @@ -323,7 +324,7 @@ static int adm1021_detect(struct i2c_client *client, /* Check unused bits */ if ((status & 0x03) || (config & 0x3F) || (conv_rate & 0xF8)) { - pr_debug("detect failed, chip not detected!\n"); + pr_debug("adm1021: detect failed, chip not detected!\n"); return -ENODEV; } @@ -352,7 +353,7 @@ static int adm1021_detect(struct i2c_client *client, else type_name = "max1617"; - pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n", + pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n", type_name, i2c_adapter_id(adapter), client->addr); strlcpy(info->type, type_name, I2C_NAME_SIZE); @@ -367,8 +368,10 @@ static int adm1021_probe(struct i2c_client *client, data = devm_kzalloc(&client->dev, sizeof(struct adm1021_data), GFP_KERNEL); - if (!data) + if (!data) { + pr_debug("adm1021: detect failed, devm_kzalloc failed!\n"); return -ENOMEM; + } i2c_set_clientdata(client, data); data->type = id->driver_data; diff --git a/trunk/drivers/hwmon/adm1026.c b/trunk/drivers/hwmon/adm1026.c index 3a6d9ef1c16c..ea09046e651d 100644 --- a/trunk/drivers/hwmon/adm1026.c +++ b/trunk/drivers/hwmon/adm1026.c @@ -49,14 +49,14 @@ static int gpio_fan[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; module_param_array(gpio_input, int, NULL, 0); MODULE_PARM_DESC(gpio_input, "List of GPIO pins (0-16) to program as inputs"); module_param_array(gpio_output, int, NULL, 0); -MODULE_PARM_DESC(gpio_output, - "List of GPIO pins (0-16) to program as outputs"); +MODULE_PARM_DESC(gpio_output, "List of GPIO pins (0-16) to program as " + "outputs"); module_param_array(gpio_inverted, int, NULL, 0); -MODULE_PARM_DESC(gpio_inverted, - "List of GPIO pins (0-16) to program as inverted"); +MODULE_PARM_DESC(gpio_inverted, "List of GPIO pins (0-16) to program as " + "inverted"); module_param_array(gpio_normal, int, NULL, 0); -MODULE_PARM_DESC(gpio_normal, - "List of GPIO pins (0-16) to program as normal/non-inverted"); +MODULE_PARM_DESC(gpio_normal, "List of GPIO pins (0-16) to program as " + "normal/non-inverted"); module_param_array(gpio_fan, int, NULL, 0); MODULE_PARM_DESC(gpio_fan, "List of GPIO pins (0-7) to program as fan tachs"); @@ -372,31 +372,31 @@ static void adm1026_init_client(struct i2c_client *client) dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n", data->config1); if ((data->config1 & CFG1_MONITOR) == 0) { - dev_dbg(&client->dev, - "Monitoring not currently enabled.\n"); + dev_dbg(&client->dev, "Monitoring not currently " + "enabled.\n"); } if (data->config1 & CFG1_INT_ENABLE) { - dev_dbg(&client->dev, - "SMBALERT interrupts are enabled.\n"); + dev_dbg(&client->dev, "SMBALERT interrupts are " + "enabled.\n"); } if (data->config1 & CFG1_AIN8_9) { - dev_dbg(&client->dev, - "in8 and in9 enabled. temp3 disabled.\n"); + dev_dbg(&client->dev, "in8 and in9 enabled. " + "temp3 disabled.\n"); } else { - dev_dbg(&client->dev, - "temp3 enabled. in8 and in9 disabled.\n"); + dev_dbg(&client->dev, "temp3 enabled. in8 and " + "in9 disabled.\n"); } if (data->config1 & CFG1_THERM_HOT) { - dev_dbg(&client->dev, - "Automatic THERM, PWM, and temp limits enabled.\n"); + dev_dbg(&client->dev, "Automatic THERM, PWM, " + "and temp limits enabled.\n"); } if (data->config3 & CFG3_GPIO16_ENABLE) { - dev_dbg(&client->dev, - "GPIO16 enabled. THERM pin disabled.\n"); + dev_dbg(&client->dev, "GPIO16 enabled. THERM " + "pin disabled.\n"); } else { - dev_dbg(&client->dev, - "THERM pin enabled. GPIO16 disabled.\n"); + dev_dbg(&client->dev, "THERM pin enabled. " + "GPIO16 disabled.\n"); } if (data->config3 & CFG3_VREF_250) dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); @@ -1798,8 +1798,8 @@ static int adm1026_detect(struct i2c_client *client, company = adm1026_read_value(client, ADM1026_REG_COMPANY); verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP); - dev_dbg(&adapter->dev, - "Detecting device at %d,0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n", + dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with" + " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", i2c_adapter_id(client->adapter), client->addr, company, verstep); @@ -1811,12 +1811,11 @@ static int adm1026_detect(struct i2c_client *client, /* Analog Devices ADM1026 */ } else if (company == ADM1026_COMPANY_ANALOG_DEV && (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { - dev_err(&adapter->dev, - "Unrecognized stepping 0x%02x. Defaulting to ADM1026.\n", - verstep); + dev_err(&adapter->dev, "Unrecognized stepping " + "0x%02x. Defaulting to ADM1026.\n", verstep); } else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) { - dev_err(&adapter->dev, - "Found version/stepping 0x%02x. Assuming generic ADM1026.\n", + dev_err(&adapter->dev, "Found version/stepping " + "0x%02x. Assuming generic ADM1026.\n", verstep); } else { dev_dbg(&adapter->dev, "Autodetection failed\n"); diff --git a/trunk/drivers/hwmon/adm1029.c b/trunk/drivers/hwmon/adm1029.c index 9ee5e066423b..97f4718382f6 100644 --- a/trunk/drivers/hwmon/adm1029.c +++ b/trunk/drivers/hwmon/adm1029.c @@ -224,9 +224,8 @@ static ssize_t set_fan_div(struct device *dev, break; default: mutex_unlock(&data->update_lock); - dev_err(&client->dev, - "fan_div value %ld not supported. Choose one of 1, 2 or 4!\n", - val); + dev_err(&client->dev, "fan_div value %ld not " + "supported. Choose one of 1, 2 or 4!\n", val); return -EINVAL; } /* Update the value */ @@ -327,8 +326,8 @@ static int adm1029_detect(struct i2c_client *client, * There are no "official" CHIP ID, so actually * we use Major/Minor revision for that */ - pr_info("Unknown major revision %x, please let us know\n", - chip_id); + pr_info("adm1029: Unknown major revision %x, " + "please let us know\n", chip_id); return -ENODEV; } diff --git a/trunk/drivers/hwmon/adm9240.c b/trunk/drivers/hwmon/adm9240.c index 086d02a9ecdc..2416628e0ab1 100644 --- a/trunk/drivers/hwmon/adm9240.c +++ b/trunk/drivers/hwmon/adm9240.c @@ -351,9 +351,8 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr, reg &= ~(3 << shift); reg |= (fan_div << shift); i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg); - dev_dbg(&client->dev, - "fan%d clock divider changed from %u to %u\n", - nr + 1, 1 << old, 1 << fan_div); + dev_dbg(&client->dev, "fan%d clock divider changed from %u " + "to %u\n", nr + 1, 1 << old, 1 << fan_div); } /* @@ -700,8 +699,8 @@ static void adm9240_init_client(struct i2c_client *client) /* start measurement cycle */ i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1); - dev_info(&client->dev, - "cold start: config was 0x%02x mode %u\n", conf, mode); + dev_info(&client->dev, "cold start: config was 0x%02x " + "mode %u\n", conf, mode); } } diff --git a/trunk/drivers/hwmon/ads7871.c b/trunk/drivers/hwmon/ads7871.c index 3eff73b6220d..a79875986f91 100644 --- a/trunk/drivers/hwmon/ads7871.c +++ b/trunk/drivers/hwmon/ads7871.c @@ -40,25 +40,25 @@ * the instruction byte */ /*Instruction Bit masks*/ -#define INST_MODE_BM (1 << 7) -#define INST_READ_BM (1 << 6) -#define INST_16BIT_BM (1 << 5) +#define INST_MODE_bm (1<<7) +#define INST_READ_bm (1<<6) +#define INST_16BIT_bm (1<<5) /*From figure 18 in the datasheet*/ /*bit masks for Rev/Oscillator Control Register*/ -#define MUX_CNV_BV 7 -#define MUX_CNV_BM (1 << MUX_CNV_BV) -#define MUX_M3_BM (1 << 3) /*M3 selects single ended*/ -#define MUX_G_BV 4 /*allows for reg = (gain << MUX_G_BV) | ...*/ +#define MUX_CNV_bv 7 +#define MUX_CNV_bm (1< #include @@ -79,7 +79,7 @@ struct ads7871_data { static int ads7871_read_reg8(struct spi_device *spi, int reg) { int ret; - reg = reg | INST_READ_BM; + reg = reg | INST_READ_bm; ret = spi_w8r8(spi, reg); return ret; } @@ -87,7 +87,7 @@ static int ads7871_read_reg8(struct spi_device *spi, int reg) static int ads7871_read_reg16(struct spi_device *spi, int reg) { int ret; - reg = reg | INST_READ_BM | INST_16BIT_BM; + reg = reg | INST_READ_bm | INST_16BIT_bm; ret = spi_w8r16(spi, reg); return ret; } @@ -111,13 +111,13 @@ static ssize_t show_voltage(struct device *dev, * TODO: add support for conversions * other than single ended with a gain of 1 */ - /*MUX_M3_BM forces single ended*/ + /*MUX_M3_bm forces single ended*/ /*This is also where the gain of the PGA would be set*/ ads7871_write_reg8(spi, REG_GAIN_MUX, - (MUX_CNV_BM | MUX_M3_BM | channel)); + (MUX_CNV_bm | MUX_M3_bm | channel)); ret = ads7871_read_reg8(spi, REG_GAIN_MUX); - mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV); + mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv); /* * on 400MHz arm9 platform the conversion * is already done when we do this test @@ -125,14 +125,14 @@ static ssize_t show_voltage(struct device *dev, while ((i < 2) && mux_cnv) { i++; ret = ads7871_read_reg8(spi, REG_GAIN_MUX); - mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV); + mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv); msleep_interruptible(1); } if (mux_cnv == 0) { val = ads7871_read_reg16(spi, REG_LS_BYTE); /*result in volts*10000 = (val/8192)*2.5*10000*/ - val = ((val >> 2) * 25000) / 8192; + val = ((val>>2) * 25000) / 8192; return sprintf(buf, "%d\n", val); } else { return -1; @@ -189,7 +189,7 @@ static int ads7871_probe(struct spi_device *spi) ads7871_write_reg8(spi, REG_SER_CONTROL, 0); ads7871_write_reg8(spi, REG_AD_CONTROL, 0); - val = (OSC_OSCR_BM | OSC_OSCE_BM | OSC_REFE_BM | OSC_BUFE_BM); + val = (OSC_OSCR_bm | OSC_OSCE_bm | OSC_REFE_bm | OSC_BUFE_bm); ads7871_write_reg8(spi, REG_OSC_CONTROL, val); ret = ads7871_read_reg8(spi, REG_OSC_CONTROL); diff --git a/trunk/drivers/hwmon/adt7310.c b/trunk/drivers/hwmon/adt7310.c deleted file mode 100644 index da5f0789fb97..000000000000 --- a/trunk/drivers/hwmon/adt7310.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * ADT7310/ADT7310 digital temperature sensor driver - * - * Copyright 2012-2013 Analog Devices Inc. - * Author: Lars-Peter Clausen - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include - -#include "adt7x10.h" - -#define ADT7310_STATUS 0 -#define ADT7310_CONFIG 1 -#define ADT7310_TEMPERATURE 2 -#define ADT7310_ID 3 -#define ADT7310_T_CRIT 4 -#define ADT7310_T_HYST 5 -#define ADT7310_T_ALARM_HIGH 6 -#define ADT7310_T_ALARM_LOW 7 - -static const u8 adt7310_reg_table[] = { - [ADT7X10_TEMPERATURE] = ADT7310_TEMPERATURE, - [ADT7X10_STATUS] = ADT7310_STATUS, - [ADT7X10_CONFIG] = ADT7310_CONFIG, - [ADT7X10_T_ALARM_HIGH] = ADT7310_T_ALARM_HIGH, - [ADT7X10_T_ALARM_LOW] = ADT7310_T_ALARM_LOW, - [ADT7X10_T_CRIT] = ADT7310_T_CRIT, - [ADT7X10_T_HYST] = ADT7310_T_HYST, - [ADT7X10_ID] = ADT7310_ID, -}; - -#define ADT7310_CMD_REG_OFFSET 3 -#define ADT7310_CMD_READ 0x40 - -#define AD7310_COMMAND(reg) (adt7310_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET) - -static int adt7310_spi_read_word(struct device *dev, u8 reg) -{ - struct spi_device *spi = to_spi_device(dev); - int ret; - - ret = spi_w8r16(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ); - if (ret < 0) - return ret; - - return be16_to_cpu((__force __be16)ret); -} - -static int adt7310_spi_write_word(struct device *dev, u8 reg, u16 data) -{ - struct spi_device *spi = to_spi_device(dev); - u8 buf[3]; - - buf[0] = AD7310_COMMAND(reg); - put_unaligned_be16(data, &buf[1]); - - return spi_write(spi, buf, sizeof(buf)); -} - -static int adt7310_spi_read_byte(struct device *dev, u8 reg) -{ - struct spi_device *spi = to_spi_device(dev); - - return spi_w8r8(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ); -} - -static int adt7310_spi_write_byte(struct device *dev, u8 reg, - u8 data) -{ - struct spi_device *spi = to_spi_device(dev); - u8 buf[2]; - - buf[0] = AD7310_COMMAND(reg); - buf[1] = data; - - return spi_write(spi, buf, sizeof(buf)); -} - -static const struct adt7x10_ops adt7310_spi_ops = { - .read_word = adt7310_spi_read_word, - .write_word = adt7310_spi_write_word, - .read_byte = adt7310_spi_read_byte, - .write_byte = adt7310_spi_write_byte, -}; - -static int adt7310_spi_probe(struct spi_device *spi) -{ - return adt7x10_probe(&spi->dev, spi_get_device_id(spi)->name, spi->irq, - &adt7310_spi_ops); -} - -static int adt7310_spi_remove(struct spi_device *spi) -{ - return adt7x10_remove(&spi->dev, spi->irq); -} - -static const struct spi_device_id adt7310_id[] = { - { "adt7310", 0 }, - { "adt7320", 0 }, - {} -}; -MODULE_DEVICE_TABLE(spi, adt7310_id); - -static struct spi_driver adt7310_driver = { - .driver = { - .name = "adt7310", - .owner = THIS_MODULE, - .pm = ADT7X10_DEV_PM_OPS, - }, - .probe = adt7310_spi_probe, - .remove = adt7310_spi_remove, - .id_table = adt7310_id, -}; -module_spi_driver(adt7310_driver); - -MODULE_AUTHOR("Lars-Peter Clausen "); -MODULE_DESCRIPTION("ADT7310/ADT7320 driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/adt7410.c b/trunk/drivers/hwmon/adt7410.c index 0dc066a939b4..99a7290da0a3 100644 --- a/trunk/drivers/hwmon/adt7410.c +++ b/trunk/drivers/hwmon/adt7410.c @@ -1,80 +1,460 @@ /* - * ADT7410/ADT7420 digital temperature sensor driver + * adt7410.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * This driver handles the ADT7410 and compatible digital temperature sensors. + * Hartmut Knaack 2012-07-22 + * based on lm75.c by Frodo Looijaard + * and adt7410.c from iio-staging by Sonic Zhang * - * Copyright 2012-2013 Analog Devices Inc. - * Author: Lars-Peter Clausen + * 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. * - * Licensed under the GPL-2 or later. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include +#include +#include #include +#include +#include +#include +#include +#include + +/* + * ADT7410 registers definition + */ + +#define ADT7410_TEMPERATURE 0 +#define ADT7410_STATUS 2 +#define ADT7410_CONFIG 3 +#define ADT7410_T_ALARM_HIGH 4 +#define ADT7410_T_ALARM_LOW 6 +#define ADT7410_T_CRIT 8 +#define ADT7410_T_HYST 0xA + +/* + * ADT7410 status + */ +#define ADT7410_STAT_T_LOW (1 << 4) +#define ADT7410_STAT_T_HIGH (1 << 5) +#define ADT7410_STAT_T_CRIT (1 << 6) +#define ADT7410_STAT_NOT_RDY (1 << 7) + +/* + * ADT7410 config + */ +#define ADT7410_FAULT_QUEUE_MASK (1 << 0 | 1 << 1) +#define ADT7410_CT_POLARITY (1 << 2) +#define ADT7410_INT_POLARITY (1 << 3) +#define ADT7410_EVENT_MODE (1 << 4) +#define ADT7410_MODE_MASK (1 << 5 | 1 << 6) +#define ADT7410_FULL (0 << 5 | 0 << 6) +#define ADT7410_PD (1 << 5 | 1 << 6) +#define ADT7410_RESOLUTION (1 << 7) + +/* + * ADT7410 masks + */ +#define ADT7410_T13_VALUE_MASK 0xFFF8 +#define ADT7410_T_HYST_MASK 0xF + +/* straight from the datasheet */ +#define ADT7410_TEMP_MIN (-55000) +#define ADT7410_TEMP_MAX 150000 + +enum adt7410_type { /* keep sorted in alphabetical order */ + adt7410, +}; + +static const u8 ADT7410_REG_TEMP[4] = { + ADT7410_TEMPERATURE, /* input */ + ADT7410_T_ALARM_HIGH, /* high */ + ADT7410_T_ALARM_LOW, /* low */ + ADT7410_T_CRIT, /* critical */ +}; + +/* Each client has this additional data */ +struct adt7410_data { + struct device *hwmon_dev; + struct mutex update_lock; + u8 config; + u8 oldconfig; + bool valid; /* true if registers valid */ + unsigned long last_updated; /* In jiffies */ + s16 temp[4]; /* Register values, + 0 = input + 1 = high + 2 = low + 3 = critical */ + u8 hyst; /* hysteresis offset */ +}; + +/* + * adt7410 register access by I2C + */ +static int adt7410_temp_ready(struct i2c_client *client) +{ + int i, status; + + for (i = 0; i < 6; i++) { + status = i2c_smbus_read_byte_data(client, ADT7410_STATUS); + if (status < 0) + return status; + if (!(status & ADT7410_STAT_NOT_RDY)) + return 0; + msleep(60); + } + return -ETIMEDOUT; +} + +static struct adt7410_data *adt7410_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + struct adt7410_data *ret = data; + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; -#include "adt7x10.h" + dev_dbg(&client->dev, "Starting update\n"); -static int adt7410_i2c_read_word(struct device *dev, u8 reg) + status = adt7410_temp_ready(client); /* check for new value */ + if (unlikely(status)) { + ret = ERR_PTR(status); + goto abort; + } + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + status = i2c_smbus_read_word_swapped(client, + ADT7410_REG_TEMP[i]); + if (unlikely(status < 0)) { + dev_dbg(dev, + "Failed to read value: reg %d, error %d\n", + ADT7410_REG_TEMP[i], status); + ret = ERR_PTR(status); + goto abort; + } + data->temp[i] = status; + } + status = i2c_smbus_read_byte_data(client, ADT7410_T_HYST); + if (unlikely(status < 0)) { + dev_dbg(dev, + "Failed to read value: reg %d, error %d\n", + ADT7410_T_HYST, status); + ret = ERR_PTR(status); + goto abort; + } + data->hyst = status; + data->last_updated = jiffies; + data->valid = true; + } + +abort: + mutex_unlock(&data->update_lock); + return ret; +} + +static s16 ADT7410_TEMP_TO_REG(long temp) { - return i2c_smbus_read_word_swapped(to_i2c_client(dev), reg); + return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7410_TEMP_MIN, + ADT7410_TEMP_MAX) * 128, 1000); } -static int adt7410_i2c_write_word(struct device *dev, u8 reg, u16 data) +static int ADT7410_REG_TO_TEMP(struct adt7410_data *data, s16 reg) { - return i2c_smbus_write_word_swapped(to_i2c_client(dev), reg, data); + /* in 13 bit mode, bits 0-2 are status flags - mask them out */ + if (!(data->config & ADT7410_RESOLUTION)) + reg &= ADT7410_T13_VALUE_MASK; + /* + * temperature is stored in twos complement format, in steps of + * 1/128°C + */ + return DIV_ROUND_CLOSEST(reg * 1000, 128); } -static int adt7410_i2c_read_byte(struct device *dev, u8 reg) +/*-----------------------------------------------------------------------*/ + +/* sysfs attributes for hwmon */ + +static ssize_t adt7410_show_temp(struct device *dev, + struct device_attribute *da, char *buf) { - return i2c_smbus_read_byte_data(to_i2c_client(dev), reg); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct adt7410_data *data = adt7410_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data, + data->temp[attr->index])); } -static int adt7410_i2c_write_byte(struct device *dev, u8 reg, u8 data) +static ssize_t adt7410_set_temp(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) { - return i2c_smbus_write_byte_data(to_i2c_client(dev), reg, data); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + int nr = attr->index; + long temp; + int ret; + + ret = kstrtol(buf, 10, &temp); + if (ret) + return ret; + + mutex_lock(&data->update_lock); + data->temp[nr] = ADT7410_TEMP_TO_REG(temp); + ret = i2c_smbus_write_word_swapped(client, ADT7410_REG_TEMP[nr], + data->temp[nr]); + if (ret) + count = ret; + mutex_unlock(&data->update_lock); + return count; } -static const struct adt7x10_ops adt7410_i2c_ops = { - .read_word = adt7410_i2c_read_word, - .write_word = adt7410_i2c_write_word, - .read_byte = adt7410_i2c_read_byte, - .write_byte = adt7410_i2c_write_byte, +static ssize_t adt7410_show_t_hyst(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct adt7410_data *data; + int nr = attr->index; + int hyst; + + data = adt7410_update_device(dev); + if (IS_ERR(data)) + return PTR_ERR(data); + hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000; + + /* + * hysteresis is stored as a 4 bit offset in the device, convert it + * to an absolute value + */ + if (nr == 2) /* min has positive offset, others have negative */ + hyst = -hyst; + return sprintf(buf, "%d\n", + ADT7410_REG_TO_TEMP(data, data->temp[nr]) - hyst); +} + +static ssize_t adt7410_set_t_hyst(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + int limit, ret; + long hyst; + + ret = kstrtol(buf, 10, &hyst); + if (ret) + return ret; + /* convert absolute hysteresis value to a 4 bit delta value */ + limit = ADT7410_REG_TO_TEMP(data, data->temp[1]); + hyst = clamp_val(hyst, ADT7410_TEMP_MIN, ADT7410_TEMP_MAX); + data->hyst = clamp_val(DIV_ROUND_CLOSEST(limit - hyst, 1000), 0, + ADT7410_T_HYST_MASK); + ret = i2c_smbus_write_byte_data(client, ADT7410_T_HYST, data->hyst); + if (ret) + return ret; + + return count; +} + +static ssize_t adt7410_show_alarm(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int ret; + + ret = i2c_smbus_read_byte_data(client, ADT7410_STATUS); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", !!(ret & attr->index)); +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, adt7410_show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, + adt7410_show_temp, adt7410_set_temp, 1); +static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, + adt7410_show_temp, adt7410_set_temp, 2); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, + adt7410_show_temp, adt7410_set_temp, 3); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, + adt7410_show_t_hyst, adt7410_set_t_hyst, 1); +static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO, + adt7410_show_t_hyst, NULL, 2); +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, + adt7410_show_t_hyst, NULL, 3); +static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, adt7410_show_alarm, + NULL, ADT7410_STAT_T_LOW); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, adt7410_show_alarm, + NULL, ADT7410_STAT_T_HIGH); +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, adt7410_show_alarm, + NULL, ADT7410_STAT_T_CRIT); + +static struct attribute *adt7410_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + NULL }; -static int adt7410_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct attribute_group adt7410_group = { + .attrs = adt7410_attributes, +}; + +/*-----------------------------------------------------------------------*/ + +/* device probe and removal */ + +static int adt7410_probe(struct i2c_client *client, + const struct i2c_device_id *id) { + struct adt7410_data *data; + int ret; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) return -ENODEV; - return adt7x10_probe(&client->dev, NULL, client->irq, &adt7410_i2c_ops); + data = devm_kzalloc(&client->dev, sizeof(struct adt7410_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* configure as specified */ + ret = i2c_smbus_read_byte_data(client, ADT7410_CONFIG); + if (ret < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", ret); + return ret; + } + data->oldconfig = ret; + /* + * Set to 16 bit resolution, continous conversion and comparator mode. + */ + ret &= ~ADT7410_MODE_MASK; + data->config = ret | ADT7410_FULL | ADT7410_RESOLUTION | + ADT7410_EVENT_MODE; + if (data->config != data->oldconfig) { + ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, + data->config); + if (ret) + return ret; + } + dev_dbg(&client->dev, "Config %02x\n", data->config); + + /* Register sysfs hooks */ + ret = sysfs_create_group(&client->dev.kobj, &adt7410_group); + if (ret) + goto exit_restore; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "sensor '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &adt7410_group); +exit_restore: + i2c_smbus_write_byte_data(client, ADT7410_CONFIG, data->oldconfig); + return ret; } -static int adt7410_i2c_remove(struct i2c_client *client) +static int adt7410_remove(struct i2c_client *client) { - return adt7x10_remove(&client->dev, client->irq); + struct adt7410_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &adt7410_group); + if (data->oldconfig != data->config) + i2c_smbus_write_byte_data(client, ADT7410_CONFIG, + data->oldconfig); + return 0; } static const struct i2c_device_id adt7410_ids[] = { - { "adt7410", 0 }, - { "adt7420", 0 }, - {} + { "adt7410", adt7410, }, + { "adt7420", adt7410, }, + { /* LIST END */ } }; MODULE_DEVICE_TABLE(i2c, adt7410_ids); +#ifdef CONFIG_PM_SLEEP +static int adt7410_suspend(struct device *dev) +{ + int ret; + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + + ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, + data->config | ADT7410_PD); + return ret; +} + +static int adt7410_resume(struct device *dev) +{ + int ret; + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + + ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, data->config); + return ret; +} + +static SIMPLE_DEV_PM_OPS(adt7410_dev_pm_ops, adt7410_suspend, adt7410_resume); + +#define ADT7410_DEV_PM_OPS (&adt7410_dev_pm_ops) +#else +#define ADT7410_DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + static struct i2c_driver adt7410_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "adt7410", - .pm = ADT7X10_DEV_PM_OPS, + .pm = ADT7410_DEV_PM_OPS, }, - .probe = adt7410_i2c_probe, - .remove = adt7410_i2c_remove, + .probe = adt7410_probe, + .remove = adt7410_remove, .id_table = adt7410_ids, .address_list = I2C_ADDRS(0x48, 0x49, 0x4a, 0x4b), }; + module_i2c_driver(adt7410_driver); -MODULE_AUTHOR("Lars-Peter Clausen "); -MODULE_DESCRIPTION("ADT7410/AD7420 driver"); +MODULE_AUTHOR("Hartmut Knaack"); +MODULE_DESCRIPTION("ADT7410/ADT7420 driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/adt7411.c b/trunk/drivers/hwmon/adt7411.c index d9299dee37d1..34ff03abb50b 100644 --- a/trunk/drivers/hwmon/adt7411.c +++ b/trunk/drivers/hwmon/adt7411.c @@ -259,17 +259,15 @@ static int adt7411_detect(struct i2c_client *client, val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID); if (val < 0 || val != ADT7411_MANUFACTURER_ID) { - dev_dbg(&client->dev, - "Wrong manufacturer ID. Got %d, expected %d\n", - val, ADT7411_MANUFACTURER_ID); + dev_dbg(&client->dev, "Wrong manufacturer ID. Got %d, " + "expected %d\n", val, ADT7411_MANUFACTURER_ID); return -ENODEV; } val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID); if (val < 0 || val != ADT7411_DEVICE_ID) { - dev_dbg(&client->dev, - "Wrong device ID. Got %d, expected %d\n", - val, ADT7411_DEVICE_ID); + dev_dbg(&client->dev, "Wrong device ID. Got %d, " + "expected %d\n", val, ADT7411_DEVICE_ID); return -ENODEV; } diff --git a/trunk/drivers/hwmon/adt7x10.c b/trunk/drivers/hwmon/adt7x10.c deleted file mode 100644 index 98141f483165..000000000000 --- a/trunk/drivers/hwmon/adt7x10.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * adt7x10.c - Part of lm_sensors, Linux kernel modules for hardware - * monitoring - * This driver handles the ADT7410 and compatible digital temperature sensors. - * Hartmut Knaack 2012-07-22 - * based on lm75.c by Frodo Looijaard - * and adt7410.c from iio-staging by Sonic Zhang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "adt7x10.h" - -/* - * ADT7X10 status - */ -#define ADT7X10_STAT_T_LOW (1 << 4) -#define ADT7X10_STAT_T_HIGH (1 << 5) -#define ADT7X10_STAT_T_CRIT (1 << 6) -#define ADT7X10_STAT_NOT_RDY (1 << 7) - -/* - * ADT7X10 config - */ -#define ADT7X10_FAULT_QUEUE_MASK (1 << 0 | 1 << 1) -#define ADT7X10_CT_POLARITY (1 << 2) -#define ADT7X10_INT_POLARITY (1 << 3) -#define ADT7X10_EVENT_MODE (1 << 4) -#define ADT7X10_MODE_MASK (1 << 5 | 1 << 6) -#define ADT7X10_FULL (0 << 5 | 0 << 6) -#define ADT7X10_PD (1 << 5 | 1 << 6) -#define ADT7X10_RESOLUTION (1 << 7) - -/* - * ADT7X10 masks - */ -#define ADT7X10_T13_VALUE_MASK 0xFFF8 -#define ADT7X10_T_HYST_MASK 0xF - -/* straight from the datasheet */ -#define ADT7X10_TEMP_MIN (-55000) -#define ADT7X10_TEMP_MAX 150000 - -/* Each client has this additional data */ -struct adt7x10_data { - const struct adt7x10_ops *ops; - const char *name; - struct device *hwmon_dev; - struct mutex update_lock; - u8 config; - u8 oldconfig; - bool valid; /* true if registers valid */ - unsigned long last_updated; /* In jiffies */ - s16 temp[4]; /* Register values, - 0 = input - 1 = high - 2 = low - 3 = critical */ - u8 hyst; /* hysteresis offset */ -}; - -static int adt7x10_read_byte(struct device *dev, u8 reg) -{ - struct adt7x10_data *d = dev_get_drvdata(dev); - return d->ops->read_byte(dev, reg); -} - -static int adt7x10_write_byte(struct device *dev, u8 reg, u8 data) -{ - struct adt7x10_data *d = dev_get_drvdata(dev); - return d->ops->write_byte(dev, reg, data); -} - -static int adt7x10_read_word(struct device *dev, u8 reg) -{ - struct adt7x10_data *d = dev_get_drvdata(dev); - return d->ops->read_word(dev, reg); -} - -static int adt7x10_write_word(struct device *dev, u8 reg, u16 data) -{ - struct adt7x10_data *d = dev_get_drvdata(dev); - return d->ops->write_word(dev, reg, data); -} - -static const u8 ADT7X10_REG_TEMP[4] = { - ADT7X10_TEMPERATURE, /* input */ - ADT7X10_T_ALARM_HIGH, /* high */ - ADT7X10_T_ALARM_LOW, /* low */ - ADT7X10_T_CRIT, /* critical */ -}; - -static irqreturn_t adt7x10_irq_handler(int irq, void *private) -{ - struct device *dev = private; - int status; - - status = adt7x10_read_byte(dev, ADT7X10_STATUS); - if (status < 0) - return IRQ_HANDLED; - - if (status & ADT7X10_STAT_T_HIGH) - sysfs_notify(&dev->kobj, NULL, "temp1_max_alarm"); - if (status & ADT7X10_STAT_T_LOW) - sysfs_notify(&dev->kobj, NULL, "temp1_min_alarm"); - if (status & ADT7X10_STAT_T_CRIT) - sysfs_notify(&dev->kobj, NULL, "temp1_crit_alarm"); - - return IRQ_HANDLED; -} - -static int adt7x10_temp_ready(struct device *dev) -{ - int i, status; - - for (i = 0; i < 6; i++) { - status = adt7x10_read_byte(dev, ADT7X10_STATUS); - if (status < 0) - return status; - if (!(status & ADT7X10_STAT_NOT_RDY)) - return 0; - msleep(60); - } - return -ETIMEDOUT; -} - -static int adt7x10_update_temp(struct device *dev) -{ - struct adt7x10_data *data = dev_get_drvdata(dev); - int ret = 0; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int temp; - - dev_dbg(dev, "Starting update\n"); - - ret = adt7x10_temp_ready(dev); /* check for new value */ - if (ret) - goto abort; - - temp = adt7x10_read_word(dev, ADT7X10_REG_TEMP[0]); - if (temp < 0) { - ret = temp; - dev_dbg(dev, "Failed to read value: reg %d, error %d\n", - ADT7X10_REG_TEMP[0], ret); - goto abort; - } - data->temp[0] = temp; - data->last_updated = jiffies; - data->valid = true; - } - -abort: - mutex_unlock(&data->update_lock); - return ret; -} - -static int adt7x10_fill_cache(struct device *dev) -{ - struct adt7x10_data *data = dev_get_drvdata(dev); - int ret; - int i; - - for (i = 1; i < ARRAY_SIZE(data->temp); i++) { - ret = adt7x10_read_word(dev, ADT7X10_REG_TEMP[i]); - if (ret < 0) { - dev_dbg(dev, "Failed to read value: reg %d, error %d\n", - ADT7X10_REG_TEMP[i], ret); - return ret; - } - data->temp[i] = ret; - } - - ret = adt7x10_read_byte(dev, ADT7X10_T_HYST); - if (ret < 0) { - dev_dbg(dev, "Failed to read value: reg %d, error %d\n", - ADT7X10_T_HYST, ret); - return ret; - } - data->hyst = ret; - - return 0; -} - -static s16 ADT7X10_TEMP_TO_REG(long temp) -{ - return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7X10_TEMP_MIN, - ADT7X10_TEMP_MAX) * 128, 1000); -} - -static int ADT7X10_REG_TO_TEMP(struct adt7x10_data *data, s16 reg) -{ - /* in 13 bit mode, bits 0-2 are status flags - mask them out */ - if (!(data->config & ADT7X10_RESOLUTION)) - reg &= ADT7X10_T13_VALUE_MASK; - /* - * temperature is stored in twos complement format, in steps of - * 1/128°C - */ - return DIV_ROUND_CLOSEST(reg * 1000, 128); -} - -/*-----------------------------------------------------------------------*/ - -/* sysfs attributes for hwmon */ - -static ssize_t adt7x10_show_temp(struct device *dev, - struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct adt7x10_data *data = dev_get_drvdata(dev); - - - if (attr->index == 0) { - int ret; - - ret = adt7x10_update_temp(dev); - if (ret) - return ret; - } - - return sprintf(buf, "%d\n", ADT7X10_REG_TO_TEMP(data, - data->temp[attr->index])); -} - -static ssize_t adt7x10_set_temp(struct device *dev, - struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct adt7x10_data *data = dev_get_drvdata(dev); - int nr = attr->index; - long temp; - int ret; - - ret = kstrtol(buf, 10, &temp); - if (ret) - return ret; - - mutex_lock(&data->update_lock); - data->temp[nr] = ADT7X10_TEMP_TO_REG(temp); - ret = adt7x10_write_word(dev, ADT7X10_REG_TEMP[nr], data->temp[nr]); - if (ret) - count = ret; - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t adt7x10_show_t_hyst(struct device *dev, - struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct adt7x10_data *data = dev_get_drvdata(dev); - int nr = attr->index; - int hyst; - - hyst = (data->hyst & ADT7X10_T_HYST_MASK) * 1000; - - /* - * hysteresis is stored as a 4 bit offset in the device, convert it - * to an absolute value - */ - if (nr == 2) /* min has positive offset, others have negative */ - hyst = -hyst; - return sprintf(buf, "%d\n", - ADT7X10_REG_TO_TEMP(data, data->temp[nr]) - hyst); -} - -static ssize_t adt7x10_set_t_hyst(struct device *dev, - struct device_attribute *da, - const char *buf, size_t count) -{ - struct adt7x10_data *data = dev_get_drvdata(dev); - int limit, ret; - long hyst; - - ret = kstrtol(buf, 10, &hyst); - if (ret) - return ret; - /* convert absolute hysteresis value to a 4 bit delta value */ - limit = ADT7X10_REG_TO_TEMP(data, data->temp[1]); - hyst = clamp_val(hyst, ADT7X10_TEMP_MIN, ADT7X10_TEMP_MAX); - data->hyst = clamp_val(DIV_ROUND_CLOSEST(limit - hyst, 1000), - 0, ADT7X10_T_HYST_MASK); - ret = adt7x10_write_byte(dev, ADT7X10_T_HYST, data->hyst); - if (ret) - return ret; - - return count; -} - -static ssize_t adt7x10_show_alarm(struct device *dev, - struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - int ret; - - ret = adt7x10_read_byte(dev, ADT7X10_STATUS); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", !!(ret & attr->index)); -} - -static ssize_t adt7x10_show_name(struct device *dev, - struct device_attribute *da, - char *buf) -{ - struct adt7x10_data *data = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", data->name); -} - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, adt7x10_show_temp, NULL, 0); -static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, - adt7x10_show_temp, adt7x10_set_temp, 1); -static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, - adt7x10_show_temp, adt7x10_set_temp, 2); -static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, - adt7x10_show_temp, adt7x10_set_temp, 3); -static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, - adt7x10_show_t_hyst, adt7x10_set_t_hyst, 1); -static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO, - adt7x10_show_t_hyst, NULL, 2); -static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, - adt7x10_show_t_hyst, NULL, 3); -static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, adt7x10_show_alarm, - NULL, ADT7X10_STAT_T_LOW); -static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, adt7x10_show_alarm, - NULL, ADT7X10_STAT_T_HIGH); -static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, adt7x10_show_alarm, - NULL, ADT7X10_STAT_T_CRIT); -static DEVICE_ATTR(name, S_IRUGO, adt7x10_show_name, NULL); - -static struct attribute *adt7x10_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_min.dev_attr.attr, - &sensor_dev_attr_temp1_crit.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, - NULL -}; - -static const struct attribute_group adt7x10_group = { - .attrs = adt7x10_attributes, -}; - -int adt7x10_probe(struct device *dev, const char *name, int irq, - const struct adt7x10_ops *ops) -{ - struct adt7x10_data *data; - int ret; - - data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->ops = ops; - data->name = name; - - dev_set_drvdata(dev, data); - mutex_init(&data->update_lock); - - /* configure as specified */ - ret = adt7x10_read_byte(dev, ADT7X10_CONFIG); - if (ret < 0) { - dev_dbg(dev, "Can't read config? %d\n", ret); - return ret; - } - data->oldconfig = ret; - - /* - * Set to 16 bit resolution, continous conversion and comparator mode. - */ - data->config = data->oldconfig; - data->config &= ~(ADT7X10_MODE_MASK | ADT7X10_CT_POLARITY | - ADT7X10_INT_POLARITY); - data->config |= ADT7X10_FULL | ADT7X10_RESOLUTION | ADT7X10_EVENT_MODE; - - if (data->config != data->oldconfig) { - ret = adt7x10_write_byte(dev, ADT7X10_CONFIG, data->config); - if (ret) - return ret; - } - dev_dbg(dev, "Config %02x\n", data->config); - - ret = adt7x10_fill_cache(dev); - if (ret) - goto exit_restore; - - /* Register sysfs hooks */ - ret = sysfs_create_group(&dev->kobj, &adt7x10_group); - if (ret) - goto exit_restore; - - /* - * The I2C device will already have it's own 'name' attribute, but for - * the SPI device we need to register it. name will only be non NULL if - * the device doesn't register the 'name' attribute on its own. - */ - if (name) { - ret = device_create_file(dev, &dev_attr_name); - if (ret) - goto exit_remove; - } - - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - ret = PTR_ERR(data->hwmon_dev); - goto exit_remove_name; - } - - if (irq > 0) { - ret = request_threaded_irq(irq, NULL, adt7x10_irq_handler, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - dev_name(dev), dev); - if (ret) - goto exit_hwmon_device_unregister; - } - - return 0; - -exit_hwmon_device_unregister: - hwmon_device_unregister(data->hwmon_dev); -exit_remove_name: - if (name) - device_remove_file(dev, &dev_attr_name); -exit_remove: - sysfs_remove_group(&dev->kobj, &adt7x10_group); -exit_restore: - adt7x10_write_byte(dev, ADT7X10_CONFIG, data->oldconfig); - return ret; -} -EXPORT_SYMBOL_GPL(adt7x10_probe); - -int adt7x10_remove(struct device *dev, int irq) -{ - struct adt7x10_data *data = dev_get_drvdata(dev); - - if (irq > 0) - free_irq(irq, dev); - - hwmon_device_unregister(data->hwmon_dev); - if (data->name) - device_remove_file(dev, &dev_attr_name); - sysfs_remove_group(&dev->kobj, &adt7x10_group); - if (data->oldconfig != data->config) - adt7x10_write_byte(dev, ADT7X10_CONFIG, data->oldconfig); - return 0; -} -EXPORT_SYMBOL_GPL(adt7x10_remove); - -#ifdef CONFIG_PM_SLEEP - -static int adt7x10_suspend(struct device *dev) -{ - struct adt7x10_data *data = dev_get_drvdata(dev); - - return adt7x10_write_byte(dev, ADT7X10_CONFIG, - data->config | ADT7X10_PD); -} - -static int adt7x10_resume(struct device *dev) -{ - struct adt7x10_data *data = dev_get_drvdata(dev); - - return adt7x10_write_byte(dev, ADT7X10_CONFIG, data->config); -} - -SIMPLE_DEV_PM_OPS(adt7x10_dev_pm_ops, adt7x10_suspend, adt7x10_resume); -EXPORT_SYMBOL_GPL(adt7x10_dev_pm_ops); - -#endif /* CONFIG_PM_SLEEP */ - -MODULE_AUTHOR("Hartmut Knaack"); -MODULE_DESCRIPTION("ADT7410/ADT7420, ADT7310/ADT7320 common code"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/adt7x10.h b/trunk/drivers/hwmon/adt7x10.h deleted file mode 100644 index d491c698529e..000000000000 --- a/trunk/drivers/hwmon/adt7x10.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __HWMON_ADT7X10_H__ -#define __HWMON_ADT7X10_H__ - -#include -#include - -/* ADT7410 registers definition */ -#define ADT7X10_TEMPERATURE 0 -#define ADT7X10_STATUS 2 -#define ADT7X10_CONFIG 3 -#define ADT7X10_T_ALARM_HIGH 4 -#define ADT7X10_T_ALARM_LOW 6 -#define ADT7X10_T_CRIT 8 -#define ADT7X10_T_HYST 0xA -#define ADT7X10_ID 0xB - -struct device; - -struct adt7x10_ops { - int (*read_byte)(struct device *, u8 reg); - int (*write_byte)(struct device *, u8 reg, u8 data); - int (*read_word)(struct device *, u8 reg); - int (*write_word)(struct device *, u8 reg, u16 data); -}; - -int adt7x10_probe(struct device *dev, const char *name, int irq, - const struct adt7x10_ops *ops); -int adt7x10_remove(struct device *dev, int irq); - -#ifdef CONFIG_PM_SLEEP -extern const struct dev_pm_ops adt7x10_dev_pm_ops; -#define ADT7X10_DEV_PM_OPS (&adt7x10_dev_pm_ops) -#else -#define ADT7X10_DEV_PM_OPS NULL -#endif - -#endif diff --git a/trunk/drivers/hwmon/applesmc.c b/trunk/drivers/hwmon/applesmc.c index 62c2e32e25ef..b41baffa20f0 100644 --- a/trunk/drivers/hwmon/applesmc.c +++ b/trunk/drivers/hwmon/applesmc.c @@ -922,7 +922,7 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev, ret = queue_work(applesmc_led_wq, &backlight_work); if (debug && (!ret)) - dev_dbg(led_cdev->dev, "work was already on the queue.\n"); + printk(KERN_DEBUG "applesmc: work was already on the queue.\n"); } static ssize_t applesmc_key_count_show(struct device *dev, diff --git a/trunk/drivers/hwmon/asb100.c b/trunk/drivers/hwmon/asb100.c index f96063680e58..6ac612cabda1 100644 --- a/trunk/drivers/hwmon/asb100.c +++ b/trunk/drivers/hwmon/asb100.c @@ -55,8 +55,8 @@ static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); -MODULE_PARM_DESC(force_subclients, - "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); +MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " + "{bus, clientaddr, subclientaddr1, subclientaddr2}"); /* Voltage IN registers 0-6 */ #define ASB100_REG_IN(nr) (0x20 + (nr)) @@ -689,8 +689,8 @@ static int asb100_detect_subclients(struct i2c_client *client) for (i = 2; i <= 3; i++) { if (force_subclients[i] < 0x48 || force_subclients[i] > 0x4f) { - dev_err(&client->dev, - "invalid subclient address %d; must be 0x48-0x4f\n", + dev_err(&client->dev, "invalid subclient " + "address %d; must be 0x48-0x4f\n", force_subclients[i]); err = -ENODEV; goto ERROR_SC_2; @@ -708,27 +708,24 @@ static int asb100_detect_subclients(struct i2c_client *client) } if (sc_addr[0] == sc_addr[1]) { - dev_err(&client->dev, - "duplicate addresses 0x%x for subclients\n", - sc_addr[0]); + dev_err(&client->dev, "duplicate addresses 0x%x " + "for subclients\n", sc_addr[0]); err = -ENODEV; goto ERROR_SC_2; } data->lm75[0] = i2c_new_dummy(adapter, sc_addr[0]); if (!data->lm75[0]) { - dev_err(&client->dev, - "subclient %d registration at address 0x%x failed.\n", - 1, sc_addr[0]); + dev_err(&client->dev, "subclient %d registration " + "at address 0x%x failed.\n", 1, sc_addr[0]); err = -ENOMEM; goto ERROR_SC_2; } data->lm75[1] = i2c_new_dummy(adapter, sc_addr[1]); if (!data->lm75[1]) { - dev_err(&client->dev, - "subclient %d registration at address 0x%x failed.\n", - 2, sc_addr[1]); + dev_err(&client->dev, "subclient %d registration " + "at address 0x%x failed.\n", 2, sc_addr[1]); err = -ENOMEM; goto ERROR_SC_3; } diff --git a/trunk/drivers/hwmon/asc7621.c b/trunk/drivers/hwmon/asc7621.c index 3ad9d849add2..da7f5b5d5db5 100644 --- a/trunk/drivers/hwmon/asc7621.c +++ b/trunk/drivers/hwmon/asc7621.c @@ -159,12 +159,12 @@ static inline int write_byte(struct i2c_client *client, u8 reg, u8 data) * and retrieval of like parameters. */ -#define SETUP_SHOW_DATA_PARAM(d, a) \ +#define SETUP_SHOW_data_param(d, a) \ struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \ struct asc7621_data *data = asc7621_update_device(d); \ struct asc7621_param *param = to_asc7621_param(sda) -#define SETUP_STORE_DATA_PARAM(d, a) \ +#define SETUP_STORE_data_param(d, a) \ struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \ struct i2c_client *client = to_i2c_client(d); \ struct asc7621_data *data = i2c_get_clientdata(client); \ @@ -177,7 +177,7 @@ static inline int write_byte(struct i2c_client *client, u8 reg, u8 data) static ssize_t show_u8(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); return sprintf(buf, "%u\n", data->reg[param->msb[0]]); } @@ -185,7 +185,7 @@ static ssize_t show_u8(struct device *dev, struct device_attribute *attr, static ssize_t store_u8(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval; if (kstrtol(buf, 10, &reqval)) @@ -206,7 +206,7 @@ static ssize_t store_u8(struct device *dev, struct device_attribute *attr, static ssize_t show_bitmask(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); return sprintf(buf, "%u\n", (data->reg[param->msb[0]] >> param-> @@ -217,7 +217,7 @@ static ssize_t store_bitmask(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval; u8 currval; @@ -246,7 +246,7 @@ static ssize_t store_bitmask(struct device *dev, static ssize_t show_fan16(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u16 regval; mutex_lock(&data->update_lock); @@ -262,7 +262,7 @@ static ssize_t store_fan16(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval; if (kstrtol(buf, 10, &reqval)) @@ -307,7 +307,7 @@ static int asc7621_in_scaling[] = { static ssize_t show_in10(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u16 regval; u8 nr = sda->index; @@ -325,7 +325,7 @@ static ssize_t show_in10(struct device *dev, struct device_attribute *attr, static ssize_t show_in8(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u8 nr = sda->index; return sprintf(buf, "%u\n", @@ -336,7 +336,7 @@ static ssize_t show_in8(struct device *dev, struct device_attribute *attr, static ssize_t store_in8(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval; u8 nr = sda->index; @@ -360,7 +360,7 @@ static ssize_t store_in8(struct device *dev, struct device_attribute *attr, static ssize_t show_temp8(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); return sprintf(buf, "%d\n", ((s8) data->reg[param->msb[0]]) * 1000); } @@ -369,7 +369,7 @@ static ssize_t store_temp8(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval; s8 temp; @@ -397,7 +397,7 @@ static ssize_t store_temp8(struct device *dev, static ssize_t show_temp10(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u8 msb, lsb; int temp; @@ -414,7 +414,7 @@ static ssize_t show_temp10(struct device *dev, static ssize_t show_temp62(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u8 regval = data->reg[param->msb[0]]; int temp = ((s8) (regval & 0xfc) * 1000) + ((regval & 0x03) * 250); @@ -425,7 +425,7 @@ static ssize_t store_temp62(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval, i, f; s8 temp; @@ -459,7 +459,7 @@ static u32 asc7621_range_map[] = { static ssize_t show_ap2_temp(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); long auto_point1; u8 regval; int temp; @@ -479,7 +479,7 @@ static ssize_t store_ap2_temp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval, auto_point1; int i; u8 currval, newval = 0; @@ -510,7 +510,7 @@ static ssize_t store_ap2_temp(struct device *dev, static ssize_t show_pwm_ac(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u8 config, altbit, regval; u8 map[] = { 0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10, @@ -530,7 +530,7 @@ static ssize_t store_pwm_ac(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); unsigned long reqval; u8 currval, config, altbit, newval; u16 map[] = { @@ -569,7 +569,7 @@ static ssize_t store_pwm_ac(struct device *dev, static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u8 config, altbit, minoff, val, newval; mutex_lock(&data->update_lock); @@ -599,7 +599,7 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval; u8 currval, config, altbit, newval, minoff = 255; @@ -659,7 +659,7 @@ static u32 asc7621_pwm_freq_map[] = { static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u8 regval = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; @@ -672,7 +672,7 @@ static ssize_t store_pwm_freq(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); unsigned long reqval; u8 currval, newval = 255; int i; @@ -707,7 +707,7 @@ static u32 asc7621_pwm_auto_spinup_map[] = { static ssize_t show_pwm_ast(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u8 regval = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; @@ -721,7 +721,7 @@ static ssize_t store_pwm_ast(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval; u8 currval, newval = 255; u32 i; @@ -756,7 +756,7 @@ static u32 asc7621_temp_smoothing_time_map[] = { static ssize_t show_temp_st(struct device *dev, struct device_attribute *attr, char *buf) { - SETUP_SHOW_DATA_PARAM(dev, attr); + SETUP_SHOW_data_param(dev, attr); u8 regval = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]; regval = clamp_val(regval, 0, 7); @@ -768,7 +768,7 @@ static ssize_t store_temp_st(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - SETUP_STORE_DATA_PARAM(dev, attr); + SETUP_STORE_data_param(dev, attr); long reqval; u8 currval, newval = 255; u32 i; diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c index 658ce3a8717f..3f1e297663ad 100644 --- a/trunk/drivers/hwmon/coretemp.c +++ b/trunk/drivers/hwmon/coretemp.c @@ -411,7 +411,8 @@ static int __cpuinit chk_ucode_version(unsigned int cpu) * fixed for stepping D0 (6EC). */ if (c->x86_model == 0xe && c->x86_mask < 0xc && c->microcode < 0x39) { - pr_err("Errata AE18 not fixed, update BIOS or microcode of the CPU!\n"); + pr_err("Errata AE18 not fixed, update BIOS or " + "microcode of the CPU!\n"); return -ENODEV; } return 0; diff --git a/trunk/drivers/hwmon/da9052-hwmon.c b/trunk/drivers/hwmon/da9052-hwmon.c index 960fac3fb166..ab4452c5a98c 100644 --- a/trunk/drivers/hwmon/da9052-hwmon.c +++ b/trunk/drivers/hwmon/da9052-hwmon.c @@ -43,19 +43,19 @@ static const char * const input_names[] = { }; /* Conversion function for VDDOUT and VBAT */ -static inline int volt_reg_to_mv(int value) +static inline int volt_reg_to_mV(int value) { return DIV_ROUND_CLOSEST(value * 1000, 512) + 2500; } /* Conversion function for ADC channels 4, 5 and 6 */ -static inline int input_reg_to_mv(int value) +static inline int input_reg_to_mV(int value) { return DIV_ROUND_CLOSEST(value * 2500, 1023); } /* Conversion function for VBBAT */ -static inline int vbbat_reg_to_mv(int value) +static inline int vbbat_reg_to_mV(int value) { return DIV_ROUND_CLOSEST(value * 2500, 512); } @@ -96,7 +96,7 @@ static ssize_t da9052_read_vddout(struct device *dev, goto hwmon_err; mutex_unlock(&hwmon->hwmon_lock); - return sprintf(buf, "%d\n", volt_reg_to_mv(vdd)); + return sprintf(buf, "%d\n", volt_reg_to_mV(vdd)); hwmon_err_release: da9052_disable_vddout_channel(hwmon->da9052); @@ -137,7 +137,7 @@ static ssize_t da9052_read_vbat(struct device *dev, if (ret < 0) return ret; - return sprintf(buf, "%d\n", volt_reg_to_mv(ret)); + return sprintf(buf, "%d\n", volt_reg_to_mV(ret)); } static ssize_t da9052_read_misc_channel(struct device *dev, @@ -152,7 +152,7 @@ static ssize_t da9052_read_misc_channel(struct device *dev, if (ret < 0) return ret; - return sprintf(buf, "%d\n", input_reg_to_mv(ret)); + return sprintf(buf, "%d\n", input_reg_to_mV(ret)); } static ssize_t da9052_read_tjunc(struct device *dev, @@ -187,7 +187,7 @@ static ssize_t da9052_read_vbbat(struct device *dev, if (ret < 0) return ret; - return sprintf(buf, "%d\n", vbbat_reg_to_mv(ret)); + return sprintf(buf, "%d\n", vbbat_reg_to_mV(ret)); } static ssize_t da9052_hwmon_show_name(struct device *dev, diff --git a/trunk/drivers/hwmon/da9055-hwmon.c b/trunk/drivers/hwmon/da9055-hwmon.c index 029ecabc4380..9465c050c326 100644 --- a/trunk/drivers/hwmon/da9055-hwmon.c +++ b/trunk/drivers/hwmon/da9055-hwmon.c @@ -119,7 +119,7 @@ static irqreturn_t da9055_auxadc_irq(int irq, void *irq_data) } /* Conversion function for VSYS and ADCINx */ -static inline int volt_reg_to_mv(int value, int channel) +static inline int volt_reg_to_mV(int value, int channel) { if (channel == DA9055_ADC_VSYS) return DIV_ROUND_CLOSEST(value * 1000, DA9055_VSYS_DIV) + 2500; @@ -168,7 +168,7 @@ static ssize_t da9055_read_auto_ch(struct device *dev, mutex_unlock(&hwmon->hwmon_lock); - return sprintf(buf, "%d\n", volt_reg_to_mv(adc, channel)); + return sprintf(buf, "%d\n", volt_reg_to_mV(adc, channel)); hwmon_err_release: da9055_disable_auto_mode(hwmon->da9055, channel); diff --git a/trunk/drivers/hwmon/dme1737.c b/trunk/drivers/hwmon/dme1737.c index 4ae3fff13f44..c347c94f2f73 100644 --- a/trunk/drivers/hwmon/dme1737.c +++ b/trunk/drivers/hwmon/dme1737.c @@ -55,16 +55,14 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); static bool probe_all_addr; module_param(probe_all_addr, bool, 0); -MODULE_PARM_DESC(probe_all_addr, - "Include probing of non-standard LPC addresses"); +MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " + "addresses"); /* Addresses to scan */ static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; enum chips { dme1737, sch5027, sch311x, sch5127 }; -#define DO_REPORT "Please report to the driver maintainer." - /* --------------------------------------------------------------------- * Registers * @@ -568,9 +566,9 @@ static u8 dme1737_read(const struct dme1737_data *data, u8 reg) val = i2c_smbus_read_byte_data(client, reg); if (val < 0) { - dev_warn(&client->dev, - "Read from register 0x%02x failed! %s\n", - reg, DO_REPORT); + dev_warn(&client->dev, "Read from register " + "0x%02x failed! Please report to the driver " + "maintainer.\n", reg); } } else { /* ISA device */ outb(reg, data->addr); @@ -589,9 +587,9 @@ static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val) res = i2c_smbus_write_byte_data(client, reg, val); if (res < 0) { - dev_warn(&client->dev, - "Write to register 0x%02x failed! %s\n", - reg, DO_REPORT); + dev_warn(&client->dev, "Write to register " + "0x%02x failed! Please report to the driver " + "maintainer.\n", reg); } } else { /* ISA device */ outb(reg, data->addr); @@ -1169,8 +1167,8 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, /* Only valid for fan[1-4] */ if (!(val == 1 || val == 2 || val == 4)) { count = -EINVAL; - dev_warn(dev, - "Fan type value %ld not supported. Choose one of 1, 2, or 4.\n", + dev_warn(dev, "Fan type value %ld not " + "supported. Choose one of 1, 2, or 4.\n", val); goto exit; } @@ -1296,8 +1294,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, /* Only valid for pwm[1-3] */ if (val < 0 || val > 2) { count = -EINVAL; - dev_warn(dev, - "PWM enable %ld not supported. Choose one of 0, 1, or 2.\n", + dev_warn(dev, "PWM enable %ld not " + "supported. Choose one of 0, 1, or 2.\n", val); goto exit; } @@ -1401,8 +1399,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, if (!(val == 1 || val == 2 || val == 4 || val == 6 || val == 7)) { count = -EINVAL; - dev_warn(dev, - "PWM auto channels zone %ld not supported. Choose one of 1, 2, 4, 6, " + dev_warn(dev, "PWM auto channels zone %ld " + "not supported. Choose one of 1, 2, 4, 6, " "or 7.\n", val); goto exit; } @@ -2180,8 +2178,8 @@ static int dme1737_create_files(struct device *dev) * selected attributes from read-only to read-writeable. */ if (data->config & 0x02) { - dev_info(dev, - "Device is locked. Some attributes will be read-only.\n"); + dev_info(dev, "Device is locked. Some attributes " + "will be read-only.\n"); } else { /* Change permissions of zone sysfs attributes */ dme1737_chmod_group(dev, &dme1737_zone_chmod_group, @@ -2249,8 +2247,9 @@ static int dme1737_init_device(struct device *dev) /* Inform if part is not monitoring/started */ if (!(data->config & 0x01)) { if (!force_start) { - dev_err(dev, - "Device is not monitoring. Use the force_start load parameter to override.\n"); + dev_err(dev, "Device is not monitoring. " + "Use the force_start load parameter to " + "override.\n"); return -EFAULT; } @@ -2290,8 +2289,8 @@ static int dme1737_init_device(struct device *dev) */ if (dme1737_i2c_get_features(0x2e, data) && dme1737_i2c_get_features(0x4e, data)) { - dev_warn(dev, - "Failed to query Super-IO for optional features.\n"); + dev_warn(dev, "Failed to query Super-IO for optional " + "features.\n"); } } @@ -2318,8 +2317,8 @@ static int dme1737_init_device(struct device *dev) break; } - dev_info(dev, - "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", + dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " + "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", (data->has_features & HAS_PWM(2)) ? "yes" : "no", (data->has_features & HAS_PWM(4)) ? "yes" : "no", (data->has_features & HAS_PWM(5)) ? "yes" : "no", @@ -2331,16 +2330,18 @@ static int dme1737_init_device(struct device *dev) reg = dme1737_read(data, DME1737_REG_TACH_PWM); /* Inform if fan-to-pwm mapping differs from the default */ if (client && reg != 0xa4) { /* I2C chip */ - dev_warn(dev, - "Non-standard fan to pwm mapping: fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, fan4->pwm%d. %s\n", + dev_warn(dev, "Non-standard fan to pwm mapping: " + "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " + "fan4->pwm%d. Please report to the driver " + "maintainer.\n", (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, - ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1, - DO_REPORT); + ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); } else if (!client && reg != 0x24) { /* ISA chip */ - dev_warn(dev, - "Non-standard fan to pwm mapping: fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. %s\n", + dev_warn(dev, "Non-standard fan to pwm mapping: " + "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. " + "Please report to the driver maintainer.\n", (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, - ((reg >> 4) & 0x03) + 1, DO_REPORT); + ((reg >> 4) & 0x03) + 1); } /* @@ -2354,9 +2355,8 @@ static int dme1737_init_device(struct device *dev) DME1737_REG_PWM_CONFIG(ix)); if ((data->has_features & HAS_PWM(ix)) && (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { - dev_info(dev, - "Switching pwm%d to manual mode.\n", - ix + 1); + dev_info(dev, "Switching pwm%d to " + "manual mode.\n", ix + 1); data->pwm_config[ix] = PWM_EN_TO_REG(1, data->pwm_config[ix]); dme1737_write(data, DME1737_REG_PWM(ix), 0); diff --git a/trunk/drivers/hwmon/f71805f.c b/trunk/drivers/hwmon/f71805f.c index 0c9f3da242bf..a9816979c5de 100644 --- a/trunk/drivers/hwmon/f71805f.c +++ b/trunk/drivers/hwmon/f71805f.c @@ -1350,7 +1350,8 @@ static void f71805f_init_device(struct f71805f_data *data) reg = f71805f_read8(data, F71805F_REG_START); if ((reg & 0x41) != 0x01) { - pr_debug("Starting monitoring operations\n"); + printk(KERN_DEBUG DRVNAME ": Starting monitoring " + "operations\n"); f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); } diff --git a/trunk/drivers/hwmon/fam15h_power.c b/trunk/drivers/hwmon/fam15h_power.c index dff841085baf..b757088aeddb 100644 --- a/trunk/drivers/hwmon/fam15h_power.c +++ b/trunk/drivers/hwmon/fam15h_power.c @@ -189,8 +189,8 @@ static void fam15h_power_init_data(struct pci_dev *f4, /* result not allowed to be >= 256W */ if ((tmp >> 16) >= 256) - dev_warn(&f4->dev, - "Bogus value for ProcessorPwrWatts (processor_pwr_watts>=%u)\n", + dev_warn(&f4->dev, "Bogus value for ProcessorPwrWatts " + "(processor_pwr_watts>=%u)\n", (unsigned int) (tmp >> 16)); /* convert to microWatt */ diff --git a/trunk/drivers/hwmon/fschmd.c b/trunk/drivers/hwmon/fschmd.c index d58abdc5a4cf..8af2755cdb87 100644 --- a/trunk/drivers/hwmon/fschmd.c +++ b/trunk/drivers/hwmon/fschmd.c @@ -463,9 +463,8 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute v = 3; break; default: - dev_err(dev, - "fan_div value %lu not supported. Choose one of 2, 4 or 8!\n", - v); + dev_err(dev, "fan_div value %lu not supported. " + "Choose one of 2, 4 or 8!\n", v); return -EINVAL; } @@ -1250,8 +1249,8 @@ static int fschmd_probe(struct i2c_client *client, } if (i == ARRAY_SIZE(watchdog_minors)) { data->watchdog_miscdev.minor = 0; - dev_warn(&client->dev, - "Couldn't register watchdog chardev (due to no free minor)\n"); + dev_warn(&client->dev, "Couldn't register watchdog chardev " + "(due to no free minor)\n"); } mutex_unlock(&watchdog_data_mutex); diff --git a/trunk/drivers/hwmon/gl518sm.c b/trunk/drivers/hwmon/gl518sm.c index 95257a5621d8..e2e5909a34df 100644 --- a/trunk/drivers/hwmon/gl518sm.c +++ b/trunk/drivers/hwmon/gl518sm.c @@ -344,9 +344,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, val = 3; break; default: - dev_err(dev, - "Invalid fan clock divider %lu, choose one of 1, 2, 4 or 8\n", - val); + dev_err(dev, "Invalid fan clock divider %lu, choose one " + "of 1, 2, 4 or 8\n", val); return -EINVAL; } diff --git a/trunk/drivers/hwmon/gpio-fan.c b/trunk/drivers/hwmon/gpio-fan.c index 3104149795c5..39781945a5d2 100644 --- a/trunk/drivers/hwmon/gpio-fan.c +++ b/trunk/drivers/hwmon/gpio-fan.c @@ -105,6 +105,10 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, if (err) return err; + err = device_create_file(&pdev->dev, &dev_attr_fan1_alarm); + if (err) + return err; + /* * If the alarm GPIO don't support interrupts, just leave * without initializing the fail notification support. @@ -117,9 +121,23 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); err = devm_request_irq(&pdev->dev, alarm_irq, fan_alarm_irq_handler, IRQF_SHARED, "GPIO fan alarm", fan_data); + if (err) + goto err_free_sysfs; + + return 0; + +err_free_sysfs: + device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); return err; } +static void fan_alarm_free(struct gpio_fan_data *fan_data) +{ + struct platform_device *pdev = fan_data->pdev; + + device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); +} + /* * Control GPIOs. */ @@ -309,12 +327,6 @@ static ssize_t set_rpm(struct device *dev, struct device_attribute *attr, return ret; } -static ssize_t show_name(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "gpio-fan\n"); -} - static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm); static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, set_pwm_enable); @@ -324,26 +336,8 @@ static DEVICE_ATTR(fan1_max, S_IRUGO, show_rpm_max, NULL); static DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, NULL); static DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, show_rpm, set_rpm); -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - -static umode_t gpio_fan_is_visible(struct kobject *kobj, - struct attribute *attr, int index) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct gpio_fan_data *data = dev_get_drvdata(dev); - - if (index == 1 && !data->alarm) - return 0; - if (index > 1 && !data->ctrl) - return 0; - - return attr->mode; -} - -static struct attribute *gpio_fan_attributes[] = { - &dev_attr_name.attr, - &dev_attr_fan1_alarm.attr, /* 1 */ - &dev_attr_pwm1.attr, /* 2 */ +static struct attribute *gpio_fan_ctrl_attributes[] = { + &dev_attr_pwm1.attr, &dev_attr_pwm1_enable.attr, &dev_attr_pwm1_mode.attr, &dev_attr_fan1_input.attr, @@ -353,9 +347,8 @@ static struct attribute *gpio_fan_attributes[] = { NULL }; -static const struct attribute_group gpio_fan_group = { - .attrs = gpio_fan_attributes, - .is_visible = gpio_fan_is_visible, +static const struct attribute_group gpio_fan_ctrl_group = { + .attrs = gpio_fan_ctrl_attributes, }; static int fan_ctrl_init(struct gpio_fan_data *fan_data, @@ -386,9 +379,30 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, if (fan_data->speed_index < 0) return -ENODEV; - return 0; + err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); + return err; } +static void fan_ctrl_free(struct gpio_fan_data *fan_data) +{ + struct platform_device *pdev = fan_data->pdev; + + sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); +} + +/* + * Platform driver. + */ + +static ssize_t show_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "gpio-fan\n"); +} + +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + + #ifdef CONFIG_OF_GPIO /* * Translate OpenFirmware node properties into platform_data @@ -532,30 +546,38 @@ static int gpio_fan_probe(struct platform_device *pdev) /* Configure control GPIOs if available. */ if (pdata->ctrl && pdata->num_ctrl > 0) { - if (!pdata->speed || pdata->num_speed <= 1) - return -EINVAL; + if (!pdata->speed || pdata->num_speed <= 1) { + err = -EINVAL; + goto err_free_alarm; + } err = fan_ctrl_init(fan_data, pdata); if (err) - return err; + goto err_free_alarm; } - err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_group); + err = device_create_file(&pdev->dev, &dev_attr_name); if (err) - return err; + goto err_free_ctrl; /* Make this driver part of hwmon class. */ fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(fan_data->hwmon_dev)) { err = PTR_ERR(fan_data->hwmon_dev); - goto err_remove; + goto err_remove_name; } dev_info(&pdev->dev, "GPIO fan initialized\n"); return 0; -err_remove: - sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_group); +err_remove_name: + device_remove_file(&pdev->dev, &dev_attr_name); +err_free_ctrl: + if (fan_data->ctrl) + fan_ctrl_free(fan_data); +err_free_alarm: + if (fan_data->alarm) + fan_alarm_free(fan_data); return err; } @@ -564,7 +586,11 @@ static int gpio_fan_remove(struct platform_device *pdev) struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); hwmon_device_unregister(fan_data->hwmon_dev); - sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_group); + device_remove_file(&pdev->dev, &dev_attr_name); + if (fan_data->alarm) + fan_alarm_free(fan_data); + if (fan_data->ctrl) + fan_ctrl_free(fan_data); return 0; } @@ -593,7 +619,7 @@ static int gpio_fan_resume(struct device *dev) } static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume); -#define GPIO_FAN_PM (&gpio_fan_pm) +#define GPIO_FAN_PM &gpio_fan_pm #else #define GPIO_FAN_PM NULL #endif diff --git a/trunk/drivers/hwmon/ibmaem.c b/trunk/drivers/hwmon/ibmaem.c index 1429f6e177f4..a14f634248e7 100644 --- a/trunk/drivers/hwmon/ibmaem.c +++ b/trunk/drivers/hwmon/ibmaem.c @@ -289,9 +289,8 @@ static int aem_init_ipmi_data(struct aem_ipmi_data *data, int iface, err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, data, &data->user); if (err < 0) { - dev_err(bmc, - "Unable to register user with IPMI interface %d\n", - data->interface); + dev_err(bmc, "Unable to register user with IPMI " + "interface %d\n", data->interface); return -EACCES; } @@ -329,8 +328,8 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) struct aem_ipmi_data *data = user_msg_data; if (msg->msgid != data->tx_msgid) { - dev_err(data->bmc_device, - "Mismatch between received msgid (%02x) and transmitted msgid (%02x)!\n", + dev_err(data->bmc_device, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", (int)msg->msgid, (int)data->tx_msgid); ipmi_free_recv_msg(msg); @@ -576,8 +575,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) /* Register with hwmon */ data->hwmon_dev = hwmon_device_register(&data->pdev->dev); if (IS_ERR(data->hwmon_dev)) { - dev_err(&data->pdev->dev, - "Unable to register hwmon device for IPMI interface %d\n", + dev_err(&data->pdev->dev, "Unable to register hwmon " + "device for IPMI interface %d\n", probe->interface); res = PTR_ERR(data->hwmon_dev); goto hwmon_reg_err; @@ -716,8 +715,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, /* Register with hwmon */ data->hwmon_dev = hwmon_device_register(&data->pdev->dev); if (IS_ERR(data->hwmon_dev)) { - dev_err(&data->pdev->dev, - "Unable to register hwmon device for IPMI interface %d\n", + dev_err(&data->pdev->dev, "Unable to register hwmon " + "device for IPMI interface %d\n", probe->interface); res = PTR_ERR(data->hwmon_dev); goto hwmon_reg_err; @@ -769,8 +768,8 @@ static void aem_init_aem2(struct aem_ipmi_data *probe) while (!aem_find_aem2(probe, &fi_resp, i)) { if (fi_resp.major != 2) { - dev_err(probe->bmc_device, - "Unknown AEM v%d; please report this to the maintainer.\n", + dev_err(probe->bmc_device, "Unknown AEM v%d; please " + "report this to the maintainer.\n", fi_resp.major); i++; continue; diff --git a/trunk/drivers/hwmon/ibmpex.c b/trunk/drivers/hwmon/ibmpex.c index 74b365ea01c7..b622a93ec32c 100644 --- a/trunk/drivers/hwmon/ibmpex.c +++ b/trunk/drivers/hwmon/ibmpex.c @@ -163,8 +163,8 @@ static int ibmpex_ver_check(struct ibmpex_bmc_data *data) data->sensor_major = data->rx_msg_data[0]; data->sensor_minor = data->rx_msg_data[1]; - dev_info(data->bmc_device, - "Found BMC with sensor interface v%d.%d %d-%02d-%02d on interface %d\n", + dev_info(data->bmc_device, "Found BMC with sensor interface " + "v%d.%d %d-%02d-%02d on interface %d\n", data->sensor_major, data->sensor_minor, extract_value(data->rx_msg_data, 2), @@ -478,9 +478,8 @@ static void ibmpex_register_bmc(int iface, struct device *dev) err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, data, &data->user); if (err < 0) { - dev_err(dev, - "Unable to register user with IPMI interface %d\n", - data->interface); + dev_err(dev, "Unable to register user with IPMI " + "interface %d\n", data->interface); goto out; } @@ -502,8 +501,8 @@ static void ibmpex_register_bmc(int iface, struct device *dev) data->hwmon_dev = hwmon_device_register(data->bmc_device); if (IS_ERR(data->hwmon_dev)) { - dev_err(data->bmc_device, - "Unable to register hwmon device for IPMI interface %d\n", + dev_err(data->bmc_device, "Unable to register hwmon " + "device for IPMI interface %d\n", data->interface); goto out_user; } @@ -568,8 +567,8 @@ static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; if (msg->msgid != data->tx_msgid) { - dev_err(data->bmc_device, - "Mismatch between received msgid (%02x) and transmitted msgid (%02x)!\n", + dev_err(data->bmc_device, "Mismatch between received msgid " + "(%02x) and transmitted msgid (%02x)!\n", (int)msg->msgid, (int)data->tx_msgid); ipmi_free_recv_msg(msg); diff --git a/trunk/drivers/hwmon/ina2xx.c b/trunk/drivers/hwmon/ina2xx.c index 4958b2f89dce..8e7158c3ad2f 100644 --- a/trunk/drivers/hwmon/ina2xx.c +++ b/trunk/drivers/hwmon/ina2xx.c @@ -186,20 +186,20 @@ static ssize_t ina2xx_show_value(struct device *dev, } /* shunt voltage */ -static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ina2xx_show_value, NULL, - INA2XX_SHUNT_VOLTAGE); +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, \ + ina2xx_show_value, NULL, INA2XX_SHUNT_VOLTAGE); /* bus voltage */ -static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ina2xx_show_value, NULL, - INA2XX_BUS_VOLTAGE); +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, \ + ina2xx_show_value, NULL, INA2XX_BUS_VOLTAGE); /* calculated current */ -static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ina2xx_show_value, NULL, - INA2XX_CURRENT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, \ + ina2xx_show_value, NULL, INA2XX_CURRENT); /* calculated power */ -static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, - INA2XX_POWER); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, \ + ina2xx_show_value, NULL, INA2XX_POWER); /* pointers to created device attributes */ static struct attribute *ina2xx_attributes[] = { diff --git a/trunk/drivers/hwmon/it87.c b/trunk/drivers/hwmon/it87.c index 72b21d5b1c62..37fc980fde24 100644 --- a/trunk/drivers/hwmon/it87.c +++ b/trunk/drivers/hwmon/it87.c @@ -1778,7 +1778,7 @@ static int __init it87_find(unsigned short *address, superio_select(5); sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; } else if (sio_data->type == it8783) { - int reg25, reg27, reg2a, reg2c, regef; + int reg25, reg27, reg2A, reg2C, regEF; sio_data->skip_vid = 1; /* No VID */ @@ -1786,15 +1786,15 @@ static int __init it87_find(unsigned short *address, reg25 = superio_inb(IT87_SIO_GPIO1_REG); reg27 = superio_inb(IT87_SIO_GPIO3_REG); - reg2a = superio_inb(IT87_SIO_PINX1_REG); - reg2c = superio_inb(IT87_SIO_PINX2_REG); - regef = superio_inb(IT87_SIO_SPI_REG); + reg2A = superio_inb(IT87_SIO_PINX1_REG); + reg2C = superio_inb(IT87_SIO_PINX2_REG); + regEF = superio_inb(IT87_SIO_SPI_REG); /* Check if fan3 is there or not */ - if ((reg27 & (1 << 0)) || !(reg2c & (1 << 2))) + if ((reg27 & (1 << 0)) || !(reg2C & (1 << 2))) sio_data->skip_fan |= (1 << 2); if ((reg25 & (1 << 4)) - || (!(reg2a & (1 << 1)) && (regef & (1 << 0)))) + || (!(reg2A & (1 << 1)) && (regEF & (1 << 0)))) sio_data->skip_pwm |= (1 << 2); /* Check if fan2 is there or not */ @@ -1804,7 +1804,7 @@ static int __init it87_find(unsigned short *address, sio_data->skip_pwm |= (1 << 1); /* VIN5 */ - if ((reg27 & (1 << 0)) || (reg2c & (1 << 2))) + if ((reg27 & (1 << 0)) || (reg2C & (1 << 2))) sio_data->skip_in |= (1 << 5); /* No VIN5 */ /* VIN6 */ @@ -1829,18 +1829,18 @@ static int __init it87_find(unsigned short *address, * not the case, and ask the user to report if the * resulting voltage is sane. */ - if (!(reg2c & (1 << 1))) { - reg2c |= (1 << 1); - superio_outb(IT87_SIO_PINX2_REG, reg2c); + if (!(reg2C & (1 << 1))) { + reg2C |= (1 << 1); + superio_outb(IT87_SIO_PINX2_REG, reg2C); pr_notice("Routing internal VCCH5V to in7.\n"); } pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n"); pr_notice("Please report if it displays a reasonable voltage.\n"); } - if (reg2c & (1 << 0)) + if (reg2C & (1 << 0)) sio_data->internal |= (1 << 0); - if (reg2c & (1 << 1)) + if (reg2C & (1 << 1)) sio_data->internal |= (1 << 1); sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; diff --git a/trunk/drivers/hwmon/k8temp.c b/trunk/drivers/hwmon/k8temp.c index 5b50e9e4f96b..9f3c0aeacdb9 100644 --- a/trunk/drivers/hwmon/k8temp.c +++ b/trunk/drivers/hwmon/k8temp.c @@ -200,8 +200,8 @@ static int k8temp_probe(struct pci_dev *pdev, */ if (model >= 0x40) { data->swap_core_select = 1; - dev_warn(&pdev->dev, - "Temperature readouts might be wrong - check erratum #141\n"); + dev_warn(&pdev->dev, "Temperature readouts might be wrong - " + "check erratum #141\n"); } /* diff --git a/trunk/drivers/hwmon/lineage-pem.c b/trunk/drivers/hwmon/lineage-pem.c index ebbb9f4f27a3..41df29f59b0e 100644 --- a/trunk/drivers/hwmon/lineage-pem.c +++ b/trunk/drivers/hwmon/lineage-pem.c @@ -422,7 +422,6 @@ static struct attribute *pem_input_attributes[] = { &sensor_dev_attr_in2_input.dev_attr.attr, &sensor_dev_attr_curr1_input.dev_attr.attr, &sensor_dev_attr_power1_input.dev_attr.attr, - NULL }; static const struct attribute_group pem_input_group = { @@ -433,7 +432,6 @@ static struct attribute *pem_fan_attributes[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan3_input.dev_attr.attr, - NULL }; static const struct attribute_group pem_fan_group = { diff --git a/trunk/drivers/hwmon/lm75.h b/trunk/drivers/hwmon/lm75.h index 5cde94e56f17..668ff4721323 100644 --- a/trunk/drivers/hwmon/lm75.h +++ b/trunk/drivers/hwmon/lm75.h @@ -25,7 +25,7 @@ which contains this code, we don't worry about the wasted space. */ -#include +#include /* straight from the datasheet */ #define LM75_TEMP_MIN (-55000) diff --git a/trunk/drivers/hwmon/lm78.c b/trunk/drivers/hwmon/lm78.c index 6cf6bff79003..483538fa1bd5 100644 --- a/trunk/drivers/hwmon/lm78.c +++ b/trunk/drivers/hwmon/lm78.c @@ -386,9 +386,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, data->fan_div[nr] = 3; break; default: - dev_err(dev, - "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", - val); + dev_err(dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); mutex_unlock(&data->update_lock); return -EINVAL; } @@ -637,9 +636,8 @@ static int lm78_i2c_detect(struct i2c_client *client, goto err_nodev; if (lm78_alias_detect(client, i)) { - dev_dbg(&adapter->dev, - "Device at 0x%02x appears to be the same as ISA device\n", - address); + dev_dbg(&adapter->dev, "Device at 0x%02x appears to " + "be the same as ISA device\n", address); goto err_nodev; } diff --git a/trunk/drivers/hwmon/lm80.c b/trunk/drivers/hwmon/lm80.c index eba89aac3ece..357fbb998728 100644 --- a/trunk/drivers/hwmon/lm80.c +++ b/trunk/drivers/hwmon/lm80.c @@ -286,9 +286,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, data->fan_div[nr] = 3; break; default: - dev_err(&client->dev, - "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", - val); + dev_err(&client->dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); mutex_unlock(&data->update_lock); return -EINVAL; } diff --git a/trunk/drivers/hwmon/lm85.c b/trunk/drivers/hwmon/lm85.c index 3894c408fda3..47ade8ba152d 100644 --- a/trunk/drivers/hwmon/lm85.c +++ b/trunk/drivers/hwmon/lm85.c @@ -1293,8 +1293,8 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info) company = lm85_read_value(client, LM85_REG_COMPANY); verstep = lm85_read_value(client, LM85_REG_VERSTEP); - dev_dbg(&adapter->dev, - "Detecting device at 0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n", + dev_dbg(&adapter->dev, "Detecting device at 0x%02x with " + "COMPANY: 0x%02x and VERSTEP: 0x%02x\n", address, company, verstep); /* All supported chips have the version in common */ diff --git a/trunk/drivers/hwmon/lm93.c b/trunk/drivers/hwmon/lm93.c index a6f46058b1be..b40f34cdb3ca 100644 --- a/trunk/drivers/hwmon/lm93.c +++ b/trunk/drivers/hwmon/lm93.c @@ -354,12 +354,12 @@ static const unsigned long lm93_vin_val_max[16] = { static unsigned LM93_IN_FROM_REG(int nr, u8 reg) { - const long uv_max = lm93_vin_val_max[nr] * 1000; - const long uv_min = lm93_vin_val_min[nr] * 1000; + const long uV_max = lm93_vin_val_max[nr] * 1000; + const long uV_min = lm93_vin_val_min[nr] * 1000; - const long slope = (uv_max - uv_min) / + const long slope = (uV_max - uV_min) / (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); - const long intercept = uv_min - slope * lm93_vin_reg_min[nr]; + const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; return (slope * reg + intercept + 500) / 1000; } @@ -371,20 +371,20 @@ static unsigned LM93_IN_FROM_REG(int nr, u8 reg) static u8 LM93_IN_TO_REG(int nr, unsigned val) { /* range limit */ - const long mv = clamp_val(val, + const long mV = clamp_val(val, lm93_vin_val_min[nr], lm93_vin_val_max[nr]); /* try not to lose too much precision here */ - const long uv = mv * 1000; - const long uv_max = lm93_vin_val_max[nr] * 1000; - const long uv_min = lm93_vin_val_min[nr] * 1000; + const long uV = mV * 1000; + const long uV_max = lm93_vin_val_max[nr] * 1000; + const long uV_min = lm93_vin_val_min[nr] * 1000; /* convert */ - const long slope = (uv_max - uv_min) / + const long slope = (uV_max - uV_min) / (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); - const long intercept = uv_min - slope * lm93_vin_reg_min[nr]; + const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; - u8 result = ((uv - intercept + (slope/2)) / slope); + u8 result = ((uV - intercept + (slope/2)) / slope); result = clamp_val(result, lm93_vin_reg_min[nr], lm93_vin_reg_max[nr]); return result; @@ -393,10 +393,10 @@ static u8 LM93_IN_TO_REG(int nr, unsigned val) /* vid in mV, upper == 0 indicates low limit, otherwise upper limit */ static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) { - const long uv_offset = upper ? (((reg >> 4 & 0x0f) + 1) * 12500) : + const long uV_offset = upper ? (((reg >> 4 & 0x0f) + 1) * 12500) : (((reg >> 0 & 0x0f) + 1) * -25000); - const long uv_vid = vid * 1000; - return (uv_vid + uv_offset + 5000) / 10000; + const long uV_vid = vid * 1000; + return (uV_vid + uV_offset + 5000) / 10000; } #define LM93_IN_MIN_FROM_REG(reg, vid) LM93_IN_REL_FROM_REG((reg), 0, (vid)) @@ -409,13 +409,13 @@ static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) */ static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) { - long uv_offset = vid * 1000 - val * 10000; + long uV_offset = vid * 1000 - val * 10000; if (upper) { - uv_offset = clamp_val(uv_offset, 12500, 200000); - return (u8)((uv_offset / 12500 - 1) << 4); + uV_offset = clamp_val(uV_offset, 12500, 200000); + return (u8)((uV_offset / 12500 - 1) << 4); } else { - uv_offset = clamp_val(uv_offset, -400000, -25000); - return (u8)((uv_offset / -25000 - 1) << 0); + uV_offset = clamp_val(uV_offset, -400000, -25000); + return (u8)((uV_offset / -25000 - 1) << 0); } } @@ -818,9 +818,8 @@ static u8 lm93_read_byte(struct i2c_client *client, u8 reg) if (value >= 0) { return value; } else { - dev_warn(&client->dev, - "lm93: read byte data failed, address 0x%02x.\n", - reg); + dev_warn(&client->dev, "lm93: read byte data failed, " + "address 0x%02x.\n", reg); mdelay(i + 3); } @@ -839,9 +838,8 @@ static int lm93_write_byte(struct i2c_client *client, u8 reg, u8 value) result = i2c_smbus_write_byte_data(client, reg, value); if (result < 0) - dev_warn(&client->dev, - "lm93: write byte data failed, 0x%02x at address 0x%02x.\n", - value, reg); + dev_warn(&client->dev, "lm93: write byte data failed, " + "0x%02x at address 0x%02x.\n", value, reg); return result; } @@ -856,9 +854,8 @@ static u16 lm93_read_word(struct i2c_client *client, u8 reg) if (value >= 0) { return value; } else { - dev_warn(&client->dev, - "lm93: read word data failed, address 0x%02x.\n", - reg); + dev_warn(&client->dev, "lm93: read word data failed, " + "address 0x%02x.\n", reg); mdelay(i + 3); } @@ -877,9 +874,8 @@ static int lm93_write_word(struct i2c_client *client, u8 reg, u16 value) result = i2c_smbus_write_word_data(client, reg, value); if (result < 0) - dev_warn(&client->dev, - "lm93: write word data failed, 0x%04x at address 0x%02x.\n", - value, reg); + dev_warn(&client->dev, "lm93: write word data failed, " + "0x%04x at address 0x%02x.\n", value, reg); return result; } @@ -902,8 +898,8 @@ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) if (result == lm93_block_read_cmds[fbn].len) { break; } else { - dev_warn(&client->dev, - "lm93: block read data failed, command 0x%02x.\n", + dev_warn(&client->dev, "lm93: block read data failed, " + "command 0x%02x.\n", lm93_block_read_cmds[fbn].cmd); mdelay(i + 3); } @@ -2676,8 +2672,8 @@ static void lm93_init_client(struct i2c_client *client) return; } - dev_warn(&client->dev, - "timed out waiting for sensor chip to signal ready!\n"); + dev_warn(&client->dev, "timed out waiting for sensor " + "chip to signal ready!\n"); } /* Return 0 if detection is successful, -ENODEV otherwise */ @@ -2737,12 +2733,12 @@ static int lm93_probe(struct i2c_client *client, dev_dbg(&client->dev, "using SMBus block data transactions\n"); update = lm93_update_client_full; } else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) { - dev_dbg(&client->dev, - "disabled SMBus block data transactions\n"); + dev_dbg(&client->dev, "disabled SMBus block data " + "transactions\n"); update = lm93_update_client_min; } else { - dev_dbg(&client->dev, - "detect failed, smbus byte and/or word data not supported!\n"); + dev_dbg(&client->dev, "detect failed, " + "smbus byte and/or word data not supported!\n"); return -ENODEV; } diff --git a/trunk/drivers/hwmon/lm95234.c b/trunk/drivers/hwmon/lm95234.c deleted file mode 100644 index 307c9eaeeb9f..000000000000 --- a/trunk/drivers/hwmon/lm95234.c +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Driver for Texas Instruments / National Semiconductor LM95234 - * - * Copyright (c) 2013 Guenter Roeck - * - * Derived from lm95241.c - * Copyright (C) 2008, 2010 Davide Rizzo - * - * 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 - -#define DRVNAME "lm95234" - -static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END }; - -/* LM95234 registers */ -#define LM95234_REG_MAN_ID 0xFE -#define LM95234_REG_CHIP_ID 0xFF -#define LM95234_REG_STATUS 0x02 -#define LM95234_REG_CONFIG 0x03 -#define LM95234_REG_CONVRATE 0x04 -#define LM95234_REG_STS_FAULT 0x07 -#define LM95234_REG_STS_TCRIT1 0x08 -#define LM95234_REG_STS_TCRIT2 0x09 -#define LM95234_REG_TEMPH(x) ((x) + 0x10) -#define LM95234_REG_TEMPL(x) ((x) + 0x20) -#define LM95234_REG_UTEMPH(x) ((x) + 0x19) /* Remote only */ -#define LM95234_REG_UTEMPL(x) ((x) + 0x29) -#define LM95234_REG_REM_MODEL 0x30 -#define LM95234_REG_REM_MODEL_STS 0x38 -#define LM95234_REG_OFFSET(x) ((x) + 0x31) /* Remote only */ -#define LM95234_REG_TCRIT1(x) ((x) + 0x40) -#define LM95234_REG_TCRIT2(x) ((x) + 0x49) /* Remote channel 1,2 */ -#define LM95234_REG_TCRIT_HYST 0x5a - -#define NATSEMI_MAN_ID 0x01 -#define LM95234_CHIP_ID 0x79 - -/* Client data (each client gets its own) */ -struct lm95234_data { - struct device *hwmon_dev; - struct mutex update_lock; - unsigned long last_updated, interval; /* in jiffies */ - bool valid; /* false until following fields are valid */ - /* registers values */ - int temp[5]; /* temperature (signed) */ - u32 status; /* fault/alarm status */ - u8 tcrit1[5]; /* critical temperature limit */ - u8 tcrit2[2]; /* high temperature limit */ - s8 toffset[4]; /* remote temperature offset */ - u8 thyst; /* common hysteresis */ - - u8 sensor_type; /* temperature sensor type */ -}; - -static int lm95234_read_temp(struct i2c_client *client, int index, int *t) -{ - int val; - u16 temp = 0; - - if (index) { - val = i2c_smbus_read_byte_data(client, - LM95234_REG_UTEMPH(index - 1)); - if (val < 0) - return val; - temp = val << 8; - val = i2c_smbus_read_byte_data(client, - LM95234_REG_UTEMPL(index - 1)); - if (val < 0) - return val; - temp |= val; - *t = temp; - } - /* - * Read signed temperature if unsigned temperature is 0, - * or if this is the local sensor. - */ - if (!temp) { - val = i2c_smbus_read_byte_data(client, - LM95234_REG_TEMPH(index)); - if (val < 0) - return val; - temp = val << 8; - val = i2c_smbus_read_byte_data(client, - LM95234_REG_TEMPL(index)); - if (val < 0) - return val; - temp |= val; - *t = (s16)temp; - } - return 0; -} - -static u16 update_intervals[] = { 143, 364, 1000, 2500 }; - -/* Fill value cache. Must be called with update lock held. */ - -static int lm95234_fill_cache(struct i2c_client *client) -{ - struct lm95234_data *data = i2c_get_clientdata(client); - int i, ret; - - ret = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); - if (ret < 0) - return ret; - - data->interval = msecs_to_jiffies(update_intervals[ret & 0x03]); - - for (i = 0; i < ARRAY_SIZE(data->tcrit1); i++) { - ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT1(i)); - if (ret < 0) - return ret; - data->tcrit1[i] = ret; - } - for (i = 0; i < ARRAY_SIZE(data->tcrit2); i++) { - ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT2(i)); - if (ret < 0) - return ret; - data->tcrit2[i] = ret; - } - for (i = 0; i < ARRAY_SIZE(data->toffset); i++) { - ret = i2c_smbus_read_byte_data(client, LM95234_REG_OFFSET(i)); - if (ret < 0) - return ret; - data->toffset[i] = ret; - } - - ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT_HYST); - if (ret < 0) - return ret; - data->thyst = ret; - - ret = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); - if (ret < 0) - return ret; - data->sensor_type = ret; - - return 0; -} - -static int lm95234_update_device(struct i2c_client *client, - struct lm95234_data *data) -{ - int ret; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + data->interval) || - !data->valid) { - int i; - - if (!data->valid) { - ret = lm95234_fill_cache(client); - if (ret < 0) - goto abort; - } - - data->valid = false; - for (i = 0; i < ARRAY_SIZE(data->temp); i++) { - ret = lm95234_read_temp(client, i, &data->temp[i]); - if (ret < 0) - goto abort; - } - - ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_FAULT); - if (ret < 0) - goto abort; - data->status = ret; - - ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_TCRIT1); - if (ret < 0) - goto abort; - data->status |= ret << 8; - - ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_TCRIT2); - if (ret < 0) - goto abort; - data->status |= ret << 16; - - data->last_updated = jiffies; - data->valid = true; - } - ret = 0; -abort: - mutex_unlock(&data->update_lock); - - return ret; -} - -static ssize_t show_temp(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - return sprintf(buf, "%d\n", - DIV_ROUND_CLOSEST(data->temp[index] * 125, 32)); -} - -static ssize_t show_alarm(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - u32 mask = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - return sprintf(buf, "%u", !!(data->status & mask)); -} - -static ssize_t show_type(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - u8 mask = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - return sprintf(buf, data->sensor_type & mask ? "1\n" : "2\n"); -} - -static ssize_t set_type(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - unsigned long val; - u8 mask = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - ret = kstrtoul(buf, 10, &val); - if (ret < 0) - return ret; - - if (val != 1 && val != 2) - return -EINVAL; - - mutex_lock(&data->update_lock); - if (val == 1) - data->sensor_type |= mask; - else - data->sensor_type &= ~mask; - data->valid = false; - i2c_smbus_write_byte_data(client, LM95234_REG_REM_MODEL, - data->sensor_type); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_tcrit2(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - return sprintf(buf, "%u", data->tcrit2[index] * 1000); -} - -static ssize_t set_tcrit2(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - long val; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - ret = kstrtol(buf, 10, &val); - if (ret < 0) - return ret; - - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, index ? 255 : 127); - - mutex_lock(&data->update_lock); - data->tcrit2[index] = val; - i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT2(index), val); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_tcrit2_hyst(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - /* Result can be negative, so be careful with unsigned operands */ - return sprintf(buf, "%d", - ((int)data->tcrit2[index] - (int)data->thyst) * 1000); -} - -static ssize_t show_tcrit1(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - - return sprintf(buf, "%u", data->tcrit1[index] * 1000); -} - -static ssize_t set_tcrit1(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - long val; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - ret = kstrtol(buf, 10, &val); - if (ret < 0) - return ret; - - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); - - mutex_lock(&data->update_lock); - data->tcrit1[index] = val; - i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT1(index), val); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_tcrit1_hyst(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - /* Result can be negative, so be careful with unsigned operands */ - return sprintf(buf, "%d", - ((int)data->tcrit1[index] - (int)data->thyst) * 1000); -} - -static ssize_t set_tcrit1_hyst(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - long val; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - ret = kstrtol(buf, 10, &val); - if (ret < 0) - return ret; - - val = DIV_ROUND_CLOSEST(val, 1000); - val = clamp_val((int)data->tcrit1[index] - val, 0, 31); - - mutex_lock(&data->update_lock); - data->thyst = val; - i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT_HYST, val); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_offset(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - return sprintf(buf, "%d", data->toffset[index] * 500); -} - -static ssize_t set_offset(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int index = to_sensor_dev_attr(attr)->index; - long val; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - ret = kstrtol(buf, 10, &val); - if (ret < 0) - return ret; - - /* Accuracy is 1/2 degrees C */ - val = clamp_val(DIV_ROUND_CLOSEST(val, 500), -128, 127); - - mutex_lock(&data->update_lock); - data->toffset[index] = val; - i2c_smbus_write_byte_data(client, LM95234_REG_OFFSET(index), val); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_interval(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - return sprintf(buf, "%lu\n", - DIV_ROUND_CLOSEST(data->interval * 1000, HZ)); -} - -static ssize_t set_interval(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - unsigned long val; - u8 regval; - int ret = lm95234_update_device(client, data); - - if (ret) - return ret; - - ret = kstrtoul(buf, 10, &val); - if (ret < 0) - return ret; - - for (regval = 0; regval < 3; regval++) { - if (val <= update_intervals[regval]) - break; - } - - mutex_lock(&data->update_lock); - data->interval = msecs_to_jiffies(update_intervals[regval]); - i2c_smbus_write_byte_data(client, LM95234_REG_CONVRATE, regval); - mutex_unlock(&data->update_lock); - - return count; -} - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); -static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); -static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); -static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); -static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); - -static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, - BIT(0) | BIT(1)); -static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, - BIT(2) | BIT(3)); -static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_alarm, NULL, - BIT(4) | BIT(5)); -static SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_alarm, NULL, - BIT(6) | BIT(7)); - -static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type, - BIT(1)); -static SENSOR_DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type, set_type, - BIT(2)); -static SENSOR_DEVICE_ATTR(temp4_type, S_IWUSR | S_IRUGO, show_type, set_type, - BIT(3)); -static SENSOR_DEVICE_ATTR(temp5_type, S_IWUSR | S_IRUGO, show_type, set_type, - BIT(4)); - -static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_tcrit1, - set_tcrit1, 0); -static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_tcrit2, - set_tcrit2, 0); -static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_tcrit2, - set_tcrit2, 1); -static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_tcrit1, - set_tcrit1, 3); -static SENSOR_DEVICE_ATTR(temp5_max, S_IWUSR | S_IRUGO, show_tcrit1, - set_tcrit1, 4); - -static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_tcrit1_hyst, - set_tcrit1_hyst, 0); -static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO, show_tcrit2_hyst, NULL, 0); -static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO, show_tcrit2_hyst, NULL, 1); -static SENSOR_DEVICE_ATTR(temp4_max_hyst, S_IRUGO, show_tcrit1_hyst, NULL, 3); -static SENSOR_DEVICE_ATTR(temp5_max_hyst, S_IRUGO, show_tcrit1_hyst, NULL, 4); - -static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, - BIT(0 + 8)); -static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, - BIT(1 + 16)); -static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, - BIT(2 + 16)); -static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, - BIT(3 + 8)); -static SENSOR_DEVICE_ATTR(temp5_max_alarm, S_IRUGO, show_alarm, NULL, - BIT(4 + 8)); - -static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_tcrit1, - set_tcrit1, 1); -static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_tcrit1, - set_tcrit1, 2); - -static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_tcrit1_hyst, NULL, 1); -static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_tcrit1_hyst, NULL, 2); - -static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, - BIT(1 + 8)); -static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, - BIT(2 + 8)); - -static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_offset, - set_offset, 0); -static SENSOR_DEVICE_ATTR(temp3_offset, S_IWUSR | S_IRUGO, show_offset, - set_offset, 1); -static SENSOR_DEVICE_ATTR(temp4_offset, S_IWUSR | S_IRUGO, show_offset, - set_offset, 2); -static SENSOR_DEVICE_ATTR(temp5_offset, S_IWUSR | S_IRUGO, show_offset, - set_offset, 3); - -static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, - set_interval); - -static struct attribute *lm95234_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp4_input.dev_attr.attr, - &sensor_dev_attr_temp5_input.dev_attr.attr, - &sensor_dev_attr_temp2_fault.dev_attr.attr, - &sensor_dev_attr_temp3_fault.dev_attr.attr, - &sensor_dev_attr_temp4_fault.dev_attr.attr, - &sensor_dev_attr_temp5_fault.dev_attr.attr, - &sensor_dev_attr_temp2_type.dev_attr.attr, - &sensor_dev_attr_temp3_type.dev_attr.attr, - &sensor_dev_attr_temp4_type.dev_attr.attr, - &sensor_dev_attr_temp5_type.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp2_max.dev_attr.attr, - &sensor_dev_attr_temp3_max.dev_attr.attr, - &sensor_dev_attr_temp4_max.dev_attr.attr, - &sensor_dev_attr_temp5_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_crit.dev_attr.attr, - &sensor_dev_attr_temp3_crit.dev_attr.attr, - &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, - &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, - &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_offset.dev_attr.attr, - &sensor_dev_attr_temp3_offset.dev_attr.attr, - &sensor_dev_attr_temp4_offset.dev_attr.attr, - &sensor_dev_attr_temp5_offset.dev_attr.attr, - &dev_attr_update_interval.attr, - NULL -}; - -static const struct attribute_group lm95234_group = { - .attrs = lm95234_attributes, -}; - -static int lm95234_detect(struct i2c_client *client, - struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = client->adapter; - int mfg_id, chip_id, val; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - mfg_id = i2c_smbus_read_byte_data(client, LM95234_REG_MAN_ID); - if (mfg_id != NATSEMI_MAN_ID) - return -ENODEV; - - chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID); - if (chip_id != LM95234_CHIP_ID) - return -ENODEV; - - val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS); - if (val & 0x30) - return -ENODEV; - - val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); - if (val & 0xbc) - return -ENODEV; - - val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); - if (val & 0xfc) - return -ENODEV; - - val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); - if (val & 0xe1) - return -ENODEV; - - val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); - if (val & 0xe1) - return -ENODEV; - - strlcpy(info->type, "lm95234", I2C_NAME_SIZE); - return 0; -} - -static int lm95234_init_client(struct i2c_client *client) -{ - int val, model; - - /* start conversion if necessary */ - val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); - if (val < 0) - return val; - if (val & 0x40) - i2c_smbus_write_byte_data(client, LM95234_REG_CONFIG, - val & ~0x40); - - /* If diode type status reports an error, try to fix it */ - val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); - if (val < 0) - return val; - model = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); - if (model < 0) - return model; - if (model & val) { - dev_notice(&client->dev, - "Fixing remote diode type misconfiguration (0x%x)\n", - val); - i2c_smbus_write_byte_data(client, LM95234_REG_REM_MODEL, - model & ~val); - } - return 0; -} - -static int lm95234_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct device *dev = &client->dev; - struct lm95234_data *data; - int err; - - data = devm_kzalloc(dev, sizeof(struct lm95234_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - /* Initialize the LM95234 chip */ - err = lm95234_init_client(client); - if (err < 0) - return err; - - /* Register sysfs hooks */ - err = sysfs_create_group(&dev->kobj, &lm95234_group); - if (err) - return err; - - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } - - return 0; - -exit_remove_files: - sysfs_remove_group(&dev->kobj, &lm95234_group); - return err; -} - -static int lm95234_remove(struct i2c_client *client) -{ - struct lm95234_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &lm95234_group); - - return 0; -} - -/* Driver data (common to all clients) */ -static const struct i2c_device_id lm95234_id[] = { - { "lm95234", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, lm95234_id); - -static struct i2c_driver lm95234_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = DRVNAME, - }, - .probe = lm95234_probe, - .remove = lm95234_remove, - .id_table = lm95234_id, - .detect = lm95234_detect, - .address_list = normal_i2c, -}; - -module_i2c_driver(lm95234_driver); - -MODULE_AUTHOR("Guenter Roeck "); -MODULE_DESCRIPTION("LM95234 sensor driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/ltc4151.c b/trunk/drivers/hwmon/ltc4151.c index af81be1237c9..4319a94f549d 100644 --- a/trunk/drivers/hwmon/ltc4151.c +++ b/trunk/drivers/hwmon/ltc4151.c @@ -146,14 +146,14 @@ static ssize_t ltc4151_show_value(struct device *dev, /* * Input voltages. */ -static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4151_show_value, NULL, - LTC4151_VIN_H); -static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4151_show_value, NULL, - LTC4151_ADIN_H); +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, \ + ltc4151_show_value, NULL, LTC4151_VIN_H); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, \ + ltc4151_show_value, NULL, LTC4151_ADIN_H); /* Currents (via sense resistor) */ -static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4151_show_value, NULL, - LTC4151_SENSE_H); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, \ + ltc4151_show_value, NULL, LTC4151_SENSE_H); /* * Finally, construct an array of pointers to members of the above objects, diff --git a/trunk/drivers/hwmon/ltc4215.c b/trunk/drivers/hwmon/ltc4215.c index 8a142960d69e..e8876108a6b3 100644 --- a/trunk/drivers/hwmon/ltc4215.c +++ b/trunk/drivers/hwmon/ltc4215.c @@ -172,12 +172,12 @@ static ssize_t ltc4215_show_alarm(struct device *dev, struct device_attribute *da, char *buf) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da); struct ltc4215_data *data = ltc4215_update_device(dev); - const u8 reg = data->regs[LTC4215_STATUS]; - const u32 mask = attr->index; + const u8 reg = data->regs[attr->index]; + const u32 mask = attr->nr; - return snprintf(buf, PAGE_SIZE, "%u\n", !!(reg & mask)); + return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0); } /* @@ -186,29 +186,39 @@ static ssize_t ltc4215_show_alarm(struct device *dev, * for each register. */ +#define LTC4215_VOLTAGE(name, ltc4215_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4215_show_voltage, NULL, ltc4215_cmd_idx) + +#define LTC4215_CURRENT(name) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4215_show_current, NULL, 0); + +#define LTC4215_POWER(name) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4215_show_power, NULL, 0); + +#define LTC4215_ALARM(name, mask, reg) \ + static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \ + ltc4215_show_alarm, NULL, (mask), reg) + /* Construct a sensor_device_attribute structure for each register */ /* Current */ -static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4215_show_current, NULL, 0); -static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, ltc4215_show_alarm, NULL, - 1 << 2); +LTC4215_CURRENT(curr1_input); +LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); /* Power (virtual) */ -static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ltc4215_show_power, NULL, 0); +LTC4215_POWER(power1_input); /* Input Voltage */ -static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4215_show_voltage, NULL, - LTC4215_ADIN); -static SENSOR_DEVICE_ATTR(in1_max_alarm, S_IRUGO, ltc4215_show_alarm, NULL, - 1 << 0); -static SENSOR_DEVICE_ATTR(in1_min_alarm, S_IRUGO, ltc4215_show_alarm, NULL, - 1 << 1); +LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); +LTC4215_ALARM(in1_max_alarm, (1 << 0), LTC4215_STATUS); +LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); /* Output Voltage */ -static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4215_show_voltage, NULL, - LTC4215_SOURCE); -static SENSOR_DEVICE_ATTR(in2_min_alarm, S_IRUGO, ltc4215_show_alarm, NULL, - 1 << 3); +LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); +LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS); /* * Finally, construct an array of pointers to members of the above objects, diff --git a/trunk/drivers/hwmon/ltc4245.c b/trunk/drivers/hwmon/ltc4245.c index cdc1ecc6734d..3653f79dc2de 100644 --- a/trunk/drivers/hwmon/ltc4245.c +++ b/trunk/drivers/hwmon/ltc4245.c @@ -319,82 +319,80 @@ static ssize_t ltc4245_show_gpio(struct device *dev, return snprintf(buf, PAGE_SIZE, "%u\n", val * 10); } +/* + * These macros are used below in constructing device attribute objects + * for use with sysfs_create_group() to make a sysfs device file + * for each register. + */ + +#define LTC4245_VOLTAGE(name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_voltage, NULL, ltc4245_cmd_idx) + +#define LTC4245_CURRENT(name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_current, NULL, ltc4245_cmd_idx) + +#define LTC4245_POWER(name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_power, NULL, ltc4245_cmd_idx) + +#define LTC4245_ALARM(name, mask, reg) \ + static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \ + ltc4245_show_alarm, NULL, (mask), reg) + +#define LTC4245_GPIO_VOLTAGE(name, gpio_num) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_gpio, NULL, gpio_num) + /* Construct a sensor_device_attribute structure for each register */ /* Input voltages */ -static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4245_show_voltage, NULL, - LTC4245_12VIN); -static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4245_show_voltage, NULL, - LTC4245_5VIN); -static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ltc4245_show_voltage, NULL, - LTC4245_3VIN); -static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ltc4245_show_voltage, NULL, - LTC4245_VEEIN); +LTC4245_VOLTAGE(in1_input, LTC4245_12VIN); +LTC4245_VOLTAGE(in2_input, LTC4245_5VIN); +LTC4245_VOLTAGE(in3_input, LTC4245_3VIN); +LTC4245_VOLTAGE(in4_input, LTC4245_VEEIN); /* Input undervoltage alarms */ -static SENSOR_DEVICE_ATTR_2(in1_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 0, LTC4245_FAULT1); -static SENSOR_DEVICE_ATTR_2(in2_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 1, LTC4245_FAULT1); -static SENSOR_DEVICE_ATTR_2(in3_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 2, LTC4245_FAULT1); -static SENSOR_DEVICE_ATTR_2(in4_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 3, LTC4245_FAULT1); +LTC4245_ALARM(in1_min_alarm, (1 << 0), LTC4245_FAULT1); +LTC4245_ALARM(in2_min_alarm, (1 << 1), LTC4245_FAULT1); +LTC4245_ALARM(in3_min_alarm, (1 << 2), LTC4245_FAULT1); +LTC4245_ALARM(in4_min_alarm, (1 << 3), LTC4245_FAULT1); /* Currents (via sense resistor) */ -static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4245_show_current, NULL, - LTC4245_12VSENSE); -static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc4245_show_current, NULL, - LTC4245_5VSENSE); -static SENSOR_DEVICE_ATTR(curr3_input, S_IRUGO, ltc4245_show_current, NULL, - LTC4245_3VSENSE); -static SENSOR_DEVICE_ATTR(curr4_input, S_IRUGO, ltc4245_show_current, NULL, - LTC4245_VEESENSE); +LTC4245_CURRENT(curr1_input, LTC4245_12VSENSE); +LTC4245_CURRENT(curr2_input, LTC4245_5VSENSE); +LTC4245_CURRENT(curr3_input, LTC4245_3VSENSE); +LTC4245_CURRENT(curr4_input, LTC4245_VEESENSE); /* Overcurrent alarms */ -static SENSOR_DEVICE_ATTR_2(curr1_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 4, LTC4245_FAULT1); -static SENSOR_DEVICE_ATTR_2(curr2_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 5, LTC4245_FAULT1); -static SENSOR_DEVICE_ATTR_2(curr3_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 6, LTC4245_FAULT1); -static SENSOR_DEVICE_ATTR_2(curr4_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 7, LTC4245_FAULT1); +LTC4245_ALARM(curr1_max_alarm, (1 << 4), LTC4245_FAULT1); +LTC4245_ALARM(curr2_max_alarm, (1 << 5), LTC4245_FAULT1); +LTC4245_ALARM(curr3_max_alarm, (1 << 6), LTC4245_FAULT1); +LTC4245_ALARM(curr4_max_alarm, (1 << 7), LTC4245_FAULT1); /* Output voltages */ -static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ltc4245_show_voltage, NULL, - LTC4245_12VOUT); -static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ltc4245_show_voltage, NULL, - LTC4245_5VOUT); -static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ltc4245_show_voltage, NULL, - LTC4245_3VOUT); -static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, ltc4245_show_voltage, NULL, - LTC4245_VEEOUT); +LTC4245_VOLTAGE(in5_input, LTC4245_12VOUT); +LTC4245_VOLTAGE(in6_input, LTC4245_5VOUT); +LTC4245_VOLTAGE(in7_input, LTC4245_3VOUT); +LTC4245_VOLTAGE(in8_input, LTC4245_VEEOUT); /* Power Bad alarms */ -static SENSOR_DEVICE_ATTR_2(in5_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 0, LTC4245_FAULT2); -static SENSOR_DEVICE_ATTR_2(in6_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 1, LTC4245_FAULT2); -static SENSOR_DEVICE_ATTR_2(in7_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 2, LTC4245_FAULT2); -static SENSOR_DEVICE_ATTR_2(in8_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, - 1 << 3, LTC4245_FAULT2); +LTC4245_ALARM(in5_min_alarm, (1 << 0), LTC4245_FAULT2); +LTC4245_ALARM(in6_min_alarm, (1 << 1), LTC4245_FAULT2); +LTC4245_ALARM(in7_min_alarm, (1 << 2), LTC4245_FAULT2); +LTC4245_ALARM(in8_min_alarm, (1 << 3), LTC4245_FAULT2); /* GPIO voltages */ -static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, ltc4245_show_gpio, NULL, 0); -static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, ltc4245_show_gpio, NULL, 1); -static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, ltc4245_show_gpio, NULL, 2); +LTC4245_GPIO_VOLTAGE(in9_input, 0); +LTC4245_GPIO_VOLTAGE(in10_input, 1); +LTC4245_GPIO_VOLTAGE(in11_input, 2); /* Power Consumption (virtual) */ -static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ltc4245_show_power, NULL, - LTC4245_12VSENSE); -static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, ltc4245_show_power, NULL, - LTC4245_5VSENSE); -static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, ltc4245_show_power, NULL, - LTC4245_3VSENSE); -static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, ltc4245_show_power, NULL, - LTC4245_VEESENSE); +LTC4245_POWER(power1_input, LTC4245_12VSENSE); +LTC4245_POWER(power2_input, LTC4245_5VSENSE); +LTC4245_POWER(power3_input, LTC4245_3VSENSE); +LTC4245_POWER(power4_input, LTC4245_VEESENSE); /* * Finally, construct an array of pointers to members of the above objects, diff --git a/trunk/drivers/hwmon/ltc4261.c b/trunk/drivers/hwmon/ltc4261.c index 487da58ec86c..84a2d2872b20 100644 --- a/trunk/drivers/hwmon/ltc4261.c +++ b/trunk/drivers/hwmon/ltc4261.c @@ -164,13 +164,25 @@ static ssize_t ltc4261_show_bool(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", fault ? 1 : 0); } +/* + * These macros are used below in constructing device attribute objects + * for use with sysfs_create_group() to make a sysfs device file + * for each register. + */ + +#define LTC4261_VALUE(name, ltc4261_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4261_show_value, NULL, ltc4261_cmd_idx) + +#define LTC4261_BOOL(name, mask) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4261_show_bool, NULL, (mask)) + /* * Input voltages. */ -static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4261_show_value, NULL, - LTC4261_ADIN_H); -static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4261_show_value, NULL, - LTC4261_ADIN2_H); +LTC4261_VALUE(in1_input, LTC4261_ADIN_H); +LTC4261_VALUE(in2_input, LTC4261_ADIN2_H); /* * Voltage alarms. The chip has only one set of voltage alarm status bits, @@ -180,22 +192,16 @@ static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4261_show_value, NULL, * To ensure that the alarm condition is reported to the user, report it * with both voltage sensors. */ -static SENSOR_DEVICE_ATTR(in1_min_alarm, S_IRUGO, ltc4261_show_bool, NULL, - FAULT_UV); -static SENSOR_DEVICE_ATTR(in1_max_alarm, S_IRUGO, ltc4261_show_bool, NULL, - FAULT_OV); -static SENSOR_DEVICE_ATTR(in2_min_alarm, S_IRUGO, ltc4261_show_bool, NULL, - FAULT_UV); -static SENSOR_DEVICE_ATTR(in2_max_alarm, S_IRUGO, ltc4261_show_bool, NULL, - FAULT_OV); +LTC4261_BOOL(in1_min_alarm, FAULT_UV); +LTC4261_BOOL(in1_max_alarm, FAULT_OV); +LTC4261_BOOL(in2_min_alarm, FAULT_UV); +LTC4261_BOOL(in2_max_alarm, FAULT_OV); /* Currents (via sense resistor) */ -static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4261_show_value, NULL, - LTC4261_SENSE_H); +LTC4261_VALUE(curr1_input, LTC4261_SENSE_H); /* Overcurrent alarm */ -static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, ltc4261_show_bool, NULL, - FAULT_OC); +LTC4261_BOOL(curr1_max_alarm, FAULT_OC); static struct attribute *ltc4261_attributes[] = { &sensor_dev_attr_in1_input.dev_attr.attr, diff --git a/trunk/drivers/hwmon/max6697.c b/trunk/drivers/hwmon/max6697.c index 328fb0353c17..bf4aa3777fc1 100644 --- a/trunk/drivers/hwmon/max6697.c +++ b/trunk/drivers/hwmon/max6697.c @@ -399,95 +399,82 @@ static SENSOR_DEVICE_ATTR(temp6_fault, S_IRUGO, show_alarm, NULL, 5); static SENSOR_DEVICE_ATTR(temp7_fault, S_IRUGO, show_alarm, NULL, 6); static SENSOR_DEVICE_ATTR(temp8_fault, S_IRUGO, show_alarm, NULL, 7); -static DEVICE_ATTR(dummy, 0, NULL, NULL); - -static umode_t max6697_is_visible(struct kobject *kobj, struct attribute *attr, - int index) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct i2c_client *client = to_i2c_client(dev); - struct max6697_data *data = i2c_get_clientdata(client); - const struct max6697_chip_data *chip = data->chip; - int channel = index / 6; /* channel number */ - int nr = index % 6; /* attribute index within channel */ - - if (channel >= chip->channels) - return 0; - - if ((nr == 3 || nr == 4) && !(chip->have_crit & (1 << channel))) - return 0; - if (nr == 5 && !(chip->have_fault & (1 << channel))) - return 0; - - return attr->mode; -} - -/* - * max6697_is_visible uses the index into the following array to determine - * if attributes should be created or not. Any change in order or content - * must be matched in max6697_is_visible. - */ -static struct attribute *max6697_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp1_crit.dev_attr.attr, - &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, - &dev_attr_dummy.attr, - - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp2_max.dev_attr.attr, - &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_crit.dev_attr.attr, - &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_fault.dev_attr.attr, - - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp3_max.dev_attr.attr, - &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp3_crit.dev_attr.attr, - &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp3_fault.dev_attr.attr, - - &sensor_dev_attr_temp4_input.dev_attr.attr, - &sensor_dev_attr_temp4_max.dev_attr.attr, - &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp4_crit.dev_attr.attr, - &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp4_fault.dev_attr.attr, - - &sensor_dev_attr_temp5_input.dev_attr.attr, - &sensor_dev_attr_temp5_max.dev_attr.attr, - &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp5_crit.dev_attr.attr, - &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp5_fault.dev_attr.attr, - - &sensor_dev_attr_temp6_input.dev_attr.attr, - &sensor_dev_attr_temp6_max.dev_attr.attr, - &sensor_dev_attr_temp6_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp6_crit.dev_attr.attr, - &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp6_fault.dev_attr.attr, - - &sensor_dev_attr_temp7_input.dev_attr.attr, - &sensor_dev_attr_temp7_max.dev_attr.attr, - &sensor_dev_attr_temp7_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp7_crit.dev_attr.attr, - &sensor_dev_attr_temp7_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp7_fault.dev_attr.attr, - - &sensor_dev_attr_temp8_input.dev_attr.attr, - &sensor_dev_attr_temp8_max.dev_attr.attr, - &sensor_dev_attr_temp8_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp8_crit.dev_attr.attr, - &sensor_dev_attr_temp8_crit_alarm.dev_attr.attr, - &sensor_dev_attr_temp8_fault.dev_attr.attr, - NULL +static struct attribute *max6697_attributes[8][7] = { + { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_crit.dev_attr.attr, + &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_fault.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp5_max.dev_attr.attr, + &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp5_crit.dev_attr.attr, + &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp5_fault.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp6_input.dev_attr.attr, + &sensor_dev_attr_temp6_max.dev_attr.attr, + &sensor_dev_attr_temp6_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp6_crit.dev_attr.attr, + &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp6_fault.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp7_input.dev_attr.attr, + &sensor_dev_attr_temp7_max.dev_attr.attr, + &sensor_dev_attr_temp7_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp7_crit.dev_attr.attr, + &sensor_dev_attr_temp7_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp7_fault.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp8_input.dev_attr.attr, + &sensor_dev_attr_temp8_max.dev_attr.attr, + &sensor_dev_attr_temp8_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp8_crit.dev_attr.attr, + &sensor_dev_attr_temp8_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp8_fault.dev_attr.attr, + NULL + } }; -static const struct attribute_group max6697_group = { - .attrs = max6697_attributes, .is_visible = max6697_is_visible, +static const struct attribute_group max6697_group[8] = { + { .attrs = max6697_attributes[0] }, + { .attrs = max6697_attributes[1] }, + { .attrs = max6697_attributes[2] }, + { .attrs = max6697_attributes[3] }, + { .attrs = max6697_attributes[4] }, + { .attrs = max6697_attributes[5] }, + { .attrs = max6697_attributes[6] }, + { .attrs = max6697_attributes[7] }, }; static void max6697_get_config_of(struct device_node *node, @@ -619,13 +606,21 @@ static int max6697_init_chip(struct i2c_client *client) return 0; } +static void max6697_remove_files(struct i2c_client *client) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(max6697_group); i++) + sysfs_remove_group(&client->dev.kobj, &max6697_group[i]); +} + static int max6697_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = client->adapter; struct device *dev = &client->dev; struct max6697_data *data; - int err; + int i, err; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; @@ -644,9 +639,37 @@ static int max6697_probe(struct i2c_client *client, if (err) return err; - err = sysfs_create_group(&client->dev.kobj, &max6697_group); - if (err) - return err; + for (i = 0; i < data->chip->channels; i++) { + err = sysfs_create_file(&dev->kobj, + max6697_attributes[i][0]); + if (err) + goto error; + err = sysfs_create_file(&dev->kobj, + max6697_attributes[i][1]); + if (err) + goto error; + err = sysfs_create_file(&dev->kobj, + max6697_attributes[i][2]); + if (err) + goto error; + + if (data->chip->have_crit & (1 << i)) { + err = sysfs_create_file(&dev->kobj, + max6697_attributes[i][3]); + if (err) + goto error; + err = sysfs_create_file(&dev->kobj, + max6697_attributes[i][4]); + if (err) + goto error; + } + if (data->chip->have_fault & (1 << i)) { + err = sysfs_create_file(&dev->kobj, + max6697_attributes[i][5]); + if (err) + goto error; + } + } data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { @@ -657,7 +680,7 @@ static int max6697_probe(struct i2c_client *client, return 0; error: - sysfs_remove_group(&client->dev.kobj, &max6697_group); + max6697_remove_files(client); return err; } @@ -666,7 +689,7 @@ static int max6697_remove(struct i2c_client *client) struct max6697_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &max6697_group); + max6697_remove_files(client); return 0; } diff --git a/trunk/drivers/hwmon/mc13783-adc.c b/trunk/drivers/hwmon/mc13783-adc.c index 982d8622c09b..2a7f331cd3c0 100644 --- a/trunk/drivers/hwmon/mc13783-adc.c +++ b/trunk/drivers/hwmon/mc13783-adc.c @@ -273,7 +273,18 @@ static struct platform_driver mc13783_adc_driver = { .id_table = mc13783_adc_idtable, }; -module_platform_driver_probe(mc13783_adc_driver, mc13783_adc_probe); +static int __init mc13783_adc_init(void) +{ + return platform_driver_probe(&mc13783_adc_driver, mc13783_adc_probe); +} + +static void __exit mc13783_adc_exit(void) +{ + platform_driver_unregister(&mc13783_adc_driver); +} + +module_init(mc13783_adc_init); +module_exit(mc13783_adc_exit); MODULE_DESCRIPTION("MC13783 ADC driver"); MODULE_AUTHOR("Luotao Fu "); diff --git a/trunk/drivers/hwmon/nct6775.c b/trunk/drivers/hwmon/nct6775.c deleted file mode 100644 index f43f5e571db9..000000000000 --- a/trunk/drivers/hwmon/nct6775.c +++ /dev/null @@ -1,4191 +0,0 @@ -/* - * nct6775 - Driver for the hardware monitoring functionality of - * Nuvoton NCT677x Super-I/O chips - * - * Copyright (C) 2012 Guenter Roeck - * - * Derived from w83627ehf driver - * Copyright (C) 2005-2012 Jean Delvare - * Copyright (C) 2006 Yuan Mu (Winbond), - * Rudolf Marek - * David Hubbard - * Daniel J Blueman - * Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00) - * - * Shamelessly ripped from the w83627hf driver - * Copyright (C) 2003 Mark Studebaker - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - * Supports the following chips: - * - * Chip #vin #fan #pwm #temp chip IDs man ID - * nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3 - * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 - * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 - * - * #temp lists the number of monitored temperature sources (first value) plus - * the number of directly connectable temperature sensors (second value). - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lm75.h" - -#define USE_ALTERNATE - -enum kinds { nct6775, nct6776, nct6779 }; - -/* used to set data->name = nct6775_device_names[data->sio_kind] */ -static const char * const nct6775_device_names[] = { - "nct6775", - "nct6776", - "nct6779", -}; - -static unsigned short force_id; -module_param(force_id, ushort, 0); -MODULE_PARM_DESC(force_id, "Override the detected device ID"); - -static unsigned short fan_debounce; -module_param(fan_debounce, ushort, 0); -MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal"); - -#define DRVNAME "nct6775" - -/* - * Super-I/O constants and functions - */ - -#define NCT6775_LD_ACPI 0x0a -#define NCT6775_LD_HWM 0x0b -#define NCT6775_LD_VID 0x0d - -#define SIO_REG_LDSEL 0x07 /* Logical device select */ -#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ -#define SIO_REG_ENABLE 0x30 /* Logical device enable */ -#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ - -#define SIO_NCT6775_ID 0xb470 -#define SIO_NCT6776_ID 0xc330 -#define SIO_NCT6779_ID 0xc560 -#define SIO_ID_MASK 0xFFF0 - -enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; - -static inline void -superio_outb(int ioreg, int reg, int val) -{ - outb(reg, ioreg); - outb(val, ioreg + 1); -} - -static inline int -superio_inb(int ioreg, int reg) -{ - outb(reg, ioreg); - return inb(ioreg + 1); -} - -static inline void -superio_select(int ioreg, int ld) -{ - outb(SIO_REG_LDSEL, ioreg); - outb(ld, ioreg + 1); -} - -static inline int -superio_enter(int ioreg) -{ - /* - * Try to reserve and for exclusive access. - */ - if (!request_muxed_region(ioreg, 2, DRVNAME)) - return -EBUSY; - - outb(0x87, ioreg); - outb(0x87, ioreg); - - return 0; -} - -static inline void -superio_exit(int ioreg) -{ - outb(0xaa, ioreg); - outb(0x02, ioreg); - outb(0x02, ioreg + 1); - release_region(ioreg, 2); -} - -/* - * ISA constants - */ - -#define IOREGION_ALIGNMENT (~7) -#define IOREGION_OFFSET 5 -#define IOREGION_LENGTH 2 -#define ADDR_REG_OFFSET 0 -#define DATA_REG_OFFSET 1 - -#define NCT6775_REG_BANK 0x4E -#define NCT6775_REG_CONFIG 0x40 - -/* - * Not currently used: - * REG_MAN_ID has the value 0x5ca3 for all supported chips. - * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. - * REG_MAN_ID is at port 0x4f - * REG_CHIP_ID is at port 0x58 - */ - -#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/ -#define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */ - -#define NUM_REG_ALARM 4 /* Max number of alarm registers */ - -/* Common and NCT6775 specific data */ - -/* Voltage min/max registers for nr=7..14 are in bank 5 */ - -static const u16 NCT6775_REG_IN_MAX[] = { - 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a, - 0x55c, 0x55e, 0x560, 0x562 }; -static const u16 NCT6775_REG_IN_MIN[] = { - 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b, - 0x55d, 0x55f, 0x561, 0x563 }; -static const u16 NCT6775_REG_IN[] = { - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552 -}; - -#define NCT6775_REG_VBAT 0x5D -#define NCT6775_REG_DIODE 0x5E - -#define NCT6775_REG_FANDIV1 0x506 -#define NCT6775_REG_FANDIV2 0x507 - -#define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0 - -static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B }; - -/* 0..15 voltages, 16..23 fans, 24..31 temperatures */ - -static const s8 NCT6775_ALARM_BITS[] = { - 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ - 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */ - -1, /* unused */ - 6, 7, 11, 10, 23, /* fan1..fan5 */ - -1, -1, -1, /* unused */ - 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ - 12, -1 }; /* intrusion0, intrusion1 */ - -#define FAN_ALARM_BASE 16 -#define TEMP_ALARM_BASE 24 -#define INTRUSION_ALARM_BASE 30 - -static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee }; -static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 }; - -/* DC or PWM output fan configuration */ -static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 }; -static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 }; - -/* Advanced Fan control, some values are common for all fans */ - -static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301, 0x801, 0x901 }; -static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 }; -static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = { - 0x103, 0x203, 0x303, 0x803, 0x903 }; -static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = { - 0x104, 0x204, 0x304, 0x804, 0x904 }; -static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { - 0x105, 0x205, 0x305, 0x805, 0x905 }; -static const u16 NCT6775_REG_FAN_START_OUTPUT[] - = { 0x106, 0x206, 0x306, 0x806, 0x906 }; -static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a }; -static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b }; - -static const u16 NCT6775_REG_FAN_STOP_TIME[] = { - 0x107, 0x207, 0x307, 0x807, 0x907 }; -static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 }; -static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 }; - -static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; -static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; -static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 }; - -static const u16 NCT6775_REG_TEMP[] = { - 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d }; - -static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { - 0, 0x152, 0x252, 0x628, 0x629, 0x62A }; -static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] = { - 0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D }; -static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = { - 0x39, 0x155, 0x255, 0x672, 0x677, 0x67C }; - -static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = { - 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 }; - -static const u16 NCT6775_REG_TEMP_SEL[] = { - 0x100, 0x200, 0x300, 0x800, 0x900 }; - -static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = { - 0x139, 0x239, 0x339, 0x839, 0x939 }; -static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = { - 0x13a, 0x23a, 0x33a, 0x83a, 0x93a }; -static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = { - 0x13b, 0x23b, 0x33b, 0x83b, 0x93b }; -static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = { - 0x13c, 0x23c, 0x33c, 0x83c, 0x93c }; -static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = { - 0x13d, 0x23d, 0x33d, 0x83d, 0x93d }; - -static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; - -static const u16 NCT6775_REG_AUTO_TEMP[] = { - 0x121, 0x221, 0x321, 0x821, 0x921 }; -static const u16 NCT6775_REG_AUTO_PWM[] = { - 0x127, 0x227, 0x327, 0x827, 0x927 }; - -#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p)) -#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p)) - -static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 }; - -static const u16 NCT6775_REG_CRITICAL_TEMP[] = { - 0x135, 0x235, 0x335, 0x835, 0x935 }; -static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = { - 0x138, 0x238, 0x338, 0x838, 0x938 }; - -static const char *const nct6775_temp_label[] = { - "", - "SYSTIN", - "CPUTIN", - "AUXTIN", - "AMD SB-TSI", - "PECI Agent 0", - "PECI Agent 1", - "PECI Agent 2", - "PECI Agent 3", - "PECI Agent 4", - "PECI Agent 5", - "PECI Agent 6", - "PECI Agent 7", - "PCH_CHIP_CPU_MAX_TEMP", - "PCH_CHIP_TEMP", - "PCH_CPU_TEMP", - "PCH_MCH_TEMP", - "PCH_DIM0_TEMP", - "PCH_DIM1_TEMP", - "PCH_DIM2_TEMP", - "PCH_DIM3_TEMP" -}; - -static const u16 NCT6775_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6775_temp_label) - 1] - = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x661, 0x662, 0x664 }; - -static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1] - = { 0, 0, 0, 0, 0xa00, 0xa01, 0xa02, 0xa03, 0xa04, 0xa05, 0xa06, - 0xa07 }; - -/* NCT6776 specific data */ - -static const s8 NCT6776_ALARM_BITS[] = { - 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ - 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */ - -1, /* unused */ - 6, 7, 11, 10, 23, /* fan1..fan5 */ - -1, -1, -1, /* unused */ - 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ - 12, 9 }; /* intrusion0, intrusion1 */ - -static const u16 NCT6776_REG_TOLERANCE_H[] = { - 0x10c, 0x20c, 0x30c, 0x80c, 0x90c }; - -static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 }; -static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 }; - -static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; -static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 }; - -static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = { - 0x13e, 0x23e, 0x33e, 0x83e, 0x93e }; - -static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { - 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A }; - -static const char *const nct6776_temp_label[] = { - "", - "SYSTIN", - "CPUTIN", - "AUXTIN", - "SMBUSMASTER 0", - "SMBUSMASTER 1", - "SMBUSMASTER 2", - "SMBUSMASTER 3", - "SMBUSMASTER 4", - "SMBUSMASTER 5", - "SMBUSMASTER 6", - "SMBUSMASTER 7", - "PECI Agent 0", - "PECI Agent 1", - "PCH_CHIP_CPU_MAX_TEMP", - "PCH_CHIP_TEMP", - "PCH_CPU_TEMP", - "PCH_MCH_TEMP", - "PCH_DIM0_TEMP", - "PCH_DIM1_TEMP", - "PCH_DIM2_TEMP", - "PCH_DIM3_TEMP", - "BYTE_TEMP" -}; - -static const u16 NCT6776_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1] - = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x401, 0x402, 0x404 }; - -static const u16 NCT6776_REG_TEMP_CRIT[ARRAY_SIZE(nct6776_temp_label) - 1] - = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a }; - -/* NCT6779 specific data */ - -static const u16 NCT6779_REG_IN[] = { - 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487, - 0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e }; - -static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = { - 0x459, 0x45A, 0x45B, 0x568 }; - -static const s8 NCT6779_ALARM_BITS[] = { - 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ - 17, 24, 25, 26, 27, 28, 29, /* in8..in14 */ - -1, /* unused */ - 6, 7, 11, 10, 23, /* fan1..fan5 */ - -1, -1, -1, /* unused */ - 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ - 12, 9 }; /* intrusion0, intrusion1 */ - -static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 }; -static const u16 NCT6779_REG_FAN_PULSES[] = { - 0x644, 0x645, 0x646, 0x647, 0x648 }; - -static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = { - 0x136, 0x236, 0x336, 0x836, 0x936 }; -static const u16 NCT6779_REG_CRITICAL_PWM[] = { - 0x137, 0x237, 0x337, 0x837, 0x937 }; - -static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; -static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = { - 0x18, 0x152 }; -static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] = { - 0x3a, 0x153 }; -static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = { - 0x39, 0x155 }; - -static const u16 NCT6779_REG_TEMP_OFFSET[] = { - 0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c }; - -static const char *const nct6779_temp_label[] = { - "", - "SYSTIN", - "CPUTIN", - "AUXTIN0", - "AUXTIN1", - "AUXTIN2", - "AUXTIN3", - "", - "SMBUSMASTER 0", - "SMBUSMASTER 1", - "SMBUSMASTER 2", - "SMBUSMASTER 3", - "SMBUSMASTER 4", - "SMBUSMASTER 5", - "SMBUSMASTER 6", - "SMBUSMASTER 7", - "PECI Agent 0", - "PECI Agent 1", - "PCH_CHIP_CPU_MAX_TEMP", - "PCH_CHIP_TEMP", - "PCH_CPU_TEMP", - "PCH_MCH_TEMP", - "PCH_DIM0_TEMP", - "PCH_DIM1_TEMP", - "PCH_DIM2_TEMP", - "PCH_DIM3_TEMP", - "BYTE_TEMP" -}; - -static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1] - = { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407, - 0x408, 0 }; - -static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1] - = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a }; - -static enum pwm_enable reg_to_pwm_enable(int pwm, int mode) -{ - if (mode == 0 && pwm == 255) - return off; - return mode + 1; -} - -static int pwm_enable_to_reg(enum pwm_enable mode) -{ - if (mode == off) - return 0; - return mode - 1; -} - -/* - * Conversions - */ - -/* 1 is DC mode, output in ms */ -static unsigned int step_time_from_reg(u8 reg, u8 mode) -{ - return mode ? 400 * reg : 100 * reg; -} - -static u8 step_time_to_reg(unsigned int msec, u8 mode) -{ - return clamp_val((mode ? (msec + 200) / 400 : - (msec + 50) / 100), 1, 255); -} - -static unsigned int fan_from_reg8(u16 reg, unsigned int divreg) -{ - if (reg == 0 || reg == 255) - return 0; - return 1350000U / (reg << divreg); -} - -static unsigned int fan_from_reg13(u16 reg, unsigned int divreg) -{ - if ((reg & 0xff1f) == 0xff1f) - return 0; - - reg = (reg & 0x1f) | ((reg & 0xff00) >> 3); - - if (reg == 0) - return 0; - - return 1350000U / reg; -} - -static unsigned int fan_from_reg16(u16 reg, unsigned int divreg) -{ - if (reg == 0 || reg == 0xffff) - return 0; - - /* - * Even though the registers are 16 bit wide, the fan divisor - * still applies. - */ - return 1350000U / (reg << divreg); -} - -static u16 fan_to_reg(u32 fan, unsigned int divreg) -{ - if (!fan) - return 0; - - return (1350000U / fan) >> divreg; -} - -static inline unsigned int -div_from_reg(u8 reg) -{ - return 1 << reg; -} - -/* - * Some of the voltage inputs have internal scaling, the tables below - * contain 8 (the ADC LSB in mV) * scaling factor * 100 - */ -static const u16 scale_in[15] = { - 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800, - 800, 800 -}; - -static inline long in_from_reg(u8 reg, u8 nr) -{ - return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100); -} - -static inline u8 in_to_reg(u32 val, u8 nr) -{ - return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255); -} - -/* - * Data structures and manipulation thereof - */ - -struct nct6775_data { - int addr; /* IO base of hw monitor block */ - enum kinds kind; - const char *name; - - struct device *hwmon_dev; - - u16 reg_temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, - * 3=temp_crit - */ - u8 temp_src[NUM_TEMP]; - u16 reg_temp_config[NUM_TEMP]; - const char * const *temp_label; - int temp_label_num; - - u16 REG_CONFIG; - u16 REG_VBAT; - u16 REG_DIODE; - - const s8 *ALARM_BITS; - - const u16 *REG_VIN; - const u16 *REG_IN_MINMAX[2]; - - const u16 *REG_TARGET; - const u16 *REG_FAN; - const u16 *REG_FAN_MODE; - const u16 *REG_FAN_MIN; - const u16 *REG_FAN_PULSES; - const u16 *REG_FAN_TIME[3]; - - const u16 *REG_TOLERANCE_H; - - const u8 *REG_PWM_MODE; - const u8 *PWM_MODE_MASK; - - const u16 *REG_PWM[7]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, - * [3]=pwm_max, [4]=pwm_step, - * [5]=weight_duty_step, [6]=weight_duty_base - */ - const u16 *REG_PWM_READ; - - const u16 *REG_AUTO_TEMP; - const u16 *REG_AUTO_PWM; - - const u16 *REG_CRITICAL_TEMP; - const u16 *REG_CRITICAL_TEMP_TOLERANCE; - - const u16 *REG_TEMP_SOURCE; /* temp register sources */ - const u16 *REG_TEMP_SEL; - const u16 *REG_WEIGHT_TEMP_SEL; - const u16 *REG_WEIGHT_TEMP[3]; /* 0=base, 1=tolerance, 2=step */ - - const u16 *REG_TEMP_OFFSET; - - const u16 *REG_ALARM; - - unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); - unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); - - struct mutex update_lock; - bool valid; /* true if following fields are valid */ - unsigned long last_updated; /* In jiffies */ - - /* Register values */ - u8 bank; /* current register bank */ - u8 in_num; /* number of in inputs we have */ - u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ - unsigned int rpm[5]; - u16 fan_min[5]; - u8 fan_pulses[5]; - u8 fan_div[5]; - u8 has_pwm; - u8 has_fan; /* some fan inputs can be disabled */ - u8 has_fan_min; /* some fans don't have min register */ - bool has_fan_div; - - u8 temp_fixed_num; /* 3 or 6 */ - u8 temp_type[NUM_TEMP_FIXED]; - s8 temp_offset[NUM_TEMP_FIXED]; - s16 temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, - * 3=temp_crit */ - u64 alarms; - - u8 pwm_num; /* number of pwm */ - u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */ - enum pwm_enable pwm_enable[5]; - /* 0->off - * 1->manual - * 2->thermal cruise mode (also called SmartFan I) - * 3->fan speed cruise mode - * 4->SmartFan III - * 5->enhanced variable thermal cruise (SmartFan IV) - */ - u8 pwm[7][5]; /* [0]=pwm, [1]=pwm_start, [2]=pwm_floor, - * [3]=pwm_max, [4]=pwm_step, - * [5]=weight_duty_step, [6]=weight_duty_base - */ - - u8 target_temp[5]; - u8 target_temp_mask; - u32 target_speed[5]; - u32 target_speed_tolerance[5]; - u8 speed_tolerance_limit; - - u8 temp_tolerance[2][5]; - u8 tolerance_mask; - - u8 fan_time[3][5]; /* 0 = stop_time, 1 = step_up, 2 = step_down */ - - /* Automatic fan speed control registers */ - int auto_pwm_num; - u8 auto_pwm[5][7]; - u8 auto_temp[5][7]; - u8 pwm_temp_sel[5]; - u8 pwm_weight_temp_sel[5]; - u8 weight_temp[3][5]; /* 0->temp_step, 1->temp_step_tol, - * 2->temp_base - */ - - u8 vid; - u8 vrm; - - u16 have_temp; - u16 have_temp_fixed; - u16 have_in; -#ifdef CONFIG_PM - /* Remember extra register values over suspend/resume */ - u8 vbat; - u8 fandiv1; - u8 fandiv2; -#endif -}; - -struct nct6775_sio_data { - int sioreg; - enum kinds kind; -}; - -static bool is_word_sized(struct nct6775_data *data, u16 reg) -{ - switch (data->kind) { - case nct6775: - return (((reg & 0xff00) == 0x100 || - (reg & 0xff00) == 0x200) && - ((reg & 0x00ff) == 0x50 || - (reg & 0x00ff) == 0x53 || - (reg & 0x00ff) == 0x55)) || - (reg & 0xfff0) == 0x630 || - reg == 0x640 || reg == 0x642 || - reg == 0x662 || - ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) || - reg == 0x73 || reg == 0x75 || reg == 0x77; - case nct6776: - return (((reg & 0xff00) == 0x100 || - (reg & 0xff00) == 0x200) && - ((reg & 0x00ff) == 0x50 || - (reg & 0x00ff) == 0x53 || - (reg & 0x00ff) == 0x55)) || - (reg & 0xfff0) == 0x630 || - reg == 0x402 || - reg == 0x640 || reg == 0x642 || - ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) || - reg == 0x73 || reg == 0x75 || reg == 0x77; - case nct6779: - return reg == 0x150 || reg == 0x153 || reg == 0x155 || - ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x09) || - reg == 0x402 || - reg == 0x63a || reg == 0x63c || reg == 0x63e || - reg == 0x640 || reg == 0x642 || - reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 || - reg == 0x7b; - } - return false; -} - -/* - * On older chips, only registers 0x50-0x5f are banked. - * On more recent chips, all registers are banked. - * Assume that is the case and set the bank number for each access. - * Cache the bank number so it only needs to be set if it changes. - */ -static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg) -{ - u8 bank = reg >> 8; - if (data->bank != bank) { - outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET); - outb_p(bank, data->addr + DATA_REG_OFFSET); - data->bank = bank; - } -} - -static u16 nct6775_read_value(struct nct6775_data *data, u16 reg) -{ - int res, word_sized = is_word_sized(data, reg); - - nct6775_set_bank(data, reg); - outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); - res = inb_p(data->addr + DATA_REG_OFFSET); - if (word_sized) { - outb_p((reg & 0xff) + 1, - data->addr + ADDR_REG_OFFSET); - res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); - } - return res; -} - -static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value) -{ - int word_sized = is_word_sized(data, reg); - - nct6775_set_bank(data, reg); - outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); - if (word_sized) { - outb_p(value >> 8, data->addr + DATA_REG_OFFSET); - outb_p((reg & 0xff) + 1, - data->addr + ADDR_REG_OFFSET); - } - outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); - return 0; -} - -/* We left-align 8-bit temperature values to make the code simpler */ -static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg) -{ - u16 res; - - res = nct6775_read_value(data, reg); - if (!is_word_sized(data, reg)) - res <<= 8; - - return res; -} - -static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value) -{ - if (!is_word_sized(data, reg)) - value >>= 8; - return nct6775_write_value(data, reg, value); -} - -/* This function assumes that the caller holds data->update_lock */ -static void nct6775_write_fan_div(struct nct6775_data *data, int nr) -{ - u8 reg; - - switch (nr) { - case 0: - reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70) - | (data->fan_div[0] & 0x7); - nct6775_write_value(data, NCT6775_REG_FANDIV1, reg); - break; - case 1: - reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7) - | ((data->fan_div[1] << 4) & 0x70); - nct6775_write_value(data, NCT6775_REG_FANDIV1, reg); - break; - case 2: - reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70) - | (data->fan_div[2] & 0x7); - nct6775_write_value(data, NCT6775_REG_FANDIV2, reg); - break; - case 3: - reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7) - | ((data->fan_div[3] << 4) & 0x70); - nct6775_write_value(data, NCT6775_REG_FANDIV2, reg); - break; - } -} - -static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr) -{ - if (data->kind == nct6775) - nct6775_write_fan_div(data, nr); -} - -static void nct6775_update_fan_div(struct nct6775_data *data) -{ - u8 i; - - i = nct6775_read_value(data, NCT6775_REG_FANDIV1); - data->fan_div[0] = i & 0x7; - data->fan_div[1] = (i & 0x70) >> 4; - i = nct6775_read_value(data, NCT6775_REG_FANDIV2); - data->fan_div[2] = i & 0x7; - if (data->has_fan & (1 << 3)) - data->fan_div[3] = (i & 0x70) >> 4; -} - -static void nct6775_update_fan_div_common(struct nct6775_data *data) -{ - if (data->kind == nct6775) - nct6775_update_fan_div(data); -} - -static void nct6775_init_fan_div(struct nct6775_data *data) -{ - int i; - - nct6775_update_fan_div_common(data); - /* - * For all fans, start with highest divider value if the divider - * register is not initialized. This ensures that we get a - * reading from the fan count register, even if it is not optimal. - * We'll compute a better divider later on. - */ - for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) { - if (!(data->has_fan & (1 << i))) - continue; - if (data->fan_div[i] == 0) { - data->fan_div[i] = 7; - nct6775_write_fan_div_common(data, i); - } - } -} - -static void nct6775_init_fan_common(struct device *dev, - struct nct6775_data *data) -{ - int i; - u8 reg; - - if (data->has_fan_div) - nct6775_init_fan_div(data); - - /* - * If fan_min is not set (0), set it to 0xff to disable it. This - * prevents the unnecessary warning when fanX_min is reported as 0. - */ - for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { - if (data->has_fan_min & (1 << i)) { - reg = nct6775_read_value(data, data->REG_FAN_MIN[i]); - if (!reg) - nct6775_write_value(data, data->REG_FAN_MIN[i], - data->has_fan_div ? 0xff - : 0xff1f); - } - } -} - -static void nct6775_select_fan_div(struct device *dev, - struct nct6775_data *data, int nr, u16 reg) -{ - u8 fan_div = data->fan_div[nr]; - u16 fan_min; - - if (!data->has_fan_div) - return; - - /* - * If we failed to measure the fan speed, or the reported value is not - * in the optimal range, and the clock divider can be modified, - * let's try that for next time. - */ - if (reg == 0x00 && fan_div < 0x07) - fan_div++; - else if (reg != 0x00 && reg < 0x30 && fan_div > 0) - fan_div--; - - if (fan_div != data->fan_div[nr]) { - dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n", - nr + 1, div_from_reg(data->fan_div[nr]), - div_from_reg(fan_div)); - - /* Preserve min limit if possible */ - if (data->has_fan_min & (1 << nr)) { - fan_min = data->fan_min[nr]; - if (fan_div > data->fan_div[nr]) { - if (fan_min != 255 && fan_min > 1) - fan_min >>= 1; - } else { - if (fan_min != 255) { - fan_min <<= 1; - if (fan_min > 254) - fan_min = 254; - } - } - if (fan_min != data->fan_min[nr]) { - data->fan_min[nr] = fan_min; - nct6775_write_value(data, data->REG_FAN_MIN[nr], - fan_min); - } - } - data->fan_div[nr] = fan_div; - nct6775_write_fan_div_common(data, nr); - } -} - -static void nct6775_update_pwm(struct device *dev) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - int i, j; - int fanmodecfg, reg; - bool duty_is_dc; - - for (i = 0; i < data->pwm_num; i++) { - if (!(data->has_pwm & (1 << i))) - continue; - - duty_is_dc = data->REG_PWM_MODE[i] && - (nct6775_read_value(data, data->REG_PWM_MODE[i]) - & data->PWM_MODE_MASK[i]); - data->pwm_mode[i] = duty_is_dc; - - fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]); - for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) { - if (data->REG_PWM[j] && data->REG_PWM[j][i]) { - data->pwm[j][i] - = nct6775_read_value(data, - data->REG_PWM[j][i]); - } - } - - data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i], - (fanmodecfg >> 4) & 7); - - if (!data->temp_tolerance[0][i] || - data->pwm_enable[i] != speed_cruise) - data->temp_tolerance[0][i] = fanmodecfg & 0x0f; - if (!data->target_speed_tolerance[i] || - data->pwm_enable[i] == speed_cruise) { - u8 t = fanmodecfg & 0x0f; - if (data->REG_TOLERANCE_H) { - t |= (nct6775_read_value(data, - data->REG_TOLERANCE_H[i]) & 0x70) >> 1; - } - data->target_speed_tolerance[i] = t; - } - - data->temp_tolerance[1][i] = - nct6775_read_value(data, - data->REG_CRITICAL_TEMP_TOLERANCE[i]); - - reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]); - data->pwm_temp_sel[i] = reg & 0x1f; - /* If fan can stop, report floor as 0 */ - if (reg & 0x80) - data->pwm[2][i] = 0; - - reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]); - data->pwm_weight_temp_sel[i] = reg & 0x1f; - /* If weight is disabled, report weight source as 0 */ - if (j == 1 && !(reg & 0x80)) - data->pwm_weight_temp_sel[i] = 0; - - /* Weight temp data */ - for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) { - data->weight_temp[j][i] - = nct6775_read_value(data, - data->REG_WEIGHT_TEMP[j][i]); - } - } -} - -static void nct6775_update_pwm_limits(struct device *dev) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - int i, j; - u8 reg; - u16 reg_t; - - for (i = 0; i < data->pwm_num; i++) { - if (!(data->has_pwm & (1 << i))) - continue; - - for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) { - data->fan_time[j][i] = - nct6775_read_value(data, data->REG_FAN_TIME[j][i]); - } - - reg_t = nct6775_read_value(data, data->REG_TARGET[i]); - /* Update only in matching mode or if never updated */ - if (!data->target_temp[i] || - data->pwm_enable[i] == thermal_cruise) - data->target_temp[i] = reg_t & data->target_temp_mask; - if (!data->target_speed[i] || - data->pwm_enable[i] == speed_cruise) { - if (data->REG_TOLERANCE_H) { - reg_t |= (nct6775_read_value(data, - data->REG_TOLERANCE_H[i]) & 0x0f) << 8; - } - data->target_speed[i] = reg_t; - } - - for (j = 0; j < data->auto_pwm_num; j++) { - data->auto_pwm[i][j] = - nct6775_read_value(data, - NCT6775_AUTO_PWM(data, i, j)); - data->auto_temp[i][j] = - nct6775_read_value(data, - NCT6775_AUTO_TEMP(data, i, j)); - } - - /* critical auto_pwm temperature data */ - data->auto_temp[i][data->auto_pwm_num] = - nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]); - - switch (data->kind) { - case nct6775: - reg = nct6775_read_value(data, - NCT6775_REG_CRITICAL_ENAB[i]); - data->auto_pwm[i][data->auto_pwm_num] = - (reg & 0x02) ? 0xff : 0x00; - break; - case nct6776: - data->auto_pwm[i][data->auto_pwm_num] = 0xff; - break; - case nct6779: - reg = nct6775_read_value(data, - NCT6779_REG_CRITICAL_PWM_ENABLE[i]); - if (reg & 1) - data->auto_pwm[i][data->auto_pwm_num] = - nct6775_read_value(data, - NCT6779_REG_CRITICAL_PWM[i]); - else - data->auto_pwm[i][data->auto_pwm_num] = 0xff; - break; - } - } -} - -static struct nct6775_data *nct6775_update_device(struct device *dev) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - int i, j; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - /* Fan clock dividers */ - nct6775_update_fan_div_common(data); - - /* Measured voltages and limits */ - for (i = 0; i < data->in_num; i++) { - if (!(data->have_in & (1 << i))) - continue; - - data->in[i][0] = nct6775_read_value(data, - data->REG_VIN[i]); - data->in[i][1] = nct6775_read_value(data, - data->REG_IN_MINMAX[0][i]); - data->in[i][2] = nct6775_read_value(data, - data->REG_IN_MINMAX[1][i]); - } - - /* Measured fan speeds and limits */ - for (i = 0; i < ARRAY_SIZE(data->rpm); i++) { - u16 reg; - - if (!(data->has_fan & (1 << i))) - continue; - - reg = nct6775_read_value(data, data->REG_FAN[i]); - data->rpm[i] = data->fan_from_reg(reg, - data->fan_div[i]); - - if (data->has_fan_min & (1 << i)) - data->fan_min[i] = nct6775_read_value(data, - data->REG_FAN_MIN[i]); - data->fan_pulses[i] = - nct6775_read_value(data, data->REG_FAN_PULSES[i]); - - nct6775_select_fan_div(dev, data, i, reg); - } - - nct6775_update_pwm(dev); - nct6775_update_pwm_limits(dev); - - /* Measured temperatures and limits */ - for (i = 0; i < NUM_TEMP; i++) { - if (!(data->have_temp & (1 << i))) - continue; - for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) { - if (data->reg_temp[j][i]) - data->temp[j][i] - = nct6775_read_temp(data, - data->reg_temp[j][i]); - } - if (!(data->have_temp_fixed & (1 << i))) - continue; - data->temp_offset[i] - = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]); - } - - data->alarms = 0; - for (i = 0; i < NUM_REG_ALARM; i++) { - u8 alarm; - if (!data->REG_ALARM[i]) - continue; - alarm = nct6775_read_value(data, data->REG_ALARM[i]); - data->alarms |= ((u64)alarm) << (i << 3); - } - - data->last_updated = jiffies; - data->valid = true; - } - - mutex_unlock(&data->update_lock); - return data; -} - -/* - * Sysfs callback functions - */ -static ssize_t -show_in_reg(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr)); -} - -static ssize_t -store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - unsigned long val; - int err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - mutex_lock(&data->update_lock); - data->in[nr][index] = in_to_reg(val, nr); - nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], - data->in[nr][index]); - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t -show_alarm(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = data->ALARM_BITS[sattr->index]; - return sprintf(buf, "%u\n", - (unsigned int)((data->alarms >> nr) & 0x01)); -} - -static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0); -static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0); -static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0); -static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in_reg, NULL, 3, 0); -static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in_reg, NULL, 4, 0); -static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in_reg, NULL, 5, 0); -static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in_reg, NULL, 6, 0); -static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in_reg, NULL, 7, 0); -static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in_reg, NULL, 8, 0); -static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in_reg, NULL, 9, 0); -static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in_reg, NULL, 10, 0); -static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in_reg, NULL, 11, 0); -static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in_reg, NULL, 12, 0); -static SENSOR_DEVICE_ATTR_2(in13_input, S_IRUGO, show_in_reg, NULL, 13, 0); -static SENSOR_DEVICE_ATTR_2(in14_input, S_IRUGO, show_in_reg, NULL, 14, 0); - -static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); -static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); -static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); -static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); -static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4); -static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5); -static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6); -static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7); -static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8); -static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9); -static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10); -static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, 11); -static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, 12); -static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, 13); -static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_alarm, NULL, 14); - -static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 0, 1); -static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 1, 1); -static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 2, 1); -static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 3, 1); -static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 4, 1); -static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 5, 1); -static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 6, 1); -static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 7, 1); -static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 8, 1); -static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 9, 1); -static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 10, 1); -static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 11, 1); -static SENSOR_DEVICE_ATTR_2(in12_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 12, 1); -static SENSOR_DEVICE_ATTR_2(in13_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 13, 1); -static SENSOR_DEVICE_ATTR_2(in14_min, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 14, 1); - -static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 0, 2); -static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 1, 2); -static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 2, 2); -static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 3, 2); -static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 4, 2); -static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 5, 2); -static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 6, 2); -static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 7, 2); -static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 8, 2); -static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 9, 2); -static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 10, 2); -static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 11, 2); -static SENSOR_DEVICE_ATTR_2(in12_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 12, 2); -static SENSOR_DEVICE_ATTR_2(in13_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 13, 2); -static SENSOR_DEVICE_ATTR_2(in14_max, S_IWUSR | S_IRUGO, show_in_reg, - store_in_reg, 14, 2); - -static struct attribute *nct6775_attributes_in[15][5] = { - { - &sensor_dev_attr_in0_input.dev_attr.attr, - &sensor_dev_attr_in0_min.dev_attr.attr, - &sensor_dev_attr_in0_max.dev_attr.attr, - &sensor_dev_attr_in0_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in1_input.dev_attr.attr, - &sensor_dev_attr_in1_min.dev_attr.attr, - &sensor_dev_attr_in1_max.dev_attr.attr, - &sensor_dev_attr_in1_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in2_input.dev_attr.attr, - &sensor_dev_attr_in2_min.dev_attr.attr, - &sensor_dev_attr_in2_max.dev_attr.attr, - &sensor_dev_attr_in2_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in3_input.dev_attr.attr, - &sensor_dev_attr_in3_min.dev_attr.attr, - &sensor_dev_attr_in3_max.dev_attr.attr, - &sensor_dev_attr_in3_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in4_input.dev_attr.attr, - &sensor_dev_attr_in4_min.dev_attr.attr, - &sensor_dev_attr_in4_max.dev_attr.attr, - &sensor_dev_attr_in4_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in5_input.dev_attr.attr, - &sensor_dev_attr_in5_min.dev_attr.attr, - &sensor_dev_attr_in5_max.dev_attr.attr, - &sensor_dev_attr_in5_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in6_input.dev_attr.attr, - &sensor_dev_attr_in6_min.dev_attr.attr, - &sensor_dev_attr_in6_max.dev_attr.attr, - &sensor_dev_attr_in6_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in7_input.dev_attr.attr, - &sensor_dev_attr_in7_min.dev_attr.attr, - &sensor_dev_attr_in7_max.dev_attr.attr, - &sensor_dev_attr_in7_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in8_input.dev_attr.attr, - &sensor_dev_attr_in8_min.dev_attr.attr, - &sensor_dev_attr_in8_max.dev_attr.attr, - &sensor_dev_attr_in8_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in9_input.dev_attr.attr, - &sensor_dev_attr_in9_min.dev_attr.attr, - &sensor_dev_attr_in9_max.dev_attr.attr, - &sensor_dev_attr_in9_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in10_input.dev_attr.attr, - &sensor_dev_attr_in10_min.dev_attr.attr, - &sensor_dev_attr_in10_max.dev_attr.attr, - &sensor_dev_attr_in10_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in11_input.dev_attr.attr, - &sensor_dev_attr_in11_min.dev_attr.attr, - &sensor_dev_attr_in11_max.dev_attr.attr, - &sensor_dev_attr_in11_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in12_input.dev_attr.attr, - &sensor_dev_attr_in12_min.dev_attr.attr, - &sensor_dev_attr_in12_max.dev_attr.attr, - &sensor_dev_attr_in12_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in13_input.dev_attr.attr, - &sensor_dev_attr_in13_min.dev_attr.attr, - &sensor_dev_attr_in13_max.dev_attr.attr, - &sensor_dev_attr_in13_alarm.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_in14_input.dev_attr.attr, - &sensor_dev_attr_in14_min.dev_attr.attr, - &sensor_dev_attr_in14_max.dev_attr.attr, - &sensor_dev_attr_in14_alarm.dev_attr.attr, - NULL - }, -}; - -static const struct attribute_group nct6775_group_in[15] = { - { .attrs = nct6775_attributes_in[0] }, - { .attrs = nct6775_attributes_in[1] }, - { .attrs = nct6775_attributes_in[2] }, - { .attrs = nct6775_attributes_in[3] }, - { .attrs = nct6775_attributes_in[4] }, - { .attrs = nct6775_attributes_in[5] }, - { .attrs = nct6775_attributes_in[6] }, - { .attrs = nct6775_attributes_in[7] }, - { .attrs = nct6775_attributes_in[8] }, - { .attrs = nct6775_attributes_in[9] }, - { .attrs = nct6775_attributes_in[10] }, - { .attrs = nct6775_attributes_in[11] }, - { .attrs = nct6775_attributes_in[12] }, - { .attrs = nct6775_attributes_in[13] }, - { .attrs = nct6775_attributes_in[14] }, -}; - -static ssize_t -show_fan(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - return sprintf(buf, "%d\n", data->rpm[nr]); -} - -static ssize_t -show_fan_min(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - return sprintf(buf, "%d\n", - data->fan_from_reg_min(data->fan_min[nr], - data->fan_div[nr])); -} - -static ssize_t -show_fan_div(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr])); -} - -static ssize_t -store_fan_min(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err; - unsigned int reg; - u8 new_div; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - mutex_lock(&data->update_lock); - if (!data->has_fan_div) { - /* NCT6776F or NCT6779D; we know this is a 13 bit register */ - if (!val) { - val = 0xff1f; - } else { - if (val > 1350000U) - val = 135000U; - val = 1350000U / val; - val = (val & 0x1f) | ((val << 3) & 0xff00); - } - data->fan_min[nr] = val; - goto write_min; /* Leave fan divider alone */ - } - if (!val) { - /* No min limit, alarm disabled */ - data->fan_min[nr] = 255; - new_div = data->fan_div[nr]; /* No change */ - dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1); - goto write_div; - } - reg = 1350000U / val; - if (reg >= 128 * 255) { - /* - * Speed below this value cannot possibly be represented, - * even with the highest divider (128) - */ - data->fan_min[nr] = 254; - new_div = 7; /* 128 == (1 << 7) */ - dev_warn(dev, - "fan%u low limit %lu below minimum %u, set to minimum\n", - nr + 1, val, data->fan_from_reg_min(254, 7)); - } else if (!reg) { - /* - * Speed above this value cannot possibly be represented, - * even with the lowest divider (1) - */ - data->fan_min[nr] = 1; - new_div = 0; /* 1 == (1 << 0) */ - dev_warn(dev, - "fan%u low limit %lu above maximum %u, set to maximum\n", - nr + 1, val, data->fan_from_reg_min(1, 0)); - } else { - /* - * Automatically pick the best divider, i.e. the one such - * that the min limit will correspond to a register value - * in the 96..192 range - */ - new_div = 0; - while (reg > 192 && new_div < 7) { - reg >>= 1; - new_div++; - } - data->fan_min[nr] = reg; - } - -write_div: - /* - * Write both the fan clock divider (if it changed) and the new - * fan min (unconditionally) - */ - if (new_div != data->fan_div[nr]) { - dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", - nr + 1, div_from_reg(data->fan_div[nr]), - div_from_reg(new_div)); - data->fan_div[nr] = new_div; - nct6775_write_fan_div_common(data, nr); - /* Give the chip time to sample a new speed value */ - data->last_updated = jiffies; - } - -write_min: - nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t -show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int p = data->fan_pulses[sattr->index]; - - return sprintf(buf, "%d\n", p ? : 4); -} - -static ssize_t -store_fan_pulses(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - if (val > 4) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->fan_pulses[nr] = val & 3; - nct6775_write_value(data, data->REG_FAN_PULSES[nr], val & 3); - mutex_unlock(&data->update_lock); - - return count; -} - -static struct sensor_device_attribute sda_fan_input[] = { - SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), - SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), - SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), - SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), - SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), -}; - -static struct sensor_device_attribute sda_fan_alarm[] = { - SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE), - SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 1), - SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 2), - SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 3), - SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, FAN_ALARM_BASE + 4), -}; - -static struct sensor_device_attribute sda_fan_min[] = { - SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 0), - SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 1), - SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 2), - SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 3), - SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 4), -}; - -static struct sensor_device_attribute sda_fan_pulses[] = { - SENSOR_ATTR(fan1_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, - store_fan_pulses, 0), - SENSOR_ATTR(fan2_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, - store_fan_pulses, 1), - SENSOR_ATTR(fan3_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, - store_fan_pulses, 2), - SENSOR_ATTR(fan4_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, - store_fan_pulses, 3), - SENSOR_ATTR(fan5_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, - store_fan_pulses, 4), -}; - -static struct sensor_device_attribute sda_fan_div[] = { - SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), - SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), - SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2), - SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3), - SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4), -}; - -static ssize_t -show_temp_label(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]); -} - -static ssize_t -show_temp(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - - return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr])); -} - -static ssize_t -store_temp(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - int err; - long val; - - err = kstrtol(buf, 10, &val); - if (err < 0) - return err; - - mutex_lock(&data->update_lock); - data->temp[index][nr] = LM75_TEMP_TO_REG(val); - nct6775_write_temp(data, data->reg_temp[index][nr], - data->temp[index][nr]); - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t -show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - - return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000); -} - -static ssize_t -store_temp_offset(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - long val; - int err; - - err = kstrtol(buf, 10, &val); - if (err < 0) - return err; - - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); - - mutex_lock(&data->update_lock); - data->temp_offset[nr] = val; - nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t -show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - return sprintf(buf, "%d\n", (int)data->temp_type[nr]); -} - -static ssize_t -store_temp_type(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err; - u8 vbat, diode, bit; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - if (val != 1 && val != 3 && val != 4) - return -EINVAL; - - mutex_lock(&data->update_lock); - - data->temp_type[nr] = val; - vbat = nct6775_read_value(data, data->REG_VBAT) & ~(0x02 << nr); - diode = nct6775_read_value(data, data->REG_DIODE) & ~(0x02 << nr); - bit = 0x02 << nr; - switch (val) { - case 1: /* CPU diode (diode, current mode) */ - vbat |= bit; - diode |= bit; - break; - case 3: /* diode, voltage mode */ - vbat |= bit; - break; - case 4: /* thermistor */ - break; - } - nct6775_write_value(data, data->REG_VBAT, vbat); - nct6775_write_value(data, data->REG_DIODE, diode); - - mutex_unlock(&data->update_lock); - return count; -} - -static struct sensor_device_attribute_2 sda_temp_input[] = { - SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), - SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0), - SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0), - SENSOR_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0), - SENSOR_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0), - SENSOR_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0), - SENSOR_ATTR_2(temp7_input, S_IRUGO, show_temp, NULL, 6, 0), - SENSOR_ATTR_2(temp8_input, S_IRUGO, show_temp, NULL, 7, 0), - SENSOR_ATTR_2(temp9_input, S_IRUGO, show_temp, NULL, 8, 0), - SENSOR_ATTR_2(temp10_input, S_IRUGO, show_temp, NULL, 9, 0), -}; - -static struct sensor_device_attribute sda_temp_label[] = { - SENSOR_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0), - SENSOR_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1), - SENSOR_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2), - SENSOR_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3), - SENSOR_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4), - SENSOR_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5), - SENSOR_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6), - SENSOR_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7), - SENSOR_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8), - SENSOR_ATTR(temp10_label, S_IRUGO, show_temp_label, NULL, 9), -}; - -static struct sensor_device_attribute_2 sda_temp_max[] = { - SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 0, 1), - SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 1, 1), - SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 2, 1), - SENSOR_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 3, 1), - SENSOR_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 4, 1), - SENSOR_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 5, 1), - SENSOR_ATTR_2(temp7_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 6, 1), - SENSOR_ATTR_2(temp8_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 7, 1), - SENSOR_ATTR_2(temp9_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 8, 1), - SENSOR_ATTR_2(temp10_max, S_IRUGO | S_IWUSR, show_temp, store_temp, - 9, 1), -}; - -static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { - SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 0, 2), - SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 1, 2), - SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 2, 2), - SENSOR_ATTR_2(temp4_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 3, 2), - SENSOR_ATTR_2(temp5_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 4, 2), - SENSOR_ATTR_2(temp6_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 5, 2), - SENSOR_ATTR_2(temp7_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 6, 2), - SENSOR_ATTR_2(temp8_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 7, 2), - SENSOR_ATTR_2(temp9_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 8, 2), - SENSOR_ATTR_2(temp10_max_hyst, S_IRUGO | S_IWUSR, show_temp, store_temp, - 9, 2), -}; - -static struct sensor_device_attribute_2 sda_temp_crit[] = { - SENSOR_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 0, 3), - SENSOR_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 1, 3), - SENSOR_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 2, 3), - SENSOR_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 3, 3), - SENSOR_ATTR_2(temp5_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 4, 3), - SENSOR_ATTR_2(temp6_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 5, 3), - SENSOR_ATTR_2(temp7_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 6, 3), - SENSOR_ATTR_2(temp8_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 7, 3), - SENSOR_ATTR_2(temp9_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 8, 3), - SENSOR_ATTR_2(temp10_crit, S_IRUGO | S_IWUSR, show_temp, store_temp, - 9, 3), -}; - -static struct sensor_device_attribute sda_temp_offset[] = { - SENSOR_ATTR(temp1_offset, S_IRUGO | S_IWUSR, show_temp_offset, - store_temp_offset, 0), - SENSOR_ATTR(temp2_offset, S_IRUGO | S_IWUSR, show_temp_offset, - store_temp_offset, 1), - SENSOR_ATTR(temp3_offset, S_IRUGO | S_IWUSR, show_temp_offset, - store_temp_offset, 2), - SENSOR_ATTR(temp4_offset, S_IRUGO | S_IWUSR, show_temp_offset, - store_temp_offset, 3), - SENSOR_ATTR(temp5_offset, S_IRUGO | S_IWUSR, show_temp_offset, - store_temp_offset, 4), - SENSOR_ATTR(temp6_offset, S_IRUGO | S_IWUSR, show_temp_offset, - store_temp_offset, 5), -}; - -static struct sensor_device_attribute sda_temp_type[] = { - SENSOR_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type, - store_temp_type, 0), - SENSOR_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type, - store_temp_type, 1), - SENSOR_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type, - store_temp_type, 2), - SENSOR_ATTR(temp4_type, S_IRUGO | S_IWUSR, show_temp_type, - store_temp_type, 3), - SENSOR_ATTR(temp5_type, S_IRUGO | S_IWUSR, show_temp_type, - store_temp_type, 4), - SENSOR_ATTR(temp6_type, S_IRUGO | S_IWUSR, show_temp_type, - store_temp_type, 5), -}; - -static struct sensor_device_attribute sda_temp_alarm[] = { - SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, - TEMP_ALARM_BASE), - SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, - TEMP_ALARM_BASE + 1), - SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, - TEMP_ALARM_BASE + 2), - SENSOR_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, - TEMP_ALARM_BASE + 3), - SENSOR_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, - TEMP_ALARM_BASE + 4), - SENSOR_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL, - TEMP_ALARM_BASE + 5), -}; - -#define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm) - -static ssize_t -show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - - return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]); -} - -static ssize_t -store_pwm_mode(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err; - u8 reg; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - if (val > 1) - return -EINVAL; - - /* Setting DC mode is not supported for all chips/channels */ - if (data->REG_PWM_MODE[nr] == 0) { - if (val) - return -EINVAL; - return count; - } - - mutex_lock(&data->update_lock); - data->pwm_mode[nr] = val; - reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]); - reg &= ~data->PWM_MODE_MASK[nr]; - if (val) - reg |= data->PWM_MODE_MASK[nr]; - nct6775_write_value(data, data->REG_PWM_MODE[nr], reg); - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t -show_pwm(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - int pwm; - - /* - * For automatic fan control modes, show current pwm readings. - * Otherwise, show the configured value. - */ - if (index == 0 && data->pwm_enable[nr] > manual) - pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]); - else - pwm = data->pwm[index][nr]; - - return sprintf(buf, "%d\n", pwm); -} - -static ssize_t -store_pwm(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - unsigned long val; - int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 }; - int maxval[7] - = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 }; - int err; - u8 reg; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - val = clamp_val(val, minval[index], maxval[index]); - - mutex_lock(&data->update_lock); - data->pwm[index][nr] = val; - nct6775_write_value(data, data->REG_PWM[index][nr], val); - if (index == 2) { /* floor: disable if val == 0 */ - reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]); - reg &= 0x7f; - if (val) - reg |= 0x80; - nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg); - } - mutex_unlock(&data->update_lock); - return count; -} - -/* Returns 0 if OK, -EINVAL otherwise */ -static int check_trip_points(struct nct6775_data *data, int nr) -{ - int i; - - for (i = 0; i < data->auto_pwm_num - 1; i++) { - if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1]) - return -EINVAL; - } - for (i = 0; i < data->auto_pwm_num - 1; i++) { - if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1]) - return -EINVAL; - } - /* validate critical temperature and pwm if enabled (pwm > 0) */ - if (data->auto_pwm[nr][data->auto_pwm_num]) { - if (data->auto_temp[nr][data->auto_pwm_num - 1] > - data->auto_temp[nr][data->auto_pwm_num] || - data->auto_pwm[nr][data->auto_pwm_num - 1] > - data->auto_pwm[nr][data->auto_pwm_num]) - return -EINVAL; - } - return 0; -} - -static void pwm_update_registers(struct nct6775_data *data, int nr) -{ - u8 reg; - - switch (data->pwm_enable[nr]) { - case off: - case manual: - break; - case speed_cruise: - reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); - reg = (reg & ~data->tolerance_mask) | - (data->target_speed_tolerance[nr] & data->tolerance_mask); - nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); - nct6775_write_value(data, data->REG_TARGET[nr], - data->target_speed[nr] & 0xff); - if (data->REG_TOLERANCE_H) { - reg = (data->target_speed[nr] >> 8) & 0x0f; - reg |= (data->target_speed_tolerance[nr] & 0x38) << 1; - nct6775_write_value(data, - data->REG_TOLERANCE_H[nr], - reg); - } - break; - case thermal_cruise: - nct6775_write_value(data, data->REG_TARGET[nr], - data->target_temp[nr]); - /* intentional */ - default: - reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); - reg = (reg & ~data->tolerance_mask) | - data->temp_tolerance[0][nr]; - nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); - break; - } -} - -static ssize_t -show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - - return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]); -} - -static ssize_t -store_pwm_enable(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err; - u16 reg; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - if (val > sf4) - return -EINVAL; - - if (val == sf3 && data->kind != nct6775) - return -EINVAL; - - if (val == sf4 && check_trip_points(data, nr)) { - dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n"); - dev_err(dev, "Adjust trip points and try again\n"); - return -EINVAL; - } - - mutex_lock(&data->update_lock); - data->pwm_enable[nr] = val; - if (val == off) { - /* - * turn off pwm control: select manual mode, set pwm to maximum - */ - data->pwm[0][nr] = 255; - nct6775_write_value(data, data->REG_PWM[0][nr], 255); - } - pwm_update_registers(data, nr); - reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); - reg &= 0x0f; - reg |= pwm_enable_to_reg(val) << 4; - nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t -show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src) -{ - int i, sel = 0; - - for (i = 0; i < NUM_TEMP; i++) { - if (!(data->have_temp & (1 << i))) - continue; - if (src == data->temp_src[i]) { - sel = i + 1; - break; - } - } - - return sprintf(buf, "%d\n", sel); -} - -static ssize_t -show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int index = sattr->index; - - return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]); -} - -static ssize_t -store_pwm_temp_sel(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err, reg, src; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - if (val == 0 || val > NUM_TEMP) - return -EINVAL; - if (!(data->have_temp & (1 << (val - 1))) || !data->temp_src[val - 1]) - return -EINVAL; - - mutex_lock(&data->update_lock); - src = data->temp_src[val - 1]; - data->pwm_temp_sel[nr] = src; - reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]); - reg &= 0xe0; - reg |= src; - nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t -show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int index = sattr->index; - - return show_pwm_temp_sel_common(data, buf, - data->pwm_weight_temp_sel[index]); -} - -static ssize_t -store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err, reg, src; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - if (val > NUM_TEMP) - return -EINVAL; - if (val && (!(data->have_temp & (1 << (val - 1))) || - !data->temp_src[val - 1])) - return -EINVAL; - - mutex_lock(&data->update_lock); - if (val) { - src = data->temp_src[val - 1]; - data->pwm_weight_temp_sel[nr] = src; - reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); - reg &= 0xe0; - reg |= (src | 0x80); - nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); - } else { - data->pwm_weight_temp_sel[nr] = 0; - reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); - reg &= 0x7f; - nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); - } - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t -show_target_temp(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - - return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000); -} - -static ssize_t -store_target_temp(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, - data->target_temp_mask); - - mutex_lock(&data->update_lock); - data->target_temp[nr] = val; - pwm_update_registers(data, nr); - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t -show_target_speed(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - - return sprintf(buf, "%d\n", - fan_from_reg16(data->target_speed[nr], - data->fan_div[nr])); -} - -static ssize_t -store_target_speed(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err; - u16 speed; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - val = clamp_val(val, 0, 1350000U); - speed = fan_to_reg(val, data->fan_div[nr]); - - mutex_lock(&data->update_lock); - data->target_speed[nr] = speed; - pwm_update_registers(data, nr); - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t -show_temp_tolerance(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - - return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000); -} - -static ssize_t -store_temp_tolerance(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - unsigned long val; - int err; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - /* Limit tolerance as needed */ - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask); - - mutex_lock(&data->update_lock); - data->temp_tolerance[index][nr] = val; - if (index) - pwm_update_registers(data, nr); - else - nct6775_write_value(data, - data->REG_CRITICAL_TEMP_TOLERANCE[nr], - val); - mutex_unlock(&data->update_lock); - return count; -} - -/* - * Fan speed tolerance is a tricky beast, since the associated register is - * a tick counter, but the value is reported and configured as rpm. - * Compute resulting low and high rpm values and report the difference. - */ -static ssize_t -show_speed_tolerance(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - int low = data->target_speed[nr] - data->target_speed_tolerance[nr]; - int high = data->target_speed[nr] + data->target_speed_tolerance[nr]; - int tolerance; - - if (low <= 0) - low = 1; - if (high > 0xffff) - high = 0xffff; - if (high < low) - high = low; - - tolerance = (fan_from_reg16(low, data->fan_div[nr]) - - fan_from_reg16(high, data->fan_div[nr])) / 2; - - return sprintf(buf, "%d\n", tolerance); -} - -static ssize_t -store_speed_tolerance(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); - int nr = sattr->index; - unsigned long val; - int err; - int low, high; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - high = fan_from_reg16(data->target_speed[nr], - data->fan_div[nr]) + val; - low = fan_from_reg16(data->target_speed[nr], - data->fan_div[nr]) - val; - if (low <= 0) - low = 1; - if (high < low) - high = low; - - val = (fan_to_reg(low, data->fan_div[nr]) - - fan_to_reg(high, data->fan_div[nr])) / 2; - - /* Limit tolerance as needed */ - val = clamp_val(val, 0, data->speed_tolerance_limit); - - mutex_lock(&data->update_lock); - data->target_speed_tolerance[nr] = val; - pwm_update_registers(data, nr); - mutex_unlock(&data->update_lock); - return count; -} - -static SENSOR_DEVICE_ATTR_2(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0); -static SENSOR_DEVICE_ATTR_2(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 0); -static SENSOR_DEVICE_ATTR_2(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 0); -static SENSOR_DEVICE_ATTR_2(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 0); -static SENSOR_DEVICE_ATTR_2(pwm5, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 0); - -static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode, - store_pwm_mode, 0); -static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode, - store_pwm_mode, 1); -static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode, - store_pwm_mode, 2); -static SENSOR_DEVICE_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode, - store_pwm_mode, 3); -static SENSOR_DEVICE_ATTR(pwm5_mode, S_IWUSR | S_IRUGO, show_pwm_mode, - store_pwm_mode, 4); - -static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable, - store_pwm_enable, 0); -static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable, - store_pwm_enable, 1); -static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable, - store_pwm_enable, 2); -static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable, - store_pwm_enable, 3); -static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable, - store_pwm_enable, 4); - -static SENSOR_DEVICE_ATTR(pwm1_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_temp_sel, store_pwm_temp_sel, 0); -static SENSOR_DEVICE_ATTR(pwm2_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_temp_sel, store_pwm_temp_sel, 1); -static SENSOR_DEVICE_ATTR(pwm3_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_temp_sel, store_pwm_temp_sel, 2); -static SENSOR_DEVICE_ATTR(pwm4_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_temp_sel, store_pwm_temp_sel, 3); -static SENSOR_DEVICE_ATTR(pwm5_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_temp_sel, store_pwm_temp_sel, 4); - -static SENSOR_DEVICE_ATTR(pwm1_target_temp, S_IWUSR | S_IRUGO, show_target_temp, - store_target_temp, 0); -static SENSOR_DEVICE_ATTR(pwm2_target_temp, S_IWUSR | S_IRUGO, show_target_temp, - store_target_temp, 1); -static SENSOR_DEVICE_ATTR(pwm3_target_temp, S_IWUSR | S_IRUGO, show_target_temp, - store_target_temp, 2); -static SENSOR_DEVICE_ATTR(pwm4_target_temp, S_IWUSR | S_IRUGO, show_target_temp, - store_target_temp, 3); -static SENSOR_DEVICE_ATTR(pwm5_target_temp, S_IWUSR | S_IRUGO, show_target_temp, - store_target_temp, 4); - -static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, show_target_speed, - store_target_speed, 0); -static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO, show_target_speed, - store_target_speed, 1); -static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO, show_target_speed, - store_target_speed, 2); -static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO, show_target_speed, - store_target_speed, 3); -static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO, show_target_speed, - store_target_speed, 4); - -static SENSOR_DEVICE_ATTR(fan1_tolerance, S_IWUSR | S_IRUGO, - show_speed_tolerance, store_speed_tolerance, 0); -static SENSOR_DEVICE_ATTR(fan2_tolerance, S_IWUSR | S_IRUGO, - show_speed_tolerance, store_speed_tolerance, 1); -static SENSOR_DEVICE_ATTR(fan3_tolerance, S_IWUSR | S_IRUGO, - show_speed_tolerance, store_speed_tolerance, 2); -static SENSOR_DEVICE_ATTR(fan4_tolerance, S_IWUSR | S_IRUGO, - show_speed_tolerance, store_speed_tolerance, 3); -static SENSOR_DEVICE_ATTR(fan5_tolerance, S_IWUSR | S_IRUGO, - show_speed_tolerance, store_speed_tolerance, 4); - -/* Smart Fan registers */ - -static ssize_t -show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - - return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000); -} - -static ssize_t -store_weight_temp(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - unsigned long val; - int err; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); - - mutex_lock(&data->update_lock); - data->weight_temp[index][nr] = val; - nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val); - mutex_unlock(&data->update_lock); - return count; -} - -static SENSOR_DEVICE_ATTR(pwm1_weight_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, - 0); -static SENSOR_DEVICE_ATTR(pwm2_weight_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, - 1); -static SENSOR_DEVICE_ATTR(pwm3_weight_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, - 2); -static SENSOR_DEVICE_ATTR(pwm4_weight_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, - 3); -static SENSOR_DEVICE_ATTR(pwm5_weight_temp_sel, S_IWUSR | S_IRUGO, - show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, - 4); - -static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 0, 0); -static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 1, 0); -static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 2, 0); -static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 3, 0); -static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 4, 0); - -static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_tol, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 0, 1); -static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_tol, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 1, 1); -static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_tol, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 2, 1); -static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_tol, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 3, 1); -static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_tol, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 4, 1); - -static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_base, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 0, 2); -static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_base, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 1, 2); -static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_base, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 2, 2); -static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_base, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 3, 2); -static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_base, S_IWUSR | S_IRUGO, - show_weight_temp, store_weight_temp, 4, 2); - -static SENSOR_DEVICE_ATTR_2(pwm1_weight_duty_step, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 0, 5); -static SENSOR_DEVICE_ATTR_2(pwm2_weight_duty_step, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 1, 5); -static SENSOR_DEVICE_ATTR_2(pwm3_weight_duty_step, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 2, 5); -static SENSOR_DEVICE_ATTR_2(pwm4_weight_duty_step, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 3, 5); -static SENSOR_DEVICE_ATTR_2(pwm5_weight_duty_step, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 4, 5); - -/* duty_base is not supported on all chips */ -static struct sensor_device_attribute_2 sda_weight_duty_base[] = { - SENSOR_ATTR_2(pwm1_weight_duty_base, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 0, 6), - SENSOR_ATTR_2(pwm2_weight_duty_base, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 1, 6), - SENSOR_ATTR_2(pwm3_weight_duty_base, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 2, 6), - SENSOR_ATTR_2(pwm4_weight_duty_base, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 3, 6), - SENSOR_ATTR_2(pwm5_weight_duty_base, S_IWUSR | S_IRUGO, - show_pwm, store_pwm, 4, 6), -}; - -static ssize_t -show_fan_time(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - - return sprintf(buf, "%d\n", - step_time_from_reg(data->fan_time[index][nr], - data->pwm_mode[nr])); -} - -static ssize_t -store_fan_time(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int index = sattr->index; - unsigned long val; - int err; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - - val = step_time_to_reg(val, data->pwm_mode[nr]); - mutex_lock(&data->update_lock); - data->fan_time[index][nr] = val; - nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val); - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t -show_name(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", data->name); -} - -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - -static SENSOR_DEVICE_ATTR_2(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 0, 0); -static SENSOR_DEVICE_ATTR_2(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 1, 0); -static SENSOR_DEVICE_ATTR_2(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 2, 0); -static SENSOR_DEVICE_ATTR_2(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 3, 0); -static SENSOR_DEVICE_ATTR_2(pwm5_stop_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 4, 0); - -static SENSOR_DEVICE_ATTR_2(pwm1_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 0, 1); -static SENSOR_DEVICE_ATTR_2(pwm2_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 1, 1); -static SENSOR_DEVICE_ATTR_2(pwm3_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 2, 1); -static SENSOR_DEVICE_ATTR_2(pwm4_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 3, 1); -static SENSOR_DEVICE_ATTR_2(pwm5_step_up_time, S_IWUSR | S_IRUGO, show_fan_time, - store_fan_time, 4, 1); - -static SENSOR_DEVICE_ATTR_2(pwm1_step_down_time, S_IWUSR | S_IRUGO, - show_fan_time, store_fan_time, 0, 2); -static SENSOR_DEVICE_ATTR_2(pwm2_step_down_time, S_IWUSR | S_IRUGO, - show_fan_time, store_fan_time, 1, 2); -static SENSOR_DEVICE_ATTR_2(pwm3_step_down_time, S_IWUSR | S_IRUGO, - show_fan_time, store_fan_time, 2, 2); -static SENSOR_DEVICE_ATTR_2(pwm4_step_down_time, S_IWUSR | S_IRUGO, - show_fan_time, store_fan_time, 3, 2); -static SENSOR_DEVICE_ATTR_2(pwm5_step_down_time, S_IWUSR | S_IRUGO, - show_fan_time, store_fan_time, 4, 2); - -static SENSOR_DEVICE_ATTR_2(pwm1_start, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 0, 1); -static SENSOR_DEVICE_ATTR_2(pwm2_start, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 1, 1); -static SENSOR_DEVICE_ATTR_2(pwm3_start, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 2, 1); -static SENSOR_DEVICE_ATTR_2(pwm4_start, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 3, 1); -static SENSOR_DEVICE_ATTR_2(pwm5_start, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 4, 1); - -static SENSOR_DEVICE_ATTR_2(pwm1_floor, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 0, 2); -static SENSOR_DEVICE_ATTR_2(pwm2_floor, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 1, 2); -static SENSOR_DEVICE_ATTR_2(pwm3_floor, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 2, 2); -static SENSOR_DEVICE_ATTR_2(pwm4_floor, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 3, 2); -static SENSOR_DEVICE_ATTR_2(pwm5_floor, S_IWUSR | S_IRUGO, show_pwm, - store_pwm, 4, 2); - -static SENSOR_DEVICE_ATTR_2(pwm1_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 0, 0); -static SENSOR_DEVICE_ATTR_2(pwm2_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 1, 0); -static SENSOR_DEVICE_ATTR_2(pwm3_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 2, 0); -static SENSOR_DEVICE_ATTR_2(pwm4_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 3, 0); -static SENSOR_DEVICE_ATTR_2(pwm5_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 4, 0); - -static SENSOR_DEVICE_ATTR_2(pwm1_crit_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 0, 1); -static SENSOR_DEVICE_ATTR_2(pwm2_crit_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 1, 1); -static SENSOR_DEVICE_ATTR_2(pwm3_crit_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 2, 1); -static SENSOR_DEVICE_ATTR_2(pwm4_crit_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 3, 1); -static SENSOR_DEVICE_ATTR_2(pwm5_crit_temp_tolerance, S_IWUSR | S_IRUGO, - show_temp_tolerance, store_temp_tolerance, 4, 1); - -/* pwm_max is not supported on all chips */ -static struct sensor_device_attribute_2 sda_pwm_max[] = { - SENSOR_ATTR_2(pwm1_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, - 0, 3), - SENSOR_ATTR_2(pwm2_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, - 1, 3), - SENSOR_ATTR_2(pwm3_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, - 2, 3), - SENSOR_ATTR_2(pwm4_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, - 3, 3), - SENSOR_ATTR_2(pwm5_max, S_IWUSR | S_IRUGO, show_pwm, store_pwm, - 4, 3), -}; - -/* pwm_step is not supported on all chips */ -static struct sensor_device_attribute_2 sda_pwm_step[] = { - SENSOR_ATTR_2(pwm1_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 4), - SENSOR_ATTR_2(pwm2_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 4), - SENSOR_ATTR_2(pwm3_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 4), - SENSOR_ATTR_2(pwm4_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 4), - SENSOR_ATTR_2(pwm5_step, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 4), -}; - -static struct attribute *nct6775_attributes_pwm[5][20] = { - { - &sensor_dev_attr_pwm1.dev_attr.attr, - &sensor_dev_attr_pwm1_mode.dev_attr.attr, - &sensor_dev_attr_pwm1_enable.dev_attr.attr, - &sensor_dev_attr_pwm1_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm1_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm1_crit_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm1_target_temp.dev_attr.attr, - &sensor_dev_attr_fan1_target.dev_attr.attr, - &sensor_dev_attr_fan1_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm1_stop_time.dev_attr.attr, - &sensor_dev_attr_pwm1_step_up_time.dev_attr.attr, - &sensor_dev_attr_pwm1_step_down_time.dev_attr.attr, - &sensor_dev_attr_pwm1_start.dev_attr.attr, - &sensor_dev_attr_pwm1_floor.dev_attr.attr, - &sensor_dev_attr_pwm1_weight_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm1_weight_temp_step.dev_attr.attr, - &sensor_dev_attr_pwm1_weight_temp_step_tol.dev_attr.attr, - &sensor_dev_attr_pwm1_weight_temp_step_base.dev_attr.attr, - &sensor_dev_attr_pwm1_weight_duty_step.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_pwm2.dev_attr.attr, - &sensor_dev_attr_pwm2_mode.dev_attr.attr, - &sensor_dev_attr_pwm2_enable.dev_attr.attr, - &sensor_dev_attr_pwm2_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm2_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm2_crit_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm2_target_temp.dev_attr.attr, - &sensor_dev_attr_fan2_target.dev_attr.attr, - &sensor_dev_attr_fan2_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm2_stop_time.dev_attr.attr, - &sensor_dev_attr_pwm2_step_up_time.dev_attr.attr, - &sensor_dev_attr_pwm2_step_down_time.dev_attr.attr, - &sensor_dev_attr_pwm2_start.dev_attr.attr, - &sensor_dev_attr_pwm2_floor.dev_attr.attr, - &sensor_dev_attr_pwm2_weight_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm2_weight_temp_step.dev_attr.attr, - &sensor_dev_attr_pwm2_weight_temp_step_tol.dev_attr.attr, - &sensor_dev_attr_pwm2_weight_temp_step_base.dev_attr.attr, - &sensor_dev_attr_pwm2_weight_duty_step.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_pwm3.dev_attr.attr, - &sensor_dev_attr_pwm3_mode.dev_attr.attr, - &sensor_dev_attr_pwm3_enable.dev_attr.attr, - &sensor_dev_attr_pwm3_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm3_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm3_crit_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm3_target_temp.dev_attr.attr, - &sensor_dev_attr_fan3_target.dev_attr.attr, - &sensor_dev_attr_fan3_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm3_stop_time.dev_attr.attr, - &sensor_dev_attr_pwm3_step_up_time.dev_attr.attr, - &sensor_dev_attr_pwm3_step_down_time.dev_attr.attr, - &sensor_dev_attr_pwm3_start.dev_attr.attr, - &sensor_dev_attr_pwm3_floor.dev_attr.attr, - &sensor_dev_attr_pwm3_weight_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm3_weight_temp_step.dev_attr.attr, - &sensor_dev_attr_pwm3_weight_temp_step_tol.dev_attr.attr, - &sensor_dev_attr_pwm3_weight_temp_step_base.dev_attr.attr, - &sensor_dev_attr_pwm3_weight_duty_step.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_pwm4.dev_attr.attr, - &sensor_dev_attr_pwm4_mode.dev_attr.attr, - &sensor_dev_attr_pwm4_enable.dev_attr.attr, - &sensor_dev_attr_pwm4_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm4_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm4_crit_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm4_target_temp.dev_attr.attr, - &sensor_dev_attr_fan4_target.dev_attr.attr, - &sensor_dev_attr_fan4_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm4_stop_time.dev_attr.attr, - &sensor_dev_attr_pwm4_step_up_time.dev_attr.attr, - &sensor_dev_attr_pwm4_step_down_time.dev_attr.attr, - &sensor_dev_attr_pwm4_start.dev_attr.attr, - &sensor_dev_attr_pwm4_floor.dev_attr.attr, - &sensor_dev_attr_pwm4_weight_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm4_weight_temp_step.dev_attr.attr, - &sensor_dev_attr_pwm4_weight_temp_step_tol.dev_attr.attr, - &sensor_dev_attr_pwm4_weight_temp_step_base.dev_attr.attr, - &sensor_dev_attr_pwm4_weight_duty_step.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_pwm5.dev_attr.attr, - &sensor_dev_attr_pwm5_mode.dev_attr.attr, - &sensor_dev_attr_pwm5_enable.dev_attr.attr, - &sensor_dev_attr_pwm5_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm5_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm5_crit_temp_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm5_target_temp.dev_attr.attr, - &sensor_dev_attr_fan5_target.dev_attr.attr, - &sensor_dev_attr_fan5_tolerance.dev_attr.attr, - &sensor_dev_attr_pwm5_stop_time.dev_attr.attr, - &sensor_dev_attr_pwm5_step_up_time.dev_attr.attr, - &sensor_dev_attr_pwm5_step_down_time.dev_attr.attr, - &sensor_dev_attr_pwm5_start.dev_attr.attr, - &sensor_dev_attr_pwm5_floor.dev_attr.attr, - &sensor_dev_attr_pwm5_weight_temp_sel.dev_attr.attr, - &sensor_dev_attr_pwm5_weight_temp_step.dev_attr.attr, - &sensor_dev_attr_pwm5_weight_temp_step_tol.dev_attr.attr, - &sensor_dev_attr_pwm5_weight_temp_step_base.dev_attr.attr, - &sensor_dev_attr_pwm5_weight_duty_step.dev_attr.attr, - NULL - }, -}; - -static const struct attribute_group nct6775_group_pwm[5] = { - { .attrs = nct6775_attributes_pwm[0] }, - { .attrs = nct6775_attributes_pwm[1] }, - { .attrs = nct6775_attributes_pwm[2] }, - { .attrs = nct6775_attributes_pwm[3] }, - { .attrs = nct6775_attributes_pwm[4] }, -}; - -static ssize_t -show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - - return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]); -} - -static ssize_t -store_auto_pwm(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int point = sattr->index; - unsigned long val; - int err; - u8 reg; - - err = kstrtoul(buf, 10, &val); - if (err < 0) - return err; - if (val > 255) - return -EINVAL; - - if (point == data->auto_pwm_num) { - if (data->kind != nct6775 && !val) - return -EINVAL; - if (data->kind != nct6779 && val) - val = 0xff; - } - - mutex_lock(&data->update_lock); - data->auto_pwm[nr][point] = val; - if (point < data->auto_pwm_num) { - nct6775_write_value(data, - NCT6775_AUTO_PWM(data, nr, point), - data->auto_pwm[nr][point]); - } else { - switch (data->kind) { - case nct6775: - /* disable if needed (pwm == 0) */ - reg = nct6775_read_value(data, - NCT6775_REG_CRITICAL_ENAB[nr]); - if (val) - reg |= 0x02; - else - reg &= ~0x02; - nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr], - reg); - break; - case nct6776: - break; /* always enabled, nothing to do */ - case nct6779: - nct6775_write_value(data, NCT6779_REG_CRITICAL_PWM[nr], - val); - reg = nct6775_read_value(data, - NCT6779_REG_CRITICAL_PWM_ENABLE[nr]); - if (val == 255) - reg &= ~0x01; - else - reg |= 0x01; - nct6775_write_value(data, - NCT6779_REG_CRITICAL_PWM_ENABLE[nr], - reg); - break; - } - } - mutex_unlock(&data->update_lock); - return count; -} - -static ssize_t -show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int point = sattr->index; - - /* - * We don't know for sure if the temperature is signed or unsigned. - * Assume it is unsigned. - */ - return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000); -} - -static ssize_t -store_auto_temp(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); - int nr = sattr->nr; - int point = sattr->index; - unsigned long val; - int err; - - err = kstrtoul(buf, 10, &val); - if (err) - return err; - if (val > 255000) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000); - if (point < data->auto_pwm_num) { - nct6775_write_value(data, - NCT6775_AUTO_TEMP(data, nr, point), - data->auto_temp[nr][point]); - } else { - nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr], - data->auto_temp[nr][point]); - } - mutex_unlock(&data->update_lock); - return count; -} - -/* - * The number of auto-point trip points is chip dependent. - * Need to check support while generating/removing attribute files. - */ -static struct sensor_device_attribute_2 sda_auto_pwm_arrays[] = { - SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 0, 0), - SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 0, 0), - SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 0, 1), - SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 0, 1), - SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 0, 2), - SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 0, 2), - SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 0, 3), - SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 0, 3), - SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 0, 4), - SENSOR_ATTR_2(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 0, 4), - SENSOR_ATTR_2(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 0, 5), - SENSOR_ATTR_2(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 0, 5), - SENSOR_ATTR_2(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 0, 6), - SENSOR_ATTR_2(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 0, 6), - - SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 1, 0), - SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 1, 0), - SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 1, 1), - SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 1, 1), - SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 1, 2), - SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 1, 2), - SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 1, 3), - SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 1, 3), - SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 1, 4), - SENSOR_ATTR_2(pwm2_auto_point5_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 1, 4), - SENSOR_ATTR_2(pwm2_auto_point6_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 1, 5), - SENSOR_ATTR_2(pwm2_auto_point6_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 1, 5), - SENSOR_ATTR_2(pwm2_auto_point7_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 1, 6), - SENSOR_ATTR_2(pwm2_auto_point7_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 1, 6), - - SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 2, 0), - SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 2, 0), - SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 2, 1), - SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 2, 1), - SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 2, 2), - SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 2, 2), - SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 2, 3), - SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 2, 3), - SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 2, 4), - SENSOR_ATTR_2(pwm3_auto_point5_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 2, 4), - SENSOR_ATTR_2(pwm3_auto_point6_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 2, 5), - SENSOR_ATTR_2(pwm3_auto_point6_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 2, 5), - SENSOR_ATTR_2(pwm3_auto_point7_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 2, 6), - SENSOR_ATTR_2(pwm3_auto_point7_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 2, 6), - - SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 3, 0), - SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 3, 0), - SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 3, 1), - SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 3, 1), - SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 3, 2), - SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 3, 2), - SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 3, 3), - SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 3, 3), - SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 3, 4), - SENSOR_ATTR_2(pwm4_auto_point5_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 3, 4), - SENSOR_ATTR_2(pwm4_auto_point6_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 3, 5), - SENSOR_ATTR_2(pwm4_auto_point6_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 3, 5), - SENSOR_ATTR_2(pwm4_auto_point7_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 3, 6), - SENSOR_ATTR_2(pwm4_auto_point7_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 3, 6), - - SENSOR_ATTR_2(pwm5_auto_point1_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 4, 0), - SENSOR_ATTR_2(pwm5_auto_point1_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 4, 0), - SENSOR_ATTR_2(pwm5_auto_point2_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 4, 1), - SENSOR_ATTR_2(pwm5_auto_point2_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 4, 1), - SENSOR_ATTR_2(pwm5_auto_point3_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 4, 2), - SENSOR_ATTR_2(pwm5_auto_point3_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 4, 2), - SENSOR_ATTR_2(pwm5_auto_point4_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 4, 3), - SENSOR_ATTR_2(pwm5_auto_point4_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 4, 3), - SENSOR_ATTR_2(pwm5_auto_point5_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 4, 4), - SENSOR_ATTR_2(pwm5_auto_point5_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 4, 4), - SENSOR_ATTR_2(pwm5_auto_point6_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 4, 5), - SENSOR_ATTR_2(pwm5_auto_point6_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 4, 5), - SENSOR_ATTR_2(pwm5_auto_point7_pwm, S_IWUSR | S_IRUGO, - show_auto_pwm, store_auto_pwm, 4, 6), - SENSOR_ATTR_2(pwm5_auto_point7_temp, S_IWUSR | S_IRUGO, - show_auto_temp, store_auto_temp, 4, 6), -}; - -static ssize_t -show_vid(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); -} - -static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); - -/* Case open detection */ - -static ssize_t -clear_caseopen(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct nct6775_sio_data *sio_data = dev->platform_data; - int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE; - unsigned long val; - u8 reg; - int ret; - - if (kstrtoul(buf, 10, &val) || val != 0) - return -EINVAL; - - mutex_lock(&data->update_lock); - - /* - * Use CR registers to clear caseopen status. - * The CR registers are the same for all chips, and not all chips - * support clearing the caseopen status through "regular" registers. - */ - ret = superio_enter(sio_data->sioreg); - if (ret) { - count = ret; - goto error; - } - - superio_select(sio_data->sioreg, NCT6775_LD_ACPI); - reg = superio_inb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]); - reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr]; - superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg); - reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr]; - superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg); - superio_exit(sio_data->sioreg); - - data->valid = false; /* Force cache refresh */ -error: - mutex_unlock(&data->update_lock); - return count; -} - -static struct sensor_device_attribute sda_caseopen[] = { - SENSOR_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm, - clear_caseopen, INTRUSION_ALARM_BASE), - SENSOR_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm, - clear_caseopen, INTRUSION_ALARM_BASE + 1), -}; - -/* - * Driver and device management - */ - -static void nct6775_device_remove_files(struct device *dev) -{ - /* - * some entries in the following arrays may not have been used in - * device_create_file(), but device_remove_file() will ignore them - */ - int i; - struct nct6775_data *data = dev_get_drvdata(dev); - - for (i = 0; i < data->pwm_num; i++) - sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]); - - for (i = 0; i < ARRAY_SIZE(sda_pwm_max); i++) - device_remove_file(dev, &sda_pwm_max[i].dev_attr); - - for (i = 0; i < ARRAY_SIZE(sda_pwm_step); i++) - device_remove_file(dev, &sda_pwm_step[i].dev_attr); - - for (i = 0; i < ARRAY_SIZE(sda_weight_duty_base); i++) - device_remove_file(dev, &sda_weight_duty_base[i].dev_attr); - - for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) - device_remove_file(dev, &sda_auto_pwm_arrays[i].dev_attr); - - for (i = 0; i < data->in_num; i++) - sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]); - - for (i = 0; i < 5; i++) { - device_remove_file(dev, &sda_fan_input[i].dev_attr); - device_remove_file(dev, &sda_fan_alarm[i].dev_attr); - device_remove_file(dev, &sda_fan_div[i].dev_attr); - device_remove_file(dev, &sda_fan_min[i].dev_attr); - device_remove_file(dev, &sda_fan_pulses[i].dev_attr); - } - for (i = 0; i < NUM_TEMP; i++) { - if (!(data->have_temp & (1 << i))) - continue; - device_remove_file(dev, &sda_temp_input[i].dev_attr); - device_remove_file(dev, &sda_temp_label[i].dev_attr); - device_remove_file(dev, &sda_temp_max[i].dev_attr); - device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr); - device_remove_file(dev, &sda_temp_crit[i].dev_attr); - if (!(data->have_temp_fixed & (1 << i))) - continue; - device_remove_file(dev, &sda_temp_type[i].dev_attr); - device_remove_file(dev, &sda_temp_offset[i].dev_attr); - if (i >= NUM_TEMP_ALARM) - continue; - device_remove_file(dev, &sda_temp_alarm[i].dev_attr); - } - - device_remove_file(dev, &sda_caseopen[0].dev_attr); - device_remove_file(dev, &sda_caseopen[1].dev_attr); - - device_remove_file(dev, &dev_attr_name); - device_remove_file(dev, &dev_attr_cpu0_vid); -} - -/* Get the monitoring functions started */ -static inline void nct6775_init_device(struct nct6775_data *data) -{ - int i; - u8 tmp, diode; - - /* Start monitoring if needed */ - if (data->REG_CONFIG) { - tmp = nct6775_read_value(data, data->REG_CONFIG); - if (!(tmp & 0x01)) - nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01); - } - - /* Enable temperature sensors if needed */ - for (i = 0; i < NUM_TEMP; i++) { - if (!(data->have_temp & (1 << i))) - continue; - if (!data->reg_temp_config[i]) - continue; - tmp = nct6775_read_value(data, data->reg_temp_config[i]); - if (tmp & 0x01) - nct6775_write_value(data, data->reg_temp_config[i], - tmp & 0xfe); - } - - /* Enable VBAT monitoring if needed */ - tmp = nct6775_read_value(data, data->REG_VBAT); - if (!(tmp & 0x01)) - nct6775_write_value(data, data->REG_VBAT, tmp | 0x01); - - diode = nct6775_read_value(data, data->REG_DIODE); - - for (i = 0; i < data->temp_fixed_num; i++) { - if (!(data->have_temp_fixed & (1 << i))) - continue; - if ((tmp & (0x02 << i))) /* diode */ - data->temp_type[i] = 3 - ((diode >> i) & 0x02); - else /* thermistor */ - data->temp_type[i] = 4; - } -} - -static int -nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data, - struct nct6775_data *data) -{ - int regval; - bool fan3pin, fan3min, fan4pin, fan4min, fan5pin; - bool pwm3pin, pwm4pin, pwm5pin; - int ret; - - ret = superio_enter(sio_data->sioreg); - if (ret) - return ret; - - /* fan4 and fan5 share some pins with the GPIO and serial flash */ - if (data->kind == nct6775) { - regval = superio_inb(sio_data->sioreg, 0x2c); - - fan3pin = regval & (1 << 6); - fan3min = fan3pin; - pwm3pin = regval & (1 << 7); - - /* On NCT6775, fan4 shares pins with the fdc interface */ - fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80); - fan4min = 0; - fan5pin = 0; - pwm4pin = 0; - pwm5pin = 0; - } else if (data->kind == nct6776) { - bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80; - - superio_select(sio_data->sioreg, NCT6775_LD_HWM); - regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE); - - if (regval & 0x80) - fan3pin = gpok; - else - fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); - - if (regval & 0x40) - fan4pin = gpok; - else - fan4pin = superio_inb(sio_data->sioreg, 0x1C) & 0x01; - - if (regval & 0x20) - fan5pin = gpok; - else - fan5pin = superio_inb(sio_data->sioreg, 0x1C) & 0x02; - - fan4min = fan4pin; - fan3min = fan3pin; - pwm3pin = fan3pin; - pwm4pin = 0; - pwm5pin = 0; - } else { /* NCT6779D */ - regval = superio_inb(sio_data->sioreg, 0x1c); - - fan3pin = !(regval & (1 << 5)); - fan4pin = !(regval & (1 << 6)); - fan5pin = !(regval & (1 << 7)); - - pwm3pin = !(regval & (1 << 0)); - pwm4pin = !(regval & (1 << 1)); - pwm5pin = !(regval & (1 << 2)); - - fan3min = fan3pin; - fan4min = fan4pin; - } - - superio_exit(sio_data->sioreg); - - data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */ - data->has_fan |= fan3pin << 2; - data->has_fan_min |= fan3min << 2; - - data->has_fan |= (fan4pin << 3) | (fan5pin << 4); - data->has_fan_min |= (fan4min << 3) | (fan5pin << 4); - - data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | (pwm5pin << 4); - - return 0; -} - -static void add_temp_sensors(struct nct6775_data *data, const u16 *regp, - int *available, int *mask) -{ - int i; - u8 src; - - for (i = 0; i < data->pwm_num && *available; i++) { - int index; - - if (!regp[i]) - continue; - src = nct6775_read_value(data, regp[i]); - src &= 0x1f; - if (!src || (*mask & (1 << src))) - continue; - if (src >= data->temp_label_num || - !strlen(data->temp_label[src])) - continue; - - index = __ffs(*available); - nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src); - *available &= ~(1 << index); - *mask |= 1 << src; - } -} - -static int nct6775_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct nct6775_sio_data *sio_data = dev->platform_data; - struct nct6775_data *data; - struct resource *res; - int i, s, err = 0; - int src, mask, available; - const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config; - const u16 *reg_temp_alternate, *reg_temp_crit; - int num_reg_temp; - bool have_vid = false; - u8 cr2a; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH, - DRVNAME)) - return -EBUSY; - - data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data), - GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->kind = sio_data->kind; - data->addr = res->start; - mutex_init(&data->update_lock); - data->name = nct6775_device_names[data->kind]; - data->bank = 0xff; /* Force initial bank selection */ - platform_set_drvdata(pdev, data); - - switch (data->kind) { - case nct6775: - data->in_num = 9; - data->pwm_num = 3; - data->auto_pwm_num = 6; - data->has_fan_div = true; - data->temp_fixed_num = 3; - - data->ALARM_BITS = NCT6775_ALARM_BITS; - - data->fan_from_reg = fan_from_reg16; - data->fan_from_reg_min = fan_from_reg8; - data->target_temp_mask = 0x7f; - data->tolerance_mask = 0x0f; - data->speed_tolerance_limit = 15; - - data->temp_label = nct6775_temp_label; - data->temp_label_num = ARRAY_SIZE(nct6775_temp_label); - - data->REG_CONFIG = NCT6775_REG_CONFIG; - data->REG_VBAT = NCT6775_REG_VBAT; - data->REG_DIODE = NCT6775_REG_DIODE; - data->REG_VIN = NCT6775_REG_IN; - data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; - data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; - data->REG_TARGET = NCT6775_REG_TARGET; - data->REG_FAN = NCT6775_REG_FAN; - data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; - data->REG_FAN_MIN = NCT6775_REG_FAN_MIN; - data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES; - data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; - data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; - data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; - data->REG_PWM[0] = NCT6775_REG_PWM; - data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; - data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; - data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT; - data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT; - data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; - data->REG_PWM_READ = NCT6775_REG_PWM_READ; - data->REG_PWM_MODE = NCT6775_REG_PWM_MODE; - data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK; - data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP; - data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM; - data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP; - data->REG_CRITICAL_TEMP_TOLERANCE - = NCT6775_REG_CRITICAL_TEMP_TOLERANCE; - data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; - data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; - data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; - data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; - data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; - data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; - data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; - data->REG_ALARM = NCT6775_REG_ALARM; - - reg_temp = NCT6775_REG_TEMP; - num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP); - reg_temp_over = NCT6775_REG_TEMP_OVER; - reg_temp_hyst = NCT6775_REG_TEMP_HYST; - reg_temp_config = NCT6775_REG_TEMP_CONFIG; - reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE; - reg_temp_crit = NCT6775_REG_TEMP_CRIT; - - break; - case nct6776: - data->in_num = 9; - data->pwm_num = 3; - data->auto_pwm_num = 4; - data->has_fan_div = false; - data->temp_fixed_num = 3; - - data->ALARM_BITS = NCT6776_ALARM_BITS; - - data->fan_from_reg = fan_from_reg13; - data->fan_from_reg_min = fan_from_reg13; - data->target_temp_mask = 0xff; - data->tolerance_mask = 0x07; - data->speed_tolerance_limit = 63; - - data->temp_label = nct6776_temp_label; - data->temp_label_num = ARRAY_SIZE(nct6776_temp_label); - - data->REG_CONFIG = NCT6775_REG_CONFIG; - data->REG_VBAT = NCT6775_REG_VBAT; - data->REG_DIODE = NCT6775_REG_DIODE; - data->REG_VIN = NCT6775_REG_IN; - data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; - data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; - data->REG_TARGET = NCT6775_REG_TARGET; - data->REG_FAN = NCT6775_REG_FAN; - data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; - data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; - data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES; - data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; - data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; - data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; - data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H; - data->REG_PWM[0] = NCT6775_REG_PWM; - data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; - data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; - data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; - data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE; - data->REG_PWM_READ = NCT6775_REG_PWM_READ; - data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; - data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; - data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP; - data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM; - data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP; - data->REG_CRITICAL_TEMP_TOLERANCE - = NCT6775_REG_CRITICAL_TEMP_TOLERANCE; - data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; - data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; - data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; - data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; - data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; - data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; - data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; - data->REG_ALARM = NCT6775_REG_ALARM; - - reg_temp = NCT6775_REG_TEMP; - num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP); - reg_temp_over = NCT6775_REG_TEMP_OVER; - reg_temp_hyst = NCT6775_REG_TEMP_HYST; - reg_temp_config = NCT6776_REG_TEMP_CONFIG; - reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE; - reg_temp_crit = NCT6776_REG_TEMP_CRIT; - - break; - case nct6779: - data->in_num = 15; - data->pwm_num = 5; - data->auto_pwm_num = 4; - data->has_fan_div = false; - data->temp_fixed_num = 6; - - data->ALARM_BITS = NCT6779_ALARM_BITS; - - data->fan_from_reg = fan_from_reg13; - data->fan_from_reg_min = fan_from_reg13; - data->target_temp_mask = 0xff; - data->tolerance_mask = 0x07; - data->speed_tolerance_limit = 63; - - data->temp_label = nct6779_temp_label; - data->temp_label_num = ARRAY_SIZE(nct6779_temp_label); - - data->REG_CONFIG = NCT6775_REG_CONFIG; - data->REG_VBAT = NCT6775_REG_VBAT; - data->REG_DIODE = NCT6775_REG_DIODE; - data->REG_VIN = NCT6779_REG_IN; - data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN; - data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; - data->REG_TARGET = NCT6775_REG_TARGET; - data->REG_FAN = NCT6779_REG_FAN; - data->REG_FAN_MODE = NCT6775_REG_FAN_MODE; - data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; - data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; - data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; - data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; - data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; - data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H; - data->REG_PWM[0] = NCT6775_REG_PWM; - data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; - data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT; - data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP; - data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE; - data->REG_PWM_READ = NCT6775_REG_PWM_READ; - data->REG_PWM_MODE = NCT6776_REG_PWM_MODE; - data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK; - data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP; - data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM; - data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP; - data->REG_CRITICAL_TEMP_TOLERANCE - = NCT6775_REG_CRITICAL_TEMP_TOLERANCE; - data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; - data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; - data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL; - data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL; - data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP; - data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; - data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; - data->REG_ALARM = NCT6779_REG_ALARM; - - reg_temp = NCT6779_REG_TEMP; - num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); - reg_temp_over = NCT6779_REG_TEMP_OVER; - reg_temp_hyst = NCT6779_REG_TEMP_HYST; - reg_temp_config = NCT6779_REG_TEMP_CONFIG; - reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE; - reg_temp_crit = NCT6779_REG_TEMP_CRIT; - - break; - default: - return -ENODEV; - } - data->have_in = (1 << data->in_num) - 1; - data->have_temp = 0; - - /* - * On some boards, not all available temperature sources are monitored, - * even though some of the monitoring registers are unused. - * Get list of unused monitoring registers, then detect if any fan - * controls are configured to use unmonitored temperature sources. - * If so, assign the unmonitored temperature sources to available - * monitoring registers. - */ - mask = 0; - available = 0; - for (i = 0; i < num_reg_temp; i++) { - if (reg_temp[i] == 0) - continue; - - src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f; - if (!src || (mask & (1 << src))) - available |= 1 << i; - - mask |= 1 << src; - } - - /* - * Now find unmonitored temperature registers and enable monitoring - * if additional monitoring registers are available. - */ - add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask); - add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask); - - mask = 0; - s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */ - for (i = 0; i < num_reg_temp; i++) { - if (reg_temp[i] == 0) - continue; - - src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f; - if (!src || (mask & (1 << src))) - continue; - - if (src >= data->temp_label_num || - !strlen(data->temp_label[src])) { - dev_info(dev, - "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n", - src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]); - continue; - } - - mask |= 1 << src; - - /* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */ - if (src <= data->temp_fixed_num) { - data->have_temp |= 1 << (src - 1); - data->have_temp_fixed |= 1 << (src - 1); - data->reg_temp[0][src - 1] = reg_temp[i]; - data->reg_temp[1][src - 1] = reg_temp_over[i]; - data->reg_temp[2][src - 1] = reg_temp_hyst[i]; - data->reg_temp_config[src - 1] = reg_temp_config[i]; - data->temp_src[src - 1] = src; - continue; - } - - if (s >= NUM_TEMP) - continue; - - /* Use dynamic index for other sources */ - data->have_temp |= 1 << s; - data->reg_temp[0][s] = reg_temp[i]; - data->reg_temp[1][s] = reg_temp_over[i]; - data->reg_temp[2][s] = reg_temp_hyst[i]; - data->reg_temp_config[s] = reg_temp_config[i]; - if (reg_temp_crit[src - 1]) - data->reg_temp[3][s] = reg_temp_crit[src - 1]; - - data->temp_src[s] = src; - s++; - } - -#ifdef USE_ALTERNATE - /* - * Go through the list of alternate temp registers and enable - * if possible. - * The temperature is already monitored if the respective bit in - * is set. - */ - for (i = 0; i < data->temp_label_num - 1; i++) { - if (!reg_temp_alternate[i]) - continue; - if (mask & (1 << (i + 1))) - continue; - if (i < data->temp_fixed_num) { - if (data->have_temp & (1 << i)) - continue; - data->have_temp |= 1 << i; - data->have_temp_fixed |= 1 << i; - data->reg_temp[0][i] = reg_temp_alternate[i]; - data->reg_temp[1][i] = reg_temp_over[i]; - data->reg_temp[2][i] = reg_temp_hyst[i]; - data->temp_src[i] = i + 1; - continue; - } - - if (s >= NUM_TEMP) /* Abort if no more space */ - break; - - data->have_temp |= 1 << s; - data->reg_temp[0][s] = reg_temp_alternate[i]; - data->temp_src[s] = i + 1; - s++; - } -#endif /* USE_ALTERNATE */ - - /* Initialize the chip */ - nct6775_init_device(data); - - err = superio_enter(sio_data->sioreg); - if (err) - return err; - - cr2a = superio_inb(sio_data->sioreg, 0x2a); - switch (data->kind) { - case nct6775: - have_vid = (cr2a & 0x40); - break; - case nct6776: - have_vid = (cr2a & 0x60) == 0x40; - break; - case nct6779: - break; - } - - /* - * Read VID value - * We can get the VID input values directly at logical device D 0xe3. - */ - if (have_vid) { - superio_select(sio_data->sioreg, NCT6775_LD_VID); - data->vid = superio_inb(sio_data->sioreg, 0xe3); - data->vrm = vid_which_vrm(); - } - - if (fan_debounce) { - u8 tmp; - - superio_select(sio_data->sioreg, NCT6775_LD_HWM); - tmp = superio_inb(sio_data->sioreg, - NCT6775_REG_CR_FAN_DEBOUNCE); - switch (data->kind) { - case nct6775: - tmp |= 0x1e; - break; - case nct6776: - case nct6779: - tmp |= 0x3e; - break; - } - superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE, - tmp); - dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n", - data->name); - } - - superio_exit(sio_data->sioreg); - - if (have_vid) { - err = device_create_file(dev, &dev_attr_cpu0_vid); - if (err) - return err; - } - - err = nct6775_check_fan_inputs(sio_data, data); - if (err) - goto exit_remove; - - /* Read fan clock dividers immediately */ - nct6775_init_fan_common(dev, data); - - /* Register sysfs hooks */ - for (i = 0; i < data->pwm_num; i++) { - if (!(data->has_pwm & (1 << i))) - continue; - - err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]); - if (err) - goto exit_remove; - - if (data->REG_PWM[3]) { - err = device_create_file(dev, - &sda_pwm_max[i].dev_attr); - if (err) - goto exit_remove; - } - if (data->REG_PWM[4]) { - err = device_create_file(dev, - &sda_pwm_step[i].dev_attr); - if (err) - goto exit_remove; - } - if (data->REG_PWM[6]) { - err = device_create_file(dev, - &sda_weight_duty_base[i].dev_attr); - if (err) - goto exit_remove; - } - } - for (i = 0; i < ARRAY_SIZE(sda_auto_pwm_arrays); i++) { - struct sensor_device_attribute_2 *attr = - &sda_auto_pwm_arrays[i]; - - if (!(data->has_pwm & (1 << attr->nr))) - continue; - if (attr->index > data->auto_pwm_num) - continue; - err = device_create_file(dev, &attr->dev_attr); - if (err) - goto exit_remove; - } - - for (i = 0; i < data->in_num; i++) { - if (!(data->have_in & (1 << i))) - continue; - err = sysfs_create_group(&dev->kobj, &nct6775_group_in[i]); - if (err) - goto exit_remove; - } - - for (i = 0; i < 5; i++) { - if (data->has_fan & (1 << i)) { - err = device_create_file(dev, - &sda_fan_input[i].dev_attr); - if (err) - goto exit_remove; - err = device_create_file(dev, - &sda_fan_alarm[i].dev_attr); - if (err) - goto exit_remove; - if (data->kind != nct6776 && - data->kind != nct6779) { - err = device_create_file(dev, - &sda_fan_div[i].dev_attr); - if (err) - goto exit_remove; - } - if (data->has_fan_min & (1 << i)) { - err = device_create_file(dev, - &sda_fan_min[i].dev_attr); - if (err) - goto exit_remove; - } - err = device_create_file(dev, - &sda_fan_pulses[i].dev_attr); - if (err) - goto exit_remove; - } - } - - for (i = 0; i < NUM_TEMP; i++) { - if (!(data->have_temp & (1 << i))) - continue; - err = device_create_file(dev, &sda_temp_input[i].dev_attr); - if (err) - goto exit_remove; - if (data->temp_label) { - err = device_create_file(dev, - &sda_temp_label[i].dev_attr); - if (err) - goto exit_remove; - } - if (data->reg_temp[1][i]) { - err = device_create_file(dev, - &sda_temp_max[i].dev_attr); - if (err) - goto exit_remove; - } - if (data->reg_temp[2][i]) { - err = device_create_file(dev, - &sda_temp_max_hyst[i].dev_attr); - if (err) - goto exit_remove; - } - if (data->reg_temp[3][i]) { - err = device_create_file(dev, - &sda_temp_crit[i].dev_attr); - if (err) - goto exit_remove; - } - if (!(data->have_temp_fixed & (1 << i))) - continue; - err = device_create_file(dev, &sda_temp_type[i].dev_attr); - if (err) - goto exit_remove; - err = device_create_file(dev, &sda_temp_offset[i].dev_attr); - if (err) - goto exit_remove; - if (i >= NUM_TEMP_ALARM || - data->ALARM_BITS[TEMP_ALARM_BASE + i] < 0) - continue; - err = device_create_file(dev, &sda_temp_alarm[i].dev_attr); - if (err) - goto exit_remove; - } - - for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) { - if (data->ALARM_BITS[INTRUSION_ALARM_BASE + i] < 0) - continue; - err = device_create_file(dev, &sda_caseopen[i].dev_attr); - if (err) - goto exit_remove; - } - - err = device_create_file(dev, &dev_attr_name); - if (err) - goto exit_remove; - - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - return 0; - -exit_remove: - nct6775_device_remove_files(dev); - return err; -} - -static int nct6775_remove(struct platform_device *pdev) -{ - struct nct6775_data *data = platform_get_drvdata(pdev); - - hwmon_device_unregister(data->hwmon_dev); - nct6775_device_remove_files(&pdev->dev); - - return 0; -} - -#ifdef CONFIG_PM -static int nct6775_suspend(struct device *dev) -{ - struct nct6775_data *data = nct6775_update_device(dev); - struct nct6775_sio_data *sio_data = dev->platform_data; - - mutex_lock(&data->update_lock); - data->vbat = nct6775_read_value(data, data->REG_VBAT); - if (sio_data->kind == nct6775) { - data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1); - data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2); - } - mutex_unlock(&data->update_lock); - - return 0; -} - -static int nct6775_resume(struct device *dev) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - struct nct6775_sio_data *sio_data = dev->platform_data; - int i, j; - - mutex_lock(&data->update_lock); - data->bank = 0xff; /* Force initial bank selection */ - - /* Restore limits */ - for (i = 0; i < data->in_num; i++) { - if (!(data->have_in & (1 << i))) - continue; - - nct6775_write_value(data, data->REG_IN_MINMAX[0][i], - data->in[i][1]); - nct6775_write_value(data, data->REG_IN_MINMAX[1][i], - data->in[i][2]); - } - - for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { - if (!(data->has_fan_min & (1 << i))) - continue; - - nct6775_write_value(data, data->REG_FAN_MIN[i], - data->fan_min[i]); - } - - for (i = 0; i < NUM_TEMP; i++) { - if (!(data->have_temp & (1 << i))) - continue; - - for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++) - if (data->reg_temp[j][i]) - nct6775_write_temp(data, data->reg_temp[j][i], - data->temp[j][i]); - } - - /* Restore other settings */ - nct6775_write_value(data, data->REG_VBAT, data->vbat); - if (sio_data->kind == nct6775) { - nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1); - nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2); - } - - /* Force re-reading all values */ - data->valid = false; - mutex_unlock(&data->update_lock); - - return 0; -} - -static const struct dev_pm_ops nct6775_dev_pm_ops = { - .suspend = nct6775_suspend, - .resume = nct6775_resume, -}; - -#define NCT6775_DEV_PM_OPS (&nct6775_dev_pm_ops) -#else -#define NCT6775_DEV_PM_OPS NULL -#endif /* CONFIG_PM */ - -static struct platform_driver nct6775_driver = { - .driver = { - .owner = THIS_MODULE, - .name = DRVNAME, - .pm = NCT6775_DEV_PM_OPS, - }, - .probe = nct6775_probe, - .remove = nct6775_remove, -}; - -static const char * const nct6775_sio_names[] __initconst = { - "NCT6775F", - "NCT6776D/F", - "NCT6779D", -}; - -/* nct6775_find() looks for a '627 in the Super-I/O config space */ -static int __init nct6775_find(int sioaddr, unsigned short *addr, - struct nct6775_sio_data *sio_data) -{ - u16 val; - int err; - - err = superio_enter(sioaddr); - if (err) - return err; - - if (force_id) - val = force_id; - else - val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) - | superio_inb(sioaddr, SIO_REG_DEVID + 1); - switch (val & SIO_ID_MASK) { - case SIO_NCT6775_ID: - sio_data->kind = nct6775; - break; - case SIO_NCT6776_ID: - sio_data->kind = nct6776; - break; - case SIO_NCT6779_ID: - sio_data->kind = nct6779; - break; - default: - if (val != 0xffff) - pr_debug("unsupported chip ID: 0x%04x\n", val); - superio_exit(sioaddr); - return -ENODEV; - } - - /* We have a known chip, find the HWM I/O address */ - superio_select(sioaddr, NCT6775_LD_HWM); - val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) - | superio_inb(sioaddr, SIO_REG_ADDR + 1); - *addr = val & IOREGION_ALIGNMENT; - if (*addr == 0) { - pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n"); - superio_exit(sioaddr); - return -ENODEV; - } - - /* Activate logical device if needed */ - val = superio_inb(sioaddr, SIO_REG_ENABLE); - if (!(val & 0x01)) { - pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); - superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); - } - - superio_exit(sioaddr); - pr_info("Found %s or compatible chip at %#x\n", - nct6775_sio_names[sio_data->kind], *addr); - sio_data->sioreg = sioaddr; - - return 0; -} - -/* - * when Super-I/O functions move to a separate file, the Super-I/O - * bus will manage the lifetime of the device and this module will only keep - * track of the nct6775 driver. But since we platform_device_alloc(), we - * must keep track of the device - */ -static struct platform_device *pdev; - -static int __init sensors_nct6775_init(void) -{ - int err; - unsigned short address; - struct resource res; - struct nct6775_sio_data sio_data; - - /* - * initialize sio_data->kind and sio_data->sioreg. - * - * when Super-I/O functions move to a separate file, the Super-I/O - * driver will probe 0x2e and 0x4e and auto-detect the presence of a - * nct6775 hardware monitor, and call probe() - */ - if (nct6775_find(0x2e, &address, &sio_data) && - nct6775_find(0x4e, &address, &sio_data)) - return -ENODEV; - - err = platform_driver_register(&nct6775_driver); - if (err) - goto exit; - - pdev = platform_device_alloc(DRVNAME, address); - if (!pdev) { - err = -ENOMEM; - pr_err("Device allocation failed\n"); - goto exit_unregister; - } - - err = platform_device_add_data(pdev, &sio_data, - sizeof(struct nct6775_sio_data)); - if (err) { - pr_err("Platform data allocation failed\n"); - goto exit_device_put; - } - - memset(&res, 0, sizeof(res)); - res.name = DRVNAME; - res.start = address + IOREGION_OFFSET; - res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; - res.flags = IORESOURCE_IO; - - err = acpi_check_resource_conflict(&res); - if (err) - goto exit_device_put; - - err = platform_device_add_resources(pdev, &res, 1); - if (err) { - pr_err("Device resource addition failed (%d)\n", err); - goto exit_device_put; - } - - /* platform_device_add calls probe() */ - err = platform_device_add(pdev); - if (err) { - pr_err("Device addition failed (%d)\n", err); - goto exit_device_put; - } - - return 0; - -exit_device_put: - platform_device_put(pdev); -exit_unregister: - platform_driver_unregister(&nct6775_driver); -exit: - return err; -} - -static void __exit sensors_nct6775_exit(void) -{ - platform_device_unregister(pdev); - platform_driver_unregister(&nct6775_driver); -} - -MODULE_AUTHOR("Guenter Roeck "); -MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver"); -MODULE_LICENSE("GPL"); - -module_init(sensors_nct6775_init); -module_exit(sensors_nct6775_exit); diff --git a/trunk/drivers/hwmon/ntc_thermistor.c b/trunk/drivers/hwmon/ntc_thermistor.c index d6d640a733d5..b5f63f9c0ce1 100644 --- a/trunk/drivers/hwmon/ntc_thermistor.c +++ b/trunk/drivers/hwmon/ntc_thermistor.c @@ -26,33 +26,17 @@ #include #include #include -#include -#include #include -#include -#include -#include -#include - #include #include struct ntc_compensation { - int temp_c; + int temp_C; unsigned int ohm; }; -static const struct platform_device_id ntc_thermistor_id[] = { - { "ncp15wb473", TYPE_NCPXXWB473 }, - { "ncp18wb473", TYPE_NCPXXWB473 }, - { "ncp21wb473", TYPE_NCPXXWB473 }, - { "ncp03wb473", TYPE_NCPXXWB473 }, - { "ncp15wl333", TYPE_NCPXXWL333 }, - { }, -}; - /* * A compensation table should be sorted by the values of .ohm * in descending order. @@ -60,76 +44,76 @@ static const struct platform_device_id ntc_thermistor_id[] = { * Thermistors Datasheet */ static const struct ntc_compensation ncpXXwb473[] = { - { .temp_c = -40, .ohm = 1747920 }, - { .temp_c = -35, .ohm = 1245428 }, - { .temp_c = -30, .ohm = 898485 }, - { .temp_c = -25, .ohm = 655802 }, - { .temp_c = -20, .ohm = 483954 }, - { .temp_c = -15, .ohm = 360850 }, - { .temp_c = -10, .ohm = 271697 }, - { .temp_c = -5, .ohm = 206463 }, - { .temp_c = 0, .ohm = 158214 }, - { .temp_c = 5, .ohm = 122259 }, - { .temp_c = 10, .ohm = 95227 }, - { .temp_c = 15, .ohm = 74730 }, - { .temp_c = 20, .ohm = 59065 }, - { .temp_c = 25, .ohm = 47000 }, - { .temp_c = 30, .ohm = 37643 }, - { .temp_c = 35, .ohm = 30334 }, - { .temp_c = 40, .ohm = 24591 }, - { .temp_c = 45, .ohm = 20048 }, - { .temp_c = 50, .ohm = 16433 }, - { .temp_c = 55, .ohm = 13539 }, - { .temp_c = 60, .ohm = 11209 }, - { .temp_c = 65, .ohm = 9328 }, - { .temp_c = 70, .ohm = 7798 }, - { .temp_c = 75, .ohm = 6544 }, - { .temp_c = 80, .ohm = 5518 }, - { .temp_c = 85, .ohm = 4674 }, - { .temp_c = 90, .ohm = 3972 }, - { .temp_c = 95, .ohm = 3388 }, - { .temp_c = 100, .ohm = 2902 }, - { .temp_c = 105, .ohm = 2494 }, - { .temp_c = 110, .ohm = 2150 }, - { .temp_c = 115, .ohm = 1860 }, - { .temp_c = 120, .ohm = 1615 }, - { .temp_c = 125, .ohm = 1406 }, + { .temp_C = -40, .ohm = 1747920 }, + { .temp_C = -35, .ohm = 1245428 }, + { .temp_C = -30, .ohm = 898485 }, + { .temp_C = -25, .ohm = 655802 }, + { .temp_C = -20, .ohm = 483954 }, + { .temp_C = -15, .ohm = 360850 }, + { .temp_C = -10, .ohm = 271697 }, + { .temp_C = -5, .ohm = 206463 }, + { .temp_C = 0, .ohm = 158214 }, + { .temp_C = 5, .ohm = 122259 }, + { .temp_C = 10, .ohm = 95227 }, + { .temp_C = 15, .ohm = 74730 }, + { .temp_C = 20, .ohm = 59065 }, + { .temp_C = 25, .ohm = 47000 }, + { .temp_C = 30, .ohm = 37643 }, + { .temp_C = 35, .ohm = 30334 }, + { .temp_C = 40, .ohm = 24591 }, + { .temp_C = 45, .ohm = 20048 }, + { .temp_C = 50, .ohm = 16433 }, + { .temp_C = 55, .ohm = 13539 }, + { .temp_C = 60, .ohm = 11209 }, + { .temp_C = 65, .ohm = 9328 }, + { .temp_C = 70, .ohm = 7798 }, + { .temp_C = 75, .ohm = 6544 }, + { .temp_C = 80, .ohm = 5518 }, + { .temp_C = 85, .ohm = 4674 }, + { .temp_C = 90, .ohm = 3972 }, + { .temp_C = 95, .ohm = 3388 }, + { .temp_C = 100, .ohm = 2902 }, + { .temp_C = 105, .ohm = 2494 }, + { .temp_C = 110, .ohm = 2150 }, + { .temp_C = 115, .ohm = 1860 }, + { .temp_C = 120, .ohm = 1615 }, + { .temp_C = 125, .ohm = 1406 }, }; static const struct ntc_compensation ncpXXwl333[] = { - { .temp_c = -40, .ohm = 1610154 }, - { .temp_c = -35, .ohm = 1130850 }, - { .temp_c = -30, .ohm = 802609 }, - { .temp_c = -25, .ohm = 575385 }, - { .temp_c = -20, .ohm = 416464 }, - { .temp_c = -15, .ohm = 304219 }, - { .temp_c = -10, .ohm = 224193 }, - { .temp_c = -5, .ohm = 166623 }, - { .temp_c = 0, .ohm = 124850 }, - { .temp_c = 5, .ohm = 94287 }, - { .temp_c = 10, .ohm = 71747 }, - { .temp_c = 15, .ohm = 54996 }, - { .temp_c = 20, .ohm = 42455 }, - { .temp_c = 25, .ohm = 33000 }, - { .temp_c = 30, .ohm = 25822 }, - { .temp_c = 35, .ohm = 20335 }, - { .temp_c = 40, .ohm = 16115 }, - { .temp_c = 45, .ohm = 12849 }, - { .temp_c = 50, .ohm = 10306 }, - { .temp_c = 55, .ohm = 8314 }, - { .temp_c = 60, .ohm = 6746 }, - { .temp_c = 65, .ohm = 5503 }, - { .temp_c = 70, .ohm = 4513 }, - { .temp_c = 75, .ohm = 3721 }, - { .temp_c = 80, .ohm = 3084 }, - { .temp_c = 85, .ohm = 2569 }, - { .temp_c = 90, .ohm = 2151 }, - { .temp_c = 95, .ohm = 1809 }, - { .temp_c = 100, .ohm = 1529 }, - { .temp_c = 105, .ohm = 1299 }, - { .temp_c = 110, .ohm = 1108 }, - { .temp_c = 115, .ohm = 949 }, - { .temp_c = 120, .ohm = 817 }, - { .temp_c = 125, .ohm = 707 }, + { .temp_C = -40, .ohm = 1610154 }, + { .temp_C = -35, .ohm = 1130850 }, + { .temp_C = -30, .ohm = 802609 }, + { .temp_C = -25, .ohm = 575385 }, + { .temp_C = -20, .ohm = 416464 }, + { .temp_C = -15, .ohm = 304219 }, + { .temp_C = -10, .ohm = 224193 }, + { .temp_C = -5, .ohm = 166623 }, + { .temp_C = 0, .ohm = 124850 }, + { .temp_C = 5, .ohm = 94287 }, + { .temp_C = 10, .ohm = 71747 }, + { .temp_C = 15, .ohm = 54996 }, + { .temp_C = 20, .ohm = 42455 }, + { .temp_C = 25, .ohm = 33000 }, + { .temp_C = 30, .ohm = 25822 }, + { .temp_C = 35, .ohm = 20335 }, + { .temp_C = 40, .ohm = 16115 }, + { .temp_C = 45, .ohm = 12849 }, + { .temp_C = 50, .ohm = 10306 }, + { .temp_C = 55, .ohm = 8314 }, + { .temp_C = 60, .ohm = 6746 }, + { .temp_C = 65, .ohm = 5503 }, + { .temp_C = 70, .ohm = 4513 }, + { .temp_C = 75, .ohm = 3721 }, + { .temp_C = 80, .ohm = 3084 }, + { .temp_C = 85, .ohm = 2569 }, + { .temp_C = 90, .ohm = 2151 }, + { .temp_C = 95, .ohm = 1809 }, + { .temp_C = 100, .ohm = 1529 }, + { .temp_C = 105, .ohm = 1299 }, + { .temp_C = 110, .ohm = 1108 }, + { .temp_C = 115, .ohm = 949 }, + { .temp_C = 120, .ohm = 817 }, + { .temp_C = 125, .ohm = 707 }, }; struct ntc_data { @@ -141,92 +125,6 @@ struct ntc_data { char name[PLATFORM_NAME_SIZE]; }; -#ifdef CONFIG_OF -static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) -{ - struct iio_channel *channel = pdata->chan; - unsigned int result; - int val, ret; - - ret = iio_read_channel_raw(channel, &val); - if (ret < 0) { - pr_err("read channel() error: %d\n", ret); - return ret; - } - - /* unit: mV */ - result = pdata->pullup_uv * val; - result >>= 12; - - return result; -} - -static const struct of_device_id ntc_match[] = { - { .compatible = "ntc,ncp15wb473", - .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, - { .compatible = "ntc,ncp18wb473", - .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, - { .compatible = "ntc,ncp21wb473", - .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, - { .compatible = "ntc,ncp03wb473", - .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, - { .compatible = "ntc,ncp15wl333", - .data = &ntc_thermistor_id[TYPE_NCPXXWL333] }, - { }, -}; -MODULE_DEVICE_TABLE(of, ntc_match); - -static struct ntc_thermistor_platform_data * -ntc_thermistor_parse_dt(struct platform_device *pdev) -{ - struct iio_channel *chan; - struct device_node *np = pdev->dev.of_node; - struct ntc_thermistor_platform_data *pdata; - - if (!np) - return NULL; - - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); - - chan = iio_channel_get(&pdev->dev, NULL); - if (IS_ERR(chan)) - return ERR_CAST(chan); - - if (of_property_read_u32(np, "pullup-uv", &pdata->pullup_uv)) - return ERR_PTR(-ENODEV); - if (of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm)) - return ERR_PTR(-ENODEV); - if (of_property_read_u32(np, "pulldown-ohm", &pdata->pulldown_ohm)) - return ERR_PTR(-ENODEV); - - if (of_find_property(np, "connected-positive", NULL)) - pdata->connect = NTC_CONNECTED_POSITIVE; - else /* status change should be possible if not always on. */ - pdata->connect = NTC_CONNECTED_GROUND; - - pdata->chan = chan; - pdata->read_uv = ntc_adc_iio_read; - - return pdata; -} -static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) -{ - if (pdata->chan) - iio_channel_release(pdata->chan); -} -#else -static struct ntc_thermistor_platform_data * -ntc_thermistor_parse_dt(struct platform_device *pdev) -{ - return NULL; -} - -static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) -{ } -#endif - static inline u64 div64_u64_safe(u64 dividend, u64 divisor) { if (divisor == 0 && dividend == 0) @@ -236,37 +134,37 @@ static inline u64 div64_u64_safe(u64 dividend, u64 divisor) return div64_u64(dividend, divisor); } -static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv) +static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uV) { struct ntc_thermistor_platform_data *pdata = data->pdata; - u64 mv = uv / 1000; - u64 pmv = pdata->pullup_uv / 1000; - u64 n, puo, pdo; - puo = pdata->pullup_ohm; - pdo = pdata->pulldown_ohm; + u64 mV = uV / 1000; + u64 pmV = pdata->pullup_uV / 1000; + u64 N, puO, pdO; + puO = pdata->pullup_ohm; + pdO = pdata->pulldown_ohm; - if (mv == 0) { + if (mV == 0) { if (pdata->connect == NTC_CONNECTED_POSITIVE) return INT_MAX; return 0; } - if (mv >= pmv) + if (mV >= pmV) return (pdata->connect == NTC_CONNECTED_POSITIVE) ? 0 : INT_MAX; - if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0) - n = div64_u64_safe(pdo * (pmv - mv), mv); - else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0) - n = div64_u64_safe(puo * mv, pmv - mv); + if (pdata->connect == NTC_CONNECTED_POSITIVE && puO == 0) + N = div64_u64_safe(pdO * (pmV - mV), mV); + else if (pdata->connect == NTC_CONNECTED_GROUND && pdO == 0) + N = div64_u64_safe(puO * mV, pmV - mV); else if (pdata->connect == NTC_CONNECTED_POSITIVE) - n = div64_u64_safe(pdo * puo * (pmv - mv), - puo * mv - pdo * (pmv - mv)); + N = div64_u64_safe(pdO * puO * (pmV - mV), + puO * mV - pdO * (pmV - mV)); else - n = div64_u64_safe(pdo * puo * mv, pdo * (pmv - mv) - puo * mv); + N = div64_u64_safe(pdO * puO * mV, pdO * (pmV - mV) - puO * mV); - if (n > INT_MAX) - n = INT_MAX; - return n; + if (N > INT_MAX) + N = INT_MAX; + return N; } static void lookup_comp(struct ntc_data *data, unsigned int ohm, @@ -335,7 +233,7 @@ static void lookup_comp(struct ntc_data *data, unsigned int ohm, *i_high = end - 1; } -static int get_temp_mc(struct ntc_data *data, unsigned int ohm) +static int get_temp_mC(struct ntc_data *data, unsigned int ohm) { int low, high; int temp; @@ -343,10 +241,10 @@ static int get_temp_mc(struct ntc_data *data, unsigned int ohm) lookup_comp(data, ohm, &low, &high); if (low == high) { /* Unable to use linear approximation */ - temp = data->comp[low].temp_c * 1000; + temp = data->comp[low].temp_C * 1000; } else { - temp = data->comp[low].temp_c * 1000 + - ((data->comp[high].temp_c - data->comp[low].temp_c) * + temp = data->comp[low].temp_C * 1000 + + ((data->comp[high].temp_C - data->comp[low].temp_C) * 1000 * ((int)ohm - (int)data->comp[low].ohm)) / ((int)data->comp[high].ohm - (int)data->comp[low].ohm); } @@ -355,16 +253,16 @@ static int get_temp_mc(struct ntc_data *data, unsigned int ohm) static int ntc_thermistor_get_ohm(struct ntc_data *data) { - int read_uv; + int read_uV; if (data->pdata->read_ohm) return data->pdata->read_ohm(); - if (data->pdata->read_uv) { - read_uv = data->pdata->read_uv(data->pdata); - if (read_uv < 0) - return read_uv; - return get_ohm_of_thermistor(data, read_uv); + if (data->pdata->read_uV) { + read_uV = data->pdata->read_uV(); + if (read_uV < 0) + return read_uV; + return get_ohm_of_thermistor(data, read_uV); } return -EINVAL; } @@ -393,7 +291,7 @@ static ssize_t ntc_show_temp(struct device *dev, if (ohm < 0) return ohm; - return sprintf(buf, "%d\n", get_temp_mc(data, ohm)); + return sprintf(buf, "%d\n", get_temp_mC(data, ohm)); } static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, ntc_show_type, NULL, 0); @@ -413,18 +311,9 @@ static const struct attribute_group ntc_attr_group = { static int ntc_thermistor_probe(struct platform_device *pdev) { - const struct of_device_id *of_id = - of_match_device(of_match_ptr(ntc_match), &pdev->dev); - const struct platform_device_id *pdev_id; - struct ntc_thermistor_platform_data *pdata; struct ntc_data *data; - int ret; - - pdata = ntc_thermistor_parse_dt(pdev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - else if (pdata == NULL) - pdata = pdev->dev.platform_data; + struct ntc_thermistor_platform_data *pdata = pdev->dev.platform_data; + int ret = 0; if (!pdata) { dev_err(&pdev->dev, "No platform init data supplied.\n"); @@ -432,19 +321,19 @@ static int ntc_thermistor_probe(struct platform_device *pdev) } /* Either one of the two is required. */ - if (!pdata->read_uv && !pdata->read_ohm) { + if (!pdata->read_uV && !pdata->read_ohm) { dev_err(&pdev->dev, - "Both read_uv and read_ohm missing. Need either one of the two.\n"); + "Both read_uV and read_ohm missing. Need either one of the two.\n"); return -EINVAL; } - if (pdata->read_uv && pdata->read_ohm) { + if (pdata->read_uV && pdata->read_ohm) { dev_warn(&pdev->dev, - "Only one of read_uv and read_ohm is needed; ignoring read_uv.\n"); - pdata->read_uv = NULL; + "Only one of read_uV and read_ohm is needed; ignoring read_uV.\n"); + pdata->read_uV = NULL; } - if (pdata->read_uv && (pdata->pullup_uv == 0 || + if (pdata->read_uV && (pdata->pullup_uV == 0 || (pdata->pullup_ohm == 0 && pdata->connect == NTC_CONNECTED_GROUND) || (pdata->pulldown_ohm == 0 && pdata->connect == @@ -452,7 +341,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) (pdata->connect != NTC_CONNECTED_POSITIVE && pdata->connect != NTC_CONNECTED_GROUND))) { dev_err(&pdev->dev, - "Required data to use read_uv not supplied.\n"); + "Required data to use read_uV not supplied.\n"); return -EINVAL; } @@ -460,13 +349,11 @@ static int ntc_thermistor_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); - data->dev = &pdev->dev; data->pdata = pdata; - strlcpy(data->name, pdev_id->name, sizeof(data->name)); + strlcpy(data->name, pdev->id_entry->name, sizeof(data->name)); - switch (pdev_id->driver_data) { + switch (pdev->id_entry->driver_data) { case TYPE_NCPXXWB473: data->comp = ncpXXwb473; data->n_comp = ARRAY_SIZE(ncpXXwb473); @@ -477,7 +364,8 @@ static int ntc_thermistor_probe(struct platform_device *pdev) break; default: dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", - pdev_id->driver_data, pdev_id->name); + pdev->id_entry->driver_data, + pdev->id_entry->name); return -EINVAL; } @@ -496,34 +384,39 @@ static int ntc_thermistor_probe(struct platform_device *pdev) goto err_after_sysfs; } - dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n", - pdev->name); - + dev_info(&pdev->dev, "Thermistor %s:%d (type: %s/%lu) successfully probed.\n", + pdev->name, pdev->id, pdev->id_entry->name, + pdev->id_entry->driver_data); return 0; err_after_sysfs: sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); - ntc_iio_channel_release(pdata); return ret; } static int ntc_thermistor_remove(struct platform_device *pdev) { struct ntc_data *data = platform_get_drvdata(pdev); - struct ntc_thermistor_platform_data *pdata = data->pdata; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); - ntc_iio_channel_release(pdata); platform_set_drvdata(pdev, NULL); return 0; } +static const struct platform_device_id ntc_thermistor_id[] = { + { "ncp15wb473", TYPE_NCPXXWB473 }, + { "ncp18wb473", TYPE_NCPXXWB473 }, + { "ncp21wb473", TYPE_NCPXXWB473 }, + { "ncp03wb473", TYPE_NCPXXWB473 }, + { "ncp15wl333", TYPE_NCPXXWL333 }, + { }, +}; + static struct platform_driver ntc_thermistor_driver = { .driver = { .name = "ntc-thermistor", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(ntc_match), }, .probe = ntc_thermistor_probe, .remove = ntc_thermistor_remove, diff --git a/trunk/drivers/hwmon/pc87360.c b/trunk/drivers/hwmon/pc87360.c index aa615ba73d4b..e35856bb79b4 100644 --- a/trunk/drivers/hwmon/pc87360.c +++ b/trunk/drivers/hwmon/pc87360.c @@ -1190,7 +1190,8 @@ static int __init pc87360_find(int sioaddr, u8 *devid, confreg[3] = superio_inb(sioaddr, 0x25); if (confreg[2] & 0x40) { - pr_info("Using thermistors for temperature monitoring\n"); + pr_info("Using thermistors for " + "temperature monitoring\n"); } if (confreg[3] & 0xE0) { pr_info("VID inputs routed (mode %u)\n", @@ -1270,9 +1271,9 @@ static int pc87360_probe(struct platform_device *pdev) if (data->address[i] && !devm_request_region(dev, extra_isa[i], PC87360_EXTENT, pc87360_driver.driver.name)) { - dev_err(dev, - "Region 0x%x-0x%x already in use!\n", - extra_isa[i], extra_isa[i]+PC87360_EXTENT-1); + dev_err(dev, "Region 0x%x-0x%x already " + "in use!\n", extra_isa[i], + extra_isa[i]+PC87360_EXTENT-1); return -EBUSY; } } @@ -1434,8 +1435,8 @@ static void pc87360_init_device(struct platform_device *pdev, if (init >= 2 && data->innr) { reg = pc87360_read_value(data, LD_IN, NO_BANK, PC87365_REG_IN_CONVRATE); - dev_info(&pdev->dev, - "VLM conversion set to 1s period, 160us delay\n"); + dev_info(&pdev->dev, "VLM conversion set to " + "1s period, 160us delay\n"); pc87360_write_value(data, LD_IN, NO_BANK, PC87365_REG_IN_CONVRATE, (reg & 0xC0) | 0x11); @@ -1449,8 +1450,8 @@ static void pc87360_init_device(struct platform_device *pdev, if (init >= init_in[i]) { /* Forcibly enable voltage channel */ if (!(reg & CHAN_ENA)) { - dev_dbg(&pdev->dev, "Forcibly enabling in%d\n", - i); + dev_dbg(&pdev->dev, "Forcibly " + "enabling in%d\n", i); pc87360_write_value(data, LD_IN, i, PC87365_REG_IN_STATUS, (reg & 0x68) | 0x87); @@ -1574,8 +1575,8 @@ static void pc87360_autodiv(struct device *dev, int nr) data->fan_status[nr] += 0x20; data->fan_min[nr] >>= 1; data->fan[nr] >>= 1; - dev_dbg(dev, - "Increasing clock divider to %d for fan %d\n", + dev_dbg(dev, "Increasing " + "clock divider to %d for fan %d\n", FAN_DIV_FROM_REG(data->fan_status[nr]), nr + 1); } } else { @@ -1586,8 +1587,8 @@ static void pc87360_autodiv(struct device *dev, int nr) data->fan_status[nr] -= 0x20; data->fan_min[nr] <<= 1; data->fan[nr] <<= 1; - dev_dbg(dev, - "Decreasing clock divider to %d for fan %d\n", + dev_dbg(dev, "Decreasing " + "clock divider to %d for fan %d\n", FAN_DIV_FROM_REG(data->fan_status[nr]), nr + 1); } diff --git a/trunk/drivers/hwmon/pc87427.c b/trunk/drivers/hwmon/pc87427.c index ea606860d2b2..6086ad039d7d 100644 --- a/trunk/drivers/hwmon/pc87427.c +++ b/trunk/drivers/hwmon/pc87427.c @@ -627,9 +627,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute pc87427_readall_pwm(data, nr); mode = data->pwm_enable[nr] & PWM_ENABLE_MODE_MASK; if (mode != PWM_MODE_MANUAL && mode != PWM_MODE_OFF) { - dev_notice(dev, - "Can't set PWM%d duty cycle while not in manual mode\n", - nr + 1); + dev_notice(dev, "Can't set PWM%d duty cycle while not in " + "manual mode\n", nr + 1); mutex_unlock(&data->lock); return -EPERM; } @@ -1246,16 +1245,16 @@ static int __init pc87427_find(int sioaddr, struct pc87427_sio_data *sio_data) val = superio_inb(sioaddr, SIOREG_MAP); if (val & 0x01) { - pr_warn("Logical device 0x%02x is memory-mapped, can't use\n", - logdev[i]); + pr_warn("Logical device 0x%02x is memory-mapped, " + "can't use\n", logdev[i]); continue; } val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8) | superio_inb(sioaddr, SIOREG_IOBASE + 1); if (!val) { - pr_info("I/O base address not set for logical device 0x%02x\n", - logdev[i]); + pr_info("I/O base address not set for logical device " + "0x%02x\n", logdev[i]); continue; } sio_data->address[i] = val; diff --git a/trunk/drivers/hwmon/pmbus/Kconfig b/trunk/drivers/hwmon/pmbus/Kconfig index 39cc63edfbb0..4f9eb0af5229 100644 --- a/trunk/drivers/hwmon/pmbus/Kconfig +++ b/trunk/drivers/hwmon/pmbus/Kconfig @@ -42,17 +42,17 @@ config SENSORS_LM25066 default n help If you say yes here you get hardware monitoring support for National - Semiconductor LM25056, LM25066, LM5064, and LM5066. + Semiconductor LM25066, LM5064, and LM5066. This driver can also be built as a module. If so, the module will be called lm25066. config SENSORS_LTC2978 - tristate "Linear Technologies LTC2974, LTC2978, LTC3880, and LTC3883" + tristate "Linear Technologies LTC2978 and LTC3880" default n help If you say yes here you get hardware monitoring support for Linear - Technology LTC2974, LTC2978, LTC3880, and LTC3883. + Technology LTC2978 and LTC3880. This driver can also be built as a module. If so, the module will be called ltc2978. diff --git a/trunk/drivers/hwmon/pmbus/lm25066.c b/trunk/drivers/hwmon/pmbus/lm25066.c index 6a9d6edaacb3..c299392716af 100644 --- a/trunk/drivers/hwmon/pmbus/lm25066.c +++ b/trunk/drivers/hwmon/pmbus/lm25066.c @@ -1,8 +1,7 @@ /* - * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066 + * Hardware monitoring driver for LM25066 / LM5064 / LM5066 * * Copyright (c) 2011 Ericsson AB. - * Copyright (c) 2013 Guenter Roeck * * 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 @@ -27,7 +26,7 @@ #include #include "pmbus.h" -enum chips { lm25056, lm25066, lm5064, lm5066 }; +enum chips { lm25066, lm5064, lm5066 }; #define LM25066_READ_VAUX 0xd0 #define LM25066_MFR_READ_IIN 0xd1 @@ -44,138 +43,6 @@ enum chips { lm25056, lm25066, lm5064, lm5066 }; #define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */ -/* LM25056 only */ - -#define LM25056_VAUX_OV_WARN_LIMIT 0xe3 -#define LM25056_VAUX_UV_WARN_LIMIT 0xe4 - -#define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1) -#define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0) - -struct __coeff { - short m, b, R; -}; - -#define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) -#define PSC_POWER_L (PSC_NUM_CLASSES + 1) - -static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { - [lm25056] = { - [PSC_VOLTAGE_IN] = { - .m = 16296, - .R = -2, - }, - [PSC_CURRENT_IN] = { - .m = 13797, - .R = -2, - }, - [PSC_CURRENT_IN_L] = { - .m = 6726, - .R = -2, - }, - [PSC_POWER] = { - .m = 5501, - .R = -3, - }, - [PSC_POWER_L] = { - .m = 26882, - .R = -4, - }, - [PSC_TEMPERATURE] = { - .m = 1580, - .b = -14500, - .R = -2, - }, - }, - [lm25066] = { - [PSC_VOLTAGE_IN] = { - .m = 22070, - .R = -2, - }, - [PSC_VOLTAGE_OUT] = { - .m = 22070, - .R = -2, - }, - [PSC_CURRENT_IN] = { - .m = 13661, - .R = -2, - }, - [PSC_CURRENT_IN_L] = { - .m = 6852, - .R = -2, - }, - [PSC_POWER] = { - .m = 736, - .R = -2, - }, - [PSC_POWER_L] = { - .m = 369, - .R = -2, - }, - [PSC_TEMPERATURE] = { - .m = 16, - }, - }, - [lm5064] = { - [PSC_VOLTAGE_IN] = { - .m = 4611, - .R = -2, - }, - [PSC_VOLTAGE_OUT] = { - .m = 4621, - .R = -2, - }, - [PSC_CURRENT_IN] = { - .m = 10742, - .R = -2, - }, - [PSC_CURRENT_IN_L] = { - .m = 5456, - .R = -2, - }, - [PSC_POWER] = { - .m = 1204, - .R = -3, - }, - [PSC_POWER_L] = { - .m = 612, - .R = -3, - }, - [PSC_TEMPERATURE] = { - .m = 16, - }, - }, - [lm5066] = { - [PSC_VOLTAGE_IN] = { - .m = 4587, - .R = -2, - }, - [PSC_VOLTAGE_OUT] = { - .m = 4587, - .R = -2, - }, - [PSC_CURRENT_IN] = { - .m = 10753, - .R = -2, - }, - [PSC_CURRENT_IN_L] = { - .m = 5405, - .R = -2, - }, - [PSC_POWER] = { - .m = 1204, - .R = -3, - }, - [PSC_POWER_L] = { - .m = 605, - .R = -3, - }, - [PSC_TEMPERATURE] = { - .m = 16, - }, - }, -}; - struct lm25066_data { int id; struct pmbus_driver_info info; @@ -189,31 +56,42 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) const struct lm25066_data *data = to_lm25066_data(info); int ret; - switch (reg) { - case PMBUS_VIRT_READ_VMON: - ret = pmbus_read_word_data(client, 0, LM25066_READ_VAUX); - if (ret < 0) - break; - /* Adjust returned value to match VIN coefficients */ - switch (data->id) { - case lm25056: - /* VIN: 6.14 mV VAUX: 293 uV LSB */ - ret = DIV_ROUND_CLOSEST(ret * 293, 6140); + if (page > 1) + return -ENXIO; + + /* Map READ_VAUX into READ_VOUT register on page 1 */ + if (page == 1) { + switch (reg) { + case PMBUS_READ_VOUT: + ret = pmbus_read_word_data(client, 0, + LM25066_READ_VAUX); + if (ret < 0) + break; + /* Adjust returned value to match VOUT coefficients */ + switch (data->id) { + case lm25066: + /* VOUT: 4.54 mV VAUX: 283.2 uV LSB */ + ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); + break; + case lm5064: + /* VOUT: 4.53 mV VAUX: 700 uV LSB */ + ret = DIV_ROUND_CLOSEST(ret * 70, 453); + break; + case lm5066: + /* VOUT: 2.18 mV VAUX: 725 uV LSB */ + ret = DIV_ROUND_CLOSEST(ret * 725, 2180); + break; + } break; - case lm25066: - /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ - ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); - break; - case lm5064: - /* VIN: 4.53 mV VAUX: 700 uV LSB */ - ret = DIV_ROUND_CLOSEST(ret * 70, 453); - break; - case lm5066: - /* VIN: 2.18 mV VAUX: 725 uV LSB */ - ret = DIV_ROUND_CLOSEST(ret * 725, 2180); + default: + /* No other valid registers on page 1 */ + ret = -ENXIO; break; } - break; + goto done; + } + + switch (reg) { case PMBUS_READ_IIN: ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN); break; @@ -250,58 +128,7 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) ret = -ENODATA; break; } - return ret; -} - -static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) -{ - int ret; - - switch (reg) { - case PMBUS_VIRT_VMON_UV_WARN_LIMIT: - ret = pmbus_read_word_data(client, 0, - LM25056_VAUX_UV_WARN_LIMIT); - if (ret < 0) - break; - /* Adjust returned value to match VIN coefficients */ - ret = DIV_ROUND_CLOSEST(ret * 293, 6140); - break; - case PMBUS_VIRT_VMON_OV_WARN_LIMIT: - ret = pmbus_read_word_data(client, 0, - LM25056_VAUX_OV_WARN_LIMIT); - if (ret < 0) - break; - /* Adjust returned value to match VIN coefficients */ - ret = DIV_ROUND_CLOSEST(ret * 293, 6140); - break; - default: - ret = lm25066_read_word_data(client, page, reg); - break; - } - return ret; -} - -static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg) -{ - int ret, s; - - switch (reg) { - case PMBUS_VIRT_STATUS_VMON: - ret = pmbus_read_byte_data(client, 0, - PMBUS_STATUS_MFR_SPECIFIC); - if (ret < 0) - break; - s = 0; - if (ret & LM25056_MFR_STS_VAUX_UV_WARN) - s |= PB_VOLTAGE_UV_WARNING; - if (ret & LM25056_MFR_STS_VAUX_OV_WARN) - s |= PB_VOLTAGE_OV_WARNING; - ret = s; - break; - default: - ret = -ENODATA; - break; - } +done: return ret; } @@ -310,45 +137,19 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, { int ret; + if (page > 1) + return -ENXIO; + switch (reg) { - case PMBUS_VOUT_UV_WARN_LIMIT: - case PMBUS_OT_FAULT_LIMIT: - case PMBUS_OT_WARN_LIMIT: - case PMBUS_VIN_UV_WARN_LIMIT: - case PMBUS_VIN_OV_WARN_LIMIT: - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); - ret = pmbus_write_word_data(client, 0, reg, word); - pmbus_clear_cache(client); - break; case PMBUS_IIN_OC_WARN_LIMIT: - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); ret = pmbus_write_word_data(client, 0, LM25066_MFR_IIN_OC_WARN_LIMIT, word); - pmbus_clear_cache(client); break; case PMBUS_PIN_OP_WARN_LIMIT: - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); ret = pmbus_write_word_data(client, 0, LM25066_MFR_PIN_OP_WARN_LIMIT, word); - pmbus_clear_cache(client); - break; - case PMBUS_VIRT_VMON_UV_WARN_LIMIT: - /* Adjust from VIN coefficients (for LM25056) */ - word = DIV_ROUND_CLOSEST((int)word * 6140, 293); - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); - ret = pmbus_write_word_data(client, 0, - LM25056_VAUX_UV_WARN_LIMIT, word); - pmbus_clear_cache(client); - break; - case PMBUS_VIRT_VMON_OV_WARN_LIMIT: - /* Adjust from VIN coefficients (for LM25056) */ - word = DIV_ROUND_CLOSEST((int)word * 6140, 293); - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); - ret = pmbus_write_word_data(client, 0, - LM25056_VAUX_OV_WARN_LIMIT, word); - pmbus_clear_cache(client); break; case PMBUS_VIRT_RESET_PIN_HISTORY: ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK); @@ -360,13 +161,23 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, return ret; } +static int lm25066_write_byte(struct i2c_client *client, int page, u8 value) +{ + if (page > 1) + return -ENXIO; + + if (page <= 0) + return pmbus_write_byte(client, page, value); + + return 0; +} + static int lm25066_probe(struct i2c_client *client, const struct i2c_device_id *id) { int config; struct lm25066_data *data; struct pmbus_driver_info *info; - struct __coeff *coeff; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) @@ -384,54 +195,107 @@ static int lm25066_probe(struct i2c_client *client, data->id = id->driver_data; info = &data->info; - info->pages = 1; + info->pages = 2; info->format[PSC_VOLTAGE_IN] = direct; info->format[PSC_VOLTAGE_OUT] = direct; info->format[PSC_CURRENT_IN] = direct; info->format[PSC_TEMPERATURE] = direct; info->format[PSC_POWER] = direct; - info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON - | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT - | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; - - if (data->id == lm25056) { - info->func[0] |= PMBUS_HAVE_STATUS_VMON; - info->read_word_data = lm25056_read_word_data; - info->read_byte_data = lm25056_read_byte_data; - } else { - info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; - info->read_word_data = lm25066_read_word_data; - } - info->write_word_data = lm25066_write_word_data; + info->m[PSC_TEMPERATURE] = 16; + info->b[PSC_TEMPERATURE] = 0; + info->R[PSC_TEMPERATURE] = 0; - coeff = &lm25066_coeff[data->id][0]; - info->m[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].m; - info->b[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].b; - info->R[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].R; - info->m[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].m; - info->b[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].b; - info->R[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].R; - info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m; - info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b; - info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R; - info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b; - info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R; - info->b[PSC_POWER] = coeff[PSC_POWER].b; - info->R[PSC_POWER] = coeff[PSC_POWER].R; - if (config & LM25066_DEV_SETUP_CL) { - info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m; - info->m[PSC_POWER] = coeff[PSC_POWER_L].m; - } else { - info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m; - info->m[PSC_POWER] = coeff[PSC_POWER].m; + info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT + | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN + | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; + info->func[1] = PMBUS_HAVE_VOUT; + + info->read_word_data = lm25066_read_word_data; + info->write_word_data = lm25066_write_word_data; + info->write_byte = lm25066_write_byte; + + switch (id->driver_data) { + case lm25066: + info->m[PSC_VOLTAGE_IN] = 22070; + info->b[PSC_VOLTAGE_IN] = 0; + info->R[PSC_VOLTAGE_IN] = -2; + info->m[PSC_VOLTAGE_OUT] = 22070; + info->b[PSC_VOLTAGE_OUT] = 0; + info->R[PSC_VOLTAGE_OUT] = -2; + + if (config & LM25066_DEV_SETUP_CL) { + info->m[PSC_CURRENT_IN] = 6852; + info->b[PSC_CURRENT_IN] = 0; + info->R[PSC_CURRENT_IN] = -2; + info->m[PSC_POWER] = 369; + info->b[PSC_POWER] = 0; + info->R[PSC_POWER] = -2; + } else { + info->m[PSC_CURRENT_IN] = 13661; + info->b[PSC_CURRENT_IN] = 0; + info->R[PSC_CURRENT_IN] = -2; + info->m[PSC_POWER] = 736; + info->b[PSC_POWER] = 0; + info->R[PSC_POWER] = -2; + } + break; + case lm5064: + info->m[PSC_VOLTAGE_IN] = 22075; + info->b[PSC_VOLTAGE_IN] = 0; + info->R[PSC_VOLTAGE_IN] = -2; + info->m[PSC_VOLTAGE_OUT] = 22075; + info->b[PSC_VOLTAGE_OUT] = 0; + info->R[PSC_VOLTAGE_OUT] = -2; + + if (config & LM25066_DEV_SETUP_CL) { + info->m[PSC_CURRENT_IN] = 6713; + info->b[PSC_CURRENT_IN] = 0; + info->R[PSC_CURRENT_IN] = -2; + info->m[PSC_POWER] = 3619; + info->b[PSC_POWER] = 0; + info->R[PSC_POWER] = -3; + } else { + info->m[PSC_CURRENT_IN] = 13426; + info->b[PSC_CURRENT_IN] = 0; + info->R[PSC_CURRENT_IN] = -2; + info->m[PSC_POWER] = 7238; + info->b[PSC_POWER] = 0; + info->R[PSC_POWER] = -3; + } + break; + case lm5066: + info->m[PSC_VOLTAGE_IN] = 4587; + info->b[PSC_VOLTAGE_IN] = 0; + info->R[PSC_VOLTAGE_IN] = -2; + info->m[PSC_VOLTAGE_OUT] = 4587; + info->b[PSC_VOLTAGE_OUT] = 0; + info->R[PSC_VOLTAGE_OUT] = -2; + + if (config & LM25066_DEV_SETUP_CL) { + info->m[PSC_CURRENT_IN] = 10753; + info->b[PSC_CURRENT_IN] = 0; + info->R[PSC_CURRENT_IN] = -2; + info->m[PSC_POWER] = 1204; + info->b[PSC_POWER] = 0; + info->R[PSC_POWER] = -3; + } else { + info->m[PSC_CURRENT_IN] = 5405; + info->b[PSC_CURRENT_IN] = 0; + info->R[PSC_CURRENT_IN] = -2; + info->m[PSC_POWER] = 605; + info->b[PSC_POWER] = 0; + info->R[PSC_POWER] = -3; + } + break; + default: + return -ENODEV; } return pmbus_do_probe(client, id, info); } static const struct i2c_device_id lm25066_id[] = { - {"lm25056", lm25056}, {"lm25066", lm25066}, {"lm5064", lm5064}, {"lm5066", lm5066}, @@ -453,5 +317,5 @@ static struct i2c_driver lm25066_driver = { module_i2c_driver(lm25066_driver); MODULE_AUTHOR("Guenter Roeck"); -MODULE_DESCRIPTION("PMBus driver for LM25056/LM25066/LM5064/LM5066"); +MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/pmbus/ltc2978.c b/trunk/drivers/hwmon/pmbus/ltc2978.c index 586a89ef9e0f..9652a2c92a24 100644 --- a/trunk/drivers/hwmon/pmbus/ltc2978.c +++ b/trunk/drivers/hwmon/pmbus/ltc2978.c @@ -1,8 +1,7 @@ /* - * Hardware monitoring driver for LTC2974, LTC2978, LTC3880, and LTC3883 + * Hardware monitoring driver for LTC2978 and LTC3880 * * Copyright (c) 2011 Ericsson AB. - * Copyright (c) 2013 Guenter Roeck * * 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 @@ -27,43 +26,28 @@ #include #include "pmbus.h" -enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; +enum chips { ltc2978, ltc3880 }; -/* Common for all chips */ +/* LTC2978 and LTC3880 */ #define LTC2978_MFR_VOUT_PEAK 0xdd #define LTC2978_MFR_VIN_PEAK 0xde #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf #define LTC2978_MFR_SPECIAL_ID 0xe7 -/* LTC2974 and LTC2978 */ +/* LTC2978 only */ #define LTC2978_MFR_VOUT_MIN 0xfb #define LTC2978_MFR_VIN_MIN 0xfc #define LTC2978_MFR_TEMPERATURE_MIN 0xfd -/* LTC2974 only */ -#define LTC2974_MFR_IOUT_PEAK 0xd7 -#define LTC2974_MFR_IOUT_MIN 0xd8 - -/* LTC3880 and LTC3883 */ +/* LTC3880 only */ #define LTC3880_MFR_IOUT_PEAK 0xd7 #define LTC3880_MFR_CLEAR_PEAKS 0xe3 #define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4 -/* LTC3883 only */ -#define LTC3883_MFR_IIN_PEAK 0xe1 - -#define LTC2974_ID 0x0212 #define LTC2978_ID_REV1 0x0121 #define LTC2978_ID_REV2 0x0122 #define LTC3880_ID 0x4000 #define LTC3880_ID_MASK 0xff00 -#define LTC3883_ID 0x4300 -#define LTC3883_ID_MASK 0xff00 - -#define LTC2974_NUM_PAGES 4 -#define LTC2978_NUM_PAGES 8 -#define LTC3880_NUM_PAGES 2 -#define LTC3883_NUM_PAGES 1 /* * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which @@ -72,15 +56,13 @@ enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; * internal cache of measured peak data, which is only cleared if an explicit * "clear peak" command is executed for the sensor in question. */ - struct ltc2978_data { enum chips id; - u16 vin_min, vin_max; - u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES]; - u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES]; - u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES]; - u16 iin_max; - u16 temp2_max; + int vin_min, vin_max; + int temp_min, temp_max; + int vout_min[8], vout_max[8]; + int iout_max[2]; + int temp2_max[2]; struct pmbus_driver_info info; }; @@ -131,10 +113,9 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page, ret = pmbus_read_word_data(client, page, LTC2978_MFR_TEMPERATURE_PEAK); if (ret >= 0) { - if (lin11_to_val(ret) - > lin11_to_val(data->temp_max[page])) - data->temp_max[page] = ret; - ret = data->temp_max[page]; + if (lin11_to_val(ret) > lin11_to_val(data->temp_max)) + data->temp_max = ret; + ret = data->temp_max; } break; case PMBUS_VIRT_RESET_VOUT_HISTORY: @@ -185,9 +166,9 @@ static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) LTC2978_MFR_TEMPERATURE_MIN); if (ret >= 0) { if (lin11_to_val(ret) - < lin11_to_val(data->temp_min[page])) - data->temp_min[page] = ret; - ret = data->temp_min[page]; + < lin11_to_val(data->temp_min)) + data->temp_min = ret; + ret = data->temp_min; } break; case PMBUS_VIRT_READ_IOUT_MAX: @@ -203,41 +184,6 @@ static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) return ret; } -static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg) -{ - const struct pmbus_driver_info *info = pmbus_get_driver_info(client); - struct ltc2978_data *data = to_ltc2978_data(info); - int ret; - - switch (reg) { - case PMBUS_VIRT_READ_IOUT_MAX: - ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_PEAK); - if (ret >= 0) { - if (lin11_to_val(ret) - > lin11_to_val(data->iout_max[page])) - data->iout_max[page] = ret; - ret = data->iout_max[page]; - } - break; - case PMBUS_VIRT_READ_IOUT_MIN: - ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_MIN); - if (ret >= 0) { - if (lin11_to_val(ret) - < lin11_to_val(data->iout_min[page])) - data->iout_min[page] = ret; - ret = data->iout_min[page]; - } - break; - case PMBUS_VIRT_RESET_IOUT_HISTORY: - ret = 0; - break; - default: - ret = ltc2978_read_word_data(client, page, reg); - break; - } - return ret; -} - static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); @@ -258,9 +204,10 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) ret = pmbus_read_word_data(client, page, LTC3880_MFR_TEMPERATURE2_PEAK); if (ret >= 0) { - if (lin11_to_val(ret) > lin11_to_val(data->temp2_max)) - data->temp2_max = ret; - ret = data->temp2_max; + if (lin11_to_val(ret) + > lin11_to_val(data->temp2_max[page])) + data->temp2_max[page] = ret; + ret = data->temp2_max[page]; } break; case PMBUS_VIRT_READ_VIN_MIN: @@ -279,41 +226,15 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) return ret; } -static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg) -{ - const struct pmbus_driver_info *info = pmbus_get_driver_info(client); - struct ltc2978_data *data = to_ltc2978_data(info); - int ret; - - switch (reg) { - case PMBUS_VIRT_READ_IIN_MAX: - ret = pmbus_read_word_data(client, page, LTC3883_MFR_IIN_PEAK); - if (ret >= 0) { - if (lin11_to_val(ret) - > lin11_to_val(data->iin_max)) - data->iin_max = ret; - ret = data->iin_max; - } - break; - case PMBUS_VIRT_RESET_IIN_HISTORY: - ret = 0; - break; - default: - ret = ltc3880_read_word_data(client, page, reg); - break; - } - return ret; -} - static int ltc2978_clear_peaks(struct i2c_client *client, int page, enum chips id) { int ret; - if (id == ltc3880 || id == ltc3883) - ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS); - else + if (id == ltc2978) ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); + else + ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS); return ret; } @@ -326,17 +247,12 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, int ret; switch (reg) { - case PMBUS_VIRT_RESET_IIN_HISTORY: - data->iin_max = 0x7c00; - ret = ltc2978_clear_peaks(client, page, data->id); - break; case PMBUS_VIRT_RESET_IOUT_HISTORY: - data->iout_max[page] = 0x7c00; - data->iout_min[page] = 0xfbff; + data->iout_max[page] = 0x7fff; ret = ltc2978_clear_peaks(client, page, data->id); break; case PMBUS_VIRT_RESET_TEMP2_HISTORY: - data->temp2_max = 0x7c00; + data->temp2_max[page] = 0x7fff; ret = ltc2978_clear_peaks(client, page, data->id); break; case PMBUS_VIRT_RESET_VOUT_HISTORY: @@ -346,12 +262,12 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, break; case PMBUS_VIRT_RESET_VIN_HISTORY: data->vin_min = 0x7bff; - data->vin_max = 0x7c00; + data->vin_max = 0; ret = ltc2978_clear_peaks(client, page, data->id); break; case PMBUS_VIRT_RESET_TEMP_HISTORY: - data->temp_min[page] = 0x7bff; - data->temp_max[page] = 0x7c00; + data->temp_min = 0x7bff; + data->temp_max = 0x7fff; ret = ltc2978_clear_peaks(client, page, data->id); break; default: @@ -362,10 +278,8 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, } static const struct i2c_device_id ltc2978_id[] = { - {"ltc2974", ltc2974}, {"ltc2978", ltc2978}, {"ltc3880", ltc3880}, - {"ltc3883", ltc3883}, {} }; MODULE_DEVICE_TABLE(i2c, ltc2978_id); @@ -390,14 +304,10 @@ static int ltc2978_probe(struct i2c_client *client, if (chip_id < 0) return chip_id; - if (chip_id == LTC2974_ID) { - data->id = ltc2974; - } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { + if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { data->id = ltc2978; } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) { data->id = ltc3880; - } else if ((chip_id & LTC3883_ID_MASK) == LTC3883_ID) { - data->id = ltc3883; } else { dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id); return -ENODEV; @@ -411,47 +321,27 @@ static int ltc2978_probe(struct i2c_client *client, info = &data->info; info->write_word_data = ltc2978_write_word_data; + data->vout_min[0] = 0xffff; data->vin_min = 0x7bff; - data->vin_max = 0x7c00; - for (i = 0; i < ARRAY_SIZE(data->vout_min); i++) - data->vout_min[i] = 0xffff; - for (i = 0; i < ARRAY_SIZE(data->iout_min); i++) - data->iout_min[i] = 0xfbff; - for (i = 0; i < ARRAY_SIZE(data->iout_max); i++) - data->iout_max[i] = 0x7c00; - for (i = 0; i < ARRAY_SIZE(data->temp_min); i++) - data->temp_min[i] = 0x7bff; - for (i = 0; i < ARRAY_SIZE(data->temp_max); i++) - data->temp_max[i] = 0x7c00; - data->temp2_max = 0x7c00; - - switch (data->id) { - case ltc2974: - info->read_word_data = ltc2974_read_word_data; - info->pages = LTC2974_NUM_PAGES; - info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT - | PMBUS_HAVE_TEMP2; - for (i = 0; i < info->pages; i++) { - info->func[i] |= PMBUS_HAVE_VOUT - | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT - | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP - | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; - } - break; + data->temp_min = 0x7bff; + data->temp_max = 0x7fff; + + switch (id->driver_data) { case ltc2978: info->read_word_data = ltc2978_read_word_data; - info->pages = LTC2978_NUM_PAGES; + info->pages = 8; info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; - for (i = 1; i < LTC2978_NUM_PAGES; i++) { + for (i = 1; i < 8; i++) { info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; + data->vout_min[i] = 0xffff; } break; case ltc3880: info->read_word_data = ltc3880_read_word_data; - info->pages = LTC3880_NUM_PAGES; + info->pages = 2; info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT @@ -462,20 +352,12 @@ static int ltc2978_probe(struct i2c_client *client, | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; - break; - case ltc3883: - info->read_word_data = ltc3883_read_word_data; - info->pages = LTC3883_NUM_PAGES; - info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN - | PMBUS_HAVE_STATUS_INPUT - | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT - | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT - | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP - | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; + data->vout_min[1] = 0xffff; break; default: return -ENODEV; } + return pmbus_do_probe(client, id, info); } @@ -492,5 +374,5 @@ static struct i2c_driver ltc2978_driver = { module_i2c_driver(ltc2978_driver); MODULE_AUTHOR("Guenter Roeck"); -MODULE_DESCRIPTION("PMBus driver for LTC2974, LTC2978, LTC3880, and LTC3883"); +MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/pmbus/pmbus_core.c b/trunk/drivers/hwmon/pmbus/pmbus_core.c index 9add60920ac0..80eef50c50fd 100644 --- a/trunk/drivers/hwmon/pmbus/pmbus_core.c +++ b/trunk/drivers/hwmon/pmbus/pmbus_core.c @@ -766,14 +766,12 @@ static ssize_t pmbus_show_label(struct device *dev, static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) { if (data->num_attributes >= data->max_attributes - 1) { - int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE; - void *new_attrs = krealloc(data->group.attrs, - new_max_attrs * sizeof(void *), - GFP_KERNEL); - if (!new_attrs) + data->max_attributes += PMBUS_ATTR_ALLOC_SIZE; + data->group.attrs = krealloc(data->group.attrs, + sizeof(struct attribute *) * + data->max_attributes, GFP_KERNEL); + if (data->group.attrs == NULL) return -ENOMEM; - data->group.attrs = new_attrs; - data->max_attributes = new_max_attrs; } data->group.attrs[data->num_attributes++] = attr; diff --git a/trunk/drivers/hwmon/s3c-hwmon.c b/trunk/drivers/hwmon/s3c-hwmon.c index a9f7e804f1e4..ff2ae0252a48 100644 --- a/trunk/drivers/hwmon/s3c-hwmon.c +++ b/trunk/drivers/hwmon/s3c-hwmon.c @@ -107,14 +107,17 @@ static ssize_t s3c_hwmon_show_raw(struct device *dev, return (ret < 0) ? ret : snprintf(buf, PAGE_SIZE, "%d\n", ret); } -static SENSOR_DEVICE_ATTR(adc0_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 0); -static SENSOR_DEVICE_ATTR(adc1_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 1); -static SENSOR_DEVICE_ATTR(adc2_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 2); -static SENSOR_DEVICE_ATTR(adc3_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 3); -static SENSOR_DEVICE_ATTR(adc4_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 4); -static SENSOR_DEVICE_ATTR(adc5_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 5); -static SENSOR_DEVICE_ATTR(adc6_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 6); -static SENSOR_DEVICE_ATTR(adc7_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, 7); +#define DEF_ADC_ATTR(x) \ + static SENSOR_DEVICE_ATTR(adc##x##_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, x) + +DEF_ADC_ATTR(0); +DEF_ADC_ATTR(1); +DEF_ADC_ATTR(2); +DEF_ADC_ATTR(3); +DEF_ADC_ATTR(4); +DEF_ADC_ATTR(5); +DEF_ADC_ATTR(6); +DEF_ADC_ATTR(7); static struct attribute *s3c_hwmon_attrs[9] = { &sensor_dev_attr_adc0_raw.dev_attr.attr, diff --git a/trunk/drivers/hwmon/sch56xx-common.c b/trunk/drivers/hwmon/sch56xx-common.c index 738681983284..d00b30adc34b 100644 --- a/trunk/drivers/hwmon/sch56xx-common.c +++ b/trunk/drivers/hwmon/sch56xx-common.c @@ -161,8 +161,8 @@ static int sch56xx_send_cmd(u16 addr, u8 cmd, u16 reg, u8 v) break; } if (i == max_busy_polls + max_lazy_polls) { - pr_err("Max retries exceeded reading virtual register 0x%04hx (%d)\n", - reg, 1); + pr_err("Max retries exceeded reading virtual " + "register 0x%04hx (%d)\n", reg, 1); return -EIO; } @@ -178,12 +178,12 @@ static int sch56xx_send_cmd(u16 addr, u8 cmd, u16 reg, u8 v) break; if (i == 0) - pr_warn("EC reports: 0x%02x reading virtual register 0x%04hx\n", - (unsigned int)val, reg); + pr_warn("EC reports: 0x%02x reading virtual register " + "0x%04hx\n", (unsigned int)val, reg); } if (i == max_busy_polls) { - pr_err("Max retries exceeded reading virtual register 0x%04hx (%d)\n", - reg, 2); + pr_err("Max retries exceeded reading virtual " + "register 0x%04hx (%d)\n", reg, 2); return -EIO; } diff --git a/trunk/drivers/hwmon/sht15.c b/trunk/drivers/hwmon/sht15.c index 2507f902fb7a..bfe326e896df 100644 --- a/trunk/drivers/hwmon/sht15.c +++ b/trunk/drivers/hwmon/sht15.c @@ -965,13 +965,7 @@ static int sht15_probe(struct platform_device *pdev) if (voltage) data->supply_uv = voltage; - ret = regulator_enable(data->reg); - if (ret != 0) { - dev_err(&pdev->dev, - "failed to enable regulator: %d\n", ret); - return ret; - } - + regulator_enable(data->reg); /* * Setup a notifier block to update this if another device * causes the voltage to change diff --git a/trunk/drivers/hwmon/sis5595.c b/trunk/drivers/hwmon/sis5595.c index 1404e6319deb..c35847a1a0a3 100644 --- a/trunk/drivers/hwmon/sis5595.c +++ b/trunk/drivers/hwmon/sis5595.c @@ -456,9 +456,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, data->fan_div[nr] = 3; break; default: - dev_err(dev, - "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", - val); + dev_err(dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); mutex_unlock(&data->update_lock); return -EINVAL; } diff --git a/trunk/drivers/hwmon/thmc50.c b/trunk/drivers/hwmon/thmc50.c index db288db7d3e9..4b59eb53b18a 100644 --- a/trunk/drivers/hwmon/thmc50.c +++ b/trunk/drivers/hwmon/thmc50.c @@ -41,8 +41,8 @@ enum chips { thmc50, adm1022 }; static unsigned short adm1022_temp3[16]; static unsigned int adm1022_temp3_num; module_param_array(adm1022_temp3, ushort, &adm1022_temp3_num, 0); -MODULE_PARM_DESC(adm1022_temp3, - "List of adapter,address pairs to enable 3rd temperature (ADM1022 only)"); +MODULE_PARM_DESC(adm1022_temp3, "List of adapter,address pairs " + "to enable 3rd temperature (ADM1022 only)"); /* Many THMC50 constants specified below */ @@ -312,7 +312,8 @@ static int thmc50_detect(struct i2c_client *client, const char *type_name; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - pr_debug("thmc50: detect failed, smbus byte data not supported!\n"); + pr_debug("thmc50: detect failed, " + "smbus byte data not supported!\n"); return -ENODEV; } diff --git a/trunk/drivers/hwmon/tmp102.c b/trunk/drivers/hwmon/tmp102.c index d7b47abf37fe..523dd89ba498 100644 --- a/trunk/drivers/hwmon/tmp102.c +++ b/trunk/drivers/hwmon/tmp102.c @@ -155,8 +155,8 @@ static int tmp102_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { - dev_err(&client->dev, - "adapter doesn't support SMBus word transactions\n"); + dev_err(&client->dev, "adapter doesn't support SMBus word " + "transactions\n"); return -ENODEV; } diff --git a/trunk/drivers/hwmon/tmp401.c b/trunk/drivers/hwmon/tmp401.c index a478454f690f..c85f6967ccc3 100644 --- a/trunk/drivers/hwmon/tmp401.c +++ b/trunk/drivers/hwmon/tmp401.c @@ -5,9 +5,6 @@ * Gabriel Konat, Sander Leget, Wouter Willems * Copyright (C) 2009 Andre Prendel * - * Cleanup and support for TMP431 and TMP432 by Guenter Roeck - * Copyright (c) 2013 Guenter Roeck - * * 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 @@ -33,7 +30,6 @@ #include #include -#include #include #include #include @@ -44,9 +40,9 @@ #include /* Addresses to scan */ -static const unsigned short normal_i2c[] = { 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; -enum chips { tmp401, tmp411, tmp431, tmp432 }; +enum chips { tmp401, tmp411 }; /* * The TMP401 registers, note some registers have different addresses for @@ -58,84 +54,42 @@ enum chips { tmp401, tmp411, tmp431, tmp432 }; #define TMP401_CONVERSION_RATE_READ 0x04 #define TMP401_CONVERSION_RATE_WRITE 0x0A #define TMP401_TEMP_CRIT_HYST 0x21 +#define TMP401_CONSECUTIVE_ALERT 0x22 #define TMP401_MANUFACTURER_ID_REG 0xFE #define TMP401_DEVICE_ID_REG 0xFF - -static const u8 TMP401_TEMP_MSB_READ[6][2] = { - { 0x00, 0x01 }, /* temp */ - { 0x06, 0x08 }, /* low limit */ - { 0x05, 0x07 }, /* high limit */ - { 0x20, 0x19 }, /* therm (crit) limit */ - { 0x30, 0x34 }, /* lowest */ - { 0x32, 0x36 }, /* highest */ -}; - -static const u8 TMP401_TEMP_MSB_WRITE[6][2] = { - { 0, 0 }, /* temp (unused) */ - { 0x0C, 0x0E }, /* low limit */ - { 0x0B, 0x0D }, /* high limit */ - { 0x20, 0x19 }, /* therm (crit) limit */ - { 0x30, 0x34 }, /* lowest */ - { 0x32, 0x36 }, /* highest */ -}; - -static const u8 TMP401_TEMP_LSB[6][2] = { - { 0x15, 0x10 }, /* temp */ - { 0x17, 0x14 }, /* low limit */ - { 0x16, 0x13 }, /* high limit */ - { 0, 0 }, /* therm (crit) limit (unused) */ - { 0x31, 0x35 }, /* lowest */ - { 0x33, 0x37 }, /* highest */ -}; - -static const u8 TMP432_TEMP_MSB_READ[4][3] = { - { 0x00, 0x01, 0x23 }, /* temp */ - { 0x06, 0x08, 0x16 }, /* low limit */ - { 0x05, 0x07, 0x15 }, /* high limit */ - { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ -}; - -static const u8 TMP432_TEMP_MSB_WRITE[4][3] = { - { 0, 0, 0 }, /* temp - unused */ - { 0x0C, 0x0E, 0x16 }, /* low limit */ - { 0x0B, 0x0D, 0x15 }, /* high limit */ - { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ -}; - -static const u8 TMP432_TEMP_LSB[3][3] = { - { 0x29, 0x10, 0x24 }, /* temp */ - { 0x3E, 0x14, 0x18 }, /* low limit */ - { 0x3D, 0x13, 0x17 }, /* high limit */ -}; - -/* [0] = fault, [1] = low, [2] = high, [3] = therm/crit */ -static const u8 TMP432_STATUS_REG[] = { - 0x1b, 0x36, 0x35, 0x37 }; +#define TMP411_N_FACTOR_REG 0x18 + +static const u8 TMP401_TEMP_MSB[2] = { 0x00, 0x01 }; +static const u8 TMP401_TEMP_LSB[2] = { 0x15, 0x10 }; +static const u8 TMP401_TEMP_LOW_LIMIT_MSB_READ[2] = { 0x06, 0x08 }; +static const u8 TMP401_TEMP_LOW_LIMIT_MSB_WRITE[2] = { 0x0C, 0x0E }; +static const u8 TMP401_TEMP_LOW_LIMIT_LSB[2] = { 0x17, 0x14 }; +static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_READ[2] = { 0x05, 0x07 }; +static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[2] = { 0x0B, 0x0D }; +static const u8 TMP401_TEMP_HIGH_LIMIT_LSB[2] = { 0x16, 0x13 }; +/* These are called the THERM limit / hysteresis / mask in the datasheet */ +static const u8 TMP401_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 }; + +static const u8 TMP411_TEMP_LOWEST_MSB[2] = { 0x30, 0x34 }; +static const u8 TMP411_TEMP_LOWEST_LSB[2] = { 0x31, 0x35 }; +static const u8 TMP411_TEMP_HIGHEST_MSB[2] = { 0x32, 0x36 }; +static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 }; /* Flags */ -#define TMP401_CONFIG_RANGE BIT(2) -#define TMP401_CONFIG_SHUTDOWN BIT(6) -#define TMP401_STATUS_LOCAL_CRIT BIT(0) -#define TMP401_STATUS_REMOTE_CRIT BIT(1) -#define TMP401_STATUS_REMOTE_OPEN BIT(2) -#define TMP401_STATUS_REMOTE_LOW BIT(3) -#define TMP401_STATUS_REMOTE_HIGH BIT(4) -#define TMP401_STATUS_LOCAL_LOW BIT(5) -#define TMP401_STATUS_LOCAL_HIGH BIT(6) - -/* On TMP432, each status has its own register */ -#define TMP432_STATUS_LOCAL BIT(0) -#define TMP432_STATUS_REMOTE1 BIT(1) -#define TMP432_STATUS_REMOTE2 BIT(2) +#define TMP401_CONFIG_RANGE 0x04 +#define TMP401_CONFIG_SHUTDOWN 0x40 +#define TMP401_STATUS_LOCAL_CRIT 0x01 +#define TMP401_STATUS_REMOTE_CRIT 0x02 +#define TMP401_STATUS_REMOTE_OPEN 0x04 +#define TMP401_STATUS_REMOTE_LOW 0x08 +#define TMP401_STATUS_REMOTE_HIGH 0x10 +#define TMP401_STATUS_LOCAL_LOW 0x20 +#define TMP401_STATUS_LOCAL_HIGH 0x40 /* Manufacturer / Device ID's */ #define TMP401_MANUFACTURER_ID 0x55 #define TMP401_DEVICE_ID 0x11 -#define TMP411A_DEVICE_ID 0x12 -#define TMP411B_DEVICE_ID 0x13 -#define TMP411C_DEVICE_ID 0x10 -#define TMP431_DEVICE_ID 0x31 -#define TMP432_DEVICE_ID 0x32 +#define TMP411_DEVICE_ID 0x12 /* * Driver data (common to all clients) @@ -144,8 +98,6 @@ static const u8 TMP432_STATUS_REG[] = { static const struct i2c_device_id tmp401_id[] = { { "tmp401", tmp401 }, { "tmp411", tmp411 }, - { "tmp431", tmp431 }, - { "tmp432", tmp432 }, { } }; MODULE_DEVICE_TABLE(i2c, tmp401_id); @@ -161,13 +113,16 @@ struct tmp401_data { unsigned long last_updated; /* in jiffies */ enum chips kind; - unsigned int update_interval; /* in milliseconds */ - /* register values */ - u8 status[4]; + u8 status; u8 config; - u16 temp[6][3]; + u16 temp[2]; + u16 temp_low[2]; + u16 temp_high[2]; + u8 temp_crit[2]; u8 temp_crit_hyst; + u16 temp_lowest[2]; + u16 temp_highest[2]; }; /* @@ -181,10 +136,31 @@ static int tmp401_register_to_temp(u16 reg, u8 config) if (config & TMP401_CONFIG_RANGE) temp -= 64 * 256; - return DIV_ROUND_CLOSEST(temp * 125, 32); + return (temp * 625 + 80) / 160; +} + +static u16 tmp401_temp_to_register(long temp, u8 config) +{ + if (config & TMP401_CONFIG_RANGE) { + temp = clamp_val(temp, -64000, 191000); + temp += 64000; + } else + temp = clamp_val(temp, 0, 127000); + + return (temp * 160 + 312) / 625; +} + +static int tmp401_crit_register_to_temp(u8 reg, u8 config) +{ + int temp = reg; + + if (config & TMP401_CONFIG_RANGE) + temp -= 64; + + return temp * 1000; } -static u16 tmp401_temp_to_register(long temp, u8 config, int zbits) +static u8 tmp401_crit_temp_to_register(long temp, u8 config) { if (config & TMP401_CONFIG_RANGE) { temp = clamp_val(temp, -64000, 191000); @@ -192,127 +168,113 @@ static u16 tmp401_temp_to_register(long temp, u8 config, int zbits) } else temp = clamp_val(temp, 0, 127000); - return DIV_ROUND_CLOSEST(temp * (1 << (8 - zbits)), 1000) << zbits; + return (temp + 500) / 1000; } -static int tmp401_update_device_reg16(struct i2c_client *client, - struct tmp401_data *data) +static struct tmp401_data *tmp401_update_device_reg16( + struct i2c_client *client, struct tmp401_data *data) { - int i, j, val; - int num_regs = data->kind == tmp411 ? 6 : 4; - int num_sensors = data->kind == tmp432 ? 3 : 2; - - for (i = 0; i < num_sensors; i++) { /* local / r1 / r2 */ - for (j = 0; j < num_regs; j++) { /* temp / low / ... */ - u8 regaddr; - /* - * High byte must be read first immediately followed - * by the low byte - */ - regaddr = data->kind == tmp432 ? - TMP432_TEMP_MSB_READ[j][i] : - TMP401_TEMP_MSB_READ[j][i]; - val = i2c_smbus_read_byte_data(client, regaddr); - if (val < 0) - return val; - data->temp[j][i] = val << 8; - if (j == 3) /* crit is msb only */ - continue; - regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[j][i] - : TMP401_TEMP_LSB[j][i]; - val = i2c_smbus_read_byte_data(client, regaddr); - if (val < 0) - return val; - data->temp[j][i] |= val; + int i; + + for (i = 0; i < 2; i++) { + /* + * High byte must be read first immediately followed + * by the low byte + */ + data->temp[i] = i2c_smbus_read_byte_data(client, + TMP401_TEMP_MSB[i]) << 8; + data->temp[i] |= i2c_smbus_read_byte_data(client, + TMP401_TEMP_LSB[i]); + data->temp_low[i] = i2c_smbus_read_byte_data(client, + TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; + data->temp_low[i] |= i2c_smbus_read_byte_data(client, + TMP401_TEMP_LOW_LIMIT_LSB[i]); + data->temp_high[i] = i2c_smbus_read_byte_data(client, + TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; + data->temp_high[i] |= i2c_smbus_read_byte_data(client, + TMP401_TEMP_HIGH_LIMIT_LSB[i]); + data->temp_crit[i] = i2c_smbus_read_byte_data(client, + TMP401_TEMP_CRIT_LIMIT[i]); + + if (data->kind == tmp411) { + data->temp_lowest[i] = i2c_smbus_read_byte_data(client, + TMP411_TEMP_LOWEST_MSB[i]) << 8; + data->temp_lowest[i] |= i2c_smbus_read_byte_data( + client, TMP411_TEMP_LOWEST_LSB[i]); + + data->temp_highest[i] = i2c_smbus_read_byte_data( + client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; + data->temp_highest[i] |= i2c_smbus_read_byte_data( + client, TMP411_TEMP_HIGHEST_LSB[i]); } } - return 0; + return data; } static struct tmp401_data *tmp401_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct tmp401_data *data = i2c_get_clientdata(client); - struct tmp401_data *ret = data; - int i, val; - unsigned long next_update; mutex_lock(&data->update_lock); - next_update = data->last_updated + - msecs_to_jiffies(data->update_interval) + 1; - if (time_after(jiffies, next_update) || !data->valid) { - if (data->kind != tmp432) { - /* - * The driver uses the TMP432 status format internally. - * Convert status to TMP432 format for other chips. - */ - val = i2c_smbus_read_byte_data(client, TMP401_STATUS); - if (val < 0) { - ret = ERR_PTR(val); - goto abort; - } - data->status[0] = - (val & TMP401_STATUS_REMOTE_OPEN) >> 1; - data->status[1] = - ((val & TMP401_STATUS_REMOTE_LOW) >> 2) | - ((val & TMP401_STATUS_LOCAL_LOW) >> 5); - data->status[2] = - ((val & TMP401_STATUS_REMOTE_HIGH) >> 3) | - ((val & TMP401_STATUS_LOCAL_HIGH) >> 6); - data->status[3] = val & (TMP401_STATUS_LOCAL_CRIT - | TMP401_STATUS_REMOTE_CRIT); - } else { - for (i = 0; i < ARRAY_SIZE(data->status); i++) { - val = i2c_smbus_read_byte_data(client, - TMP432_STATUS_REG[i]); - if (val < 0) { - ret = ERR_PTR(val); - goto abort; - } - data->status[i] = val; - } - } + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); + data->config = i2c_smbus_read_byte_data(client, + TMP401_CONFIG_READ); + tmp401_update_device_reg16(client, data); - val = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); - if (val < 0) { - ret = ERR_PTR(val); - goto abort; - } - data->config = val; - val = tmp401_update_device_reg16(client, data); - if (val < 0) { - ret = ERR_PTR(val); - goto abort; - } - val = i2c_smbus_read_byte_data(client, TMP401_TEMP_CRIT_HYST); - if (val < 0) { - ret = ERR_PTR(val); - goto abort; - } - data->temp_crit_hyst = val; + data->temp_crit_hyst = i2c_smbus_read_byte_data(client, + TMP401_TEMP_CRIT_HYST); data->last_updated = jiffies; data->valid = 1; } -abort: mutex_unlock(&data->update_lock); - return ret; + + return data; +} + +static ssize_t show_temp_value(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + return sprintf(buf, "%d\n", + tmp401_register_to_temp(data->temp[index], data->config)); +} + +static ssize_t show_temp_min(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + return sprintf(buf, "%d\n", + tmp401_register_to_temp(data->temp_low[index], data->config)); } -static ssize_t show_temp(struct device *dev, - struct device_attribute *devattr, char *buf) +static ssize_t show_temp_max(struct device *dev, + struct device_attribute *devattr, char *buf) { - int nr = to_sensor_dev_attr_2(devattr)->nr; - int index = to_sensor_dev_attr_2(devattr)->index; + int index = to_sensor_dev_attr(devattr)->index; struct tmp401_data *data = tmp401_update_device(dev); - if (IS_ERR(data)) - return PTR_ERR(data); + return sprintf(buf, "%d\n", + tmp401_register_to_temp(data->temp_high[index], data->config)); +} + +static ssize_t show_temp_crit(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); return sprintf(buf, "%d\n", - tmp401_register_to_temp(data->temp[nr][index], data->config)); + tmp401_crit_register_to_temp(data->temp_crit[index], + data->config)); } static ssize_t show_temp_crit_hyst(struct device *dev, @@ -321,60 +283,122 @@ static ssize_t show_temp_crit_hyst(struct device *dev, int temp, index = to_sensor_dev_attr(devattr)->index; struct tmp401_data *data = tmp401_update_device(dev); - if (IS_ERR(data)) - return PTR_ERR(data); - mutex_lock(&data->update_lock); - temp = tmp401_register_to_temp(data->temp[3][index], data->config); + temp = tmp401_crit_register_to_temp(data->temp_crit[index], + data->config); temp -= data->temp_crit_hyst * 1000; mutex_unlock(&data->update_lock); return sprintf(buf, "%d\n", temp); } +static ssize_t show_temp_lowest(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + return sprintf(buf, "%d\n", + tmp401_register_to_temp(data->temp_lowest[index], + data->config)); +} + +static ssize_t show_temp_highest(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + return sprintf(buf, "%d\n", + tmp401_register_to_temp(data->temp_highest[index], + data->config)); +} + static ssize_t show_status(struct device *dev, struct device_attribute *devattr, char *buf) { - int nr = to_sensor_dev_attr_2(devattr)->nr; - int mask = to_sensor_dev_attr_2(devattr)->index; + int mask = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (data->status & mask) + return sprintf(buf, "1\n"); + else + return sprintf(buf, "0\n"); +} + +static ssize_t store_temp_min(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + int index = to_sensor_dev_attr(devattr)->index; struct tmp401_data *data = tmp401_update_device(dev); + long val; + u16 reg; + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + reg = tmp401_temp_to_register(val, data->config); + + mutex_lock(&data->update_lock); + + i2c_smbus_write_byte_data(to_i2c_client(dev), + TMP401_TEMP_LOW_LIMIT_MSB_WRITE[index], reg >> 8); + i2c_smbus_write_byte_data(to_i2c_client(dev), + TMP401_TEMP_LOW_LIMIT_LSB[index], reg & 0xFF); + + data->temp_low[index] = reg; - if (IS_ERR(data)) - return PTR_ERR(data); + mutex_unlock(&data->update_lock); - return sprintf(buf, "%d\n", !!(data->status[nr] & mask)); + return count; } -static ssize_t store_temp(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) +static ssize_t store_temp_max(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) { - int nr = to_sensor_dev_attr_2(devattr)->nr; - int index = to_sensor_dev_attr_2(devattr)->index; - struct i2c_client *client = to_i2c_client(dev); + int index = to_sensor_dev_attr(devattr)->index; struct tmp401_data *data = tmp401_update_device(dev); long val; u16 reg; - u8 regaddr; - if (IS_ERR(data)) - return PTR_ERR(data); + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + reg = tmp401_temp_to_register(val, data->config); + + mutex_lock(&data->update_lock); + + i2c_smbus_write_byte_data(to_i2c_client(dev), + TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[index], reg >> 8); + i2c_smbus_write_byte_data(to_i2c_client(dev), + TMP401_TEMP_HIGH_LIMIT_LSB[index], reg & 0xFF); + + data->temp_high[index] = reg; + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t store_temp_crit(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + long val; + u8 reg; if (kstrtol(buf, 10, &val)) return -EINVAL; - reg = tmp401_temp_to_register(val, data->config, nr == 3 ? 8 : 4); + reg = tmp401_crit_temp_to_register(val, data->config); mutex_lock(&data->update_lock); - regaddr = data->kind == tmp432 ? TMP432_TEMP_MSB_WRITE[nr][index] - : TMP401_TEMP_MSB_WRITE[nr][index]; - i2c_smbus_write_byte_data(client, regaddr, reg >> 8); - if (nr != 3) { - regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[nr][index] - : TMP401_TEMP_LSB[nr][index]; - i2c_smbus_write_byte_data(client, regaddr, reg & 0xFF); - } - data->temp[nr][index] = reg; + i2c_smbus_write_byte_data(to_i2c_client(dev), + TMP401_TEMP_CRIT_LIMIT[index], reg); + + data->temp_crit[index] = reg; mutex_unlock(&data->update_lock); @@ -389,9 +413,6 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute long val; u8 reg; - if (IS_ERR(data)) - return PTR_ERR(data); - if (kstrtol(buf, 10, &val)) return -EINVAL; @@ -401,12 +422,13 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute val = clamp_val(val, 0, 127000); mutex_lock(&data->update_lock); - temp = tmp401_register_to_temp(data->temp[3][index], data->config); + temp = tmp401_crit_register_to_temp(data->temp_crit[index], + data->config); val = clamp_val(val, temp - 255000, temp); reg = ((temp - val) + 500) / 1000; - i2c_smbus_write_byte_data(to_i2c_client(dev), TMP401_TEMP_CRIT_HYST, - reg); + i2c_smbus_write_byte_data(to_i2c_client(dev), + TMP401_TEMP_CRIT_HYST, reg); data->temp_crit_hyst = reg; @@ -423,130 +445,54 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute static ssize_t reset_temp_history(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = i2c_get_clientdata(client); long val; if (kstrtol(buf, 10, &val)) return -EINVAL; if (val != 1) { - dev_err(dev, - "temp_reset_history value %ld not supported. Use 1 to reset the history!\n", - val); + dev_err(dev, "temp_reset_history value %ld not" + " supported. Use 1 to reset the history!\n", val); return -EINVAL; } - mutex_lock(&data->update_lock); - i2c_smbus_write_byte_data(client, TMP401_TEMP_MSB_WRITE[5][0], val); - data->valid = 0; - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_update_interval(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = i2c_get_clientdata(client); - - return sprintf(buf, "%u\n", data->update_interval); -} - -static ssize_t set_update_interval(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = i2c_get_clientdata(client); - unsigned long val; - int err, rate; - - err = kstrtoul(buf, 10, &val); - if (err) - return err; - - /* - * For valid rates, interval can be calculated as - * interval = (1 << (7 - rate)) * 125; - * Rounded rate is therefore - * rate = 7 - __fls(interval * 4 / (125 * 3)); - * Use clamp_val() to avoid overflows, and to ensure valid input - * for __fls. - */ - val = clamp_val(val, 125, 16000); - rate = 7 - __fls(val * 4 / (125 * 3)); - mutex_lock(&data->update_lock); - i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, rate); - data->update_interval = (1 << (7 - rate)) * 125; - mutex_unlock(&data->update_lock); + i2c_smbus_write_byte_data(to_i2c_client(dev), + TMP411_TEMP_LOWEST_MSB[0], val); return count; } -static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); -static SENSOR_DEVICE_ATTR_2(temp1_min, S_IWUSR | S_IRUGO, show_temp, - store_temp, 1, 0); -static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp, - store_temp, 2, 0); -static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IWUSR | S_IRUGO, show_temp, - store_temp, 3, 0); -static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, - show_temp_crit_hyst, store_temp_crit_hyst, 0); -static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_status, NULL, - 1, TMP432_STATUS_LOCAL); -static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_status, NULL, - 2, TMP432_STATUS_LOCAL); -static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_status, NULL, - 3, TMP432_STATUS_LOCAL); -static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1); -static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp, - store_temp, 1, 1); -static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp, - store_temp, 2, 1); -static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IWUSR | S_IRUGO, show_temp, - store_temp, 3, 1); -static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, - NULL, 1); -static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_status, NULL, - 0, TMP432_STATUS_REMOTE1); -static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_status, NULL, - 1, TMP432_STATUS_REMOTE1); -static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_status, NULL, - 2, TMP432_STATUS_REMOTE1); -static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_status, NULL, - 3, TMP432_STATUS_REMOTE1); - -static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, - set_update_interval); - -static struct attribute *tmp401_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_min.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_crit.dev_attr.attr, - &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, - - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp2_min.dev_attr.attr, - &sensor_dev_attr_temp2_max.dev_attr.attr, - &sensor_dev_attr_temp2_crit.dev_attr.attr, - &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, - &sensor_dev_attr_temp2_fault.dev_attr.attr, - &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, - - &dev_attr_update_interval.attr, - - NULL -}; - -static const struct attribute_group tmp401_group = { - .attrs = tmp401_attributes, +static struct sensor_device_attribute tmp401_attr[] = { + SENSOR_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0), + SENSOR_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, + store_temp_min, 0), + SENSOR_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, + store_temp_max, 0), + SENSOR_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit, + store_temp_crit, 0), + SENSOR_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_crit_hyst, + store_temp_crit_hyst, 0), + SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_status, NULL, + TMP401_STATUS_LOCAL_LOW), + SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_status, NULL, + TMP401_STATUS_LOCAL_HIGH), + SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_status, NULL, + TMP401_STATUS_LOCAL_CRIT), + SENSOR_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1), + SENSOR_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, + store_temp_min, 1), + SENSOR_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, + store_temp_max, 1), + SENSOR_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit, + store_temp_crit, 1), + SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), + SENSOR_ATTR(temp2_fault, S_IRUGO, show_status, NULL, + TMP401_STATUS_REMOTE_OPEN), + SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_status, NULL, + TMP401_STATUS_REMOTE_LOW), + SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_status, NULL, + TMP401_STATUS_REMOTE_HIGH), + SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_status, NULL, + TMP401_STATUS_REMOTE_CRIT), }; /* @@ -556,60 +502,12 @@ static const struct attribute_group tmp401_group = { * minimum and maximum register reset for both the local * and remote channels. */ -static SENSOR_DEVICE_ATTR_2(temp1_lowest, S_IRUGO, show_temp, NULL, 4, 0); -static SENSOR_DEVICE_ATTR_2(temp1_highest, S_IRUGO, show_temp, NULL, 5, 0); -static SENSOR_DEVICE_ATTR_2(temp2_lowest, S_IRUGO, show_temp, NULL, 4, 1); -static SENSOR_DEVICE_ATTR_2(temp2_highest, S_IRUGO, show_temp, NULL, 5, 1); -static SENSOR_DEVICE_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, - 0); - -static struct attribute *tmp411_attributes[] = { - &sensor_dev_attr_temp1_highest.dev_attr.attr, - &sensor_dev_attr_temp1_lowest.dev_attr.attr, - &sensor_dev_attr_temp2_highest.dev_attr.attr, - &sensor_dev_attr_temp2_lowest.dev_attr.attr, - &sensor_dev_attr_temp_reset_history.dev_attr.attr, - NULL -}; - -static const struct attribute_group tmp411_group = { - .attrs = tmp411_attributes, -}; - -static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2); -static SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp, - store_temp, 1, 2); -static SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp, - store_temp, 2, 2); -static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IWUSR | S_IRUGO, show_temp, - store_temp, 3, 2); -static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, - NULL, 2); -static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_status, NULL, - 0, TMP432_STATUS_REMOTE2); -static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_status, NULL, - 1, TMP432_STATUS_REMOTE2); -static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_status, NULL, - 2, TMP432_STATUS_REMOTE2); -static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_status, NULL, - 3, TMP432_STATUS_REMOTE2); - -static struct attribute *tmp432_attributes[] = { - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp3_min.dev_attr.attr, - &sensor_dev_attr_temp3_max.dev_attr.attr, - &sensor_dev_attr_temp3_crit.dev_attr.attr, - &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, - &sensor_dev_attr_temp3_fault.dev_attr.attr, - &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, - &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, - &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, - - NULL -}; - -static const struct attribute_group tmp432_group = { - .attrs = tmp432_attributes, +static struct sensor_device_attribute tmp411_attr[] = { + SENSOR_ATTR(temp1_highest, S_IRUGO, show_temp_highest, NULL, 0), + SENSOR_ATTR(temp1_lowest, S_IRUGO, show_temp_lowest, NULL, 0), + SENSOR_ATTR(temp2_highest, S_IRUGO, show_temp_highest, NULL, 1), + SENSOR_ATTR(temp2_lowest, S_IRUGO, show_temp_lowest, NULL, 1), + SENSOR_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, 0), }; /* @@ -619,11 +517,9 @@ static const struct attribute_group tmp432_group = { static void tmp401_init_client(struct i2c_client *client) { int config, config_orig; - struct tmp401_data *data = i2c_get_clientdata(client); /* Set the conversion rate to 2 Hz */ i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); - data->update_interval = 500; /* Start conversions (disable shutdown if necessary) */ config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); @@ -658,35 +554,11 @@ static int tmp401_detect(struct i2c_client *client, switch (reg) { case TMP401_DEVICE_ID: - if (client->addr != 0x4c) - return -ENODEV; kind = tmp401; break; - case TMP411A_DEVICE_ID: - if (client->addr != 0x4c) - return -ENODEV; - kind = tmp411; - break; - case TMP411B_DEVICE_ID: - if (client->addr != 0x4d) - return -ENODEV; + case TMP411_DEVICE_ID: kind = tmp411; break; - case TMP411C_DEVICE_ID: - if (client->addr != 0x4e) - return -ENODEV; - kind = tmp411; - break; - case TMP431_DEVICE_ID: - if (client->addr == 0x4e) - return -ENODEV; - kind = tmp431; - break; - case TMP432_DEVICE_ID: - if (client->addr == 0x4e) - return -ENODEV; - kind = tmp432; - break; default: return -ENODEV; } @@ -707,19 +579,20 @@ static int tmp401_detect(struct i2c_client *client, static int tmp401_remove(struct i2c_client *client) { - struct device *dev = &client->dev; struct tmp401_data *data = i2c_get_clientdata(client); + int i; if (data->hwmon_dev) hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&dev->kobj, &tmp401_group); - - if (data->kind == tmp411) - sysfs_remove_group(&dev->kobj, &tmp411_group); + for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) + device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); - if (data->kind == tmp432) - sysfs_remove_group(&dev->kobj, &tmp432_group); + if (data->kind == tmp411) { + for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) + device_remove_file(&client->dev, + &tmp411_attr[i].dev_attr); + } return 0; } @@ -727,12 +600,12 @@ static int tmp401_remove(struct i2c_client *client) static int tmp401_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct device *dev = &client->dev; - int err; + int i, err = 0; struct tmp401_data *data; - const char *names[] = { "TMP401", "TMP411", "TMP431", "TMP432" }; + const char *names[] = { "TMP401", "TMP411" }; - data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct tmp401_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -744,32 +617,31 @@ static int tmp401_probe(struct i2c_client *client, tmp401_init_client(client); /* Register sysfs hooks */ - err = sysfs_create_group(&dev->kobj, &tmp401_group); - if (err) - return err; - - /* Register additional tmp411 sysfs hooks */ - if (data->kind == tmp411) { - err = sysfs_create_group(&dev->kobj, &tmp411_group); + for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) { + err = device_create_file(&client->dev, + &tmp401_attr[i].dev_attr); if (err) goto exit_remove; } - /* Register additional tmp432 sysfs hooks */ - if (data->kind == tmp432) { - err = sysfs_create_group(&dev->kobj, &tmp432_group); - if (err) - goto exit_remove; + /* Register additional tmp411 sysfs hooks */ + if (data->kind == tmp411) { + for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) { + err = device_create_file(&client->dev, + &tmp411_attr[i].dev_attr); + if (err) + goto exit_remove; + } } - data->hwmon_dev = hwmon_device_register(dev); + data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); data->hwmon_dev = NULL; goto exit_remove; } - dev_info(dev, "Detected TI %s chip\n", names[data->kind]); + dev_info(&client->dev, "Detected TI %s chip\n", names[data->kind]); return 0; diff --git a/trunk/drivers/hwmon/tmp421.c b/trunk/drivers/hwmon/tmp421.c index 964c1d688274..6a8ded29f1ed 100644 --- a/trunk/drivers/hwmon/tmp421.c +++ b/trunk/drivers/hwmon/tmp421.c @@ -208,8 +208,8 @@ static int tmp421_init_client(struct i2c_client *client) /* Start conversions (disable shutdown if necessary) */ config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); if (config < 0) { - dev_err(&client->dev, - "Could not read configuration register (%d)\n", config); + dev_err(&client->dev, "Could not read configuration" + " register (%d)\n", config); return -ENODEV; } @@ -322,5 +322,6 @@ static struct i2c_driver tmp421_driver = { module_i2c_driver(tmp421_driver); MODULE_AUTHOR("Andre Prendel "); -MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor driver"); +MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor" + " driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/via686a.c b/trunk/drivers/hwmon/via686a.c index c9dcce8c3dc3..3123b30208c5 100644 --- a/trunk/drivers/hwmon/via686a.c +++ b/trunk/drivers/hwmon/via686a.c @@ -125,7 +125,7 @@ static const u8 VIA686A_REG_TEMP_HYST[] = { 0x3a, 0x3e, 0x1e }; * (These conversions were contributed by Jonathan Teh Soon Yew * ) */ -static inline u8 IN_TO_REG(long val, int in_num) +static inline u8 IN_TO_REG(long val, int inNum) { /* * To avoid floating point, we multiply constants by 10 (100 for +12V). @@ -134,29 +134,29 @@ static inline u8 IN_TO_REG(long val, int in_num) * by an additional 10000 (100000 for +12V): 1000 for val and 10 (100) * for the constants. */ - if (in_num <= 1) + if (inNum <= 1) return (u8) clamp_val((val * 21024 - 1205000) / 250000, 0, 255); - else if (in_num == 2) + else if (inNum == 2) return (u8) clamp_val((val * 15737 - 1205000) / 250000, 0, 255); - else if (in_num == 3) + else if (inNum == 3) return (u8) clamp_val((val * 10108 - 1205000) / 250000, 0, 255); else return (u8) clamp_val((val * 41714 - 12050000) / 2500000, 0, 255); } -static inline long IN_FROM_REG(u8 val, int in_num) +static inline long IN_FROM_REG(u8 val, int inNum) { /* * To avoid floating point, we multiply constants by 10 (100 for +12V). * We also multiply them by 1000 because we want 0.001V/bit for the * output value. Rounding is done. */ - if (in_num <= 1) + if (inNum <= 1) return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024); - else if (in_num == 2) + else if (inNum == 2) return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737); - else if (in_num == 3) + else if (inNum == 3) return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108); else return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714); @@ -210,10 +210,10 @@ static inline u8 FAN_TO_REG(long rpm, int div) * VIA register values 0-255. I *10 before rounding, so we get tenth-degree * precision. (I could have done all 1024 values for our 10-bit readings, * but the function is very linear in the useful range (0-80 deg C), so - * we'll just use linear interpolation for 10-bit readings.) So, temp_lut + * we'll just use linear interpolation for 10-bit readings.) So, tempLUT * is the temp at via register values 0-255: */ -static const s16 temp_lut[] = { +static const s16 tempLUT[] = { -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519, -503, -487, -471, -456, -442, -428, -414, -400, -387, -375, -362, -350, -339, -327, -316, -305, -295, -285, -275, -265, @@ -261,7 +261,7 @@ static const s16 temp_lut[] = { * - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01) * Note that n=161: */ -static const u8 via_lut[] = { +static const u8 viaLUT[] = { 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40, 41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66, @@ -284,26 +284,26 @@ static const u8 via_lut[] = { */ static inline u8 TEMP_TO_REG(long val) { - return via_lut[val <= -50000 ? 0 : val >= 110000 ? 160 : + return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 : (val < 0 ? val - 500 : val + 500) / 1000 + 50]; } /* for 8-bit temperature hyst and over registers */ -#define TEMP_FROM_REG(val) ((long)temp_lut[val] * 100) +#define TEMP_FROM_REG(val) ((long)tempLUT[val] * 100) /* for 10-bit temperature readings */ static inline long TEMP_FROM_REG10(u16 val) { - u16 eight_bits = val >> 2; - u16 two_bits = val & 3; + u16 eightBits = val >> 2; + u16 twoBits = val & 3; /* no interpolation for these */ - if (two_bits == 0 || eight_bits == 255) - return TEMP_FROM_REG(eight_bits); + if (twoBits == 0 || eightBits == 255) + return TEMP_FROM_REG(eightBits); /* do some linear interpolation */ - return (temp_lut[eight_bits] * (4 - two_bits) + - temp_lut[eight_bits + 1] * two_bits) * 25; + return (tempLUT[eightBits] * (4 - twoBits) + + tempLUT[eightBits + 1] * twoBits) * 25; } #define DIV_FROM_REG(val) (1 << (val)) @@ -889,8 +889,8 @@ static int via686a_pci_probe(struct pci_dev *dev, address = val & ~(VIA686A_EXTENT - 1); if (address == 0) { - dev_err(&dev->dev, - "base address not set - upgrade BIOS or use force_addr=0xaddr\n"); + dev_err(&dev->dev, "base address not set - upgrade BIOS " + "or use force_addr=0xaddr\n"); return -ENODEV; } @@ -899,9 +899,8 @@ static int via686a_pci_probe(struct pci_dev *dev, return -ENODEV; if (!(val & 0x0001)) { if (!force_addr) { - dev_warn(&dev->dev, - "Sensors disabled, enable with force_addr=0x%x\n", - address); + dev_warn(&dev->dev, "Sensors disabled, enable " + "with force_addr=0x%x\n", address); return -ENODEV; } diff --git a/trunk/drivers/hwmon/vt1211.c b/trunk/drivers/hwmon/vt1211.c index 6b2f1a42b3ff..dcc62f80f67b 100644 --- a/trunk/drivers/hwmon/vt1211.c +++ b/trunk/drivers/hwmon/vt1211.c @@ -571,9 +571,8 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, break; default: count = -EINVAL; - dev_warn(dev, - "fan div value %ld not supported. Choose one of 1, 2, 4, or 8.\n", - val); + dev_warn(dev, "fan div value %ld not supported. " + "Choose one of 1, 2, 4, or 8.\n", val); goto EXIT; } vt1211_write8(data, VT1211_REG_FAN_DIV, @@ -675,9 +674,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, break; default: count = -EINVAL; - dev_warn(dev, - "pwm mode %ld not supported. Choose one of 0 or 2.\n", - val); + dev_warn(dev, "pwm mode %ld not supported. " + "Choose one of 0 or 2.\n", val); goto EXIT; } vt1211_write8(data, VT1211_REG_PWM_CTL, @@ -702,9 +700,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, case SHOW_SET_PWM_AUTO_CHANNELS_TEMP: if (val < 1 || val > 7) { count = -EINVAL; - dev_warn(dev, - "temp channel %ld not supported. Choose a value between 1 and 7.\n", - val); + dev_warn(dev, "temp channel %ld not supported. " + "Choose a value between 1 and 7.\n", val); goto EXIT; } if (!ISTEMP(val - 1, data->uch_config)) { @@ -1328,15 +1325,15 @@ static int __init vt1211_init(void) if ((uch_config < -1) || (uch_config > 31)) { err = -EINVAL; - pr_warn("Invalid UCH configuration %d. Choose a value between 0 and 31.\n", - uch_config); + pr_warn("Invalid UCH configuration %d. " + "Choose a value between 0 and 31.\n", uch_config); goto EXIT; } if ((int_mode < -1) || (int_mode > 0)) { err = -EINVAL; - pr_warn("Invalid interrupt mode %d. Only mode 0 is supported.\n", - int_mode); + pr_warn("Invalid interrupt mode %d. " + "Only mode 0 is supported.\n", int_mode); goto EXIT; } diff --git a/trunk/drivers/hwmon/vt8231.c b/trunk/drivers/hwmon/vt8231.c index 0e7017841f7d..988a2a796764 100644 --- a/trunk/drivers/hwmon/vt8231.c +++ b/trunk/drivers/hwmon/vt8231.c @@ -573,9 +573,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, data->fan_div[nr] = 3; break; default: - dev_err(dev, - "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", - val); + dev_err(dev, "fan_div value %ld not supported. " + "Choose one of 1, 2, 4 or 8!\n", val); mutex_unlock(&data->update_lock); return -EINVAL; } diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index 016027229e81..0a89211c25f6 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -840,8 +840,8 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) && (reg >= 0xff || (sio_data->kind == nct6775 && reg == 0x00)) && data->fan_div[i] < 0x07) { - dev_dbg(dev, - "Increasing fan%d clock divider from %u to %u\n", + dev_dbg(dev, "Increasing fan%d " + "clock divider from %u to %u\n", i + 1, div_from_reg(data->fan_div[i]), div_from_reg(data->fan_div[i] + 1)); data->fan_div[i]++; @@ -1110,9 +1110,9 @@ store_fan_min(struct device *dev, struct device_attribute *attr, */ data->fan_min[nr] = 254; new_div = 7; /* 128 == (1 << 7) */ - dev_warn(dev, - "fan%u low limit %lu below minimum %u, set to minimum\n", - nr + 1, val, data->fan_from_reg_min(254, 7)); + dev_warn(dev, "fan%u low limit %lu below minimum %u, set to " + "minimum\n", nr + 1, val, + data->fan_from_reg_min(254, 7)); } else if (!reg) { /* * Speed above this value cannot possibly be represented, @@ -1120,9 +1120,9 @@ store_fan_min(struct device *dev, struct device_attribute *attr, */ data->fan_min[nr] = 1; new_div = 0; /* 1 == (1 << 0) */ - dev_warn(dev, - "fan%u low limit %lu above maximum %u, set to maximum\n", - nr + 1, val, data->fan_from_reg_min(1, 0)); + dev_warn(dev, "fan%u low limit %lu above maximum %u, set to " + "maximum\n", nr + 1, val, + data->fan_from_reg_min(1, 0)); } else { /* * Automatically pick the best divider, i.e. the one such @@ -2396,15 +2396,15 @@ static int w83627ehf_probe(struct platform_device *pdev) en_vrm10 = superio_inb(sio_data->sioreg, SIO_REG_EN_VRM10); if ((en_vrm10 & 0x08) && data->vrm == 90) { - dev_warn(dev, - "Setting VID input voltage to TTL\n"); + dev_warn(dev, "Setting VID input " + "voltage to TTL\n"); superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, en_vrm10 & ~0x08); } else if (!(en_vrm10 & 0x08) && data->vrm == 100) { - dev_warn(dev, - "Setting VID input voltage to VRM10\n"); + dev_warn(dev, "Setting VID input " + "voltage to VRM10\n"); superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, en_vrm10 | 0x08); @@ -2420,8 +2420,8 @@ static int w83627ehf_probe(struct platform_device *pdev) if (err) goto exit_release; } else { - dev_info(dev, - "VID pins in output mode, CPU VID not available\n"); + dev_info(dev, "VID pins in output mode, CPU VID not " + "available\n"); } } @@ -2795,7 +2795,8 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, /* Activate logical device if needed */ val = superio_inb(sioaddr, SIO_REG_ENABLE); if (!(val & 0x01)) { - pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); + pr_warn("Forcibly enabling Super-I/O. " + "Sensor is probably unusable.\n"); superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); } diff --git a/trunk/drivers/hwmon/w83781d.c b/trunk/drivers/hwmon/w83781d.c index f9d513949a38..aeec5b1d81c9 100644 --- a/trunk/drivers/hwmon/w83781d.c +++ b/trunk/drivers/hwmon/w83781d.c @@ -64,8 +64,8 @@ enum chips { w83781d, w83782d, w83783s, as99127f }; /* Insmod parameters */ static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); -MODULE_PARM_DESC(force_subclients, - "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); +MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " + "{bus, clientaddr, subclientaddr1, subclientaddr2}"); static bool reset; module_param(reset, bool, 0); @@ -826,9 +826,8 @@ store_sensor(struct device *dev, struct device_attribute *da, data->sens[nr] = val; break; case W83781D_DEFAULT_BETA: - dev_warn(dev, - "Sensor type %d is deprecated, please use 4 instead\n", - W83781D_DEFAULT_BETA); + dev_warn(dev, "Sensor type %d is deprecated, please use 4 " + "instead\n", W83781D_DEFAULT_BETA); /* fall through */ case 4: /* thermistor */ tmp = w83781d_read_value(data, W83781D_REG_SCFG1); @@ -875,8 +874,8 @@ w83781d_detect_subclients(struct i2c_client *new_client) for (i = 2; i <= 3; i++) { if (force_subclients[i] < 0x48 || force_subclients[i] > 0x4f) { - dev_err(&new_client->dev, - "Invalid subclient address %d; must be 0x48-0x4f\n", + dev_err(&new_client->dev, "Invalid subclient " + "address %d; must be 0x48-0x4f\n", force_subclients[i]); err = -EINVAL; goto ERROR_SC_1; @@ -911,9 +910,9 @@ w83781d_detect_subclients(struct i2c_client *new_client) for (i = 0; i < num_sc; i++) { data->lm75[i] = i2c_new_dummy(adapter, sc_addr[i]); if (!data->lm75[i]) { - dev_err(&new_client->dev, - "Subclient %d registration at address 0x%x failed.\n", - i, sc_addr[i]); + dev_err(&new_client->dev, "Subclient %d " + "registration at address 0x%x " + "failed.\n", i, sc_addr[i]); err = -ENOMEM; if (i == 1) goto ERROR_SC_3; @@ -1177,9 +1176,8 @@ w83781d_detect(struct i2c_client *client, struct i2c_board_info *info) goto err_nodev; if (val1 <= 0x30 && w83781d_alias_detect(client, val1)) { - dev_dbg(&adapter->dev, - "Device at 0x%02x appears to be the same as ISA device\n", - address); + dev_dbg(&adapter->dev, "Device at 0x%02x appears to " + "be the same as ISA device\n", address); goto err_nodev; } @@ -1369,8 +1367,8 @@ w83781d_init_device(struct device *dev) * as I see very little reason why this would be needed at * all. */ - dev_info(dev, - "If reset=1 solved a problem you were having, please report!\n"); + dev_info(dev, "If reset=1 solved a problem you were " + "having, please report!\n"); /* save these registers */ i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); @@ -1427,8 +1425,8 @@ w83781d_init_device(struct device *dev) /* Enable temp2 */ tmp = w83781d_read_value(data, W83781D_REG_TEMP2_CONFIG); if (tmp & 0x01) { - dev_warn(dev, - "Enabling temp2, readings might not make sense\n"); + dev_warn(dev, "Enabling temp2, readings " + "might not make sense\n"); w83781d_write_value(data, W83781D_REG_TEMP2_CONFIG, tmp & 0xfe); } @@ -1438,8 +1436,8 @@ w83781d_init_device(struct device *dev) tmp = w83781d_read_value(data, W83781D_REG_TEMP3_CONFIG); if (tmp & 0x01) { - dev_warn(dev, - "Enabling temp3, readings might not make sense\n"); + dev_warn(dev, "Enabling temp3, " + "readings might not make sense\n"); w83781d_write_value(data, W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); } diff --git a/trunk/drivers/hwmon/w83791d.c b/trunk/drivers/hwmon/w83791d.c index a3feee332e20..38dddddf8875 100644 --- a/trunk/drivers/hwmon/w83791d.c +++ b/trunk/drivers/hwmon/w83791d.c @@ -56,8 +56,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); -MODULE_PARM_DESC(force_subclients, - "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); +MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " + "{bus, clientaddr, subclientaddr1, subclientaddr2}"); static bool reset; module_param(reset, bool, 0); diff --git a/trunk/drivers/hwmon/w83792d.c b/trunk/drivers/hwmon/w83792d.c index 0b804895be43..5cb83ddf2cc6 100644 --- a/trunk/drivers/hwmon/w83792d.c +++ b/trunk/drivers/hwmon/w83792d.c @@ -54,8 +54,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); -MODULE_PARM_DESC(force_subclients, - "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); +MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " + "{bus, clientaddr, subclientaddr1, subclientaddr2}"); static bool init; module_param(init, bool, 0); @@ -951,8 +951,8 @@ w83792d_detect_subclients(struct i2c_client *new_client) for (i = 2; i <= 3; i++) { if (force_subclients[i] < 0x48 || force_subclients[i] > 0x4f) { - dev_err(&new_client->dev, - "invalid subclient address %d; must be 0x48-0x4f\n", + dev_err(&new_client->dev, "invalid subclient " + "address %d; must be 0x48-0x4f\n", force_subclients[i]); err = -ENODEV; goto ERROR_SC_0; @@ -969,9 +969,8 @@ w83792d_detect_subclients(struct i2c_client *new_client) if (!(val & 0x80)) { if ((data->lm75[0] != NULL) && ((val & 0x7) == ((val >> 4) & 0x7))) { - dev_err(&new_client->dev, - "duplicate addresses 0x%x, use force_subclient\n", - data->lm75[0]->addr); + dev_err(&new_client->dev, "duplicate addresses 0x%x, " + "use force_subclient\n", data->lm75[0]->addr); err = -ENODEV; goto ERROR_SC_1; } diff --git a/trunk/drivers/hwmon/w83793.c b/trunk/drivers/hwmon/w83793.c index b0c30a546ff2..660427520c53 100644 --- a/trunk/drivers/hwmon/w83793.c +++ b/trunk/drivers/hwmon/w83793.c @@ -59,8 +59,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); -MODULE_PARM_DESC(force_subclients, - "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); +MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " + "{bus, clientaddr, subclientaddr1, subclientaddr2}"); static bool reset; module_param(reset, bool, 0); @@ -1921,8 +1921,8 @@ static int w83793_probe(struct i2c_client *client, } if (i == ARRAY_SIZE(watchdog_minors)) { data->watchdog_miscdev.minor = 0; - dev_warn(&client->dev, - "Couldn't register watchdog chardev (due to no free minor)\n"); + dev_warn(&client->dev, "Couldn't register watchdog chardev " + "(due to no free minor)\n"); } mutex_unlock(&watchdog_data_mutex); diff --git a/trunk/drivers/hwmon/w83795.c b/trunk/drivers/hwmon/w83795.c index 908209d24664..e226096148eb 100644 --- a/trunk/drivers/hwmon/w83795.c +++ b/trunk/drivers/hwmon/w83795.c @@ -2120,12 +2120,11 @@ static void w83795_check_dynamic_in_limits(struct i2c_client *client) &w83795_in[i][3].dev_attr.attr, S_IRUGO); if (err_max || err_min) - dev_warn(&client->dev, - "Failed to set in%d limits read-only (%d, %d)\n", - i, err_max, err_min); + dev_warn(&client->dev, "Failed to set in%d limits " + "read-only (%d, %d)\n", i, err_max, err_min); else - dev_info(&client->dev, - "in%d limits set dynamically from VID\n", i); + dev_info(&client->dev, "in%d limits set dynamically " + "from VID\n", i); } } diff --git a/trunk/drivers/hwspinlock/hwspinlock_core.c b/trunk/drivers/hwspinlock/hwspinlock_core.c index 461a0d739d75..db713c0dfba4 100644 --- a/trunk/drivers/hwspinlock/hwspinlock_core.c +++ b/trunk/drivers/hwspinlock/hwspinlock_core.c @@ -416,8 +416,6 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock) ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "%s: can't power on device\n", __func__); - pm_runtime_put_noidle(dev); - module_put(dev->driver->owner); return ret; } diff --git a/trunk/drivers/i2c/Kconfig b/trunk/drivers/i2c/Kconfig index e380c6eef3af..46cde098c11c 100644 --- a/trunk/drivers/i2c/Kconfig +++ b/trunk/drivers/i2c/Kconfig @@ -4,6 +4,7 @@ menuconfig I2C tristate "I2C support" + depends on !S390 select RT_MUTEXES ---help--- I2C (pronounce: I-squared-C) is a slow serial bus protocol used in @@ -75,7 +76,6 @@ config I2C_HELPER_AUTO config I2C_SMBUS tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO - depends on GENERIC_HARDIRQS help Say Y here if you want support for SMBus extensions to the I2C specification. At the moment, the only supported extension is diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index adfee98486b1..a3725de92384 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -114,7 +114,7 @@ config I2C_I801 config I2C_ISCH tristate "Intel SCH SMBus 1.0" - depends on PCI && GENERIC_HARDIRQS + depends on PCI select LPC_SCH help Say Y here if you want to use SMBus controller on the Intel SCH @@ -543,7 +543,6 @@ config I2C_NUC900 config I2C_OCORES tristate "OpenCores I2C Controller" - depends on GENERIC_HARDIRQS help If you say yes to this option, support will be included for the OpenCores I2C controller. For details see @@ -778,7 +777,7 @@ config I2C_DIOLAN_U2C config I2C_PARPORT tristate "Parallel port adapter" - depends on PARPORT && GENERIC_HARDIRQS + depends on PARPORT select I2C_ALGOBIT select I2C_SMBUS help @@ -803,7 +802,6 @@ config I2C_PARPORT config I2C_PARPORT_LIGHT tristate "Parallel port adapter (light)" - depends on GENERIC_HARDIRQS select I2C_ALGOBIT select I2C_SMBUS help diff --git a/trunk/drivers/i2c/busses/i2c-designware-platdrv.c b/trunk/drivers/i2c/busses/i2c-designware-platdrv.c index e3085c487ace..0ceb6e1b0f65 100644 --- a/trunk/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/trunk/drivers/i2c/busses/i2c-designware-platdrv.c @@ -182,6 +182,7 @@ static int dw_i2c_probe(struct platform_device *pdev) adap->algo = &i2c_dw_algo; adap->dev.parent = &pdev->dev; adap->dev.of_node = pdev->dev.of_node; + ACPI_HANDLE_SET(&adap->dev, ACPI_HANDLE(&pdev->dev)); r = i2c_add_numbered_adapter(adap); if (r) { diff --git a/trunk/drivers/i2c/busses/i2c-ismt.c b/trunk/drivers/i2c/busses/i2c-ismt.c index 130f02cc9d94..e9205ee8cf94 100644 --- a/trunk/drivers/i2c/busses/i2c-ismt.c +++ b/trunk/drivers/i2c/busses/i2c-ismt.c @@ -80,7 +80,6 @@ /* PCI DIDs for the Intel SMBus Message Transport (SMT) Devices */ #define PCI_DEVICE_ID_INTEL_S1200_SMT0 0x0c59 #define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a -#define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15 #define ISMT_DESC_ENTRIES 32 /* number of descriptor entries */ #define ISMT_MAX_RETRIES 3 /* number of SMBus retries to attempt */ @@ -186,7 +185,6 @@ struct ismt_priv { static const DEFINE_PCI_DEVICE_TABLE(ismt_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, { 0, } }; diff --git a/trunk/drivers/i2c/busses/i2c-tegra.c b/trunk/drivers/i2c/busses/i2c-tegra.c index b714776b6ddd..36704e3ab3fa 100644 --- a/trunk/drivers/i2c/busses/i2c-tegra.c +++ b/trunk/drivers/i2c/busses/i2c-tegra.c @@ -411,11 +411,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) int clk_multiplier = I2C_CLK_MULTIPLIER_STD_FAST_MODE; u32 clk_divisor; - err = tegra_i2c_clock_enable(i2c_dev); - if (err < 0) { - dev_err(i2c_dev->dev, "Clock enable failed %d\n", err); - return err; - } + tegra_i2c_clock_enable(i2c_dev); tegra_periph_reset_assert(i2c_dev->div_clk); udelay(2); @@ -632,12 +628,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (i2c_dev->is_suspended) return -EBUSY; - ret = tegra_i2c_clock_enable(i2c_dev); - if (ret < 0) { - dev_err(i2c_dev->dev, "Clock enable failed %d\n", ret); - return ret; - } - + tegra_i2c_clock_enable(i2c_dev); for (i = 0; i < num; i++) { enum msg_end_type end_type = MSG_END_STOP; if (i < (num - 1)) { diff --git a/trunk/drivers/i2c/muxes/i2c-mux-pca9541.c b/trunk/drivers/i2c/muxes/i2c-mux-pca9541.c index 966a18a5d12d..f3b8f9a6a89b 100644 --- a/trunk/drivers/i2c/muxes/i2c-mux-pca9541.c +++ b/trunk/drivers/i2c/muxes/i2c-mux-pca9541.c @@ -3,7 +3,7 @@ * * Copyright (c) 2010 Ericsson AB. * - * Author: Guenter Roeck + * Author: Guenter Roeck * * Derived from: * pca954x.c diff --git a/trunk/drivers/idle/intel_idle.c b/trunk/drivers/idle/intel_idle.c index 1a38dd7dfe4e..5d6675013864 100644 --- a/trunk/drivers/idle/intel_idle.c +++ b/trunk/drivers/idle/intel_idle.c @@ -465,7 +465,6 @@ static const struct x86_cpu_id intel_idle_ids[] = { ICPU(0x3c, idle_cpu_hsw), ICPU(0x3f, idle_cpu_hsw), ICPU(0x45, idle_cpu_hsw), - ICPU(0x46, idle_cpu_hsw), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); diff --git a/trunk/drivers/iio/common/st_sensors/st_sensors_core.c b/trunk/drivers/iio/common/st_sensors/st_sensors_core.c index bd33473f8e38..0198324a8b0c 100644 --- a/trunk/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/trunk/drivers/iio/common/st_sensors/st_sensors_core.c @@ -62,7 +62,7 @@ static int st_sensors_match_odr(struct st_sensors *sensor, int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) { int err; - struct st_sensor_odr_avl odr_out = {0, 0}; + struct st_sensor_odr_avl odr_out; struct st_sensor_data *sdata = iio_priv(indio_dev); err = st_sensors_match_odr(sdata->sensor, odr, &odr_out); @@ -114,7 +114,7 @@ static int st_sensors_match_fs(struct st_sensors *sensor, static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs) { - int err, i = 0; + int err, i; struct st_sensor_data *sdata = iio_priv(indio_dev); err = st_sensors_match_fs(sdata->sensor, fs, &i); @@ -139,13 +139,14 @@ static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs) int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) { + bool found; u8 tmp_value; int err = -EINVAL; - bool found = false; - struct st_sensor_odr_avl odr_out = {0, 0}; + struct st_sensor_odr_avl odr_out; struct st_sensor_data *sdata = iio_priv(indio_dev); if (enable) { + found = false; tmp_value = sdata->sensor->pw.value_on; if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) && (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) { diff --git a/trunk/drivers/iio/dac/ad5064.c b/trunk/drivers/iio/dac/ad5064.c index 74f2d52795f6..2fe1d4edcb2f 100644 --- a/trunk/drivers/iio/dac/ad5064.c +++ b/trunk/drivers/iio/dac/ad5064.c @@ -27,6 +27,7 @@ #define AD5064_ADDR(x) ((x) << 20) #define AD5064_CMD(x) ((x) << 24) +#define AD5064_ADDR_DAC(chan) (chan) #define AD5064_ADDR_ALL_DAC 0xF #define AD5064_CMD_WRITE_INPUT_N 0x0 @@ -130,15 +131,15 @@ static int ad5064_write(struct ad5064_state *st, unsigned int cmd, } static int ad5064_sync_powerdown_mode(struct ad5064_state *st, - const struct iio_chan_spec *chan) + unsigned int channel) { unsigned int val; int ret; - val = (0x1 << chan->address); + val = (0x1 << channel); - if (st->pwr_down[chan->channel]) - val |= st->pwr_down_mode[chan->channel] << 8; + if (st->pwr_down[channel]) + val |= st->pwr_down_mode[channel] << 8; ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0); @@ -168,7 +169,7 @@ static int ad5064_set_powerdown_mode(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); st->pwr_down_mode[chan->channel] = mode + 1; - ret = ad5064_sync_powerdown_mode(st, chan); + ret = ad5064_sync_powerdown_mode(st, chan->channel); mutex_unlock(&indio_dev->mlock); return ret; @@ -204,7 +205,7 @@ static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); st->pwr_down[chan->channel] = pwr_down; - ret = ad5064_sync_powerdown_mode(st, chan); + ret = ad5064_sync_powerdown_mode(st, chan->channel); mutex_unlock(&indio_dev->mlock); return ret ? ret : len; } @@ -257,7 +258,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - if (val >= (1 << chan->scan_type.realbits) || val < 0) + if (val > (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; mutex_lock(&indio_dev->mlock); @@ -291,44 +292,34 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = { { }, }; -#define AD5064_CHANNEL(chan, addr, bits) { \ +#define AD5064_CHANNEL(chan, bits) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ .channel = (chan), \ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = addr, \ + .address = AD5064_ADDR_DAC(chan), \ .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)), \ .ext_info = ad5064_ext_info, \ } #define DECLARE_AD5064_CHANNELS(name, bits) \ const struct iio_chan_spec name[] = { \ - AD5064_CHANNEL(0, 0, bits), \ - AD5064_CHANNEL(1, 1, bits), \ - AD5064_CHANNEL(2, 2, bits), \ - AD5064_CHANNEL(3, 3, bits), \ - AD5064_CHANNEL(4, 4, bits), \ - AD5064_CHANNEL(5, 5, bits), \ - AD5064_CHANNEL(6, 6, bits), \ - AD5064_CHANNEL(7, 7, bits), \ -} - -#define DECLARE_AD5065_CHANNELS(name, bits) \ -const struct iio_chan_spec name[] = { \ - AD5064_CHANNEL(0, 0, bits), \ - AD5064_CHANNEL(1, 3, bits), \ + AD5064_CHANNEL(0, bits), \ + AD5064_CHANNEL(1, bits), \ + AD5064_CHANNEL(2, bits), \ + AD5064_CHANNEL(3, bits), \ + AD5064_CHANNEL(4, bits), \ + AD5064_CHANNEL(5, bits), \ + AD5064_CHANNEL(6, bits), \ + AD5064_CHANNEL(7, bits), \ } static DECLARE_AD5064_CHANNELS(ad5024_channels, 12); static DECLARE_AD5064_CHANNELS(ad5044_channels, 14); static DECLARE_AD5064_CHANNELS(ad5064_channels, 16); -static DECLARE_AD5065_CHANNELS(ad5025_channels, 12); -static DECLARE_AD5065_CHANNELS(ad5045_channels, 14); -static DECLARE_AD5065_CHANNELS(ad5065_channels, 16); - static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { [ID_AD5024] = { .shared_vref = false, @@ -337,7 +328,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { }, [ID_AD5025] = { .shared_vref = false, - .channels = ad5025_channels, + .channels = ad5024_channels, .num_channels = 2, }, [ID_AD5044] = { @@ -347,7 +338,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { }, [ID_AD5045] = { .shared_vref = false, - .channels = ad5045_channels, + .channels = ad5044_channels, .num_channels = 2, }, [ID_AD5064] = { @@ -362,7 +353,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { }, [ID_AD5065] = { .shared_vref = false, - .channels = ad5065_channels, + .channels = ad5064_channels, .num_channels = 2, }, [ID_AD5628_1] = { @@ -438,7 +429,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, { struct iio_dev *indio_dev; struct ad5064_state *st; - unsigned int midscale; unsigned int i; int ret; @@ -475,6 +465,11 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, goto error_free_reg; } + for (i = 0; i < st->chip_info->num_channels; ++i) { + st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K; + st->dac_cache[i] = 0x8000; + } + indio_dev->dev.parent = dev; indio_dev->name = name; indio_dev->info = &ad5064_info; @@ -482,13 +477,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, indio_dev->channels = st->chip_info->channels; indio_dev->num_channels = st->chip_info->num_channels; - midscale = (1 << indio_dev->channels[0].scan_type.realbits) / 2; - - for (i = 0; i < st->chip_info->num_channels; ++i) { - st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K; - st->dac_cache[i] = midscale; - } - ret = iio_device_register(indio_dev); if (ret) goto error_disable_reg; diff --git a/trunk/drivers/iio/imu/inv_mpu6050/Kconfig b/trunk/drivers/iio/imu/inv_mpu6050/Kconfig index 361b2328453d..b5cfa3a354cf 100644 --- a/trunk/drivers/iio/imu/inv_mpu6050/Kconfig +++ b/trunk/drivers/iio/imu/inv_mpu6050/Kconfig @@ -5,7 +5,6 @@ config INV_MPU6050_IIO tristate "Invensense MPU6050 devices" depends on I2C && SYSFS - select IIO_BUFFER select IIO_TRIGGERED_BUFFER help This driver supports the Invensense MPU6050 devices. diff --git a/trunk/drivers/infiniband/hw/cxgb4/cm.c b/trunk/drivers/infiniband/hw/cxgb4/cm.c index a3fde52840ca..565bfb161c1a 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/cm.c +++ b/trunk/drivers/infiniband/hw/cxgb4/cm.c @@ -1575,12 +1575,6 @@ static int c4iw_reconnect(struct c4iw_ep *ep) neigh = dst_neigh_lookup(ep->dst, &ep->com.cm_id->remote_addr.sin_addr.s_addr); - if (!neigh) { - pr_err("%s - cannot alloc neigh.\n", __func__); - err = -ENOMEM; - goto fail4; - } - /* get a l2t entry */ if (neigh->dev->flags & IFF_LOOPBACK) { PDBG("%s LOOPBACK\n", __func__); @@ -3059,12 +3053,6 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb) dst = &rt->dst; neigh = dst_neigh_lookup_skb(dst, skb); - if (!neigh) { - pr_err("%s - failed to allocate neigh!\n", - __func__); - goto free_dst; - } - if (neigh->dev->flags & IFF_LOOPBACK) { pdev = ip_dev_find(&init_net, iph->daddr); e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, diff --git a/trunk/drivers/infiniband/hw/cxgb4/qp.c b/trunk/drivers/infiniband/hw/cxgb4/qp.c index 70b1808a08f4..17ba4f8bc12d 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/qp.c +++ b/trunk/drivers/infiniband/hw/cxgb4/qp.c @@ -186,10 +186,8 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, wq->rq.queue = dma_alloc_coherent(&(rdev->lldi.pdev->dev), wq->rq.memsize, &(wq->rq.dma_addr), GFP_KERNEL); - if (!wq->rq.queue) { - ret = -ENOMEM; + if (!wq->rq.queue) goto free_sq; - } PDBG("%s sq base va 0x%p pa 0x%llx rq base va 0x%p pa 0x%llx\n", __func__, wq->sq.queue, (unsigned long long)virt_to_phys(wq->sq.queue), diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c index e0c404bdc4a8..a479375a8fd8 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c @@ -410,7 +410,6 @@ static struct file_system_type ipathfs_fs_type = { .mount = ipathfs_mount, .kill_sb = ipathfs_kill_super, }; -MODULE_ALIAS_FS("ipathfs"); int __init ipath_init_ipathfs(void) { diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c index ea93870266eb..439c35d4a669 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -620,7 +620,7 @@ void ipath_ib_rcv(struct ipath_ibdev *dev, void *rhdr, void *data, goto bail; } - opcode = (be32_to_cpu(ohdr->bth[0]) >> 24) & 0x7f; + opcode = be32_to_cpu(ohdr->bth[0]) >> 24; dev->opstats[opcode].n_bytes += tlen; dev->opstats[opcode].n_packets++; diff --git a/trunk/drivers/infiniband/hw/mlx4/cm.c b/trunk/drivers/infiniband/hw/mlx4/cm.c index add98d01476c..e0d79b2395e4 100644 --- a/trunk/drivers/infiniband/hw/mlx4/cm.c +++ b/trunk/drivers/infiniband/hw/mlx4/cm.c @@ -362,6 +362,7 @@ void mlx4_ib_cm_paravirt_init(struct mlx4_ib_dev *dev) INIT_LIST_HEAD(&dev->sriov.cm_list); dev->sriov.sl_id_map = RB_ROOT; idr_init(&dev->sriov.pv_id_table); + idr_pre_get(&dev->sriov.pv_id_table, GFP_KERNEL); } /* slave = -1 ==> all slaves */ diff --git a/trunk/drivers/infiniband/hw/qib/Kconfig b/trunk/drivers/infiniband/hw/qib/Kconfig index 1e603a375069..8349f9c5064c 100644 --- a/trunk/drivers/infiniband/hw/qib/Kconfig +++ b/trunk/drivers/infiniband/hw/qib/Kconfig @@ -1,7 +1,7 @@ config INFINIBAND_QIB - tristate "Intel PCIe HCA support" + tristate "QLogic PCIe HCA support" depends on 64BIT ---help--- - This is a low-level driver for Intel PCIe QLE InfiniBand host - channel adapters. This driver does not support the Intel + This is a low-level driver for QLogic PCIe QLE InfiniBand host + channel adapters. This driver does not support the QLogic HyperTransport card (model QHT7140). diff --git a/trunk/drivers/infiniband/hw/qib/qib_driver.c b/trunk/drivers/infiniband/hw/qib/qib_driver.c index 216092477dfc..5423edcab51f 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_driver.c +++ b/trunk/drivers/infiniband/hw/qib/qib_driver.c @@ -1,5 +1,4 @@ /* - * Copyright (c) 2013 Intel Corporation. All rights reserved. * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. * @@ -64,8 +63,8 @@ MODULE_PARM_DESC(compat_ddr_negotiate, "Attempt pre-IBTA 1.2 DDR speed negotiation"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_AUTHOR("Intel "); -MODULE_DESCRIPTION("Intel IB driver"); +MODULE_AUTHOR("QLogic "); +MODULE_DESCRIPTION("QLogic IB driver"); MODULE_VERSION(QIB_DRIVER_VERSION); /* diff --git a/trunk/drivers/infiniband/hw/qib/qib_fs.c b/trunk/drivers/infiniband/hw/qib/qib_fs.c index f247fc6e6182..644bd6f6467c 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_fs.c +++ b/trunk/drivers/infiniband/hw/qib/qib_fs.c @@ -604,7 +604,6 @@ static struct file_system_type qibfs_fs_type = { .mount = qibfs_mount, .kill_sb = qibfs_kill_super, }; -MODULE_ALIAS_FS("ipathfs"); int __init qib_init_qibfs(void) { diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c index 0232ae56b1fa..a099ac171e22 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c @@ -1,5 +1,4 @@ /* - * Copyright (c) 2013 Intel Corporation. All rights reserved. * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. * All rights reserved. * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. @@ -52,7 +51,7 @@ static u32 qib_6120_iblink_state(u64); /* * This file contains all the chip-specific register information and - * access functions for the Intel Intel_IB PCI-Express chip. + * access functions for the QLogic QLogic_IB PCI-Express chip. * */ diff --git a/trunk/drivers/infiniband/hw/qib/qib_init.c b/trunk/drivers/infiniband/hw/qib/qib_init.c index 173f805790da..50e33aa0b4e3 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_init.c +++ b/trunk/drivers/infiniband/hw/qib/qib_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved. + * Copyright (c) 2012 Intel Corporation. All rights reserved. * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. * @@ -1138,7 +1138,7 @@ void qib_disable_after_error(struct qib_devdata *dd) static void qib_remove_one(struct pci_dev *); static int qib_init_one(struct pci_dev *, const struct pci_device_id *); -#define DRIVER_LOAD_MSG "Intel " QIB_DRV_NAME " loaded: " +#define DRIVER_LOAD_MSG "QLogic " QIB_DRV_NAME " loaded: " #define PFX QIB_DRV_NAME ": " static DEFINE_PCI_DEVICE_TABLE(qib_pci_tbl) = { @@ -1355,7 +1355,7 @@ static int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dd = qib_init_iba6120_funcs(pdev, ent); #else qib_early_err(&pdev->dev, - "Intel PCIE device 0x%x cannot work if CONFIG_PCI_MSI is not enabled\n", + "QLogic PCIE device 0x%x cannot work if CONFIG_PCI_MSI is not enabled\n", ent->device); dd = ERR_PTR(-ENODEV); #endif @@ -1371,7 +1371,7 @@ static int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) default: qib_early_err(&pdev->dev, - "Failing on unknown Intel deviceid 0x%x\n", + "Failing on unknown QLogic deviceid 0x%x\n", ent->device); ret = -ENODEV; } diff --git a/trunk/drivers/infiniband/hw/qib/qib_sd7220.c b/trunk/drivers/infiniband/hw/qib/qib_sd7220.c index 911205d3d5a0..50a8a0d4fe67 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_sd7220.c +++ b/trunk/drivers/infiniband/hw/qib/qib_sd7220.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Intel Corporation. All rights reserved. + * Copyright (c) 2012 Intel Corporation. All rights reserved. * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. * diff --git a/trunk/drivers/infiniband/hw/qib/qib_verbs.c b/trunk/drivers/infiniband/hw/qib/qib_verbs.c index 7c0ab16a2fe2..ba51a4715a1d 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_verbs.c +++ b/trunk/drivers/infiniband/hw/qib/qib_verbs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved. + * Copyright (c) 2012 Intel Corporation. All rights reserved. * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. * @@ -2224,7 +2224,7 @@ int qib_register_ib_device(struct qib_devdata *dd) ibdev->dma_ops = &qib_dma_mapping_ops; snprintf(ibdev->node_desc, sizeof(ibdev->node_desc), - "Intel Infiniband HCA %s", init_utsname()->nodename); + "QLogic Infiniband HCA %s", init_utsname()->nodename); ret = ib_register_device(ibdev, qib_create_port_files); if (ret) diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 1ef880de3a41..67b0c1d23678 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -758,13 +758,9 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ if (++priv->tx_outstanding == ipoib_sendq_size) { ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", tx->qp->qp_num); - netif_stop_queue(dev); - rc = ib_req_notify_cq(priv->send_cq, - IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS); - if (rc < 0) + if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) ipoib_warn(priv, "request notify on send CQ failed\n"); - else if (rc) - ipoib_send_comp_handler(priv->send_cq, dev); + netif_stop_queue(dev); } } } diff --git a/trunk/drivers/input/joystick/analog.c b/trunk/drivers/input/joystick/analog.c index 9135606c8649..7cd74e29cbc8 100644 --- a/trunk/drivers/input/joystick/analog.c +++ b/trunk/drivers/input/joystick/analog.c @@ -158,10 +158,14 @@ static unsigned int get_time_pit(void) #define GET_TIME(x) rdtscl(x) #define DELTA(x,y) ((y)-(x)) #define TIME_NAME "TSC" -#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_TILE) +#elif defined(__alpha__) #define GET_TIME(x) do { x = get_cycles(); } while (0) #define DELTA(x,y) ((y)-(x)) -#define TIME_NAME "get_cycles" +#define TIME_NAME "PCC" +#elif defined(CONFIG_MN10300) || defined(CONFIG_TILE) +#define GET_TIME(x) do { x = get_cycles(); } while (0) +#define DELTA(x, y) ((x) - (y)) +#define TIME_NAME "TSC" #else #define FAKE_TIME static unsigned long analog_faketime = 0; diff --git a/trunk/drivers/input/keyboard/tc3589x-keypad.c b/trunk/drivers/input/keyboard/tc3589x-keypad.c index 208de7cbb7fa..2fb0d76a04c4 100644 --- a/trunk/drivers/input/keyboard/tc3589x-keypad.c +++ b/trunk/drivers/input/keyboard/tc3589x-keypad.c @@ -70,6 +70,8 @@ #define TC3589x_EVT_INT_CLR 0x2 #define TC3589x_KBD_INT_CLR 0x1 +#define TC3589x_KBD_KEYMAP_SIZE 64 + /** * struct tc_keypad - data structure used by keypad driver * @tc3589x: pointer to tc35893 @@ -86,7 +88,7 @@ struct tc_keypad { const struct tc3589x_keypad_platform_data *board; unsigned int krow; unsigned int kcol; - unsigned short *keymap; + unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE]; bool keypad_stopped; }; @@ -336,14 +338,12 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) error = matrix_keypad_build_keymap(plat->keymap_data, NULL, TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL, - NULL, input); + keypad->keymap, input); if (error) { dev_err(&pdev->dev, "Failed to build keymap\n"); goto err_free_mem; } - keypad->keymap = input->keycode; - input_set_capability(input, EV_MSC, MSC_SCAN); if (!plat->no_autorepeat) __set_bit(EV_REP, input->evbit); diff --git a/trunk/drivers/input/mouse/alps.c b/trunk/drivers/input/mouse/alps.c index 0238e0e14335..7b99fc7c9438 100644 --- a/trunk/drivers/input/mouse/alps.c +++ b/trunk/drivers/input/mouse/alps.c @@ -490,29 +490,6 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p) f->y_map |= (p[5] & 0x20) << 6; } -static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p) -{ - f->first_mp = !!(p[0] & 0x02); - f->is_mp = !!(p[0] & 0x20); - - f->fingers = ((p[0] & 0x6) >> 1 | - (p[0] & 0x10) >> 2); - f->x_map = ((p[2] & 0x60) >> 5) | - ((p[4] & 0x7f) << 2) | - ((p[5] & 0x7f) << 9) | - ((p[3] & 0x07) << 16) | - ((p[3] & 0x70) << 15) | - ((p[0] & 0x01) << 22); - f->y_map = (p[1] & 0x7f) | - ((p[2] & 0x1f) << 7); - - f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7)); - f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3)); - f->z = (p[0] & 4) ? 0 : p[5] & 0x7f; - - alps_decode_buttons_v3(f, p); -} - static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; @@ -897,8 +874,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) } /* Bytes 2 - pktsize should have 0 in the highest bit */ - if (priv->proto_version != ALPS_PROTO_V5 && - psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && + if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", psmouse->pktcnt - 1, @@ -1018,7 +994,8 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command, return 0; } -static int alps_enter_command_mode(struct psmouse *psmouse) +static int alps_enter_command_mode(struct psmouse *psmouse, + unsigned char *resp) { unsigned char param[4]; @@ -1027,12 +1004,14 @@ static int alps_enter_command_mode(struct psmouse *psmouse) return -1; } - if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) && - param[0] != 0x73) { + if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) { psmouse_dbg(psmouse, "unknown response while entering command mode\n"); return -1; } + + if (resp) + *resp = param[2]; return 0; } @@ -1197,7 +1176,7 @@ static int alps_passthrough_mode_v3(struct psmouse *psmouse, { int reg_val, ret = -1; - if (alps_enter_command_mode(psmouse)) + if (alps_enter_command_mode(psmouse, NULL)) return -1; reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008); @@ -1237,7 +1216,7 @@ static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base) { int ret = -EIO, reg_val; - if (alps_enter_command_mode(psmouse)) + if (alps_enter_command_mode(psmouse, NULL)) goto error; reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08); @@ -1300,7 +1279,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base) * supported by this driver. If bit 1 isn't set the packet * format is different. */ - if (alps_enter_command_mode(psmouse) || + if (alps_enter_command_mode(psmouse, NULL) || alps_command_mode_write_reg(psmouse, reg_base + 0x08, 0x82) || alps_exit_command_mode(psmouse)) @@ -1327,7 +1306,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse) alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO) goto error; - if (alps_enter_command_mode(psmouse) || + if (alps_enter_command_mode(psmouse, NULL) || alps_absolute_mode_v3(psmouse)) { psmouse_err(psmouse, "Failed to enter absolute mode\n"); goto error; @@ -1402,7 +1381,7 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) priv->flags &= ~ALPS_DUALPOINT; } - if (alps_enter_command_mode(psmouse) || + if (alps_enter_command_mode(psmouse, NULL) || alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 || alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00)) goto error; @@ -1452,7 +1431,7 @@ static int alps_hw_init_v4(struct psmouse *psmouse) struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[4]; - if (alps_enter_command_mode(psmouse)) + if (alps_enter_command_mode(psmouse, NULL)) goto error; if (alps_absolute_mode_v4(psmouse)) { @@ -1520,23 +1499,6 @@ static int alps_hw_init_v4(struct psmouse *psmouse) return -1; } -static int alps_hw_init_dolphin_v1(struct psmouse *psmouse) -{ - struct ps2dev *ps2dev = &psmouse->ps2dev; - unsigned char param[2]; - - /* This is dolphin "v1" as empirically defined by florin9doi */ - param[0] = 0x64; - param[1] = 0x28; - - if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) || - ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) || - ps2_command(ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE)) - return -1; - - return 0; -} - static void alps_set_defaults(struct alps_data *priv) { priv->byte0 = 0x8f; @@ -1570,21 +1532,6 @@ static void alps_set_defaults(struct alps_data *priv) priv->nibble_commands = alps_v4_nibble_commands; priv->addr_command = PSMOUSE_CMD_DISABLE; break; - case ALPS_PROTO_V5: - priv->hw_init = alps_hw_init_dolphin_v1; - priv->process_packet = alps_process_packet_v3; - priv->decode_fields = alps_decode_dolphin; - priv->set_abs_params = alps_set_abs_params_mt; - priv->nibble_commands = alps_v3_nibble_commands; - priv->addr_command = PSMOUSE_CMD_RESET_WRAP; - priv->byte0 = 0xc8; - priv->mask0 = 0xc8; - priv->flags = 0; - priv->x_max = 1360; - priv->y_max = 660; - priv->x_bits = 23; - priv->y_bits = 12; - break; } } @@ -1644,12 +1591,6 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) return -EIO; if (alps_match_table(psmouse, priv, e7, ec) == 0) { - return 0; - } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && - ec[0] == 0x73 && ec[1] == 0x01) { - priv->proto_version = ALPS_PROTO_V5; - alps_set_defaults(priv); - return 0; } else if (ec[0] == 0x88 && ec[1] == 0x08) { priv->proto_version = ALPS_PROTO_V3; diff --git a/trunk/drivers/input/mouse/alps.h b/trunk/drivers/input/mouse/alps.h index eee59853b9ce..970480551b6e 100644 --- a/trunk/drivers/input/mouse/alps.h +++ b/trunk/drivers/input/mouse/alps.h @@ -16,7 +16,6 @@ #define ALPS_PROTO_V2 2 #define ALPS_PROTO_V3 3 #define ALPS_PROTO_V4 4 -#define ALPS_PROTO_V5 5 /** * struct alps_model_info - touchpad ID table diff --git a/trunk/drivers/input/mouse/cypress_ps2.c b/trunk/drivers/input/mouse/cypress_ps2.c index f51765fff054..1673dc6c8092 100644 --- a/trunk/drivers/input/mouse/cypress_ps2.c +++ b/trunk/drivers/input/mouse/cypress_ps2.c @@ -236,13 +236,6 @@ static int cypress_read_fw_version(struct psmouse *psmouse) cytp->fw_version = param[2] & FW_VERSION_MASX; cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0; - /* - * Trackpad fw_version 11 (in Dell XPS12) yields a bogus response to - * CYTP_CMD_READ_TP_METRICS so do not try to use it. LP: #1103594. - */ - if (cytp->fw_version >= 11) - cytp->tp_metrics_supported = 0; - psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version); psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n", cytp->tp_metrics_supported); @@ -265,9 +258,6 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse) cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width; cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high; - if (!cytp->tp_metrics_supported) - return 0; - memset(param, 0, sizeof(param)); if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_TP_METRICS, param) == 0) { /* Update trackpad parameters. */ @@ -325,15 +315,18 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse) static int cypress_query_hardware(struct psmouse *psmouse) { + struct cytp_data *cytp = psmouse->private; int ret; ret = cypress_read_fw_version(psmouse); if (ret) return ret; - ret = cypress_read_tp_metrics(psmouse); - if (ret) - return ret; + if (cytp->tp_metrics_supported) { + ret = cypress_read_tp_metrics(psmouse); + if (ret) + return ret; + } return 0; } diff --git a/trunk/drivers/input/tablet/wacom_wac.c b/trunk/drivers/input/tablet/wacom_wac.c index 0bfd8cf25200..41b6fbf60112 100644 --- a/trunk/drivers/input/tablet/wacom_wac.c +++ b/trunk/drivers/input/tablet/wacom_wac.c @@ -359,7 +359,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) case 0x802: /* Intuos4 General Pen */ case 0x804: /* Intuos4 Marker Pen */ case 0x40802: /* Intuos4 Classic Pen */ - case 0x18802: /* DTH2242 Grip Pen */ + case 0x18803: /* DTH2242 Grip Pen */ case 0x022: wacom->tool[idx] = BTN_TOOL_PEN; break; @@ -1912,7 +1912,7 @@ static const struct wacom_features wacom_features_0xBB = { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xBC = - { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40640, 25400, 2047, + { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0x26 = { "Wacom Intuos5 touch S", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, @@ -2017,9 +2017,6 @@ static const struct wacom_features wacom_features_0x100 = static const struct wacom_features wacom_features_0x101 = { "Wacom ISDv4 101", WACOM_PKGLEN_MTTPC, 26202, 16325, 255, 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x10D = - { "Wacom ISDv4 10D", WACOM_PKGLEN_MTTPC, 26202, 16325, 255, - 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x4001 = { "Wacom ISDv4 4001", WACOM_PKGLEN_MTTPC, 26202, 16325, 255, 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -2144,7 +2141,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x44) }, { USB_DEVICE_WACOM(0x45) }, { USB_DEVICE_WACOM(0x59) }, - { USB_DEVICE_DETAILED(0x5D, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_WACOM(0x5D) }, { USB_DEVICE_WACOM(0xB0) }, { USB_DEVICE_WACOM(0xB1) }, { USB_DEVICE_WACOM(0xB2) }, @@ -2204,12 +2201,11 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xEF) }, { USB_DEVICE_WACOM(0x100) }, { USB_DEVICE_WACOM(0x101) }, - { USB_DEVICE_WACOM(0x10D) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_WACOM(0xF4) }, { USB_DEVICE_WACOM(0xF8) }, - { USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_WACOM(0xF6) }, { USB_DEVICE_WACOM(0xFA) }, { USB_DEVICE_LENOVO(0x6004) }, { } diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index 434c3df250ca..4f702b3ec1a3 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -236,12 +236,7 @@ static void __ads7846_disable(struct ads7846 *ts) /* Must be called with ts->lock held */ static void __ads7846_enable(struct ads7846 *ts) { - int error; - - error = regulator_enable(ts->reg); - if (error != 0) - dev_err(&ts->spi->dev, "Failed to enable supply: %d\n", error); - + regulator_enable(ts->reg); ads7846_restart(ts); } diff --git a/trunk/drivers/input/touchscreen/atmel_mxt_ts.c b/trunk/drivers/input/touchscreen/atmel_mxt_ts.c index 59aa24002c7b..d04f810cb1dd 100644 --- a/trunk/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/trunk/drivers/input/touchscreen/atmel_mxt_ts.c @@ -176,17 +176,11 @@ /* Define for MXT_GEN_COMMAND_T6 */ #define MXT_BOOT_VALUE 0xa5 #define MXT_BACKUP_VALUE 0x55 -#define MXT_BACKUP_TIME 50 /* msec */ -#define MXT_RESET_TIME 200 /* msec */ +#define MXT_BACKUP_TIME 25 /* msec */ +#define MXT_RESET_TIME 65 /* msec */ #define MXT_FWRESET_TIME 175 /* msec */ -/* MXT_SPT_GPIOPWM_T19 field */ -#define MXT_GPIO0_MASK 0x04 -#define MXT_GPIO1_MASK 0x08 -#define MXT_GPIO2_MASK 0x10 -#define MXT_GPIO3_MASK 0x20 - /* Command to unlock bootloader */ #define MXT_UNLOCK_CMD_MSB 0xaa #define MXT_UNLOCK_CMD_LSB 0xdc @@ -218,8 +212,6 @@ /* Touchscreen absolute values */ #define MXT_MAX_AREA 0xff -#define MXT_PIXELS_PER_MM 20 - struct mxt_info { u8 family_id; u8 variant_id; @@ -251,8 +243,6 @@ struct mxt_data { const struct mxt_platform_data *pdata; struct mxt_object *object_table; struct mxt_info info; - bool is_tp; - unsigned int irq; unsigned int max_x; unsigned int max_y; @@ -261,7 +251,6 @@ struct mxt_data { u8 T6_reportid; u8 T9_reportid_min; u8 T9_reportid_max; - u8 T19_reportid; }; static bool mxt_object_readable(unsigned int type) @@ -513,21 +502,6 @@ static int mxt_write_object(struct mxt_data *data, return mxt_write_reg(data->client, reg + offset, val); } -static void mxt_input_button(struct mxt_data *data, struct mxt_message *message) -{ - struct input_dev *input = data->input_dev; - bool button; - int i; - - /* Active-low switch */ - for (i = 0; i < MXT_NUM_GPIO; i++) { - if (data->pdata->key_map[i] == KEY_RESERVED) - continue; - button = !(message->message[0] & MXT_GPIO0_MASK << i); - input_report_key(input, data->pdata->key_map[i], button); - } -} - static void mxt_input_touchevent(struct mxt_data *data, struct mxt_message *message, int id) { @@ -611,9 +585,6 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) int id = reportid - data->T9_reportid_min; mxt_input_touchevent(data, &message, id); update_input = true; - } else if (message.reportid == data->T19_reportid) { - mxt_input_button(data, &message); - update_input = true; } else { mxt_dump_message(dev, &message); } @@ -793,9 +764,6 @@ static int mxt_get_object_table(struct mxt_data *data) data->T9_reportid_min = min_id; data->T9_reportid_max = max_id; break; - case MXT_SPT_GPIOPWM_T19: - data->T19_reportid = min_id; - break; } } @@ -809,7 +777,7 @@ static void mxt_free_object_table(struct mxt_data *data) data->T6_reportid = 0; data->T9_reportid_min = 0; data->T9_reportid_max = 0; - data->T19_reportid = 0; + } static int mxt_initialize(struct mxt_data *data) @@ -1147,13 +1115,9 @@ static int mxt_probe(struct i2c_client *client, goto err_free_mem; } - data->is_tp = pdata && pdata->is_tp; - - input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" : - "Atmel maXTouch Touchscreen"; + input_dev->name = "Atmel maXTouch Touchscreen"; snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", client->adapter->nr, client->addr); - input_dev->phys = data->phys; input_dev->id.bustype = BUS_I2C; @@ -1176,29 +1140,6 @@ static int mxt_probe(struct i2c_client *client, __set_bit(EV_KEY, input_dev->evbit); __set_bit(BTN_TOUCH, input_dev->keybit); - if (data->is_tp) { - int i; - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); - - for (i = 0; i < MXT_NUM_GPIO; i++) - if (pdata->key_map[i] != KEY_RESERVED) - __set_bit(pdata->key_map[i], input_dev->keybit); - - __set_bit(BTN_TOOL_FINGER, input_dev->keybit); - __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); - __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); - __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); - __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit); - - input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM); - input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM); - input_abs_set_res(input_dev, ABS_MT_POSITION_X, - MXT_PIXELS_PER_MM); - input_abs_set_res(input_dev, ABS_MT_POSITION_Y, - MXT_PIXELS_PER_MM); - } - /* For single touch */ input_set_abs_params(input_dev, ABS_X, 0, data->max_x, 0, 0); @@ -1317,7 +1258,6 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); static const struct i2c_device_id mxt_id[] = { { "qt602240_ts", 0 }, { "atmel_mxt_ts", 0 }, - { "atmel_mxt_tp", 0 }, { "mXT224", 0 }, { } }; diff --git a/trunk/drivers/input/touchscreen/mms114.c b/trunk/drivers/input/touchscreen/mms114.c index 1443532fe6c4..4a29ddf6bf1e 100644 --- a/trunk/drivers/input/touchscreen/mms114.c +++ b/trunk/drivers/input/touchscreen/mms114.c @@ -314,27 +314,15 @@ static int mms114_start(struct mms114_data *data) struct i2c_client *client = data->client; int error; - error = regulator_enable(data->core_reg); - if (error) { - dev_err(&client->dev, "Failed to enable avdd: %d\n", error); - return error; - } - - error = regulator_enable(data->io_reg); - if (error) { - dev_err(&client->dev, "Failed to enable vdd: %d\n", error); - regulator_disable(data->core_reg); - return error; - } - + if (data->core_reg) + regulator_enable(data->core_reg); + if (data->io_reg) + regulator_enable(data->io_reg); mdelay(MMS114_POWERON_DELAY); error = mms114_setup_regs(data); - if (error < 0) { - regulator_disable(data->io_reg); - regulator_disable(data->core_reg); + if (error < 0) return error; - } if (data->pdata->cfg_pin) data->pdata->cfg_pin(true); @@ -347,20 +335,16 @@ static int mms114_start(struct mms114_data *data) static void mms114_stop(struct mms114_data *data) { struct i2c_client *client = data->client; - int error; disable_irq(client->irq); if (data->pdata->cfg_pin) data->pdata->cfg_pin(false); - error = regulator_disable(data->io_reg); - if (error) - dev_warn(&client->dev, "Failed to disable vdd: %d\n", error); - - error = regulator_disable(data->core_reg); - if (error) - dev_warn(&client->dev, "Failed to disable avdd: %d\n", error); + if (data->io_reg) + regulator_disable(data->io_reg); + if (data->core_reg) + regulator_disable(data->core_reg); } static int mms114_input_open(struct input_dev *dev) diff --git a/trunk/drivers/iommu/Kconfig b/trunk/drivers/iommu/Kconfig index c332fb98480d..5c514d0711d1 100644 --- a/trunk/drivers/iommu/Kconfig +++ b/trunk/drivers/iommu/Kconfig @@ -130,7 +130,7 @@ config IRQ_REMAP # OMAP IOMMU support config OMAP_IOMMU bool "OMAP IOMMU Support" - depends on ARCH_OMAP2PLUS + depends on ARCH_OMAP select IOMMU_API config OMAP_IOVMM diff --git a/trunk/drivers/iommu/amd_iommu.c b/trunk/drivers/iommu/amd_iommu.c index 830183737b0f..98f555dafb55 100644 --- a/trunk/drivers/iommu/amd_iommu.c +++ b/trunk/drivers/iommu/amd_iommu.c @@ -173,7 +173,7 @@ static inline u16 get_device_id(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - return PCI_DEVID(pdev->bus->number, pdev->devfn); + return calc_devid(pdev->bus->number, pdev->devfn); } static struct iommu_dev_data *get_dev_data(struct device *dev) @@ -649,26 +649,26 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) case EVENT_TYPE_ILL_DEV: printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x " "address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), address, flags); dump_dte_entry(devid); break; case EVENT_TYPE_IO_FAULT: printk("IO_PAGE_FAULT device=%02x:%02x.%x " "domain=0x%04x address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), domid, address, flags); break; case EVENT_TYPE_DEV_TAB_ERR: printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x " "address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), address, flags); break; case EVENT_TYPE_PAGE_TAB_ERR: printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x " "domain=0x%04x address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), domid, address, flags); break; case EVENT_TYPE_ILL_CMD: @@ -682,13 +682,13 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) case EVENT_TYPE_IOTLB_INV_TO: printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x " "address=0x%016llx]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), address); break; case EVENT_TYPE_INV_DEV_REQ: printk("INVALID_DEVICE_REQUEST device=%02x:%02x.%x " "address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), address, flags); break; default: @@ -2466,16 +2466,18 @@ static int device_change_notifier(struct notifier_block *nb, /* allocate a protection domain if a device is added */ dma_domain = find_protection_domain(devid); - if (!dma_domain) { - dma_domain = dma_ops_domain_alloc(); - if (!dma_domain) - goto out; - dma_domain->target_dev = devid; - - spin_lock_irqsave(&iommu_pd_list_lock, flags); - list_add_tail(&dma_domain->list, &iommu_pd_list); - spin_unlock_irqrestore(&iommu_pd_list_lock, flags); - } + if (dma_domain) + goto out; + dma_domain = dma_ops_domain_alloc(); + if (!dma_domain) + goto out; + dma_domain->target_dev = devid; + + spin_lock_irqsave(&iommu_pd_list_lock, flags); + list_add_tail(&dma_domain->list, &iommu_pd_list); + spin_unlock_irqrestore(&iommu_pd_list_lock, flags); + + dev_data = get_dev_data(dev); dev->archdata.dma_ops = &amd_iommu_dma_ops; diff --git a/trunk/drivers/iommu/amd_iommu_init.c b/trunk/drivers/iommu/amd_iommu_init.c index 2f46881256a2..b6ecddb63cd0 100644 --- a/trunk/drivers/iommu/amd_iommu_init.c +++ b/trunk/drivers/iommu/amd_iommu_init.c @@ -406,7 +406,7 @@ static int __init find_last_devid_on_pci(int bus, int dev, int fn, int cap_ptr) u32 cap; cap = read_pci_config(bus, dev, fn, cap_ptr+MMIO_RANGE_OFFSET); - update_last_devid(PCI_DEVID(MMIO_GET_BUS(cap), MMIO_GET_LD(cap))); + update_last_devid(calc_devid(MMIO_GET_BUS(cap), MMIO_GET_LD(cap))); return 0; } @@ -423,7 +423,7 @@ static int __init find_last_devid_from_ivhd(struct ivhd_header *h) p += sizeof(*h); end += h->length; - find_last_devid_on_pci(PCI_BUS_NUM(h->devid), + find_last_devid_on_pci(PCI_BUS(h->devid), PCI_SLOT(h->devid), PCI_FUNC(h->devid), h->cap_ptr); @@ -784,10 +784,10 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_ALL\t\t\t first devid: %02x:%02x.%x" " last device %02x:%02x.%x flags: %02x\n", - PCI_BUS_NUM(iommu->first_device), + PCI_BUS(iommu->first_device), PCI_SLOT(iommu->first_device), PCI_FUNC(iommu->first_device), - PCI_BUS_NUM(iommu->last_device), + PCI_BUS(iommu->last_device), PCI_SLOT(iommu->last_device), PCI_FUNC(iommu->last_device), e->flags); @@ -801,7 +801,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_SELECT\t\t\t devid: %02x:%02x.%x " "flags: %02x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags); @@ -813,7 +813,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_SELECT_RANGE_START\t " "devid: %02x:%02x.%x flags: %02x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags); @@ -827,11 +827,11 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_ALIAS\t\t\t devid: %02x:%02x.%x " "flags: %02x devid_to: %02x:%02x.%x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags, - PCI_BUS_NUM(e->ext >> 8), + PCI_BUS(e->ext >> 8), PCI_SLOT(e->ext >> 8), PCI_FUNC(e->ext >> 8)); @@ -846,11 +846,11 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_ALIAS_RANGE\t\t " "devid: %02x:%02x.%x flags: %02x " "devid_to: %02x:%02x.%x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags, - PCI_BUS_NUM(e->ext >> 8), + PCI_BUS(e->ext >> 8), PCI_SLOT(e->ext >> 8), PCI_FUNC(e->ext >> 8)); @@ -864,7 +864,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_EXT_SELECT\t\t devid: %02x:%02x.%x " "flags: %02x ext: %08x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags, e->ext); @@ -877,7 +877,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_EXT_SELECT_RANGE\t devid: " "%02x:%02x.%x flags: %02x ext: %08x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags, e->ext); @@ -890,7 +890,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, case IVHD_DEV_RANGE_END: DUMP_printk(" DEV_RANGE_END\t\t devid: %02x:%02x.%x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid)); @@ -924,7 +924,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_SPECIAL(%s[%d])\t\tdevid: %02x:%02x.%x\n", var, (int)handle, - PCI_BUS_NUM(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid)); @@ -980,7 +980,7 @@ static void __init free_iommu_all(void) * BIOS should disable L2B micellaneous clock gating by setting * L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b */ -static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu) +static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu) { u32 value; @@ -1086,7 +1086,7 @@ static int __init init_iommu_all(struct acpi_table_header *table) DUMP_printk("device: %02x:%02x.%01x cap: %04x " "seg: %d flags: %01x info %04x\n", - PCI_BUS_NUM(h->devid), PCI_SLOT(h->devid), + PCI_BUS(h->devid), PCI_SLOT(h->devid), PCI_FUNC(h->devid), h->cap_ptr, h->pci_seg, h->flags, h->info); DUMP_printk(" mmio-addr: %016llx\n", @@ -1116,7 +1116,7 @@ static int iommu_init_pci(struct amd_iommu *iommu) int cap_ptr = iommu->cap_ptr; u32 range, misc, low, high; - iommu->dev = pci_get_bus_and_slot(PCI_BUS_NUM(iommu->devid), + iommu->dev = pci_get_bus_and_slot(PCI_BUS(iommu->devid), iommu->devid & 0xff); if (!iommu->dev) return -ENODEV; @@ -1128,9 +1128,9 @@ static int iommu_init_pci(struct amd_iommu *iommu) pci_read_config_dword(iommu->dev, cap_ptr + MMIO_MISC_OFFSET, &misc); - iommu->first_device = PCI_DEVID(MMIO_GET_BUS(range), + iommu->first_device = calc_devid(MMIO_GET_BUS(range), MMIO_GET_FD(range)); - iommu->last_device = PCI_DEVID(MMIO_GET_BUS(range), + iommu->last_device = calc_devid(MMIO_GET_BUS(range), MMIO_GET_LD(range)); if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB))) @@ -1388,8 +1388,8 @@ static int __init init_unity_map_range(struct ivmd_header *m) DUMP_printk("%s devid_start: %02x:%02x.%x devid_end: %02x:%02x.%x" " range_start: %016llx range_end: %016llx flags: %x\n", s, - PCI_BUS_NUM(e->devid_start), PCI_SLOT(e->devid_start), - PCI_FUNC(e->devid_start), PCI_BUS_NUM(e->devid_end), + PCI_BUS(e->devid_start), PCI_SLOT(e->devid_start), + PCI_FUNC(e->devid_start), PCI_BUS(e->devid_end), PCI_SLOT(e->devid_end), PCI_FUNC(e->devid_end), e->address_start, e->address_end, m->flags); diff --git a/trunk/drivers/iommu/amd_iommu_types.h b/trunk/drivers/iommu/amd_iommu_types.h index ec36cf63e0ca..e38ab438bb34 100644 --- a/trunk/drivers/iommu/amd_iommu_types.h +++ b/trunk/drivers/iommu/amd_iommu_types.h @@ -24,7 +24,6 @@ #include #include #include -#include /* * Maximum number of IOMMUs supported @@ -316,6 +315,9 @@ #define MAX_DOMAIN_ID 65536 +/* FIXME: move this macro to */ +#define PCI_BUS(x) (((x) >> 8) & 0xff) + /* Protection domain flags */ #define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */ #define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops @@ -701,6 +703,13 @@ extern int amd_iommu_max_glx_val; */ extern void iommu_flush_all_caches(struct amd_iommu *iommu); +/* takes bus and device/function and returns the device id + * FIXME: should that be in generic PCI code? */ +static inline u16 calc_devid(u8 bus, u8 devfn) +{ + return (((u16)bus) << 8) | devfn; +} + static inline int get_ioapic_devid(int id) { struct devid_map *entry; diff --git a/trunk/drivers/iommu/dmar.c b/trunk/drivers/iommu/dmar.c index e5cdaf87822c..dc7e478b7e5f 100644 --- a/trunk/drivers/iommu/dmar.c +++ b/trunk/drivers/iommu/dmar.c @@ -1083,7 +1083,6 @@ static const char *dma_remap_fault_reasons[] = "non-zero reserved fields in RTP", "non-zero reserved fields in CTP", "non-zero reserved fields in PTE", - "PCE for translation request specifies blocking", }; static const char *irq_remap_fault_reasons[] = diff --git a/trunk/drivers/iommu/irq_remapping.c b/trunk/drivers/iommu/irq_remapping.c index 7c11ff368d07..d56f8c17c5fe 100644 --- a/trunk/drivers/iommu/irq_remapping.c +++ b/trunk/drivers/iommu/irq_remapping.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/ipack/carriers/tpci200.c b/trunk/drivers/ipack/carriers/tpci200.c index c276fde318e5..0246b1fddffe 100644 --- a/trunk/drivers/ipack/carriers/tpci200.c +++ b/trunk/drivers/ipack/carriers/tpci200.c @@ -480,7 +480,6 @@ static void tpci200_release_device(struct ipack_device *dev) static int tpci200_create_device(struct tpci200_board *tpci200, int i) { - int ret; enum ipack_space space; struct ipack_device *dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL); @@ -496,18 +495,7 @@ static int tpci200_create_device(struct tpci200_board *tpci200, int i) + tpci200_space_interval[space] * i; dev->region[space].size = tpci200_space_size[space]; } - - ret = ipack_device_init(dev); - if (ret < 0) { - ipack_put_device(dev); - return ret; - } - - ret = ipack_device_add(dev); - if (ret < 0) - ipack_put_device(dev); - - return ret; + return ipack_device_register(dev); } static int tpci200_pci_probe(struct pci_dev *pdev, diff --git a/trunk/drivers/ipack/ipack.c b/trunk/drivers/ipack/ipack.c index 6e066c53acce..7ec6b208b1cb 100644 --- a/trunk/drivers/ipack/ipack.c +++ b/trunk/drivers/ipack/ipack.c @@ -227,7 +227,7 @@ static int ipack_unregister_bus_member(struct device *dev, void *data) struct ipack_bus_device *bus = data; if (idev->bus == bus) - ipack_device_del(idev); + ipack_device_unregister(idev); return 1; } @@ -419,7 +419,7 @@ static int ipack_device_read_id(struct ipack_device *dev) return ret; } -int ipack_device_init(struct ipack_device *dev) +int ipack_device_register(struct ipack_device *dev) { int ret; @@ -428,7 +428,6 @@ int ipack_device_init(struct ipack_device *dev) dev->dev.parent = dev->bus->parent; dev_set_name(&dev->dev, "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot); - device_initialize(&dev->dev); if (dev->bus->ops->set_clockrate(dev, 8)) dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); @@ -448,34 +447,19 @@ int ipack_device_init(struct ipack_device *dev) dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n"); } - return 0; -} -EXPORT_SYMBOL_GPL(ipack_device_init); - -int ipack_device_add(struct ipack_device *dev) -{ - return device_add(&dev->dev); -} -EXPORT_SYMBOL_GPL(ipack_device_add); + ret = device_register(&dev->dev); + if (ret < 0) + kfree(dev->id); -void ipack_device_del(struct ipack_device *dev) -{ - device_del(&dev->dev); - ipack_put_device(dev); -} -EXPORT_SYMBOL_GPL(ipack_device_del); - -void ipack_get_device(struct ipack_device *dev) -{ - get_device(&dev->dev); + return ret; } -EXPORT_SYMBOL_GPL(ipack_get_device); +EXPORT_SYMBOL_GPL(ipack_device_register); -void ipack_put_device(struct ipack_device *dev) +void ipack_device_unregister(struct ipack_device *dev) { - put_device(&dev->dev); + device_unregister(&dev->dev); } -EXPORT_SYMBOL_GPL(ipack_put_device); +EXPORT_SYMBOL_GPL(ipack_device_unregister); static int __init ipack_init(void) { diff --git a/trunk/drivers/irqchip/irq-gic.c b/trunk/drivers/irqchip/irq-gic.c index fc6aebf1e4b2..644d72468423 100644 --- a/trunk/drivers/irqchip/irq-gic.c +++ b/trunk/drivers/irqchip/irq-gic.c @@ -236,8 +236,7 @@ static int gic_retrigger(struct irq_data *d) if (gic_arch_extn.irq_retrigger) return gic_arch_extn.irq_retrigger(d); - /* the genirq layer expects 0 if we can't retrigger in hardware */ - return 0; + return -ENXIO; } #ifdef CONFIG_SMP @@ -649,7 +648,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) /* Convert our logical CPU mask into a physical one. */ for_each_cpu(cpu, mask) - map |= gic_cpu_map[cpu]; + map |= 1 << cpu_logical_map(cpu); /* * Ensure that stores to Normal memory are visible to the diff --git a/trunk/drivers/isdn/hardware/avm/avm_cs.c b/trunk/drivers/isdn/hardware/avm/avm_cs.c index 62b8030ee331..c21353d8e915 100644 --- a/trunk/drivers/isdn/hardware/avm/avm_cs.c +++ b/trunk/drivers/isdn/hardware/avm/avm_cs.c @@ -163,4 +163,16 @@ static struct pcmcia_driver avmcs_driver = { .remove = avmcs_detach, .id_table = avmcs_ids, }; -module_pcmcia_driver(avmcs_driver); + +static int __init avmcs_init(void) +{ + return pcmcia_register_driver(&avmcs_driver); +} + +static void __exit avmcs_exit(void) +{ + pcmcia_unregister_driver(&avmcs_driver); +} + +module_init(avmcs_init); +module_exit(avmcs_exit); diff --git a/trunk/drivers/isdn/hisax/Kconfig b/trunk/drivers/isdn/hisax/Kconfig index d9edcc94c2a8..5313c9ea44dc 100644 --- a/trunk/drivers/isdn/hisax/Kconfig +++ b/trunk/drivers/isdn/hisax/Kconfig @@ -237,8 +237,7 @@ config HISAX_MIC config HISAX_NETJET bool "NETjet card" - depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN))) - depends on VIRT_TO_BUS + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN))) help This enables HiSax support for the NetJet from Traverse Technologies. @@ -249,8 +248,7 @@ config HISAX_NETJET config HISAX_NETJET_U bool "NETspider U card" - depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN))) - depends on VIRT_TO_BUS + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN))) help This enables HiSax support for the Netspider U interface ISDN card from Traverse Technologies. diff --git a/trunk/drivers/isdn/hisax/avma1_cs.c b/trunk/drivers/isdn/hisax/avma1_cs.c index baad94ec1f4a..4e676bcf8506 100644 --- a/trunk/drivers/isdn/hisax/avma1_cs.c +++ b/trunk/drivers/isdn/hisax/avma1_cs.c @@ -159,4 +159,16 @@ static struct pcmcia_driver avma1cs_driver = { .remove = avma1cs_detach, .id_table = avma1cs_ids, }; -module_pcmcia_driver(avma1cs_driver); + +static int __init init_avma1_cs(void) +{ + return pcmcia_register_driver(&avma1cs_driver); +} + +static void __exit exit_avma1_cs(void) +{ + pcmcia_unregister_driver(&avma1cs_driver); +} + +module_init(init_avma1_cs); +module_exit(exit_avma1_cs); diff --git a/trunk/drivers/isdn/hisax/elsa_cs.c b/trunk/drivers/isdn/hisax/elsa_cs.c index 40f6fad79de3..ebe56918f6fc 100644 --- a/trunk/drivers/isdn/hisax/elsa_cs.c +++ b/trunk/drivers/isdn/hisax/elsa_cs.c @@ -215,4 +215,16 @@ static struct pcmcia_driver elsa_cs_driver = { .suspend = elsa_suspend, .resume = elsa_resume, }; -module_pcmcia_driver(elsa_cs_driver); + +static int __init init_elsa_cs(void) +{ + return pcmcia_register_driver(&elsa_cs_driver); +} + +static void __exit exit_elsa_cs(void) +{ + pcmcia_unregister_driver(&elsa_cs_driver); +} + +module_init(init_elsa_cs); +module_exit(exit_elsa_cs); diff --git a/trunk/drivers/isdn/hisax/sedlbauer_cs.c b/trunk/drivers/isdn/hisax/sedlbauer_cs.c index 92ef62d4caf4..90f81291641b 100644 --- a/trunk/drivers/isdn/hisax/sedlbauer_cs.c +++ b/trunk/drivers/isdn/hisax/sedlbauer_cs.c @@ -206,4 +206,16 @@ static struct pcmcia_driver sedlbauer_driver = { .suspend = sedlbauer_suspend, .resume = sedlbauer_resume, }; -module_pcmcia_driver(sedlbauer_driver); + +static int __init init_sedlbauer_cs(void) +{ + return pcmcia_register_driver(&sedlbauer_driver); +} + +static void __exit exit_sedlbauer_cs(void) +{ + pcmcia_unregister_driver(&sedlbauer_driver); +} + +module_init(init_sedlbauer_cs); +module_exit(exit_sedlbauer_cs); diff --git a/trunk/drivers/isdn/hisax/st5481_usb.c b/trunk/drivers/isdn/hisax/st5481_usb.c index ead0a4fb7448..017c67ea3f4c 100644 --- a/trunk/drivers/isdn/hisax/st5481_usb.c +++ b/trunk/drivers/isdn/hisax/st5481_usb.c @@ -294,13 +294,13 @@ int st5481_setup_usb(struct st5481_adapter *adapter) // Allocate URBs and buffers for interrupt endpoint urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - goto err1; + return -ENOMEM; } intr->urb = urb; buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL); if (!buf) { - goto err2; + return -ENOMEM; } endpoint = &altsetting->endpoint[EP_INT-1]; @@ -313,14 +313,6 @@ int st5481_setup_usb(struct st5481_adapter *adapter) endpoint->desc.bInterval); return 0; -err2: - usb_free_urb(intr->urb); - intr->urb = NULL; -err1: - usb_free_urb(ctrl->urb); - ctrl->urb = NULL; - - return -ENOMEM; } /* diff --git a/trunk/drivers/isdn/hisax/teles_cs.c b/trunk/drivers/isdn/hisax/teles_cs.c index b8dd14958757..f2476ffb04fd 100644 --- a/trunk/drivers/isdn/hisax/teles_cs.c +++ b/trunk/drivers/isdn/hisax/teles_cs.c @@ -197,4 +197,16 @@ static struct pcmcia_driver teles_cs_driver = { .suspend = teles_suspend, .resume = teles_resume, }; -module_pcmcia_driver(teles_cs_driver); + +static int __init init_teles_cs(void) +{ + return pcmcia_register_driver(&teles_cs_driver); +} + +static void __exit exit_teles_cs(void) +{ + pcmcia_unregister_driver(&teles_cs_driver); +} + +module_init(init_teles_cs); +module_exit(exit_teles_cs); diff --git a/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c index ebaebdf30f98..d8a7d8323414 100644 --- a/trunk/drivers/isdn/i4l/isdn_tty.c +++ b/trunk/drivers/isdn/i4l/isdn_tty.c @@ -902,9 +902,7 @@ isdn_tty_send_msg(modem_info *info, atemu *m, char *msg) int j; int l; - l = min(strlen(msg), sizeof(cmd.parm) - sizeof(cmd.parm.cmsg) - + sizeof(cmd.parm.cmsg.para) - 2); - + l = strlen(msg); if (!l) { isdn_tty_modem_result(RESULT_ERROR, info); return; diff --git a/trunk/drivers/mailbox/pl320-ipc.c b/trunk/drivers/mailbox/pl320-ipc.c index d873cbae2fbb..c45b3aedafba 100644 --- a/trunk/drivers/mailbox/pl320-ipc.c +++ b/trunk/drivers/mailbox/pl320-ipc.c @@ -138,7 +138,8 @@ int pl320_ipc_unregister_notifier(struct notifier_block *nb) } EXPORT_SYMBOL_GPL(pl320_ipc_unregister_notifier); -static int pl320_probe(struct amba_device *adev, const struct amba_id *id) +static int __init pl320_probe(struct amba_device *adev, + const struct amba_id *id) { int ret; diff --git a/trunk/drivers/md/Kconfig b/trunk/drivers/md/Kconfig index 4d8d90b4fe78..e30b490055aa 100644 --- a/trunk/drivers/md/Kconfig +++ b/trunk/drivers/md/Kconfig @@ -154,6 +154,17 @@ config MD_RAID456 If unsure, say Y. +config MULTICORE_RAID456 + bool "RAID-4/RAID-5/RAID-6 Multicore processing (EXPERIMENTAL)" + depends on MD_RAID456 + depends on SMP + depends on EXPERIMENTAL + ---help--- + Enable the raid456 module to dispatch per-stripe raid operations to a + thread pool. + + If unsure, say N. + config MD_MULTIPATH tristate "Multipath I/O support" depends on BLK_DEV_MD diff --git a/trunk/drivers/md/dm-bufio.c b/trunk/drivers/md/dm-bufio.c index c6083132c4b8..3c955e10a618 100644 --- a/trunk/drivers/md/dm-bufio.c +++ b/trunk/drivers/md/dm-bufio.c @@ -1025,8 +1025,6 @@ void dm_bufio_prefetch(struct dm_bufio_client *c, { struct blk_plug plug; - BUG_ON(dm_bufio_in_request()); - blk_start_plug(&plug); dm_bufio_lock(c); diff --git a/trunk/drivers/md/dm-cache-metadata.c b/trunk/drivers/md/dm-cache-metadata.c index 83e995fece88..fbd3625f2748 100644 --- a/trunk/drivers/md/dm-cache-metadata.c +++ b/trunk/drivers/md/dm-cache-metadata.c @@ -83,8 +83,6 @@ struct cache_disk_superblock { __le32 read_misses; __le32 write_hits; __le32 write_misses; - - __le32 policy_version[CACHE_POLICY_VERSION_SIZE]; } __packed; struct dm_cache_metadata { @@ -111,7 +109,6 @@ struct dm_cache_metadata { bool clean_when_opened:1; char policy_name[CACHE_POLICY_NAME_SIZE]; - unsigned policy_version[CACHE_POLICY_VERSION_SIZE]; size_t policy_hint_size; struct dm_cache_statistics stats; }; @@ -271,8 +268,7 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd) memset(disk_super->uuid, 0, sizeof(disk_super->uuid)); disk_super->magic = cpu_to_le64(CACHE_SUPERBLOCK_MAGIC); disk_super->version = cpu_to_le32(CACHE_VERSION); - memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name)); - memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version)); + memset(disk_super->policy_name, 0, CACHE_POLICY_NAME_SIZE); disk_super->policy_hint_size = 0; r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root, @@ -288,6 +284,7 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd) disk_super->metadata_block_size = cpu_to_le32(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); disk_super->data_block_size = cpu_to_le32(cmd->data_block_size); disk_super->cache_blocks = cpu_to_le32(0); + memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name)); disk_super->read_hits = cpu_to_le32(0); disk_super->read_misses = cpu_to_le32(0); @@ -481,9 +478,6 @@ static void read_superblock_fields(struct dm_cache_metadata *cmd, cmd->data_block_size = le32_to_cpu(disk_super->data_block_size); cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks)); strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name)); - cmd->policy_version[0] = le32_to_cpu(disk_super->policy_version[0]); - cmd->policy_version[1] = le32_to_cpu(disk_super->policy_version[1]); - cmd->policy_version[2] = le32_to_cpu(disk_super->policy_version[2]); cmd->policy_hint_size = le32_to_cpu(disk_super->policy_hint_size); cmd->stats.read_hits = le32_to_cpu(disk_super->read_hits); @@ -578,9 +572,6 @@ static int __commit_transaction(struct dm_cache_metadata *cmd, disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks)); disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks)); strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name)); - disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]); - disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]); - disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]); disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits); disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses); @@ -863,43 +854,18 @@ struct thunk { bool hints_valid; }; -static bool policy_unchanged(struct dm_cache_metadata *cmd, - struct dm_cache_policy *policy) -{ - const char *policy_name = dm_cache_policy_get_name(policy); - const unsigned *policy_version = dm_cache_policy_get_version(policy); - size_t policy_hint_size = dm_cache_policy_get_hint_size(policy); - - /* - * Ensure policy names match. - */ - if (strncmp(cmd->policy_name, policy_name, sizeof(cmd->policy_name))) - return false; - - /* - * Ensure policy major versions match. - */ - if (cmd->policy_version[0] != policy_version[0]) - return false; - - /* - * Ensure policy hint sizes match. - */ - if (cmd->policy_hint_size != policy_hint_size) - return false; - - return true; -} - static bool hints_array_initialized(struct dm_cache_metadata *cmd) { return cmd->hint_root && cmd->policy_hint_size; } static bool hints_array_available(struct dm_cache_metadata *cmd, - struct dm_cache_policy *policy) + const char *policy_name) { - return cmd->clean_when_opened && policy_unchanged(cmd, policy) && + bool policy_names_match = !strncmp(cmd->policy_name, policy_name, + sizeof(cmd->policy_name)); + + return cmd->clean_when_opened && policy_names_match && hints_array_initialized(cmd); } @@ -933,8 +899,7 @@ static int __load_mapping(void *context, uint64_t cblock, void *leaf) return r; } -static int __load_mappings(struct dm_cache_metadata *cmd, - struct dm_cache_policy *policy, +static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_name, load_mapping_fn fn, void *context) { struct thunk thunk; @@ -944,19 +909,18 @@ static int __load_mappings(struct dm_cache_metadata *cmd, thunk.cmd = cmd; thunk.respect_dirty_flags = cmd->clean_when_opened; - thunk.hints_valid = hints_array_available(cmd, policy); + thunk.hints_valid = hints_array_available(cmd, policy_name); return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk); } -int dm_cache_load_mappings(struct dm_cache_metadata *cmd, - struct dm_cache_policy *policy, +int dm_cache_load_mappings(struct dm_cache_metadata *cmd, const char *policy_name, load_mapping_fn fn, void *context) { int r; down_read(&cmd->root_lock); - r = __load_mappings(cmd, policy, fn, context); + r = __load_mappings(cmd, policy_name, fn, context); up_read(&cmd->root_lock); return r; @@ -1015,7 +979,7 @@ static int __dirty(struct dm_cache_metadata *cmd, dm_cblock_t cblock, bool dirty /* nothing to be done */ return 0; - value = pack_value(oblock, (flags & ~M_DIRTY) | (dirty ? M_DIRTY : 0)); + value = pack_value(oblock, flags | (dirty ? M_DIRTY : 0)); __dm_bless_for_disk(&value); r = dm_array_set_value(&cmd->info, cmd->root, from_cblock(cblock), @@ -1106,15 +1070,13 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po __le32 value; size_t hint_size; const char *policy_name = dm_cache_policy_get_name(policy); - const unsigned *policy_version = dm_cache_policy_get_version(policy); if (!policy_name[0] || (strlen(policy_name) > sizeof(cmd->policy_name) - 1)) return -EINVAL; - if (!policy_unchanged(cmd, policy)) { + if (strcmp(cmd->policy_name, policy_name)) { strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name)); - memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version)); hint_size = dm_cache_policy_get_hint_size(policy); if (!hint_size) diff --git a/trunk/drivers/md/dm-cache-metadata.h b/trunk/drivers/md/dm-cache-metadata.h index f45cef21f3d0..135864ea0eee 100644 --- a/trunk/drivers/md/dm-cache-metadata.h +++ b/trunk/drivers/md/dm-cache-metadata.h @@ -89,7 +89,7 @@ typedef int (*load_mapping_fn)(void *context, dm_oblock_t oblock, dm_cblock_t cblock, bool dirty, uint32_t hint, bool hint_valid); int dm_cache_load_mappings(struct dm_cache_metadata *cmd, - struct dm_cache_policy *policy, + const char *policy_name, load_mapping_fn fn, void *context); diff --git a/trunk/drivers/md/dm-cache-policy-cleaner.c b/trunk/drivers/md/dm-cache-policy-cleaner.c index b04d1f904d07..cc05d70b3cb8 100644 --- a/trunk/drivers/md/dm-cache-policy-cleaner.c +++ b/trunk/drivers/md/dm-cache-policy-cleaner.c @@ -17,6 +17,7 @@ /*----------------------------------------------------------------*/ #define DM_MSG_PREFIX "cache cleaner" +#define CLEANER_VERSION "1.0.0" /* Cache entry struct. */ struct wb_cache_entry { @@ -433,7 +434,6 @@ static struct dm_cache_policy *wb_create(dm_cblock_t cache_size, static struct dm_cache_policy_type wb_policy_type = { .name = "cleaner", - .version = {1, 0, 0}, .hint_size = 0, .owner = THIS_MODULE, .create = wb_create @@ -446,10 +446,7 @@ static int __init wb_init(void) if (r < 0) DMERR("register failed %d", r); else - DMINFO("version %u.%u.%u loaded", - wb_policy_type.version[0], - wb_policy_type.version[1], - wb_policy_type.version[2]); + DMINFO("version " CLEANER_VERSION " loaded"); return r; } diff --git a/trunk/drivers/md/dm-cache-policy-internal.h b/trunk/drivers/md/dm-cache-policy-internal.h index 0928abdc49f0..52a75beeced5 100644 --- a/trunk/drivers/md/dm-cache-policy-internal.h +++ b/trunk/drivers/md/dm-cache-policy-internal.h @@ -117,8 +117,6 @@ void dm_cache_policy_destroy(struct dm_cache_policy *p); */ const char *dm_cache_policy_get_name(struct dm_cache_policy *p); -const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p); - size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p); /*----------------------------------------------------------------*/ diff --git a/trunk/drivers/md/dm-cache-policy-mq.c b/trunk/drivers/md/dm-cache-policy-mq.c index dc112a7137fe..964153255076 100644 --- a/trunk/drivers/md/dm-cache-policy-mq.c +++ b/trunk/drivers/md/dm-cache-policy-mq.c @@ -14,6 +14,7 @@ #include #define DM_MSG_PREFIX "cache-policy-mq" +#define MQ_VERSION "1.0.0" static struct kmem_cache *mq_entry_cache; @@ -1132,7 +1133,6 @@ static struct dm_cache_policy *mq_create(dm_cblock_t cache_size, static struct dm_cache_policy_type mq_policy_type = { .name = "mq", - .version = {1, 0, 0}, .hint_size = 4, .owner = THIS_MODULE, .create = mq_create @@ -1140,7 +1140,6 @@ static struct dm_cache_policy_type mq_policy_type = { static struct dm_cache_policy_type default_policy_type = { .name = "default", - .version = {1, 0, 0}, .hint_size = 4, .owner = THIS_MODULE, .create = mq_create @@ -1165,10 +1164,7 @@ static int __init mq_init(void) r = dm_cache_policy_register(&default_policy_type); if (!r) { - DMINFO("version %u.%u.%u loaded", - mq_policy_type.version[0], - mq_policy_type.version[1], - mq_policy_type.version[2]); + DMINFO("version " MQ_VERSION " loaded"); return 0; } diff --git a/trunk/drivers/md/dm-cache-policy.c b/trunk/drivers/md/dm-cache-policy.c index 21c03c570c06..2cbf5fdaac52 100644 --- a/trunk/drivers/md/dm-cache-policy.c +++ b/trunk/drivers/md/dm-cache-policy.c @@ -150,14 +150,6 @@ const char *dm_cache_policy_get_name(struct dm_cache_policy *p) } EXPORT_SYMBOL_GPL(dm_cache_policy_get_name); -const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p) -{ - struct dm_cache_policy_type *t = p->private; - - return t->version; -} -EXPORT_SYMBOL_GPL(dm_cache_policy_get_version); - size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p) { struct dm_cache_policy_type *t = p->private; diff --git a/trunk/drivers/md/dm-cache-policy.h b/trunk/drivers/md/dm-cache-policy.h index 558bdfdabf5f..f0f51b260544 100644 --- a/trunk/drivers/md/dm-cache-policy.h +++ b/trunk/drivers/md/dm-cache-policy.h @@ -196,7 +196,6 @@ struct dm_cache_policy { * We maintain a little register of the different policy types. */ #define CACHE_POLICY_NAME_SIZE 16 -#define CACHE_POLICY_VERSION_SIZE 3 struct dm_cache_policy_type { /* For use by the register code only. */ @@ -207,7 +206,6 @@ struct dm_cache_policy_type { * what gets passed on the target line to select your policy. */ char name[CACHE_POLICY_NAME_SIZE]; - unsigned version[CACHE_POLICY_VERSION_SIZE]; /* * Policies may store a hint for each each cache block. diff --git a/trunk/drivers/md/dm-cache-target.c b/trunk/drivers/md/dm-cache-target.c index 10744091e6ca..0f4e84b15c30 100644 --- a/trunk/drivers/md/dm-cache-target.c +++ b/trunk/drivers/md/dm-cache-target.c @@ -6,7 +6,6 @@ #include "dm.h" #include "dm-bio-prison.h" -#include "dm-bio-record.h" #include "dm-cache-metadata.h" #include @@ -143,7 +142,6 @@ struct cache { spinlock_t lock; struct bio_list deferred_bios; struct bio_list deferred_flush_bios; - struct bio_list deferred_writethrough_bios; struct list_head quiesced_migrations; struct list_head completed_migrations; struct list_head need_commit_migrations; @@ -160,7 +158,7 @@ struct cache { /* * origin_blocks entries, discarded if set. */ - uint32_t discard_block_size; /* a power of 2 times sectors per block */ + sector_t discard_block_size; /* a power of 2 times sectors per block */ dm_dblock_t discard_nr_blocks; unsigned long *discard_bitset; @@ -201,16 +199,6 @@ struct per_bio_data { bool tick:1; unsigned req_nr:2; struct dm_deferred_entry *all_io_entry; - - /* - * writethrough fields. These MUST remain at the end of this - * structure and the 'cache' member must be the first as it - * is used to determine the offsetof the writethrough fields. - */ - struct cache *cache; - dm_cblock_t cblock; - bio_end_io_t *saved_bi_end_io; - struct dm_bio_details bio_details; }; struct dm_cache_migration { @@ -424,24 +412,17 @@ static bool block_size_is_power_of_two(struct cache *cache) return cache->sectors_per_block_shift >= 0; } -static dm_block_t block_div(dm_block_t b, uint32_t n) -{ - do_div(b, n); - - return b; -} - static dm_dblock_t oblock_to_dblock(struct cache *cache, dm_oblock_t oblock) { - uint32_t discard_blocks = cache->discard_block_size; + sector_t discard_blocks = cache->discard_block_size; dm_block_t b = from_oblock(oblock); if (!block_size_is_power_of_two(cache)) - discard_blocks = discard_blocks / cache->sectors_per_block; + (void) sector_div(discard_blocks, cache->sectors_per_block); else discard_blocks >>= cache->sectors_per_block_shift; - b = block_div(b, discard_blocks); + (void) sector_div(b, discard_blocks); return to_dblock(b); } @@ -519,28 +500,16 @@ static void save_stats(struct cache *cache) /*---------------------------------------------------------------- * Per bio data *--------------------------------------------------------------*/ - -/* - * If using writeback, leave out struct per_bio_data's writethrough fields. - */ -#define PB_DATA_SIZE_WB (offsetof(struct per_bio_data, cache)) -#define PB_DATA_SIZE_WT (sizeof(struct per_bio_data)) - -static size_t get_per_bio_data_size(struct cache *cache) +static struct per_bio_data *get_per_bio_data(struct bio *bio) { - return cache->features.write_through ? PB_DATA_SIZE_WT : PB_DATA_SIZE_WB; -} - -static struct per_bio_data *get_per_bio_data(struct bio *bio, size_t data_size) -{ - struct per_bio_data *pb = dm_per_bio_data(bio, data_size); + struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); BUG_ON(!pb); return pb; } -static struct per_bio_data *init_per_bio_data(struct bio *bio, size_t data_size) +static struct per_bio_data *init_per_bio_data(struct bio *bio) { - struct per_bio_data *pb = get_per_bio_data(bio, data_size); + struct per_bio_data *pb = get_per_bio_data(bio); pb->tick = false; pb->req_nr = dm_bio_get_target_bio_nr(bio); @@ -574,8 +543,7 @@ static void remap_to_cache(struct cache *cache, struct bio *bio, static void check_if_tick_bio_needed(struct cache *cache, struct bio *bio) { unsigned long flags; - size_t pb_data_size = get_per_bio_data_size(cache); - struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); + struct per_bio_data *pb = get_per_bio_data(bio); spin_lock_irqsave(&cache->lock, flags); if (cache->need_tick_bio && @@ -641,58 +609,6 @@ static void issue(struct cache *cache, struct bio *bio) spin_unlock_irqrestore(&cache->lock, flags); } -static void defer_writethrough_bio(struct cache *cache, struct bio *bio) -{ - unsigned long flags; - - spin_lock_irqsave(&cache->lock, flags); - bio_list_add(&cache->deferred_writethrough_bios, bio); - spin_unlock_irqrestore(&cache->lock, flags); - - wake_worker(cache); -} - -static void writethrough_endio(struct bio *bio, int err) -{ - struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT); - bio->bi_end_io = pb->saved_bi_end_io; - - if (err) { - bio_endio(bio, err); - return; - } - - dm_bio_restore(&pb->bio_details, bio); - remap_to_cache(pb->cache, bio, pb->cblock); - - /* - * We can't issue this bio directly, since we're in interrupt - * context. So it get's put on a bio list for processing by the - * worker thread. - */ - defer_writethrough_bio(pb->cache, bio); -} - -/* - * When running in writethrough mode we need to send writes to clean blocks - * to both the cache and origin devices. In future we'd like to clone the - * bio and send them in parallel, but for now we're doing them in - * series as this is easier. - */ -static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio, - dm_oblock_t oblock, dm_cblock_t cblock) -{ - struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT); - - pb->cache = cache; - pb->cblock = cblock; - pb->saved_bi_end_io = bio->bi_end_io; - dm_bio_record(&pb->bio_details, bio); - bio->bi_end_io = writethrough_endio; - - remap_to_origin_clear_discard(pb->cache, bio, oblock); -} - /*---------------------------------------------------------------- * Migration processing * @@ -1056,8 +972,7 @@ static void defer_bio(struct cache *cache, struct bio *bio) static void process_flush_bio(struct cache *cache, struct bio *bio) { - size_t pb_data_size = get_per_bio_data_size(cache); - struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); + struct per_bio_data *pb = get_per_bio_data(bio); BUG_ON(bio->bi_size); if (!pb->req_nr) @@ -1087,7 +1002,7 @@ static void process_discard_bio(struct cache *cache, struct bio *bio) dm_block_t end_block = bio->bi_sector + bio_sectors(bio); dm_block_t b; - end_block = block_div(end_block, cache->discard_block_size); + (void) sector_div(end_block, cache->discard_block_size); for (b = start_block; b < end_block; b++) set_discard(cache, to_dblock(b)); @@ -1129,8 +1044,7 @@ static void process_bio(struct cache *cache, struct prealloc *structs, dm_oblock_t block = get_bio_block(cache, bio); struct dm_bio_prison_cell *cell_prealloc, *old_ocell, *new_ocell; struct policy_result lookup_result; - size_t pb_data_size = get_per_bio_data_size(cache); - struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); + struct per_bio_data *pb = get_per_bio_data(bio); bool discarded_block = is_discarded_oblock(cache, block); bool can_migrate = discarded_block || spare_migration_bandwidth(cache); @@ -1156,9 +1070,14 @@ static void process_bio(struct cache *cache, struct prealloc *structs, inc_hit_counter(cache, bio); pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds); - if (is_writethrough_io(cache, bio, lookup_result.cblock)) - remap_to_origin_then_cache(cache, bio, block, lookup_result.cblock); - else + if (is_writethrough_io(cache, bio, lookup_result.cblock)) { + /* + * No need to mark anything dirty in write through mode. + */ + pb->req_nr == 0 ? + remap_to_cache(cache, bio, lookup_result.cblock) : + remap_to_origin_clear_discard(cache, bio, block); + } else remap_to_cache_dirty(cache, bio, block, lookup_result.cblock); issue(cache, bio); @@ -1167,8 +1086,17 @@ static void process_bio(struct cache *cache, struct prealloc *structs, case POLICY_MISS: inc_miss_counter(cache, bio); pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds); - remap_to_origin_clear_discard(cache, bio, block); - issue(cache, bio); + + if (pb->req_nr != 0) { + /* + * This is a duplicate writethrough io that is no + * longer needed because the block has been demoted. + */ + bio_endio(bio, 0); + } else { + remap_to_origin_clear_discard(cache, bio, block); + issue(cache, bio); + } break; case POLICY_NEW: @@ -1289,23 +1217,6 @@ static void process_deferred_flush_bios(struct cache *cache, bool submit_bios) submit_bios ? generic_make_request(bio) : bio_io_error(bio); } -static void process_deferred_writethrough_bios(struct cache *cache) -{ - unsigned long flags; - struct bio_list bios; - struct bio *bio; - - bio_list_init(&bios); - - spin_lock_irqsave(&cache->lock, flags); - bio_list_merge(&bios, &cache->deferred_writethrough_bios); - bio_list_init(&cache->deferred_writethrough_bios); - spin_unlock_irqrestore(&cache->lock, flags); - - while ((bio = bio_list_pop(&bios))) - generic_make_request(bio); -} - static void writeback_some_dirty_blocks(struct cache *cache) { int r = 0; @@ -1402,7 +1313,6 @@ static int more_work(struct cache *cache) else return !bio_list_empty(&cache->deferred_bios) || !bio_list_empty(&cache->deferred_flush_bios) || - !bio_list_empty(&cache->deferred_writethrough_bios) || !list_empty(&cache->quiesced_migrations) || !list_empty(&cache->completed_migrations) || !list_empty(&cache->need_commit_migrations); @@ -1421,8 +1331,6 @@ static void do_worker(struct work_struct *ws) writeback_some_dirty_blocks(cache); - process_deferred_writethrough_bios(cache); - if (commit_if_needed(cache)) { process_deferred_flush_bios(cache, false); @@ -1848,11 +1756,8 @@ static int create_cache_policy(struct cache *cache, struct cache_args *ca, } r = set_config_values(cache->policy, ca->policy_argc, ca->policy_argv); - if (r) { - *error = "Error setting cache policy's config values"; + if (r) dm_cache_policy_destroy(cache->policy); - cache->policy = NULL; - } return r; } @@ -1888,6 +1793,8 @@ static sector_t calculate_discard_block_size(sector_t cache_block_size, #define DEFAULT_MIGRATION_THRESHOLD (2048 * 100) +static unsigned cache_num_write_bios(struct dm_target *ti, struct bio *bio); + static int cache_create(struct cache_args *ca, struct cache **result) { int r = 0; @@ -1904,6 +1811,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) cache->ti = ca->ti; ti->private = cache; + ti->per_bio_data_size = sizeof(struct per_bio_data); ti->num_flush_bios = 2; ti->flush_supported = true; @@ -1912,7 +1820,9 @@ static int cache_create(struct cache_args *ca, struct cache **result) ti->discard_zeroes_data_unsupported = true; memcpy(&cache->features, &ca->features, sizeof(cache->features)); - ti->per_bio_data_size = get_per_bio_data_size(cache); + + if (cache->features.write_through) + ti->num_write_bios = cache_num_write_bios; cache->callbacks.congested_fn = cache_is_congested; dm_table_add_target_callbacks(ti->table, &cache->callbacks); @@ -1925,7 +1835,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) /* FIXME: factor out this whole section */ origin_blocks = cache->origin_sectors = ca->origin_sectors; - origin_blocks = block_div(origin_blocks, ca->block_size); + (void) sector_div(origin_blocks, ca->block_size); cache->origin_blocks = to_oblock(origin_blocks); cache->sectors_per_block = ca->block_size; @@ -1938,7 +1848,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) dm_block_t cache_size = ca->cache_sectors; cache->sectors_per_block_shift = -1; - cache_size = block_div(cache_size, ca->block_size); + (void) sector_div(cache_size, ca->block_size); cache->cache_size = to_cblock(cache_size); } else { cache->sectors_per_block_shift = __ffs(ca->block_size); @@ -1963,7 +1873,6 @@ static int cache_create(struct cache_args *ca, struct cache **result) spin_lock_init(&cache->lock); bio_list_init(&cache->deferred_bios); bio_list_init(&cache->deferred_flush_bios); - bio_list_init(&cache->deferred_writethrough_bios); INIT_LIST_HEAD(&cache->quiesced_migrations); INIT_LIST_HEAD(&cache->completed_migrations); INIT_LIST_HEAD(&cache->need_commit_migrations); @@ -2093,8 +2002,6 @@ static int cache_ctr(struct dm_target *ti, unsigned argc, char **argv) goto out; r = cache_create(ca, &cache); - if (r) - goto out; r = copy_ctr_args(cache, argc - 3, (const char **)argv + 3); if (r) { @@ -2109,13 +2016,26 @@ static int cache_ctr(struct dm_target *ti, unsigned argc, char **argv) return r; } +static unsigned cache_num_write_bios(struct dm_target *ti, struct bio *bio) +{ + int r; + struct cache *cache = ti->private; + dm_oblock_t block = get_bio_block(cache, bio); + dm_cblock_t cblock; + + r = policy_lookup(cache->policy, block, &cblock); + if (r < 0) + return 2; /* assume the worst */ + + return (!r && !is_dirty(cache, cblock)) ? 2 : 1; +} + static int cache_map(struct dm_target *ti, struct bio *bio) { struct cache *cache = ti->private; int r; dm_oblock_t block = get_bio_block(cache, bio); - size_t pb_data_size = get_per_bio_data_size(cache); bool can_migrate = false; bool discarded_block; struct dm_bio_prison_cell *cell; @@ -2132,7 +2052,7 @@ static int cache_map(struct dm_target *ti, struct bio *bio) return DM_MAPIO_REMAPPED; } - pb = init_per_bio_data(bio, pb_data_size); + pb = init_per_bio_data(bio); if (bio->bi_rw & (REQ_FLUSH | REQ_FUA | REQ_DISCARD)) { defer_bio(cache, bio); @@ -2177,12 +2097,18 @@ static int cache_map(struct dm_target *ti, struct bio *bio) inc_hit_counter(cache, bio); pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds); - if (is_writethrough_io(cache, bio, lookup_result.cblock)) - remap_to_origin_then_cache(cache, bio, block, lookup_result.cblock); - else + if (is_writethrough_io(cache, bio, lookup_result.cblock)) { + /* + * No need to mark anything dirty in write through mode. + */ + pb->req_nr == 0 ? + remap_to_cache(cache, bio, lookup_result.cblock) : + remap_to_origin_clear_discard(cache, bio, block); + cell_defer(cache, cell, false); + } else { remap_to_cache_dirty(cache, bio, block, lookup_result.cblock); - - cell_defer(cache, cell, false); + cell_defer(cache, cell, false); + } break; case POLICY_MISS: @@ -2217,8 +2143,7 @@ static int cache_end_io(struct dm_target *ti, struct bio *bio, int error) { struct cache *cache = ti->private; unsigned long flags; - size_t pb_data_size = get_per_bio_data_size(cache); - struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); + struct per_bio_data *pb = get_per_bio_data(bio); if (pb->tick) { policy_tick(cache->policy); @@ -2394,7 +2319,8 @@ static int cache_preresume(struct dm_target *ti) } if (!cache->loaded_mappings) { - r = dm_cache_load_mappings(cache->cmd, cache->policy, + r = dm_cache_load_mappings(cache->cmd, + dm_cache_policy_get_name(cache->policy), load_mapping, cache); if (r) { DMERR("could not load cache mappings"); @@ -2609,7 +2535,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits) static struct target_type cache_target = { .name = "cache", - .version = {1, 1, 0}, + .version = {1, 0, 0}, .module = THIS_MODULE, .ctr = cache_ctr, .dtr = cache_dtr, diff --git a/trunk/drivers/md/dm-raid.c b/trunk/drivers/md/dm-raid.c index 311e3d35b272..9a01d1e4c783 100644 --- a/trunk/drivers/md/dm-raid.c +++ b/trunk/drivers/md/dm-raid.c @@ -91,44 +91,15 @@ static struct raid_type { {"raid6_nc", "RAID6 (N continue)", 2, 4, 6, ALGORITHM_ROTATING_N_CONTINUE} }; -static char *raid10_md_layout_to_format(int layout) -{ - /* - * Bit 16 and 17 stand for "offset" and "use_far_sets" - * Refer to MD's raid10.c for details - */ - if ((layout & 0x10000) && (layout & 0x20000)) - return "offset"; - - if ((layout & 0xFF) > 1) - return "near"; - - return "far"; -} - static unsigned raid10_md_layout_to_copies(int layout) { - if ((layout & 0xFF) > 1) - return layout & 0xFF; - return (layout >> 8) & 0xFF; + return layout & 0xFF; } static int raid10_format_to_md_layout(char *format, unsigned copies) { - unsigned n = 1, f = 1; - - if (!strcmp("near", format)) - n = copies; - else - f = copies; - - if (!strcmp("offset", format)) - return 0x30000 | (f << 8) | n; - - if (!strcmp("far", format)) - return 0x20000 | (f << 8) | n; - - return (f << 8) | n; + /* 1 "far" copy, and 'copies' "near" copies */ + return (1 << 8) | (copies & 0xFF); } static struct raid_type *get_raid_type(char *name) @@ -381,7 +352,6 @@ static int validate_raid_redundancy(struct raid_set *rs) { unsigned i, rebuild_cnt = 0; unsigned rebuilds_per_group, copies, d; - unsigned group_size, last_group_start; for (i = 0; i < rs->md.raid_disks; i++) if (!test_bit(In_sync, &rs->dev[i].rdev.flags) || @@ -409,6 +379,9 @@ static int validate_raid_redundancy(struct raid_set *rs) * as long as the failed devices occur in different mirror * groups (i.e. different stripes). * + * Right now, we only allow for "near" copies. When other + * formats are added, we will have to check those too. + * * When checking "near" format, make sure no adjacent devices * have failed beyond what can be handled. In addition to the * simple case where the number of devices is a multiple of the @@ -418,41 +391,14 @@ static int validate_raid_redundancy(struct raid_set *rs) * A A B B C * C D D E E */ - if (!strcmp("near", raid10_md_layout_to_format(rs->md.layout))) { - for (i = 0; i < rs->md.raid_disks * copies; i++) { - if (!(i % copies)) - rebuilds_per_group = 0; - d = i % rs->md.raid_disks; - if ((!rs->dev[d].rdev.sb_page || - !test_bit(In_sync, &rs->dev[d].rdev.flags)) && - (++rebuilds_per_group >= copies)) - goto too_many; - } - break; - } - - /* - * When checking "far" and "offset" formats, we need to ensure - * that the device that holds its copy is not also dead or - * being rebuilt. (Note that "far" and "offset" formats only - * support two copies right now. These formats also only ever - * use the 'use_far_sets' variant.) - * - * This check is somewhat complicated by the need to account - * for arrays that are not a multiple of (far) copies. This - * results in the need to treat the last (potentially larger) - * set differently. - */ - group_size = (rs->md.raid_disks / copies); - last_group_start = (rs->md.raid_disks / group_size) - 1; - last_group_start *= group_size; - for (i = 0; i < rs->md.raid_disks; i++) { - if (!(i % copies) && !(i > last_group_start)) + for (i = 0; i < rs->md.raid_disks * copies; i++) { + if (!(i % copies)) rebuilds_per_group = 0; - if ((!rs->dev[i].rdev.sb_page || - !test_bit(In_sync, &rs->dev[i].rdev.flags)) && + d = i % rs->md.raid_disks; + if ((!rs->dev[d].rdev.sb_page || + !test_bit(In_sync, &rs->dev[d].rdev.flags)) && (++rebuilds_per_group >= copies)) - goto too_many; + goto too_many; } break; default: @@ -487,7 +433,7 @@ static int validate_raid_redundancy(struct raid_set *rs) * * RAID10-only options: * [raid10_copies <# copies>] Number of copies. (Default: 2) - * [raid10_format ] Layout algorithm. (Default: near) + * [raid10_format ] Layout algorithm. (Default: near) */ static int parse_raid_params(struct raid_set *rs, char **argv, unsigned num_raid_params) @@ -574,9 +520,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv, rs->ti->error = "'raid10_format' is an invalid parameter for this RAID type"; return -EINVAL; } - if (strcmp("near", argv[i]) && - strcmp("far", argv[i]) && - strcmp("offset", argv[i])) { + if (strcmp("near", argv[i])) { rs->ti->error = "Invalid 'raid10_format' value given"; return -EINVAL; } @@ -700,15 +644,6 @@ static int parse_raid_params(struct raid_set *rs, char **argv, return -EINVAL; } - /* - * If the format is not "near", we only support - * two copies at the moment. - */ - if (strcmp("near", raid10_format) && (raid10_copies > 2)) { - rs->ti->error = "Too many copies for given RAID10 format."; - return -EINVAL; - } - /* (Len * #mirrors) / #devices */ sectors_per_dev = rs->ti->len * raid10_copies; sector_div(sectors_per_dev, rs->md.raid_disks); @@ -919,30 +854,17 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev) /* * Reshaping is not currently allowed */ - if (le32_to_cpu(sb->level) != mddev->level) { - DMERR("Reshaping arrays not yet supported. (RAID level change)"); - return -EINVAL; - } - if (le32_to_cpu(sb->layout) != mddev->layout) { - DMERR("Reshaping arrays not yet supported. (RAID layout change)"); - DMERR(" 0x%X vs 0x%X", le32_to_cpu(sb->layout), mddev->layout); - DMERR(" Old layout: %s w/ %d copies", - raid10_md_layout_to_format(le32_to_cpu(sb->layout)), - raid10_md_layout_to_copies(le32_to_cpu(sb->layout))); - DMERR(" New layout: %s w/ %d copies", - raid10_md_layout_to_format(mddev->layout), - raid10_md_layout_to_copies(mddev->layout)); - return -EINVAL; - } - if (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors) { - DMERR("Reshaping arrays not yet supported. (stripe sectors change)"); + if ((le32_to_cpu(sb->level) != mddev->level) || + (le32_to_cpu(sb->layout) != mddev->layout) || + (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors)) { + DMERR("Reshaping arrays not yet supported."); return -EINVAL; } /* We can only change the number of devices in RAID1 right now */ if ((rs->raid_type->level != 1) && (le32_to_cpu(sb->num_devices) != mddev->raid_disks)) { - DMERR("Reshaping arrays not yet supported. (device count change)"); + DMERR("Reshaping arrays not yet supported."); return -EINVAL; } @@ -1407,8 +1329,7 @@ static void raid_status(struct dm_target *ti, status_type_t type, raid10_md_layout_to_copies(rs->md.layout)); if (rs->print_flags & DMPF_RAID10_FORMAT) - DMEMIT(" raid10_format %s", - raid10_md_layout_to_format(rs->md.layout)); + DMEMIT(" raid10_format near"); DMEMIT(" %d", rs->md.raid_disks); for (i = 0; i < rs->md.raid_disks; i++) { @@ -1497,10 +1418,6 @@ static struct target_type raid_target = { static int __init dm_raid_init(void) { - DMINFO("Loading target version %u.%u.%u", - raid_target.version[0], - raid_target.version[1], - raid_target.version[2]); return dm_register_target(&raid_target); } diff --git a/trunk/drivers/md/dm-thin.c b/trunk/drivers/md/dm-thin.c index 004ad1652b73..009339d62828 100644 --- a/trunk/drivers/md/dm-thin.c +++ b/trunk/drivers/md/dm-thin.c @@ -1577,11 +1577,6 @@ static bool data_dev_supports_discard(struct pool_c *pt) return q && blk_queue_discard(q); } -static bool is_factor(sector_t block_size, uint32_t n) -{ - return !sector_div(block_size, n); -} - /* * If discard_passdown was enabled verify that the data device * supports discards. Disable discard_passdown if not. @@ -1607,7 +1602,7 @@ static void disable_passdown_if_not_supported(struct pool_c *pt) else if (data_limits->discard_granularity > block_size) reason = "discard granularity larger than a block"; - else if (!is_factor(block_size, data_limits->discard_granularity)) + else if (block_size & (data_limits->discard_granularity - 1)) reason = "discard granularity not a factor of block size"; if (reason) { @@ -2549,7 +2544,7 @@ static struct target_type pool_target = { .name = "thin-pool", .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | DM_TARGET_IMMUTABLE, - .version = {1, 7, 0}, + .version = {1, 6, 1}, .module = THIS_MODULE, .ctr = pool_ctr, .dtr = pool_dtr, @@ -2836,7 +2831,7 @@ static int thin_iterate_devices(struct dm_target *ti, static struct target_type thin_target = { .name = "thin", - .version = {1, 8, 0}, + .version = {1, 7, 1}, .module = THIS_MODULE, .ctr = thin_ctr, .dtr = thin_dtr, diff --git a/trunk/drivers/md/dm-verity.c b/trunk/drivers/md/dm-verity.c index a746f1d21c66..6ad538375c3c 100644 --- a/trunk/drivers/md/dm-verity.c +++ b/trunk/drivers/md/dm-verity.c @@ -93,13 +93,6 @@ struct dm_verity_io { */ }; -struct dm_verity_prefetch_work { - struct work_struct work; - struct dm_verity *v; - sector_t block; - unsigned n_blocks; -}; - static struct shash_desc *io_hash_desc(struct dm_verity *v, struct dm_verity_io *io) { return (struct shash_desc *)(io + 1); @@ -431,18 +424,15 @@ static void verity_end_io(struct bio *bio, int error) * The root buffer is not prefetched, it is assumed that it will be cached * all the time. */ -static void verity_prefetch_io(struct work_struct *work) +static void verity_prefetch_io(struct dm_verity *v, struct dm_verity_io *io) { - struct dm_verity_prefetch_work *pw = - container_of(work, struct dm_verity_prefetch_work, work); - struct dm_verity *v = pw->v; int i; for (i = v->levels - 2; i >= 0; i--) { sector_t hash_block_start; sector_t hash_block_end; - verity_hash_at_level(v, pw->block, i, &hash_block_start, NULL); - verity_hash_at_level(v, pw->block + pw->n_blocks - 1, i, &hash_block_end, NULL); + verity_hash_at_level(v, io->block, i, &hash_block_start, NULL); + verity_hash_at_level(v, io->block + io->n_blocks - 1, i, &hash_block_end, NULL); if (!i) { unsigned cluster = ACCESS_ONCE(dm_verity_prefetch_cluster); @@ -462,25 +452,6 @@ static void verity_prefetch_io(struct work_struct *work) dm_bufio_prefetch(v->bufio, hash_block_start, hash_block_end - hash_block_start + 1); } - - kfree(pw); -} - -static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io) -{ - struct dm_verity_prefetch_work *pw; - - pw = kmalloc(sizeof(struct dm_verity_prefetch_work), - GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); - - if (!pw) - return; - - INIT_WORK(&pw->work, verity_prefetch_io); - pw->v = v; - pw->block = io->block; - pw->n_blocks = io->n_blocks; - queue_work(v->verify_wq, &pw->work); } /* @@ -527,7 +498,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio) memcpy(io->io_vec, bio_iovec(bio), io->io_vec_size * sizeof(struct bio_vec)); - verity_submit_prefetch(v, io); + verity_prefetch_io(v, io); generic_make_request(bio); @@ -887,7 +858,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv) static struct target_type verity_target = { .name = "verity", - .version = {1, 2, 0}, + .version = {1, 1, 1}, .module = THIS_MODULE, .ctr = verity_ctr, .dtr = verity_dtr, diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 9a0bdad9ad8f..7e469260fe5e 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -611,7 +611,6 @@ static void dec_pending(struct dm_io *io, int error) queue_io(md, bio); } else { /* done with normal IO or empty flush */ - trace_block_bio_complete(md->queue, bio, io_error); bio_endio(bio, io_error); } } diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index aeceedfc530b..3db3d1b271f7 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -307,10 +307,6 @@ static void md_make_request(struct request_queue *q, struct bio *bio) bio_io_error(bio); return; } - if (mddev->ro == 1 && unlikely(rw == WRITE)) { - bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS); - return; - } smp_rmb(); /* Ensure implications of 'active' are visible */ rcu_read_lock(); if (mddev->suspended) { @@ -2998,9 +2994,6 @@ rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len) } else if (!sectors) sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - rdev->data_offset; - if (!my_mddev->pers->resize) - /* Cannot change size for RAID0 or Linear etc */ - return -EINVAL; } if (sectors < my_mddev->dev_sectors) return -EINVAL; /* component must fit device */ @@ -6532,17 +6525,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, mddev->ro = 0; sysfs_notify_dirent_safe(mddev->sysfs_state); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); - /* mddev_unlock will wake thread */ - /* If a device failed while we were read-only, we - * need to make sure the metadata is updated now. - */ - if (test_bit(MD_CHANGE_DEVS, &mddev->flags)) { - mddev_unlock(mddev); - wait_event(mddev->sb_wait, - !test_bit(MD_CHANGE_DEVS, &mddev->flags) && - !test_bit(MD_CHANGE_PENDING, &mddev->flags)); - mddev_lock(mddev); - } + md_wakeup_thread(mddev->thread); } else { err = -EROFS; goto abort_unlock; @@ -7663,8 +7646,10 @@ static int remove_and_add_spares(struct mddev *mddev) removed++; } } - if (removed && mddev->kobj.sd) - sysfs_notify(&mddev->kobj, NULL, "degraded"); + if (removed) + sysfs_notify(&mddev->kobj, NULL, + "degraded"); + rdev_for_each(rdev, mddev) { if (rdev->raid_disk >= 0 && diff --git a/trunk/drivers/md/md.h b/trunk/drivers/md/md.h index d90fb1a879e1..eca59c3074ef 100644 --- a/trunk/drivers/md/md.h +++ b/trunk/drivers/md/md.h @@ -506,7 +506,7 @@ static inline char * mdname (struct mddev * mddev) static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) { char nm[20]; - if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { + if (!test_bit(Replacement, &rdev->flags)) { sprintf(nm, "rd%d", rdev->raid_disk); return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); } else @@ -516,7 +516,7 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev) { char nm[20]; - if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { + if (!test_bit(Replacement, &rdev->flags)) { sprintf(nm, "rd%d", rdev->raid_disk); sysfs_remove_link(&mddev->kobj, nm); } diff --git a/trunk/drivers/md/persistent-data/dm-btree-remove.c b/trunk/drivers/md/persistent-data/dm-btree-remove.c index b88757cd0d1d..c4f28133ef82 100644 --- a/trunk/drivers/md/persistent-data/dm-btree-remove.c +++ b/trunk/drivers/md/persistent-data/dm-btree-remove.c @@ -139,8 +139,15 @@ struct child { struct btree_node *n; }; -static int init_child(struct dm_btree_info *info, struct dm_btree_value_type *vt, - struct btree_node *parent, +static struct dm_btree_value_type le64_type = { + .context = NULL, + .size = sizeof(__le64), + .inc = NULL, + .dec = NULL, + .equal = NULL +}; + +static int init_child(struct dm_btree_info *info, struct btree_node *parent, unsigned index, struct child *result) { int r, inc; @@ -157,7 +164,7 @@ static int init_child(struct dm_btree_info *info, struct dm_btree_value_type *vt result->n = dm_block_data(result->block); if (inc) - inc_children(info->tm, result->n, vt); + inc_children(info->tm, result->n, &le64_type); *((__le64 *) value_ptr(parent, index)) = cpu_to_le64(dm_block_location(result->block)); @@ -229,7 +236,7 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent, } static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info, - struct dm_btree_value_type *vt, unsigned left_index) + unsigned left_index) { int r; struct btree_node *parent; @@ -237,11 +244,11 @@ static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info, parent = dm_block_data(shadow_current(s)); - r = init_child(info, vt, parent, left_index, &left); + r = init_child(info, parent, left_index, &left); if (r) return r; - r = init_child(info, vt, parent, left_index + 1, &right); + r = init_child(info, parent, left_index + 1, &right); if (r) { exit_child(info, &left); return r; @@ -361,7 +368,7 @@ static void __rebalance3(struct dm_btree_info *info, struct btree_node *parent, } static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info, - struct dm_btree_value_type *vt, unsigned left_index) + unsigned left_index) { int r; struct btree_node *parent = dm_block_data(shadow_current(s)); @@ -370,17 +377,17 @@ static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info, /* * FIXME: fill out an array? */ - r = init_child(info, vt, parent, left_index, &left); + r = init_child(info, parent, left_index, &left); if (r) return r; - r = init_child(info, vt, parent, left_index + 1, ¢er); + r = init_child(info, parent, left_index + 1, ¢er); if (r) { exit_child(info, &left); return r; } - r = init_child(info, vt, parent, left_index + 2, &right); + r = init_child(info, parent, left_index + 2, &right); if (r) { exit_child(info, &left); exit_child(info, ¢er); @@ -427,8 +434,7 @@ static int get_nr_entries(struct dm_transaction_manager *tm, } static int rebalance_children(struct shadow_spine *s, - struct dm_btree_info *info, - struct dm_btree_value_type *vt, uint64_t key) + struct dm_btree_info *info, uint64_t key) { int i, r, has_left_sibling, has_right_sibling; uint32_t child_entries; @@ -466,13 +472,13 @@ static int rebalance_children(struct shadow_spine *s, has_right_sibling = i < (le32_to_cpu(n->header.nr_entries) - 1); if (!has_left_sibling) - r = rebalance2(s, info, vt, i); + r = rebalance2(s, info, i); else if (!has_right_sibling) - r = rebalance2(s, info, vt, i - 1); + r = rebalance2(s, info, i - 1); else - r = rebalance3(s, info, vt, i - 1); + r = rebalance3(s, info, i - 1); return r; } @@ -523,7 +529,7 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info, if (le32_to_cpu(n->header.flags) & LEAF_NODE) return do_leaf(n, key, index); - r = rebalance_children(s, info, vt, key); + r = rebalance_children(s, info, key); if (r) break; @@ -544,14 +550,6 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info, return r; } -static struct dm_btree_value_type le64_type = { - .context = NULL, - .size = sizeof(__le64), - .inc = NULL, - .dec = NULL, - .equal = NULL -}; - int dm_btree_remove(struct dm_btree_info *info, dm_block_t root, uint64_t *keys, dm_block_t *new_root) { diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c index 0505452de8d6..24b359717a7e 100644 --- a/trunk/drivers/md/raid0.c +++ b/trunk/drivers/md/raid0.c @@ -175,13 +175,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) rdev1->new_raid_disk = j; } - if (j < 0) { - printk(KERN_ERR - "md/raid0:%s: remove inactive devices before converting to RAID0\n", - mdname(mddev)); - goto abort; - } - if (j >= mddev->raid_disks) { + if (j < 0 || j >= mddev->raid_disks) { printk(KERN_ERR "md/raid0:%s: bad disk number %d - " "aborting!\n", mdname(mddev), j); goto abort; @@ -295,7 +289,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) kfree(conf->strip_zone); kfree(conf->devlist); kfree(conf); - *private_conf = ERR_PTR(err); + *private_conf = NULL; return err; } @@ -417,8 +411,7 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks "%s does not support generic reshape\n", __func__); rdev_for_each(rdev, mddev) - array_sectors += (rdev->sectors & - ~(sector_t)(mddev->chunk_sectors-1)); + array_sectors += rdev->sectors; return array_sectors; } diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index fd86b372692d..d5bddfc4010e 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -967,7 +967,6 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) bio_list_merge(&conf->pending_bio_list, &plug->pending); conf->pending_count += plug->pending_cnt; spin_unlock_irq(&conf->device_lock); - wake_up(&conf->wait_barrier); md_wakeup_thread(mddev->thread); kfree(plug); return; @@ -1001,7 +1000,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); const unsigned long do_discard = (bio->bi_rw & (REQ_DISCARD | REQ_SECURE)); - const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME); struct md_rdev *blocked_rdev; struct blk_plug_cb *cb; struct raid1_plug_cb *plug = NULL; @@ -1303,8 +1301,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) conf->mirrors[i].rdev->data_offset); mbio->bi_bdev = conf->mirrors[i].rdev->bdev; mbio->bi_end_io = raid1_end_write_request; - mbio->bi_rw = - WRITE | do_flush_fua | do_sync | do_discard | do_same; + mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard; mbio->bi_private = r1_bio; atomic_inc(&r1_bio->remaining); @@ -2821,9 +2818,6 @@ static int run(struct mddev *mddev) if (IS_ERR(conf)) return PTR_ERR(conf); - if (mddev->queue) - blk_queue_max_write_same_sectors(mddev->queue, - mddev->chunk_sectors); rdev_for_each(rdev, mddev) { if (!mddev->gendisk) continue; diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 77b562d18a90..64d48249c03b 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -38,36 +38,21 @@ * near_copies (stored in low byte of layout) * far_copies (stored in second byte of layout) * far_offset (stored in bit 16 of layout ) - * use_far_sets (stored in bit 17 of layout ) * - * The data to be stored is divided into chunks using chunksize. Each device - * is divided into far_copies sections. In each section, chunks are laid out - * in a style similar to raid0, but near_copies copies of each chunk is stored - * (each on a different drive). The starting device for each section is offset - * near_copies from the starting device of the previous section. Thus there - * are (near_copies * far_copies) of each chunk, and each is on a different - * drive. near_copies and far_copies must be at least one, and their product - * is at most raid_disks. + * The data to be stored is divided into chunks using chunksize. + * Each device is divided into far_copies sections. + * In each section, chunks are laid out in a style similar to raid0, but + * near_copies copies of each chunk is stored (each on a different drive). + * The starting device for each section is offset near_copies from the starting + * device of the previous section. + * Thus they are (near_copies*far_copies) of each chunk, and each is on a different + * drive. + * near_copies and far_copies must be at least one, and their product is at most + * raid_disks. * * If far_offset is true, then the far_copies are handled a bit differently. - * The copies are still in different stripes, but instead of being very far - * apart on disk, there are adjacent stripes. - * - * The far and offset algorithms are handled slightly differently if - * 'use_far_sets' is true. In this case, the array's devices are grouped into - * sets that are (near_copies * far_copies) in size. The far copied stripes - * are still shifted by 'near_copies' devices, but this shifting stays confined - * to the set rather than the entire array. This is done to improve the number - * of device combinations that can fail without causing the array to fail. - * Example 'far' algorithm w/o 'use_far_sets' (each letter represents a chunk - * on a device): - * A B C D A B C D E - * ... ... - * D A B C E A B C D - * Example 'far' algorithm w/ 'use_far_sets' enabled (sets illustrated w/ []'s): - * [A B] [C D] [A B] [C D E] - * |...| |...| |...| | ... | - * [B A] [D C] [B A] [E C D] + * The copies are still in different stripes, but instead of be very far apart + * on disk, there are adjacent stripes. */ /* @@ -550,13 +535,6 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio) sector_t stripe; int dev; int slot = 0; - int last_far_set_start, last_far_set_size; - - last_far_set_start = (geo->raid_disks / geo->far_set_size) - 1; - last_far_set_start *= geo->far_set_size; - - last_far_set_size = geo->far_set_size; - last_far_set_size += (geo->raid_disks % geo->far_set_size); /* now calculate first sector/dev */ chunk = r10bio->sector >> geo->chunk_shift; @@ -573,25 +551,15 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio) /* and calculate all the others */ for (n = 0; n < geo->near_copies; n++) { int d = dev; - int set; sector_t s = sector; + r10bio->devs[slot].addr = sector; r10bio->devs[slot].devnum = d; - r10bio->devs[slot].addr = s; slot++; for (f = 1; f < geo->far_copies; f++) { - set = d / geo->far_set_size; d += geo->near_copies; - - if ((geo->raid_disks % geo->far_set_size) && - (d > last_far_set_start)) { - d -= last_far_set_start; - d %= last_far_set_size; - d += last_far_set_start; - } else { - d %= geo->far_set_size; - d += geo->far_set_size * set; - } + if (d >= geo->raid_disks) + d -= geo->raid_disks; s += geo->stride; r10bio->devs[slot].devnum = d; r10bio->devs[slot].addr = s; @@ -627,20 +595,6 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev) * or recovery, so reshape isn't happening */ struct geom *geo = &conf->geo; - int far_set_start = (dev / geo->far_set_size) * geo->far_set_size; - int far_set_size = geo->far_set_size; - int last_far_set_start; - - if (geo->raid_disks % geo->far_set_size) { - last_far_set_start = (geo->raid_disks / geo->far_set_size) - 1; - last_far_set_start *= geo->far_set_size; - - if (dev >= last_far_set_start) { - far_set_size = geo->far_set_size; - far_set_size += (geo->raid_disks % geo->far_set_size); - far_set_start = last_far_set_start; - } - } offset = sector & geo->chunk_mask; if (geo->far_offset) { @@ -648,13 +602,13 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev) chunk = sector >> geo->chunk_shift; fc = sector_div(chunk, geo->far_copies); dev -= fc * geo->near_copies; - if (dev < far_set_start) - dev += far_set_size; + if (dev < 0) + dev += geo->raid_disks; } else { while (sector >= geo->stride) { sector -= geo->stride; - if (dev < (geo->near_copies + far_set_start)) - dev += far_set_size - geo->near_copies; + if (dev < geo->near_copies) + dev += geo->raid_disks - geo->near_copies; else dev -= geo->near_copies; } @@ -1119,7 +1073,6 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) bio_list_merge(&conf->pending_bio_list, &plug->pending); conf->pending_count += plug->pending_cnt; spin_unlock_irq(&conf->device_lock); - wake_up(&conf->wait_barrier); md_wakeup_thread(mddev->thread); kfree(plug); return; @@ -1152,7 +1105,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_fua = (bio->bi_rw & REQ_FUA); const unsigned long do_discard = (bio->bi_rw & (REQ_DISCARD | REQ_SECURE)); - const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME); unsigned long flags; struct md_rdev *blocked_rdev; struct blk_plug_cb *cb; @@ -1508,8 +1460,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) rdev)); mbio->bi_bdev = rdev->bdev; mbio->bi_end_io = raid10_end_write_request; - mbio->bi_rw = - WRITE | do_sync | do_fua | do_discard | do_same; + mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; mbio->bi_private = r10_bio; atomic_inc(&r10_bio->remaining); @@ -1551,8 +1502,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) r10_bio, rdev)); mbio->bi_bdev = rdev->bdev; mbio->bi_end_io = raid10_end_write_request; - mbio->bi_rw = - WRITE | do_sync | do_fua | do_discard | do_same; + mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; mbio->bi_private = r10_bio; atomic_inc(&r10_bio->remaining); @@ -3486,7 +3436,7 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new) disks = mddev->raid_disks + mddev->delta_disks; break; } - if (layout >> 18) + if (layout >> 17) return -1; if (chunk < (PAGE_SIZE >> 9) || !is_power_of_2(chunk)) @@ -3498,7 +3448,6 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new) geo->near_copies = nc; geo->far_copies = fc; geo->far_offset = fo; - geo->far_set_size = (layout & (1<<17)) ? disks / fc : disks; geo->chunk_mask = chunk - 1; geo->chunk_shift = ffz(~chunk); return nc*fc; @@ -3620,8 +3569,6 @@ static int run(struct mddev *mddev) if (mddev->queue) { blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors); - blk_queue_max_write_same_sectors(mddev->queue, - mddev->chunk_sectors); blk_queue_io_min(mddev->queue, chunk_size); if (conf->geo.raid_disks % conf->geo.near_copies) blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks); diff --git a/trunk/drivers/md/raid10.h b/trunk/drivers/md/raid10.h index 157d69e83ff4..1054cf602345 100644 --- a/trunk/drivers/md/raid10.h +++ b/trunk/drivers/md/raid10.h @@ -33,11 +33,6 @@ struct r10conf { * far_offset, in which case it is * 1 stripe. */ - int far_set_size; /* The number of devices in a set, - * where a 'set' are devices that - * contain far/offset copies of - * each other. - */ int chunk_shift; /* shift from chunks to sectors */ sector_t chunk_mask; } prev, geo; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index f4e87bfc7567..5af2d2709081 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -184,8 +184,6 @@ static void return_io(struct bio *return_bi) return_bi = bi->bi_next; bi->bi_next = NULL; bi->bi_size = 0; - trace_block_bio_complete(bdev_get_queue(bi->bi_bdev), - bi, 0); bio_endio(bi, 0); bi = return_bi; } @@ -673,11 +671,9 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) bi->bi_next = NULL; if (rrdev) set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); - - if (conf->mddev->gendisk) - trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), - bi, disk_devt(conf->mddev->gendisk), - sh->dev[i].sector); + trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), + bi, disk_devt(conf->mddev->gendisk), + sh->dev[i].sector); generic_make_request(bi); } if (rrdev) { @@ -705,10 +701,9 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) rbi->bi_io_vec[0].bv_offset = 0; rbi->bi_size = STRIPE_SIZE; rbi->bi_next = NULL; - if (conf->mddev->gendisk) - trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), - rbi, disk_devt(conf->mddev->gendisk), - sh->dev[i].sector); + trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), + rbi, disk_devt(conf->mddev->gendisk), + sh->dev[i].sector); generic_make_request(rbi); } if (!rdev && !rrdev) { @@ -1408,7 +1403,7 @@ static void ops_run_check_pq(struct stripe_head *sh, struct raid5_percpu *percpu &sh->ops.zero_sum_result, percpu->spare_page, &submit); } -static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) +static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request) { int overlap_clear = 0, i, disks = sh->disks; struct dma_async_tx_descriptor *tx = NULL; @@ -1473,6 +1468,36 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) put_cpu(); } +#ifdef CONFIG_MULTICORE_RAID456 +static void async_run_ops(void *param, async_cookie_t cookie) +{ + struct stripe_head *sh = param; + unsigned long ops_request = sh->ops.request; + + clear_bit_unlock(STRIPE_OPS_REQ_PENDING, &sh->state); + wake_up(&sh->ops.wait_for_ops); + + __raid_run_ops(sh, ops_request); + release_stripe(sh); +} + +static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) +{ + /* since handle_stripe can be called outside of raid5d context + * we need to ensure sh->ops.request is de-staged before another + * request arrives + */ + wait_event(sh->ops.wait_for_ops, + !test_and_set_bit_lock(STRIPE_OPS_REQ_PENDING, &sh->state)); + sh->ops.request = ops_request; + + atomic_inc(&sh->count); + async_schedule(async_run_ops, sh); +} +#else +#define raid_run_ops __raid_run_ops +#endif + static int grow_one_stripe(struct r5conf *conf) { struct stripe_head *sh; @@ -1481,6 +1506,9 @@ static int grow_one_stripe(struct r5conf *conf) return 0; sh->raid_conf = conf; + #ifdef CONFIG_MULTICORE_RAID456 + init_waitqueue_head(&sh->ops.wait_for_ops); + #endif spin_lock_init(&sh->stripe_lock); @@ -1599,6 +1627,9 @@ static int resize_stripes(struct r5conf *conf, int newsize) break; nsh->raid_conf = conf; + #ifdef CONFIG_MULTICORE_RAID456 + init_waitqueue_head(&nsh->ops.wait_for_ops); + #endif spin_lock_init(&nsh->stripe_lock); list_add(&nsh->lru, &newstripes); @@ -2285,26 +2316,11 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, int level = conf->level; if (rcw) { - - for (i = disks; i--; ) { - struct r5dev *dev = &sh->dev[i]; - - if (dev->towrite) { - set_bit(R5_LOCKED, &dev->flags); - set_bit(R5_Wantdrain, &dev->flags); - if (!expand) - clear_bit(R5_UPTODATE, &dev->flags); - s->locked++; - } - } /* if we are not expanding this is a proper write request, and * there will be bios with new data to be drained into the * stripe cache */ if (!expand) { - if (!s->locked) - /* False alarm, nothing to do */ - return; sh->reconstruct_state = reconstruct_state_drain_run; set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); } else @@ -2312,6 +2328,17 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); + for (i = disks; i--; ) { + struct r5dev *dev = &sh->dev[i]; + + if (dev->towrite) { + set_bit(R5_LOCKED, &dev->flags); + set_bit(R5_Wantdrain, &dev->flags); + if (!expand) + clear_bit(R5_UPTODATE, &dev->flags); + s->locked++; + } + } if (s->locked + conf->max_degraded == disks) if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state)) atomic_inc(&conf->pending_full_writes); @@ -2320,6 +2347,11 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) || test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags))); + sh->reconstruct_state = reconstruct_state_prexor_drain_run; + set_bit(STRIPE_OP_PREXOR, &s->ops_request); + set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); + set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); + for (i = disks; i--; ) { struct r5dev *dev = &sh->dev[i]; if (i == pd_idx) @@ -2334,13 +2366,6 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, s->locked++; } } - if (!s->locked) - /* False alarm - nothing to do */ - return; - sh->reconstruct_state = reconstruct_state_prexor_drain_run; - set_bit(STRIPE_OP_PREXOR, &s->ops_request); - set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); - set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); } /* keep the parity disk(s) locked while asynchronous operations @@ -2575,8 +2600,6 @@ handle_failed_sync(struct r5conf *conf, struct stripe_head *sh, int i; clear_bit(STRIPE_SYNCING, &sh->state); - if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags)) - wake_up(&conf->wait_for_overlap); s->syncing = 0; s->replacing = 0; /* There is nothing more to do for sync/check/repair. @@ -2750,7 +2773,6 @@ static void handle_stripe_clean_event(struct r5conf *conf, { int i; struct r5dev *dev; - int discard_pending = 0; for (i = disks; i--; ) if (sh->dev[i].written) { @@ -2779,23 +2801,9 @@ static void handle_stripe_clean_event(struct r5conf *conf, STRIPE_SECTORS, !test_bit(STRIPE_DEGRADED, &sh->state), 0); - } else if (test_bit(R5_Discard, &dev->flags)) - discard_pending = 1; - } - if (!discard_pending && - test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags)) { - clear_bit(R5_Discard, &sh->dev[sh->pd_idx].flags); - clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags); - if (sh->qd_idx >= 0) { - clear_bit(R5_Discard, &sh->dev[sh->qd_idx].flags); - clear_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags); - } - /* now that discard is done we can proceed with any sync */ - clear_bit(STRIPE_DISCARD, &sh->state); - if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) - set_bit(STRIPE_HANDLE, &sh->state); - - } + } + } else if (test_bit(R5_Discard, &sh->dev[i].flags)) + clear_bit(R5_Discard, &sh->dev[i].flags); if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) if (atomic_dec_and_test(&conf->pending_full_writes)) @@ -2854,10 +2862,8 @@ static void handle_stripe_dirtying(struct r5conf *conf, set_bit(STRIPE_HANDLE, &sh->state); if (rmw < rcw && rmw > 0) { /* prefer read-modify-write, but need to get some data */ - if (conf->mddev->queue) - blk_add_trace_msg(conf->mddev->queue, - "raid5 rmw %llu %d", - (unsigned long long)sh->sector, rmw); + blk_add_trace_msg(conf->mddev->queue, "raid5 rmw %llu %d", + (unsigned long long)sh->sector, rmw); for (i = disks; i--; ) { struct r5dev *dev = &sh->dev[i]; if ((dev->towrite || i == sh->pd_idx) && @@ -2907,7 +2913,7 @@ static void handle_stripe_dirtying(struct r5conf *conf, } } } - if (rcw && conf->mddev->queue) + if (rcw) blk_add_trace_msg(conf->mddev->queue, "raid5 rcw %llu %d %d %d", (unsigned long long)sh->sector, rcw, qread, test_bit(STRIPE_DELAYED, &sh->state)); @@ -3447,15 +3453,9 @@ static void handle_stripe(struct stripe_head *sh) return; } - if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { - spin_lock(&sh->stripe_lock); - /* Cannot process 'sync' concurrently with 'discard' */ - if (!test_bit(STRIPE_DISCARD, &sh->state) && - test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { - set_bit(STRIPE_SYNCING, &sh->state); - clear_bit(STRIPE_INSYNC, &sh->state); - } - spin_unlock(&sh->stripe_lock); + if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { + set_bit(STRIPE_SYNCING, &sh->state); + clear_bit(STRIPE_INSYNC, &sh->state); } clear_bit(STRIPE_DELAYED, &sh->state); @@ -3615,8 +3615,6 @@ static void handle_stripe(struct stripe_head *sh) test_bit(STRIPE_INSYNC, &sh->state)) { md_done_sync(conf->mddev, STRIPE_SECTORS, 1); clear_bit(STRIPE_SYNCING, &sh->state); - if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags)) - wake_up(&conf->wait_for_overlap); } /* If the failed drives are just a ReadError, then we might need @@ -3916,8 +3914,6 @@ static void raid5_align_endio(struct bio *bi, int error) rdev_dec_pending(rdev, conf->mddev); if (!error && uptodate) { - trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev), - raid_bi, 0); bio_endio(raid_bi, 0); if (atomic_dec_and_test(&conf->active_aligned_reads)) wake_up(&conf->wait_for_stripe); @@ -4022,10 +4018,9 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) atomic_inc(&conf->active_aligned_reads); spin_unlock_irq(&conf->device_lock); - if (mddev->gendisk) - trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), - align_bi, disk_devt(mddev->gendisk), - raid_bio->bi_sector); + trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), + align_bi, disk_devt(mddev->gendisk), + raid_bio->bi_sector); generic_make_request(align_bi); return 1; } else { @@ -4119,8 +4114,7 @@ static void raid5_unplug(struct blk_plug_cb *blk_cb, bool from_schedule) } spin_unlock_irq(&conf->device_lock); } - if (mddev->queue) - trace_block_unplug(mddev->queue, cnt, !from_schedule); + trace_block_unplug(mddev->queue, cnt, !from_schedule); kfree(cb); } @@ -4183,13 +4177,6 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi) sh = get_active_stripe(conf, logical_sector, 0, 0, 0); prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); - set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags); - if (test_bit(STRIPE_SYNCING, &sh->state)) { - release_stripe(sh); - schedule(); - goto again; - } - clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags); spin_lock_irq(&sh->stripe_lock); for (d = 0; d < conf->raid_disks; d++) { if (d == sh->pd_idx || d == sh->qd_idx) @@ -4202,7 +4189,6 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi) goto again; } } - set_bit(STRIPE_DISCARD, &sh->state); finish_wait(&conf->wait_for_overlap, &w); for (d = 0; d < conf->raid_disks; d++) { if (d == sh->pd_idx || d == sh->qd_idx) @@ -4386,8 +4372,6 @@ static void make_request(struct mddev *mddev, struct bio * bi) if ( rw == WRITE ) md_write_end(mddev); - trace_block_bio_complete(bdev_get_queue(bi->bi_bdev), - bi, 0); bio_endio(bi, 0); } } @@ -4764,11 +4748,8 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio) handled++; } remaining = raid5_dec_bi_active_stripes(raid_bio); - if (remaining == 0) { - trace_block_bio_complete(bdev_get_queue(raid_bio->bi_bdev), - raid_bio, 0); + if (remaining == 0) bio_endio(raid_bio, 0); - } if (atomic_dec_and_test(&conf->active_aligned_reads)) wake_up(&conf->wait_for_stripe); return handled; diff --git a/trunk/drivers/md/raid5.h b/trunk/drivers/md/raid5.h index b0b663b119a8..18b2c4a8a1fd 100644 --- a/trunk/drivers/md/raid5.h +++ b/trunk/drivers/md/raid5.h @@ -221,6 +221,10 @@ struct stripe_head { struct stripe_operations { int target, target2; enum sum_check_flags zero_sum_result; + #ifdef CONFIG_MULTICORE_RAID456 + unsigned long request; + wait_queue_head_t wait_for_ops; + #endif } ops; struct r5dev { /* rreq and rvec are used for the replacement device when @@ -319,7 +323,6 @@ enum { STRIPE_COMPUTE_RUN, STRIPE_OPS_REQ_PENDING, STRIPE_ON_UNPLUG_LIST, - STRIPE_DISCARD, }; /* diff --git a/trunk/drivers/media/dvb-frontends/mb86a20s.c b/trunk/drivers/media/dvb-frontends/mb86a20s.c index 4faaf8053f26..f19cd7367040 100644 --- a/trunk/drivers/media/dvb-frontends/mb86a20s.c +++ b/trunk/drivers/media/dvb-frontends/mb86a20s.c @@ -610,7 +610,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer, __func__, 'A' + layer, segment * isdbt_rate[m][f][i]/1000, rate, rate); - state->estimated_rate[layer] = rate; + state->estimated_rate[i] = rate; } diff --git a/trunk/drivers/media/i2c/m5mols/m5mols_core.c b/trunk/drivers/media/i2c/m5mols/m5mols_core.c index 0b899cb6cda1..d4e7567b367c 100644 --- a/trunk/drivers/media/i2c/m5mols/m5mols_core.c +++ b/trunk/drivers/media/i2c/m5mols/m5mols_core.c @@ -724,7 +724,7 @@ static int m5mols_s_stream(struct v4l2_subdev *sd, int enable) if (enable) { if (is_code(code, M5MOLS_RESTYPE_MONITOR)) ret = m5mols_start_monitor(info); - else if (is_code(code, M5MOLS_RESTYPE_CAPTURE)) + if (is_code(code, M5MOLS_RESTYPE_CAPTURE)) ret = m5mols_start_capture(info); else ret = -EINVAL; diff --git a/trunk/drivers/media/pci/bt8xx/bttv-driver.c b/trunk/drivers/media/pci/bt8xx/bttv-driver.c index 54579e4c740b..ccd18e4ee789 100644 --- a/trunk/drivers/media/pci/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/pci/bt8xx/bttv-driver.c @@ -250,19 +250,17 @@ static u8 SRAM_Table[][60] = vdelay start of active video in 2 * field lines relative to trailing edge of /VRESET pulse (VDELAY register). sheight height of active video in 2 * field lines. - extraheight Added to sheight for cropcap.bounds.height only videostart0 ITU-R frame line number of the line corresponding to vdelay in the first field. */ #define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth, \ - vdelay, sheight, extraheight, videostart0) \ + vdelay, sheight, videostart0) \ .cropcap.bounds.left = minhdelayx1, \ /* * 2 because vertically we count field lines times two, */ \ /* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */ \ .cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \ /* 4 is a safety margin at the end of the line. */ \ .cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4, \ - .cropcap.bounds.height = (sheight) + (extraheight) + (vdelay) - \ - MIN_VDELAY, \ + .cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY, \ .cropcap.defrect.left = hdelayx1, \ .cropcap.defrect.top = (videostart0) * 2, \ .cropcap.defrect.width = swidth, \ @@ -303,10 +301,9 @@ const struct bttv_tvnorm bttv_tvnorms[] = { /* totalwidth */ 1135, /* sqwidth */ 944, /* vdelay */ 0x20, - /* sheight */ 576, - /* bt878 (and bt848?) can capture another - line below active video. */ - /* extraheight */ 2, + /* bt878 (and bt848?) can capture another + line below active video. */ + /* sheight */ (576 + 2) + 0x20 - 2, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, @@ -333,7 +330,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { /* sqwidth */ 780, /* vdelay */ 0x1a, /* sheight */ 480, - /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_SECAM, @@ -359,7 +355,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { /* sqwidth */ 944, /* vdelay */ 0x20, /* sheight */ 576, - /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_PAL_Nc, @@ -385,7 +380,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { /* sqwidth */ 780, /* vdelay */ 0x1a, /* sheight */ 576, - /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_PAL_M, @@ -411,7 +405,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { /* sqwidth */ 780, /* vdelay */ 0x1a, /* sheight */ 480, - /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_PAL_N, @@ -437,7 +430,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { /* sqwidth */ 944, /* vdelay */ 0x20, /* sheight */ 576, - /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_NTSC_M_JP, @@ -463,7 +455,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { /* sqwidth */ 780, /* vdelay */ 0x16, /* sheight */ 480, - /* extraheight */ 0, /* videostart0 */ 23) },{ /* that one hopefully works with the strange timing @@ -493,7 +484,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { /* sqwidth */ 944, /* vdelay */ 0x1a, /* sheight */ 480, - /* extraheight */ 0, /* videostart0 */ 23) } }; diff --git a/trunk/drivers/media/pci/cx25821/cx25821-video.c b/trunk/drivers/media/pci/cx25821/cx25821-video.c index 31ce7698acb9..d4de021dc844 100644 --- a/trunk/drivers/media/pci/cx25821/cx25821-video.c +++ b/trunk/drivers/media/pci/cx25821/cx25821-video.c @@ -461,7 +461,7 @@ int cx25821_video_register(struct cx25821_dev *dev) spin_lock_init(&dev->slock); - for (i = 0; i < VID_CHANNEL_NUM; ++i) { + for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) { cx25821_init_controls(dev, i); cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, diff --git a/trunk/drivers/media/platform/Kconfig b/trunk/drivers/media/platform/Kconfig index a0639e779973..05d7b6333461 100644 --- a/trunk/drivers/media/platform/Kconfig +++ b/trunk/drivers/media/platform/Kconfig @@ -204,7 +204,7 @@ config VIDEO_SAMSUNG_EXYNOS_GSC config VIDEO_SH_VEU tristate "SuperH VEU mem2mem video processing driver" - depends on VIDEO_DEV && VIDEO_V4L2 && GENERIC_HARDIRQS + depends on VIDEO_DEV && VIDEO_V4L2 select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV help diff --git a/trunk/drivers/media/platform/exynos-gsc/gsc-core.c b/trunk/drivers/media/platform/exynos-gsc/gsc-core.c index 33b5ffc8d66d..82d9f6ac12f3 100644 --- a/trunk/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/trunk/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1054,18 +1054,16 @@ static int gsc_m2m_suspend(struct gsc_dev *gsc) static int gsc_m2m_resume(struct gsc_dev *gsc) { - struct gsc_ctx *ctx; unsigned long flags; spin_lock_irqsave(&gsc->slock, flags); /* Clear for full H/W setup in first run after resume */ - ctx = gsc->m2m.ctx; gsc->m2m.ctx = NULL; spin_unlock_irqrestore(&gsc->slock, flags); if (test_and_clear_bit(ST_M2M_SUSPENDED, &gsc->state)) - gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); - + gsc_m2m_job_finish(gsc->m2m.ctx, + VB2_BUF_STATE_ERROR); return 0; } @@ -1206,7 +1204,7 @@ static int gsc_resume(struct device *dev) /* Do not resume if the device was idle before system suspend */ spin_lock_irqsave(&gsc->slock, flags); if (!test_and_clear_bit(ST_SUSPEND, &gsc->state) || - !gsc_m2m_opened(gsc)) { + !gsc_m2m_active(gsc)) { spin_unlock_irqrestore(&gsc->slock, flags); return 0; } diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-core.c b/trunk/drivers/media/platform/s5p-fimc/fimc-core.c index 0f513dd19f86..e3916bde45cf 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-core.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-core.c @@ -850,18 +850,16 @@ static int fimc_m2m_suspend(struct fimc_dev *fimc) static int fimc_m2m_resume(struct fimc_dev *fimc) { - struct fimc_ctx *ctx; unsigned long flags; spin_lock_irqsave(&fimc->slock, flags); /* Clear for full H/W setup in first run after resume */ - ctx = fimc->m2m.ctx; fimc->m2m.ctx = NULL; spin_unlock_irqrestore(&fimc->slock, flags); if (test_and_clear_bit(ST_M2M_SUSPENDED, &fimc->state)) - fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); - + fimc_m2m_job_finish(fimc->m2m.ctx, + VB2_BUF_STATE_ERROR); return 0; } diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-lite-reg.c b/trunk/drivers/media/platform/s5p-fimc/fimc-lite-reg.c index ac9663ce2a49..f0af0754a7b4 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-lite-reg.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-lite-reg.c @@ -128,10 +128,10 @@ static const u32 src_pixfmt_map[8][3] = { void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f) { enum v4l2_mbus_pixelcode pixelcode = dev->fmt->mbus_code; - int i = ARRAY_SIZE(src_pixfmt_map); + unsigned int i = ARRAY_SIZE(src_pixfmt_map); u32 cfg; - while (--i >= 0) { + while (i-- >= 0) { if (src_pixfmt_map[i][0] == pixelcode) break; } @@ -224,9 +224,9 @@ static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f) { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY }, }; u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT); - int i = ARRAY_SIZE(pixcode); + unsigned int i = ARRAY_SIZE(pixcode); - while (--i >= 0) + while (i-- >= 0) if (pixcode[i][0] == dev->fmt->mbus_code) break; cfg &= ~FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK; diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c b/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c index bbc35de7db27..bfc4206935c8 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c @@ -1408,7 +1408,6 @@ static const struct v4l2_ctrl_config fimc_lite_ctrl = { .id = V4L2_CTRL_CLASS_USER | 0x1001, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Test Pattern 640x480", - .step = 1, }; static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc) diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c index cd38d708ab58..a17fcb2d5d41 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -827,7 +827,7 @@ static int fimc_md_link_notify(struct media_pad *source, struct fimc_pipeline *pipeline; struct v4l2_subdev *sd; struct mutex *lock; - int i, ret = 0; + int ret = 0; int ref_count; if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV) @@ -854,28 +854,29 @@ static int fimc_md_link_notify(struct media_pad *source, return 0; } - mutex_lock(lock); - ref_count = fimc ? fimc->vid_cap.refcnt : fimc_lite->ref_count; - if (!(flags & MEDIA_LNK_FL_ENABLED)) { - if (ref_count > 0) { - ret = __fimc_pipeline_close(pipeline); - if (!ret && fimc) - fimc_ctrls_delete(fimc->vid_cap.ctx); - } + int i; + mutex_lock(lock); + ret = __fimc_pipeline_close(pipeline); for (i = 0; i < IDX_MAX; i++) pipeline->subdevs[i] = NULL; - } else if (ref_count > 0) { - /* - * Link activation. Enable power of pipeline elements only if - * the pipeline is already in use, i.e. its video node is open. - * Recreate the controls destroyed during the link deactivation. - */ - ret = __fimc_pipeline_open(pipeline, - source->entity, true); - if (!ret && fimc) - ret = fimc_capture_ctrls_create(fimc); + if (fimc) + fimc_ctrls_delete(fimc->vid_cap.ctx); + mutex_unlock(lock); + return ret; } + /* + * Link activation. Enable power of pipeline elements only if the + * pipeline is already in use, i.e. its video node is opened. + * Recreate the controls destroyed during the link deactivation. + */ + mutex_lock(lock); + + ref_count = fimc ? fimc->vid_cap.refcnt : fimc_lite->ref_count; + if (ref_count > 0) + ret = __fimc_pipeline_open(pipeline, source->entity, true); + if (!ret && fimc) + ret = fimc_capture_ctrls_create(fimc); mutex_unlock(lock); return ret ? -EPIPE : ret; diff --git a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c index 1cb6d57987c6..e84703c314ce 100644 --- a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -276,7 +276,7 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err) unsigned int frame_type; dspl_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_y_adr, dev); - frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_disp_frame_type, ctx); + frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev); /* If frame is same as previous then skip and do not dequeue */ if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) { diff --git a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 4f6b553c4b2d..2356fd52a169 100644 --- a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -232,7 +232,6 @@ static struct mfc_control controls[] = { .minimum = 0, .maximum = 1, .default_value = 0, - .step = 1, .menu_skip_mask = 0, }, { diff --git a/trunk/drivers/media/radio/radio-ma901.c b/trunk/drivers/media/radio/radio-ma901.c index 348dafc0318a..c61f590029ad 100644 --- a/trunk/drivers/media/radio/radio-ma901.c +++ b/trunk/drivers/media/radio/radio-ma901.c @@ -347,20 +347,9 @@ static void usb_ma901radio_release(struct v4l2_device *v4l2_dev) static int usb_ma901radio_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *dev = interface_to_usbdev(intf); struct ma901radio_device *radio; int retval = 0; - /* Masterkit MA901 usb radio has the same USB ID as many others - * Atmel V-USB devices. Let's make additional checks to be sure - * that this is our device. - */ - - if (dev->product && dev->manufacturer && - (strncmp(dev->product, "MA901", 5) != 0 - || strncmp(dev->manufacturer, "www.masterkit.ru", 16) != 0)) - return -ENODEV; - radio = kzalloc(sizeof(struct ma901radio_device), GFP_KERNEL); if (!radio) { dev_err(&intf->dev, "kzalloc for ma901radio_device failed\n"); diff --git a/trunk/drivers/media/rc/Kconfig b/trunk/drivers/media/rc/Kconfig index 5a79c333d45e..19f3563c61da 100644 --- a/trunk/drivers/media/rc/Kconfig +++ b/trunk/drivers/media/rc/Kconfig @@ -291,7 +291,7 @@ config IR_TTUSBIR config IR_RX51 tristate "Nokia N900 IR transmitter diode" - depends on OMAP_DM_TIMER && ARCH_OMAP2PLUS && LIRC && !ARCH_MULTIPLATFORM + depends on OMAP_DM_TIMER && LIRC && !ARCH_MULTIPLATFORM ---help--- Say Y or M here if you want to enable support for the IR transmitter diode built in the Nokia N900 (RX51) device. diff --git a/trunk/drivers/media/v4l2-core/Makefile b/trunk/drivers/media/v4l2-core/Makefile index 768aaf62d5dc..a9d355230e8e 100644 --- a/trunk/drivers/media/v4l2-core/Makefile +++ b/trunk/drivers/media/v4l2-core/Makefile @@ -10,7 +10,7 @@ ifeq ($(CONFIG_COMPAT),y) videodev-objs += v4l2-compat-ioctl32.o endif -obj-$(CONFIG_VIDEO_V4L2) += videodev.o +obj-$(CONFIG_VIDEO_DEV) += videodev.o obj-$(CONFIG_VIDEO_V4L2_INT_DEVICE) += v4l2-int-device.o obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o diff --git a/trunk/drivers/memory/emif.c b/trunk/drivers/memory/emif.c index cadf1cc19aaf..df0873694858 100644 --- a/trunk/drivers/memory/emif.c +++ b/trunk/drivers/memory/emif.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "emif.h" #include "of_memory.h" @@ -257,41 +256,6 @@ static void set_lpmode(struct emif_data *emif, u8 lpmode) u32 temp; void __iomem *base = emif->base; - /* - * Workaround for errata i743 - LPDDR2 Power-Down State is Not - * Efficient - * - * i743 DESCRIPTION: - * The EMIF supports power-down state for low power. The EMIF - * automatically puts the SDRAM into power-down after the memory is - * not accessed for a defined number of cycles and the - * EMIF_PWR_MGMT_CTRL[10:8] REG_LP_MODE bit field is set to 0x4. - * As the EMIF supports automatic output impedance calibration, a ZQ - * calibration long command is issued every time it exits active - * power-down and precharge power-down modes. The EMIF waits and - * blocks any other command during this calibration. - * The EMIF does not allow selective disabling of ZQ calibration upon - * exit of power-down mode. Due to very short periods of power-down - * cycles, ZQ calibration overhead creates bandwidth issues and - * increases overall system power consumption. On the other hand, - * issuing ZQ calibration long commands when exiting self-refresh is - * still required. - * - * WORKAROUND - * Because there is no power consumption benefit of the power-down due - * to the calibration and there is a performance risk, the guideline - * is to not allow power-down state and, therefore, to not have set - * the EMIF_PWR_MGMT_CTRL[10:8] REG_LP_MODE bit field to 0x4. - */ - if ((emif->plat_data->ip_rev == EMIF_4D) && - (EMIF_LP_MODE_PWR_DN == lpmode)) { - WARN_ONCE(1, - "REG_LP_MODE = LP_MODE_PWR_DN(4) is prohibited by" - "erratum i743 switch to LP_MODE_SELF_REFRESH(2)\n"); - /* rollback LP_MODE to Self-refresh mode */ - lpmode = EMIF_LP_MODE_SELF_REFRESH; - } - temp = readl(base + EMIF_POWER_MANAGEMENT_CONTROL); temp &= ~LP_MODE_MASK; temp |= (lpmode << LP_MODE_SHIFT); @@ -751,8 +715,6 @@ static u32 get_pwr_mgmt_ctrl(u32 freq, struct emif_data *emif, u32 ip_rev) u32 timeout_perf = EMIF_LP_MODE_TIMEOUT_PERFORMANCE; u32 timeout_pwr = EMIF_LP_MODE_TIMEOUT_POWER; u32 freq_threshold = EMIF_LP_MODE_FREQ_THRESHOLD; - u32 mask; - u8 shift; struct emif_custom_configs *cust_cfgs = emif->plat_data->custom_configs; @@ -766,59 +728,37 @@ static u32 get_pwr_mgmt_ctrl(u32 freq, struct emif_data *emif, u32 ip_rev) /* Timeout based on DDR frequency */ timeout = freq >= freq_threshold ? timeout_perf : timeout_pwr; - /* - * The value to be set in register is "log2(timeout) - 3" - * if timeout < 16 load 0 in register - * if timeout is not a power of 2, round to next highest power of 2 - */ + /* The value to be set in register is "log2(timeout) - 3" */ if (timeout < 16) { timeout = 0; } else { - if (timeout & (timeout - 1)) - timeout <<= 1; timeout = __fls(timeout) - 3; + if (timeout & (timeout - 1)) + timeout++; } switch (lpmode) { case EMIF_LP_MODE_CLOCK_STOP: - shift = CS_TIM_SHIFT; - mask = CS_TIM_MASK; + pwr_mgmt_ctrl = (timeout << CS_TIM_SHIFT) | + SR_TIM_MASK | PD_TIM_MASK; break; case EMIF_LP_MODE_SELF_REFRESH: /* Workaround for errata i735 */ if (timeout < 6) timeout = 6; - shift = SR_TIM_SHIFT; - mask = SR_TIM_MASK; + pwr_mgmt_ctrl = (timeout << SR_TIM_SHIFT) | + CS_TIM_MASK | PD_TIM_MASK; break; case EMIF_LP_MODE_PWR_DN: - shift = PD_TIM_SHIFT; - mask = PD_TIM_MASK; + pwr_mgmt_ctrl = (timeout << PD_TIM_SHIFT) | + CS_TIM_MASK | SR_TIM_MASK; break; case EMIF_LP_MODE_DISABLE: default: - mask = 0; - shift = 0; - break; + pwr_mgmt_ctrl = CS_TIM_MASK | + PD_TIM_MASK | SR_TIM_MASK; } - /* Round to maximum in case of overflow, BUT warn! */ - if (lpmode != EMIF_LP_MODE_DISABLE && timeout > mask >> shift) { - pr_err("TIMEOUT Overflow - lpmode=%d perf=%d pwr=%d freq=%d\n", - lpmode, - timeout_perf, - timeout_pwr, - freq_threshold); - WARN(1, "timeout=0x%02x greater than 0x%02x. Using max\n", - timeout, mask >> shift); - timeout = mask >> shift; - } - - /* Setup required timing */ - pwr_mgmt_ctrl = (timeout << shift) & mask; - /* setup a default mask for rest of the modes */ - pwr_mgmt_ctrl |= (SR_TIM_MASK | CS_TIM_MASK | PD_TIM_MASK) & - ~mask; /* No CS_TIM in EMIF_4D5 */ if (ip_rev == EMIF_4D5) @@ -875,8 +815,6 @@ static void setup_registers(struct emif_data *emif, struct emif_regs *regs) writel(regs->sdram_tim2_shdw, base + EMIF_SDRAM_TIMING_2_SHDW); writel(regs->phy_ctrl_1_shdw, base + EMIF_DDR_PHY_CTRL_1_SHDW); - writel(regs->pwr_mgmt_ctrl_shdw, - base + EMIF_POWER_MANAGEMENT_CTRL_SHDW); /* Settings specific for EMIF4D5 */ if (emif->plat_data->ip_rev != EMIF_4D5) @@ -954,7 +892,6 @@ static irqreturn_t handle_temp_alert(void __iomem *base, struct emif_data *emif) { u32 old_temp_level; irqreturn_t ret = IRQ_HANDLED; - struct emif_custom_configs *custom_configs; spin_lock_irqsave(&emif_lock, irq_state); old_temp_level = emif->temperature_level; @@ -967,29 +904,6 @@ static irqreturn_t handle_temp_alert(void __iomem *base, struct emif_data *emif) goto out; } - custom_configs = emif->plat_data->custom_configs; - - /* - * IF we detect higher than "nominal rating" from DDR sensor - * on an unsupported DDR part, shutdown system - */ - if (custom_configs && !(custom_configs->mask & - EMIF_CUSTOM_CONFIG_EXTENDED_TEMP_PART)) { - if (emif->temperature_level >= SDRAM_TEMP_HIGH_DERATE_REFRESH) { - dev_err(emif->dev, - "%s:NOT Extended temperature capable memory." - "Converting MR4=0x%02x as shutdown event\n", - __func__, emif->temperature_level); - /* - * Temperature far too high - do kernel_power_off() - * from thread context - */ - emif->temperature_level = SDRAM_TEMP_VERY_HIGH_SHUTDOWN; - ret = IRQ_WAKE_THREAD; - goto out; - } - } - if (emif->temperature_level < old_temp_level || emif->temperature_level == SDRAM_TEMP_VERY_HIGH_SHUTDOWN) { /* @@ -1051,14 +965,7 @@ static irqreturn_t emif_threaded_isr(int irq, void *dev_id) if (emif->temperature_level == SDRAM_TEMP_VERY_HIGH_SHUTDOWN) { dev_emerg(emif->dev, "SDRAM temperature exceeds operating limit.. Needs shut down!!!\n"); - - /* If we have Power OFF ability, use it, else try restarting */ - if (pm_power_off) { - kernel_power_off(); - } else { - WARN(1, "FIXME: NO pm_power_off!!! trying restart\n"); - kernel_restart("SDRAM Over-temp Emergency restart"); - } + kernel_power_off(); return IRQ_HANDLED; } @@ -1263,7 +1170,7 @@ static void __init_or_module of_get_custom_configs(struct device_node *np_emif, { struct emif_custom_configs *cust_cfgs = NULL; int len; - const __be32 *lpmode, *poll_intvl; + const int *lpmode, *poll_intvl; lpmode = of_get_property(np_emif, "low-power-mode", &len); poll_intvl = of_get_property(np_emif, "temp-alert-poll-interval", &len); @@ -1277,7 +1184,7 @@ static void __init_or_module of_get_custom_configs(struct device_node *np_emif, if (lpmode) { cust_cfgs->mask |= EMIF_CUSTOM_CONFIG_LPMODE; - cust_cfgs->lpmode = be32_to_cpup(lpmode); + cust_cfgs->lpmode = *lpmode; of_property_read_u32(np_emif, "low-power-mode-timeout-performance", &cust_cfgs->lpmode_timeout_performance); @@ -1292,13 +1199,9 @@ static void __init_or_module of_get_custom_configs(struct device_node *np_emif, if (poll_intvl) { cust_cfgs->mask |= EMIF_CUSTOM_CONFIG_TEMP_ALERT_POLL_INTERVAL; - cust_cfgs->temp_alert_poll_interval_ms = - be32_to_cpup(poll_intvl); + cust_cfgs->temp_alert_poll_interval_ms = *poll_intvl; } - if (of_find_property(np_emif, "extended-temp-part", &len)) - cust_cfgs->mask |= EMIF_CUSTOM_CONFIG_EXTENDED_TEMP_PART; - if (!is_custom_config_valid(cust_cfgs, emif->dev)) { devm_kfree(emif->dev, cust_cfgs); return; @@ -1504,7 +1407,7 @@ static struct emif_data *__init_or_module get_device_details( if (pd->timings) { temp = devm_kzalloc(dev, size, GFP_KERNEL); if (temp) { - memcpy(temp, pd->timings, size); + memcpy(temp, pd->timings, sizeof(*pd->timings)); pd->timings = temp; } else { dev_warn(dev, "%s:%d: allocation error\n", __func__, @@ -1938,8 +1841,18 @@ static struct platform_driver emif_driver = { }, }; -module_platform_driver_probe(emif_driver, emif_probe); +static int __init_or_module emif_register(void) +{ + return platform_driver_probe(&emif_driver, emif_probe); +} + +static void __exit emif_unregister(void) +{ + platform_driver_unregister(&emif_driver); +} +module_init(emif_register); +module_exit(emif_unregister); MODULE_DESCRIPTION("TI EMIF SDRAM Controller Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:emif"); diff --git a/trunk/drivers/memory/tegra30-mc.c b/trunk/drivers/memory/tegra30-mc.c index f4ae074badc3..0b975986777d 100644 --- a/trunk/drivers/memory/tegra30-mc.c +++ b/trunk/drivers/memory/tegra30-mc.c @@ -268,7 +268,6 @@ static const u32 tegra30_mc_ctx[] = { MC_INTMASK, }; -#ifdef CONFIG_PM static int tegra30_mc_suspend(struct device *dev) { int i; @@ -292,7 +291,6 @@ static int tegra30_mc_resume(struct device *dev) mc_readl(mc, MC_TIMING_CONTROL); return 0; } -#endif static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm, tegra30_mc_suspend, diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index ca86581d02ce..671f5b171c73 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -858,7 +858,6 @@ config EZX_PCAP config AB8500_CORE bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" depends on GENERIC_HARDIRQS && ABX500_CORE && MFD_DB8500_PRCMU - select POWER_SUPPLY select MFD_CORE select IRQ_DOMAIN help @@ -991,7 +990,7 @@ config MFD_PM8XXX config MFD_PM8921_CORE tristate "Qualcomm PM8921 PMIC chip" - depends on SSBI && BROKEN + depends on MSM_SSBI select MFD_CORE select MFD_PM8XXX help diff --git a/trunk/drivers/mfd/ab8500-gpadc.c b/trunk/drivers/mfd/ab8500-gpadc.c index 5f341a50ee5a..b1f3561b023f 100644 --- a/trunk/drivers/mfd/ab8500-gpadc.c +++ b/trunk/drivers/mfd/ab8500-gpadc.c @@ -594,12 +594,9 @@ static int ab8500_gpadc_runtime_suspend(struct device *dev) static int ab8500_gpadc_runtime_resume(struct device *dev) { struct ab8500_gpadc *gpadc = dev_get_drvdata(dev); - int ret; - ret = regulator_enable(gpadc->regu); - if (ret) - dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret); - return ret; + regulator_enable(gpadc->regu); + return 0; } static int ab8500_gpadc_runtime_idle(struct device *dev) @@ -646,7 +643,7 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) } /* VTVout LDO used to power up ab8500-GPADC */ - gpadc->regu = devm_regulator_get(&pdev->dev, "vddadc"); + gpadc->regu = regulator_get(&pdev->dev, "vddadc"); if (IS_ERR(gpadc->regu)) { ret = PTR_ERR(gpadc->regu); dev_err(gpadc->dev, "failed to get vtvout LDO\n"); @@ -655,11 +652,7 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpadc); - ret = regulator_enable(gpadc->regu); - if (ret) { - dev_err(gpadc->dev, "Failed to enable vtvout LDO: %d\n", ret); - goto fail_enable; - } + regulator_enable(gpadc->regu); pm_runtime_set_autosuspend_delay(gpadc->dev, GPADC_AUDOSUSPEND_DELAY); pm_runtime_use_autosuspend(gpadc->dev); @@ -670,8 +663,6 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) list_add_tail(&gpadc->node, &ab8500_gpadc_list); dev_dbg(gpadc->dev, "probe success\n"); return 0; - -fail_enable: fail_irq: free_irq(gpadc->irq, gpadc); fail: diff --git a/trunk/drivers/mfd/omap-usb-host.c b/trunk/drivers/mfd/omap-usb-host.c index 4febc5c7fdee..6b5edf64de2b 100644 --- a/trunk/drivers/mfd/omap-usb-host.c +++ b/trunk/drivers/mfd/omap-usb-host.c @@ -460,15 +460,15 @@ static void omap_usbhs_init(struct device *dev) switch (omap->usbhs_rev) { case OMAP_USBHS_REV1: - reg = omap_usbhs_rev1_hostconfig(omap, reg); + omap_usbhs_rev1_hostconfig(omap, reg); break; case OMAP_USBHS_REV2: - reg = omap_usbhs_rev2_hostconfig(omap, reg); + omap_usbhs_rev2_hostconfig(omap, reg); break; default: /* newer revisions */ - reg = omap_usbhs_rev2_hostconfig(omap, reg); + omap_usbhs_rev2_hostconfig(omap, reg); break; } diff --git a/trunk/drivers/mfd/palmas.c b/trunk/drivers/mfd/palmas.c index 73bf76df1044..bbdbc50a3cca 100644 --- a/trunk/drivers/mfd/palmas.c +++ b/trunk/drivers/mfd/palmas.c @@ -257,24 +257,9 @@ static struct regmap_irq_chip palmas_irq_chip = { PALMAS_INT1_MASK), }; -static int palmas_set_pdata_irq_flag(struct i2c_client *i2c, +static void palmas_dt_to_pdata(struct device_node *node, struct palmas_platform_data *pdata) { - struct irq_data *irq_data = irq_get_irq_data(i2c->irq); - if (!irq_data) { - dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq); - return -EINVAL; - } - - pdata->irq_flags = irqd_get_trigger_type(irq_data); - dev_info(&i2c->dev, "Irq flag is 0x%08x\n", pdata->irq_flags); - return 0; -} - -static void palmas_dt_to_pdata(struct i2c_client *i2c, - struct palmas_platform_data *pdata) -{ - struct device_node *node = i2c->dev.of_node; int ret; u32 prop; @@ -298,8 +283,6 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c, pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK | PALMAS_POWER_CTRL_ENABLE1_MASK | PALMAS_POWER_CTRL_ENABLE2_MASK; - if (i2c->irq) - palmas_set_pdata_irq_flag(i2c, pdata); } static int palmas_i2c_probe(struct i2c_client *i2c, @@ -321,7 +304,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c, if (!pdata) return -ENOMEM; - palmas_dt_to_pdata(i2c, pdata); + palmas_dt_to_pdata(node, pdata); } if (!pdata) @@ -361,19 +344,6 @@ static int palmas_i2c_probe(struct i2c_client *i2c, } } - /* Change interrupt line output polarity */ - if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH) - reg = PALMAS_POLARITY_CTRL_INT_POLARITY; - else - reg = 0; - ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE, - PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY, - reg); - if (ret < 0) { - dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret); - goto err; - } - /* Change IRQ into clear on read mode for efficiency */ slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); @@ -382,7 +352,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c, regmap_write(palmas->regmap[slave], addr, reg); ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, - IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip, + IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip, &palmas->irq_data); if (ret < 0) goto err; diff --git a/trunk/drivers/mfd/pm8921-core.c b/trunk/drivers/mfd/pm8921-core.c index ecc137ffa8c3..d4b297cbd801 100644 --- a/trunk/drivers/mfd/pm8921-core.c +++ b/trunk/drivers/mfd/pm8921-core.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -35,7 +35,7 @@ static int pm8921_readb(const struct device *dev, u16 addr, u8 *val) const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - return ssbi_read(pmic->dev->parent, addr, val, 1); + return msm_ssbi_read(pmic->dev->parent, addr, val, 1); } static int pm8921_writeb(const struct device *dev, u16 addr, u8 val) @@ -43,7 +43,7 @@ static int pm8921_writeb(const struct device *dev, u16 addr, u8 val) const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - return ssbi_write(pmic->dev->parent, addr, &val, 1); + return msm_ssbi_write(pmic->dev->parent, addr, &val, 1); } static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf, @@ -52,7 +52,7 @@ static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf, const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - return ssbi_read(pmic->dev->parent, addr, buf, cnt); + return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt); } static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf, @@ -61,7 +61,7 @@ static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf, const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; - return ssbi_write(pmic->dev->parent, addr, buf, cnt); + return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt); } static int pm8921_read_irq_stat(const struct device *dev, int irq) @@ -124,7 +124,7 @@ static int pm8921_probe(struct platform_device *pdev) } /* Read PMIC chip revision */ - rc = ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val)); + rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val)); if (rc) { pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc); goto err_read_rev; @@ -133,7 +133,7 @@ static int pm8921_probe(struct platform_device *pdev) rev = val; /* Read PMIC chip revision 2 */ - rc = ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val)); + rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val)); if (rc) { pr_err("Failed to read hw rev 2 reg %d:rc=%d\n", REG_HWREV_2, rc); diff --git a/trunk/drivers/mfd/tps65912-core.c b/trunk/drivers/mfd/tps65912-core.c index aeb8e40ab424..4658b5bdcd84 100644 --- a/trunk/drivers/mfd/tps65912-core.c +++ b/trunk/drivers/mfd/tps65912-core.c @@ -169,7 +169,6 @@ int tps65912_device_init(struct tps65912 *tps65912) void tps65912_device_exit(struct tps65912 *tps65912) { mfd_remove_devices(tps65912->dev); - tps65912_irq_exit(tps65912); kfree(tps65912); } diff --git a/trunk/drivers/mfd/twl4030-audio.c b/trunk/drivers/mfd/twl4030-audio.c index d2ab222138c2..e16edca92670 100644 --- a/trunk/drivers/mfd/twl4030-audio.c +++ b/trunk/drivers/mfd/twl4030-audio.c @@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(twl4030_audio_enable_resource); * Disable the resource. * The function returns with error or the content of the register */ -int twl4030_audio_disable_resource(enum twl4030_audio_res id) +int twl4030_audio_disable_resource(unsigned id) { struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev); int val; diff --git a/trunk/drivers/mfd/twl4030-madc.c b/trunk/drivers/mfd/twl4030-madc.c index 942b666a2a07..88ff9dc83305 100644 --- a/trunk/drivers/mfd/twl4030-madc.c +++ b/trunk/drivers/mfd/twl4030-madc.c @@ -800,7 +800,7 @@ static int twl4030_madc_remove(struct platform_device *pdev) static struct platform_driver twl4030_madc_driver = { .probe = twl4030_madc_probe, - .remove = twl4030_madc_remove, + .remove = __exit_p(twl4030_madc_remove), .driver = { .name = "twl4030_madc", .owner = THIS_MODULE, diff --git a/trunk/drivers/mfd/wm5102-tables.c b/trunk/drivers/mfd/wm5102-tables.c index ca2aed6bc830..a433f580aa4c 100644 --- a/trunk/drivers/mfd/wm5102-tables.c +++ b/trunk/drivers/mfd/wm5102-tables.c @@ -331,10 +331,6 @@ static const struct reg_default wm5102_reg_default[] = { { 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */ { 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */ { 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */ - { 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */ - { 0x000002A7, 0x372C }, /* R679 - Mic Detect Level 2 */ - { 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */ - { 0x000002A9, 0x030A }, /* R681 - Mic Detect Level 4 */ { 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */ { 0x000002CB, 0x0000 }, /* R715 - Isolation control */ { 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */ @@ -1094,10 +1090,6 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) case ARIZONA_MIC_DETECT_1: case ARIZONA_MIC_DETECT_2: case ARIZONA_MIC_DETECT_3: - case ARIZONA_MIC_DETECT_LEVEL_1: - case ARIZONA_MIC_DETECT_LEVEL_2: - case ARIZONA_MIC_DETECT_LEVEL_3: - case ARIZONA_MIC_DETECT_LEVEL_4: case ARIZONA_MIC_NOISE_MIX_CONTROL_1: case ARIZONA_ISOLATION_CONTROL: case ARIZONA_JACK_DETECT_ANALOGUE: diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index e29e7980a359..e83fdfe0c8ca 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -93,14 +93,6 @@ config ATMEL_TCB_CLKSRC_BLOCK TC can be used for other purposes, such as PWM generation and interval timing. -config DUMMY_IRQ - tristate "Dummy IRQ handler" - default n - ---help--- - This module accepts a single 'irq' parameter, which it should register for. - The sole purpose of this module is to help with debugging of systems on - which spurious IRQs would happen on disabled IRQ vector. - config IBM_ASM tristate "Device driver for IBM RSA service processor" depends on X86 && PCI && INPUT @@ -406,7 +398,7 @@ config DS1682 config SPEAR13XX_PCIE_GADGET bool "PCIe gadget support for SPEAr13XX platform" - depends on ARCH_SPEAR13XX && BROKEN + depends on ARCH_SPEAR13XX default n help This option enables gadget support for PCIe controller. If diff --git a/trunk/drivers/misc/Makefile b/trunk/drivers/misc/Makefile index 865cbc6a7ae1..35a1463c72d9 100644 --- a/trunk/drivers/misc/Makefile +++ b/trunk/drivers/misc/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o obj-$(CONFIG_BMP085) += bmp085.o obj-$(CONFIG_BMP085_I2C) += bmp085-i2c.o obj-$(CONFIG_BMP085_SPI) += bmp085-spi.o -obj-$(CONFIG_DUMMY_IRQ) += dummy-irq.o obj-$(CONFIG_ICS932S401) += ics932s401.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o @@ -50,5 +49,6 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_INTEL_MEI) += mei/ +obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o diff --git a/trunk/drivers/misc/apds9802als.c b/trunk/drivers/misc/apds9802als.c index 5b5fd8416b3e..d648b0893027 100644 --- a/trunk/drivers/misc/apds9802als.c +++ b/trunk/drivers/misc/apds9802als.c @@ -272,8 +272,19 @@ static int apds9802als_remove(struct i2c_client *client) } #ifdef CONFIG_PM +static int apds9802als_suspend(struct i2c_client *client, pm_message_t mesg) +{ + als_set_power_state(client, false); + return 0; +} + +static int apds9802als_resume(struct i2c_client *client) +{ + als_set_default_config(client); + return 0; +} -static int apds9802als_suspend(struct device *dev) +static int apds9802als_runtime_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -281,7 +292,7 @@ static int apds9802als_suspend(struct device *dev) return 0; } -static int apds9802als_resume(struct device *dev) +static int apds9802als_runtime_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -289,12 +300,16 @@ static int apds9802als_resume(struct device *dev) return 0; } -static UNIVERSAL_DEV_PM_OPS(apds9802als_pm_ops, apds9802als_suspend, - apds9802als_resume, NULL); +static const struct dev_pm_ops apds9802als_pm_ops = { + .runtime_suspend = apds9802als_runtime_suspend, + .runtime_resume = apds9802als_runtime_resume, +}; #define APDS9802ALS_PM_OPS (&apds9802als_pm_ops) #else /* CONFIG_PM */ +#define apds9802als_suspend NULL +#define apds9802als_resume NULL #define APDS9802ALS_PM_OPS NULL #endif /* CONFIG_PM */ @@ -312,6 +327,8 @@ static struct i2c_driver apds9802als_driver = { }, .probe = apds9802als_probe, .remove = apds9802als_remove, + .suspend = apds9802als_suspend, + .resume = apds9802als_resume, .id_table = apds9802als_id, }; diff --git a/trunk/drivers/misc/apds990x.c b/trunk/drivers/misc/apds990x.c index 98f9bb26492a..0e67f8263cd8 100644 --- a/trunk/drivers/misc/apds990x.c +++ b/trunk/drivers/misc/apds990x.c @@ -700,6 +700,9 @@ static ssize_t apds990x_lux_calib_store(struct device *dev, if (strict_strtoul(buf, 0, &value)) return -EINVAL; + if (chip->lux_calib > APDS_RANGE) + return -EINVAL; + chip->lux_calib = value; return len; @@ -1201,7 +1204,7 @@ static int apds990x_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int apds990x_suspend(struct device *dev) { struct i2c_client *client = container_of(dev, struct i2c_client, dev); @@ -1224,6 +1227,10 @@ static int apds990x_resume(struct device *dev) return 0; } +#else +#define apds990x_suspend NULL +#define apds990x_resume NULL +#define apds990x_shutdown NULL #endif #ifdef CONFIG_PM_RUNTIME diff --git a/trunk/drivers/misc/arm-charlcd.c b/trunk/drivers/misc/arm-charlcd.c index 48651ef0028c..fe8616a8d287 100644 --- a/trunk/drivers/misc/arm-charlcd.c +++ b/trunk/drivers/misc/arm-charlcd.c @@ -378,7 +378,18 @@ static struct platform_driver charlcd_driver = { .remove = __exit_p(charlcd_remove), }; -module_platform_driver_probe(charlcd_driver, charlcd_probe); +static int __init charlcd_init(void) +{ + return platform_driver_probe(&charlcd_driver, charlcd_probe); +} + +static void __exit charlcd_exit(void) +{ + platform_driver_unregister(&charlcd_driver); +} + +module_init(charlcd_init); +module_exit(charlcd_exit); MODULE_AUTHOR("Linus Walleij "); MODULE_DESCRIPTION("ARM Character LCD Driver"); diff --git a/trunk/drivers/misc/atmel_pwm.c b/trunk/drivers/misc/atmel_pwm.c index 494d0500bda6..28f5aaa19d4a 100644 --- a/trunk/drivers/misc/atmel_pwm.c +++ b/trunk/drivers/misc/atmel_pwm.c @@ -393,7 +393,17 @@ static struct platform_driver atmel_pwm_driver = { */ }; -module_platform_driver_probe(atmel_pwm_driver, pwm_probe); +static int __init pwm_init(void) +{ + return platform_driver_probe(&atmel_pwm_driver, pwm_probe); +} +module_init(pwm_init); + +static void __exit pwm_exit(void) +{ + platform_driver_unregister(&atmel_pwm_driver); +} +module_exit(pwm_exit); MODULE_DESCRIPTION("Driver for AT32/AT91 PWM module"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/misc/bh1770glc.c b/trunk/drivers/misc/bh1770glc.c index f4975f7d0d5b..2ed8fc3be7e6 100644 --- a/trunk/drivers/misc/bh1770glc.c +++ b/trunk/drivers/misc/bh1770glc.c @@ -1310,7 +1310,7 @@ static int bh1770_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int bh1770_suspend(struct device *dev) { struct i2c_client *client = container_of(dev, struct i2c_client, dev); @@ -1346,6 +1346,11 @@ static int bh1770_resume(struct device *dev) } return ret; } + +#else +#define bh1770_suspend NULL +#define bh1770_shutdown NULL +#define bh1770_resume NULL #endif #ifdef CONFIG_PM_RUNTIME diff --git a/trunk/drivers/misc/bh1780gli.c b/trunk/drivers/misc/bh1780gli.c index 818f3a0e62bf..cf03d0abf33e 100644 --- a/trunk/drivers/misc/bh1780gli.c +++ b/trunk/drivers/misc/bh1780gli.c @@ -196,7 +196,7 @@ static int bh1780_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int bh1780_suspend(struct device *dev) { struct bh1780_data *ddata; @@ -235,9 +235,11 @@ static int bh1780_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM_SLEEP */ - static SIMPLE_DEV_PM_OPS(bh1780_pm, bh1780_suspend, bh1780_resume); +#define BH1780_PMOPS (&bh1780_pm) +#else +#define BH1780_PMOPS NULL +#endif /* CONFIG_PM */ static const struct i2c_device_id bh1780_id[] = { { "bh1780", 0 }, @@ -250,7 +252,7 @@ static struct i2c_driver bh1780_driver = { .id_table = bh1780_id, .driver = { .name = "bh1780", - .pm = &bh1780_pm, + .pm = BH1780_PMOPS, }, }; diff --git a/trunk/drivers/misc/cs5535-mfgpt.c b/trunk/drivers/misc/cs5535-mfgpt.c index effd8c6b2b94..9858f36dad8b 100644 --- a/trunk/drivers/misc/cs5535-mfgpt.c +++ b/trunk/drivers/misc/cs5535-mfgpt.c @@ -24,11 +24,8 @@ static int mfgpt_reset_timers; module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); -MODULE_PARM_DESC(mfgptfix, "Try to reset the MFGPT timers during init; " - "required by some broken BIOSes (ie, TinyBIOS < 0.99) or kexec " - "(1 = reset the MFGPT using an undocumented bit, " - "2 = perform a soft reset by unconfiguring all timers); " - "use what works best for you."); +MODULE_PARM_DESC(mfgptfix, "Reset the MFGPT timers during init; " + "required by some broken BIOSes (ie, TinyBIOS < 0.99)."); struct cs5535_mfgpt_timer { struct cs5535_mfgpt_chip *chip; @@ -258,28 +255,6 @@ static void reset_all_timers(void) wrmsr(MSR_MFGPT_SETUP, val, dummy); } -/* - * This is another sledgehammer to reset all MFGPT timers. - * Instead of using the undocumented bit method it clears - * IRQ, NMI and RESET settings. - */ -static void soft_reset(void) -{ - int i; - struct cs5535_mfgpt_timer t; - - for (i = 0; i < MFGPT_MAX_TIMERS; i++) { - t.nr = i; - - cs5535_mfgpt_toggle_event(&t, MFGPT_CMP1, MFGPT_EVENT_RESET, 0); - cs5535_mfgpt_toggle_event(&t, MFGPT_CMP2, MFGPT_EVENT_RESET, 0); - cs5535_mfgpt_toggle_event(&t, MFGPT_CMP1, MFGPT_EVENT_NMI, 0); - cs5535_mfgpt_toggle_event(&t, MFGPT_CMP2, MFGPT_EVENT_NMI, 0); - cs5535_mfgpt_toggle_event(&t, MFGPT_CMP1, MFGPT_EVENT_IRQ, 0); - cs5535_mfgpt_toggle_event(&t, MFGPT_CMP2, MFGPT_EVENT_IRQ, 0); - } -} - /* * Check whether any MFGPTs are available for the kernel to use. In most * cases, firmware that uses AMD's VSA code will claim all timers during @@ -296,17 +271,15 @@ static int scan_timers(struct cs5535_mfgpt_chip *mfgpt) int i; /* bios workaround */ - if (mfgpt_reset_timers == 1) + if (mfgpt_reset_timers) reset_all_timers(); - else if (mfgpt_reset_timers == 2) - soft_reset(); /* just to be safe, protect this section w/ lock */ spin_lock_irqsave(&mfgpt->lock, flags); for (i = 0; i < MFGPT_MAX_TIMERS; i++) { timer.nr = i; val = cs5535_mfgpt_read(&timer, MFGPT_REG_SETUP); - if (!(val & MFGPT_SETUP_SETUP) || mfgpt_reset_timers == 2) { + if (!(val & MFGPT_SETUP_SETUP)) { __set_bit(i, mfgpt->avail); timers++; } @@ -321,12 +294,6 @@ static int cs5535_mfgpt_probe(struct platform_device *pdev) struct resource *res; int err = -EIO, t; - if (mfgpt_reset_timers < 0 || mfgpt_reset_timers > 2) { - dev_err(&pdev->dev, "Bad mfgpt_reset_timers value: %i\n", - mfgpt_reset_timers); - goto done; - } - /* There are two ways to get the MFGPT base address; one is by * fetching it from MSR_LBAR_MFGPT, the other is by reading the * PCI BAR info. The latter method is easier (especially across diff --git a/trunk/drivers/misc/dummy-irq.c b/trunk/drivers/misc/dummy-irq.c deleted file mode 100644 index 7014167e2c61..000000000000 --- a/trunk/drivers/misc/dummy-irq.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Dummy IRQ handler driver. - * - * This module only registers itself as a handler that is specified to it - * by the 'irq' parameter. - * - * The sole purpose of this module is to help with debugging of systems on - * which spurious IRQs would happen on disabled IRQ vector. - * - * Copyright (C) 2013 Jiri Kosina - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include -#include -#include - -static int irq; - -static irqreturn_t dummy_interrupt(int irq, void *dev_id) -{ - static int count = 0; - - if (count == 0) { - printk(KERN_INFO "dummy-irq: interrupt occured on IRQ %d\n", - irq); - count++; - } - - return IRQ_NONE; -} - -static int __init dummy_irq_init(void) -{ - if (request_irq(irq, &dummy_interrupt, IRQF_SHARED, "dummy_irq", &irq)) { - printk(KERN_ERR "dummy-irq: cannot register IRQ %d\n", irq); - return -EIO; - } - printk(KERN_INFO "dummy-irq: registered for IRQ %d\n", irq); - return 0; -} - -static void __exit dummy_irq_exit(void) -{ - printk(KERN_INFO "dummy-irq unloaded\n"); - free_irq(irq, &irq); -} - -module_init(dummy_irq_init); -module_exit(dummy_irq_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jiri Kosina"); -module_param(irq, uint, 0444); -MODULE_PARM_DESC(irq, "The IRQ to register for"); diff --git a/trunk/drivers/misc/eeprom/at25.c b/trunk/drivers/misc/eeprom/at25.c index ad8fd8e64937..b08cf8a08789 100644 --- a/trunk/drivers/misc/eeprom/at25.c +++ b/trunk/drivers/misc/eeprom/at25.c @@ -412,7 +412,7 @@ static int at25_probe(struct spi_device *spi) mutex_init(&at25->lock); at25->chip = chip; at25->spi = spi_dev_get(spi); - spi_set_drvdata(spi, at25); + dev_set_drvdata(&spi->dev, at25); at25->addrlen = addrlen; /* Export the EEPROM bytes through sysfs, since that's convenient. @@ -463,7 +463,7 @@ static int at25_remove(struct spi_device *spi) { struct at25_data *at25; - at25 = spi_get_drvdata(spi); + at25 = dev_get_drvdata(&spi->dev); sysfs_remove_bin_file(&spi->dev.kobj, &at25->bin); kfree(at25); return 0; diff --git a/trunk/drivers/misc/eeprom/eeprom_93xx46.c b/trunk/drivers/misc/eeprom/eeprom_93xx46.c index 94cfc1212577..a6b5d5e73485 100644 --- a/trunk/drivers/misc/eeprom/eeprom_93xx46.c +++ b/trunk/drivers/misc/eeprom/eeprom_93xx46.c @@ -363,7 +363,7 @@ static int eeprom_93xx46_probe(struct spi_device *spi) dev_err(&spi->dev, "can't create erase interface\n"); } - spi_set_drvdata(spi, edev); + dev_set_drvdata(&spi->dev, edev); return 0; fail: kfree(edev); @@ -372,13 +372,13 @@ static int eeprom_93xx46_probe(struct spi_device *spi) static int eeprom_93xx46_remove(struct spi_device *spi) { - struct eeprom_93xx46_dev *edev = spi_get_drvdata(spi); + struct eeprom_93xx46_dev *edev = dev_get_drvdata(&spi->dev); if (!(edev->pdata->flags & EE_READONLY)) device_remove_file(&spi->dev, &dev_attr_erase); sysfs_remove_bin_file(&spi->dev.kobj, &edev->bin); - spi_set_drvdata(spi, NULL); + dev_set_drvdata(&spi->dev, NULL); kfree(edev); return 0; } diff --git a/trunk/drivers/misc/ep93xx_pwm.c b/trunk/drivers/misc/ep93xx_pwm.c index 96787ec15cad..16d7179e2f9b 100644 --- a/trunk/drivers/misc/ep93xx_pwm.c +++ b/trunk/drivers/misc/ep93xx_pwm.c @@ -365,7 +365,18 @@ static struct platform_driver ep93xx_pwm_driver = { .remove = __exit_p(ep93xx_pwm_remove), }; -module_platform_driver_probe(ep93xx_pwm_driver, ep93xx_pwm_probe); +static int __init ep93xx_pwm_init(void) +{ + return platform_driver_probe(&ep93xx_pwm_driver, ep93xx_pwm_probe); +} + +static void __exit ep93xx_pwm_exit(void) +{ + platform_driver_unregister(&ep93xx_pwm_driver); +} + +module_init(ep93xx_pwm_init); +module_exit(ep93xx_pwm_exit); MODULE_AUTHOR("Matthieu Crapet , " "H Hartley Sweeten "); diff --git a/trunk/drivers/misc/fsa9480.c b/trunk/drivers/misc/fsa9480.c index a725c79c35f5..e8cbb1c59f4c 100644 --- a/trunk/drivers/misc/fsa9480.c +++ b/trunk/drivers/misc/fsa9480.c @@ -474,11 +474,10 @@ static int fsa9480_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM -static int fsa9480_suspend(struct device *dev) +static int fsa9480_suspend(struct i2c_client *client, pm_message_t state) { - struct i2c_client *client = to_i2c_client(dev); struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); struct fsa9480_platform_data *pdata = usbsw->pdata; @@ -491,9 +490,8 @@ static int fsa9480_suspend(struct device *dev) return 0; } -static int fsa9480_resume(struct device *dev) +static int fsa9480_resume(struct i2c_client *client) { - struct i2c_client *client = to_i2c_client(dev); struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); int dev1, dev2; @@ -517,14 +515,12 @@ static int fsa9480_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(fsa9480_pm_ops, fsa9480_suspend, fsa9480_resume); -#define FSA9480_PM_OPS (&fsa9480_pm_ops) - #else -#define FSA9480_PM_OPS NULL +#define fsa9480_suspend NULL +#define fsa9480_resume NULL -#endif /* CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM */ static const struct i2c_device_id fsa9480_id[] = { {"fsa9480", 0}, @@ -535,10 +531,11 @@ MODULE_DEVICE_TABLE(i2c, fsa9480_id); static struct i2c_driver fsa9480_i2c_driver = { .driver = { .name = "fsa9480", - .pm = FSA9480_PM_OPS, }, .probe = fsa9480_probe, .remove = fsa9480_remove, + .resume = fsa9480_resume, + .suspend = fsa9480_suspend, .id_table = fsa9480_id, }; diff --git a/trunk/drivers/misc/ibmasm/ibmasmfs.c b/trunk/drivers/misc/ibmasm/ibmasmfs.c index ce5b75616b45..6673e578b3e9 100644 --- a/trunk/drivers/misc/ibmasm/ibmasmfs.c +++ b/trunk/drivers/misc/ibmasm/ibmasmfs.c @@ -110,7 +110,6 @@ static struct file_system_type ibmasmfs_type = { .mount = ibmasmfs_mount, .kill_sb = kill_litter_super, }; -MODULE_ALIAS_FS("ibmasmfs"); static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent) { diff --git a/trunk/drivers/misc/isl29003.c b/trunk/drivers/misc/isl29003.c index c5145b3fcce8..29b306c6bdb3 100644 --- a/trunk/drivers/misc/isl29003.c +++ b/trunk/drivers/misc/isl29003.c @@ -409,20 +409,18 @@ static int isl29003_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int isl29003_suspend(struct device *dev) +#ifdef CONFIG_PM +static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg) { - struct i2c_client *client = to_i2c_client(dev); struct isl29003_data *data = i2c_get_clientdata(client); data->power_state_before_suspend = isl29003_get_power_state(client); return isl29003_set_power_state(client, 0); } -static int isl29003_resume(struct device *dev) +static int isl29003_resume(struct i2c_client *client) { int i; - struct i2c_client *client = to_i2c_client(dev); struct isl29003_data *data = i2c_get_clientdata(client); /* restore registers from cache */ @@ -434,12 +432,10 @@ static int isl29003_resume(struct device *dev) data->power_state_before_suspend); } -static SIMPLE_DEV_PM_OPS(isl29003_pm_ops, isl29003_suspend, isl29003_resume); -#define ISL29003_PM_OPS (&isl29003_pm_ops) - #else -#define ISL29003_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ +#define isl29003_suspend NULL +#define isl29003_resume NULL +#endif /* CONFIG_PM */ static const struct i2c_device_id isl29003_id[] = { { "isl29003", 0 }, @@ -451,8 +447,9 @@ static struct i2c_driver isl29003_driver = { .driver = { .name = ISL29003_DRV_NAME, .owner = THIS_MODULE, - .pm = ISL29003_PM_OPS, }, + .suspend = isl29003_suspend, + .resume = isl29003_resume, .probe = isl29003_probe, .remove = isl29003_remove, .id_table = isl29003_id, diff --git a/trunk/drivers/misc/lattice-ecp3-config.c b/trunk/drivers/misc/lattice-ecp3-config.c index bb26f086bd8b..155700bfd2b6 100644 --- a/trunk/drivers/misc/lattice-ecp3-config.c +++ b/trunk/drivers/misc/lattice-ecp3-config.c @@ -69,7 +69,7 @@ static const struct ecp3_dev ecp3_dev[] = { static void firmware_load(const struct firmware *fw, void *context) { struct spi_device *spi = (struct spi_device *)context; - struct fpga_data *data = spi_get_drvdata(spi); + struct fpga_data *data = dev_get_drvdata(&spi->dev); u8 *buffer; int ret; u8 txbuf[8]; diff --git a/trunk/drivers/misc/mei/Kconfig b/trunk/drivers/misc/mei/Kconfig index c76fa31e9bf6..d21b4d006a55 100644 --- a/trunk/drivers/misc/mei/Kconfig +++ b/trunk/drivers/misc/mei/Kconfig @@ -10,9 +10,10 @@ config INTEL_MEI config INTEL_MEI_ME - tristate "ME Enabled Intel Chipsets" - select INTEL_MEI + bool "ME Enabled Intel Chipsets" + depends on INTEL_MEI depends on X86 && PCI && WATCHDOG_CORE + default y help MEI support for ME Enabled Intel chipsets. diff --git a/trunk/drivers/misc/mei/Makefile b/trunk/drivers/misc/mei/Makefile index 08698a466268..040af6c7b147 100644 --- a/trunk/drivers/misc/mei/Makefile +++ b/trunk/drivers/misc/mei/Makefile @@ -10,10 +10,5 @@ mei-objs += client.o mei-objs += main.o mei-objs += amthif.o mei-objs += wd.o -mei-objs += bus.o -mei-objs += nfc.o -mei-$(CONFIG_DEBUG_FS) += debugfs.o - -obj-$(CONFIG_INTEL_MEI_ME) += mei-me.o -mei-me-objs := pci-me.o -mei-me-objs += hw-me.o +mei-$(CONFIG_INTEL_MEI_ME) += pci-me.o +mei-$(CONFIG_INTEL_MEI_ME) += hw-me.o diff --git a/trunk/drivers/misc/mei/amthif.c b/trunk/drivers/misc/mei/amthif.c index 31a6212cb8b1..c86d7e3839a4 100644 --- a/trunk/drivers/misc/mei/amthif.c +++ b/trunk/drivers/misc/mei/amthif.c @@ -449,7 +449,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, struct mei_msg_hdr mei_hdr; struct mei_cl *cl = cb->cl; size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; - u32 msg_slots = mei_data2slots(len); + size_t msg_slots = mei_data2slots(len); mei_hdr.host_addr = cl->host_client_id; mei_hdr.me_addr = cl->me_client_id; @@ -505,15 +505,14 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, * mei_amthif_irq_read_message - read routine after ISR to * handle the read amthif message * + * @complete_list: An instance of our list structure * @dev: the device structure * @mei_hdr: header of amthif message - * @complete_list: An instance of our list structure * * returns 0 on success, <0 on failure. */ -int mei_amthif_irq_read_msg(struct mei_device *dev, - struct mei_msg_hdr *mei_hdr, - struct mei_cl_cb *complete_list) +int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, + struct mei_device *dev, struct mei_msg_hdr *mei_hdr) { struct mei_cl_cb *cb; unsigned char *buffer; @@ -531,7 +530,8 @@ int mei_amthif_irq_read_msg(struct mei_device *dev, if (!mei_hdr->msg_complete) return 0; - dev_dbg(&dev->pdev->dev, "amthif_message_buffer_index =%d\n", + dev_dbg(&dev->pdev->dev, + "amthif_message_buffer_index =%d\n", mei_hdr->length); dev_dbg(&dev->pdev->dev, "completed amthif read.\n "); @@ -566,13 +566,12 @@ int mei_amthif_irq_read_msg(struct mei_device *dev, */ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) { - u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); - if (*slots < msg_slots) + if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control))) { return -EMSGSIZE; - - *slots -= msg_slots; - + } + *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); if (mei_hbm_cl_flow_control_req(dev, &dev->iamthif_cl)) { dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); return -EIO; diff --git a/trunk/drivers/misc/mei/bus.c b/trunk/drivers/misc/mei/bus.c deleted file mode 100644 index 1e935eacaa7f..000000000000 --- a/trunk/drivers/misc/mei/bus.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2012-2013, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mei_dev.h" -#include "hw-me.h" -#include "client.h" - -#define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver) -#define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev) - -static int mei_cl_device_match(struct device *dev, struct device_driver *drv) -{ - struct mei_cl_device *device = to_mei_cl_device(dev); - struct mei_cl_driver *driver = to_mei_cl_driver(drv); - const struct mei_cl_device_id *id; - - if (!device) - return 0; - - if (!driver || !driver->id_table) - return 0; - - id = driver->id_table; - - while (id->name[0]) { - if (!strcmp(dev_name(dev), id->name)) - return 1; - - id++; - } - - return 0; -} - -static int mei_cl_device_probe(struct device *dev) -{ - struct mei_cl_device *device = to_mei_cl_device(dev); - struct mei_cl_driver *driver; - struct mei_cl_device_id id; - - if (!device) - return 0; - - driver = to_mei_cl_driver(dev->driver); - if (!driver || !driver->probe) - return -ENODEV; - - dev_dbg(dev, "Device probe\n"); - - strncpy(id.name, dev_name(dev), MEI_CL_NAME_SIZE); - - return driver->probe(device, &id); -} - -static int mei_cl_device_remove(struct device *dev) -{ - struct mei_cl_device *device = to_mei_cl_device(dev); - struct mei_cl_driver *driver; - - if (!device || !dev->driver) - return 0; - - if (device->event_cb) { - device->event_cb = NULL; - cancel_work_sync(&device->event_work); - } - - driver = to_mei_cl_driver(dev->driver); - if (!driver->remove) { - dev->driver = NULL; - - return 0; - } - - return driver->remove(device); -} - -static ssize_t modalias_show(struct device *dev, struct device_attribute *a, - char *buf) -{ - int len; - - len = snprintf(buf, PAGE_SIZE, "mei:%s\n", dev_name(dev)); - - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; -} - -static struct device_attribute mei_cl_dev_attrs[] = { - __ATTR_RO(modalias), - __ATTR_NULL, -}; - -static int mei_cl_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - if (add_uevent_var(env, "MODALIAS=mei:%s", dev_name(dev))) - return -ENOMEM; - - return 0; -} - -static struct bus_type mei_cl_bus_type = { - .name = "mei", - .dev_attrs = mei_cl_dev_attrs, - .match = mei_cl_device_match, - .probe = mei_cl_device_probe, - .remove = mei_cl_device_remove, - .uevent = mei_cl_uevent, -}; - -static void mei_cl_dev_release(struct device *dev) -{ - kfree(to_mei_cl_device(dev)); -} - -static struct device_type mei_cl_device_type = { - .release = mei_cl_dev_release, -}; - -static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev, - uuid_le uuid) -{ - struct mei_cl *cl, *next; - - list_for_each_entry_safe(cl, next, &dev->device_list, device_link) { - if (!uuid_le_cmp(uuid, cl->device_uuid)) - return cl; - } - - return NULL; -} -struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, - uuid_le uuid, char *name, - struct mei_cl_ops *ops) -{ - struct mei_cl_device *device; - struct mei_cl *cl; - int status; - - cl = mei_bus_find_mei_cl_by_uuid(dev, uuid); - if (cl == NULL) - return NULL; - - device = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL); - if (!device) - return NULL; - - device->cl = cl; - device->ops = ops; - - device->dev.parent = &dev->pdev->dev; - device->dev.bus = &mei_cl_bus_type; - device->dev.type = &mei_cl_device_type; - - dev_set_name(&device->dev, "%s", name); - - status = device_register(&device->dev); - if (status) { - dev_err(&dev->pdev->dev, "Failed to register MEI device\n"); - kfree(device); - return NULL; - } - - cl->device = device; - - dev_dbg(&device->dev, "client %s registered\n", name); - - return device; -} -EXPORT_SYMBOL_GPL(mei_cl_add_device); - -void mei_cl_remove_device(struct mei_cl_device *device) -{ - device_unregister(&device->dev); -} -EXPORT_SYMBOL_GPL(mei_cl_remove_device); - -int __mei_cl_driver_register(struct mei_cl_driver *driver, struct module *owner) -{ - int err; - - driver->driver.name = driver->name; - driver->driver.owner = owner; - driver->driver.bus = &mei_cl_bus_type; - - err = driver_register(&driver->driver); - if (err) - return err; - - pr_debug("mei: driver [%s] registered\n", driver->driver.name); - - return 0; -} -EXPORT_SYMBOL_GPL(__mei_cl_driver_register); - -void mei_cl_driver_unregister(struct mei_cl_driver *driver) -{ - driver_unregister(&driver->driver); - - pr_debug("mei: driver [%s] unregistered\n", driver->driver.name); -} -EXPORT_SYMBOL_GPL(mei_cl_driver_unregister); - -static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, - bool blocking) -{ - struct mei_device *dev; - struct mei_cl_cb *cb; - int id; - int rets; - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - if (cl->state != MEI_FILE_CONNECTED) - return -ENODEV; - - /* Check if we have an ME client device */ - id = mei_me_cl_by_id(dev, cl->me_client_id); - if (id < 0) - return -ENODEV; - - if (length > dev->me_clients[id].props.max_msg_length) - return -EINVAL; - - cb = mei_io_cb_init(cl, NULL); - if (!cb) - return -ENOMEM; - - rets = mei_io_cb_alloc_req_buf(cb, length); - if (rets < 0) { - mei_io_cb_free(cb); - return rets; - } - - memcpy(cb->request_buffer.data, buf, length); - - mutex_lock(&dev->device_lock); - - rets = mei_cl_write(cl, cb, blocking); - - mutex_unlock(&dev->device_lock); - if (rets < 0) - mei_io_cb_free(cb); - - return rets; -} - -int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) -{ - struct mei_device *dev; - struct mei_cl_cb *cb; - size_t r_length; - int err; - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - - if (!cl->read_cb) { - err = mei_cl_read_start(cl, length); - if (err < 0) { - mutex_unlock(&dev->device_lock); - return err; - } - } - - if (cl->reading_state != MEI_READ_COMPLETE && - !waitqueue_active(&cl->rx_wait)) { - mutex_unlock(&dev->device_lock); - - if (wait_event_interruptible(cl->rx_wait, - (MEI_READ_COMPLETE == cl->reading_state))) { - if (signal_pending(current)) - return -EINTR; - return -ERESTARTSYS; - } - - mutex_lock(&dev->device_lock); - } - - cb = cl->read_cb; - - if (cl->reading_state != MEI_READ_COMPLETE) { - r_length = 0; - goto out; - } - - r_length = min_t(size_t, length, cb->buf_idx); - - memcpy(buf, cb->response_buffer.data, r_length); - - mei_io_cb_free(cb); - cl->reading_state = MEI_IDLE; - cl->read_cb = NULL; - -out: - mutex_unlock(&dev->device_lock); - - return r_length; -} - -inline int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length) -{ - return ___mei_cl_send(cl, buf, length, 0); -} - -inline int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length) -{ - return ___mei_cl_send(cl, buf, length, 1); -} - -int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) -{ - struct mei_cl *cl = device->cl; - - if (cl == NULL) - return -ENODEV; - - if (device->ops && device->ops->send) - return device->ops->send(device, buf, length); - - return __mei_cl_send(cl, buf, length); -} -EXPORT_SYMBOL_GPL(mei_cl_send); - -int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length) -{ - struct mei_cl *cl = device->cl; - - if (cl == NULL) - return -ENODEV; - - if (device->ops && device->ops->recv) - return device->ops->recv(device, buf, length); - - return __mei_cl_recv(cl, buf, length); -} -EXPORT_SYMBOL_GPL(mei_cl_recv); - -static void mei_bus_event_work(struct work_struct *work) -{ - struct mei_cl_device *device; - - device = container_of(work, struct mei_cl_device, event_work); - - if (device->event_cb) - device->event_cb(device, device->events, device->event_context); - - device->events = 0; - - /* Prepare for the next read */ - mei_cl_read_start(device->cl, 0); -} - -int mei_cl_register_event_cb(struct mei_cl_device *device, - mei_cl_event_cb_t event_cb, void *context) -{ - if (device->event_cb) - return -EALREADY; - - device->events = 0; - device->event_cb = event_cb; - device->event_context = context; - INIT_WORK(&device->event_work, mei_bus_event_work); - - mei_cl_read_start(device->cl, 0); - - return 0; -} -EXPORT_SYMBOL_GPL(mei_cl_register_event_cb); - -void *mei_cl_get_drvdata(const struct mei_cl_device *device) -{ - return dev_get_drvdata(&device->dev); -} -EXPORT_SYMBOL_GPL(mei_cl_get_drvdata); - -void mei_cl_set_drvdata(struct mei_cl_device *device, void *data) -{ - dev_set_drvdata(&device->dev, data); -} -EXPORT_SYMBOL_GPL(mei_cl_set_drvdata); - -int mei_cl_enable_device(struct mei_cl_device *device) -{ - int err; - struct mei_device *dev; - struct mei_cl *cl = device->cl; - - if (cl == NULL) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - - cl->state = MEI_FILE_CONNECTING; - - err = mei_cl_connect(cl, NULL); - if (err < 0) { - mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, "Could not connect to the ME client"); - - return err; - } - - mutex_unlock(&dev->device_lock); - - if (device->event_cb && !cl->read_cb) - mei_cl_read_start(device->cl, 0); - - if (!device->ops || !device->ops->enable) - return 0; - - return device->ops->enable(device); -} -EXPORT_SYMBOL_GPL(mei_cl_enable_device); - -int mei_cl_disable_device(struct mei_cl_device *device) -{ - int err; - struct mei_device *dev; - struct mei_cl *cl = device->cl; - - if (cl == NULL) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - - if (cl->state != MEI_FILE_CONNECTED) { - mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, "Already disconnected"); - - return 0; - } - - cl->state = MEI_FILE_DISCONNECTING; - - err = mei_cl_disconnect(cl); - if (err < 0) { - mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, - "Could not disconnect from the ME client"); - - return err; - } - - /* Flush queues and remove any pending read */ - mei_cl_flush_queues(cl); - - if (cl->read_cb) { - struct mei_cl_cb *cb = NULL; - - cb = mei_cl_find_read_cb(cl); - /* Remove entry from read list */ - if (cb) - list_del(&cb->list); - - cb = cl->read_cb; - cl->read_cb = NULL; - - if (cb) { - mei_io_cb_free(cb); - cb = NULL; - } - } - - mutex_unlock(&dev->device_lock); - - if (!device->ops || !device->ops->disable) - return 0; - - return device->ops->disable(device); -} -EXPORT_SYMBOL_GPL(mei_cl_disable_device); - -void mei_cl_bus_rx_event(struct mei_cl *cl) -{ - struct mei_cl_device *device = cl->device; - - if (!device || !device->event_cb) - return; - - set_bit(MEI_CL_EVENT_RX, &device->events); - - schedule_work(&device->event_work); -} - -int __init mei_cl_bus_init(void) -{ - return bus_register(&mei_cl_bus_type); -} - -void __exit mei_cl_bus_exit(void) -{ - bus_unregister(&mei_cl_bus_type); -} diff --git a/trunk/drivers/misc/mei/client.c b/trunk/drivers/misc/mei/client.c index 71892745e2e8..1569afe935de 100644 --- a/trunk/drivers/misc/mei/client.c +++ b/trunk/drivers/misc/mei/client.c @@ -216,7 +216,6 @@ void mei_cl_init(struct mei_cl *cl, struct mei_device *dev) init_waitqueue_head(&cl->rx_wait); init_waitqueue_head(&cl->tx_wait); INIT_LIST_HEAD(&cl->link); - INIT_LIST_HEAD(&cl->device_link); cl->reading_state = MEI_IDLE; cl->writing_state = MEI_IDLE; cl->dev = dev; @@ -358,9 +357,6 @@ void mei_host_client_init(struct work_struct *work) mei_amthif_host_init(dev); else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid)) mei_wd_host_init(dev); - else if (!uuid_le_cmp(client_props->protocol_name, mei_nfc_guid)) - mei_nfc_host_init(dev); - } dev->dev_state = MEI_DEV_ENABLED; @@ -624,7 +620,7 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl) * * returns 0 on success, <0 on failure. */ -int mei_cl_read_start(struct mei_cl *cl, size_t length) +int mei_cl_read_start(struct mei_cl *cl) { struct mei_device *dev; struct mei_cl_cb *cb; @@ -657,9 +653,8 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) if (!cb) return -ENOMEM; - /* always allocate at least client max message */ - length = max_t(size_t, length, dev->me_clients[i].props.max_msg_length); - rets = mei_io_cb_alloc_resp_buf(cb, length); + rets = mei_io_cb_alloc_resp_buf(cb, + dev->me_clients[i].props.max_msg_length); if (rets) goto err; @@ -681,111 +676,6 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) return rets; } -/** - * mei_cl_write - submit a write cb to mei device - assumes device_lock is locked - * - * @cl: host client - * @cl: write callback with filled data - * - * returns numbe of bytes sent on success, <0 on failure. - */ -int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) -{ - struct mei_device *dev; - struct mei_msg_data *buf; - struct mei_msg_hdr mei_hdr; - int rets; - - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - if (WARN_ON(!cb)) - return -EINVAL; - - dev = cl->dev; - - - buf = &cb->request_buffer; - - dev_dbg(&dev->pdev->dev, "mei_cl_write %d\n", buf->size); - - - cb->fop_type = MEI_FOP_WRITE; - - rets = mei_cl_flow_ctrl_creds(cl); - if (rets < 0) - goto err; - - /* Host buffer is not ready, we queue the request */ - if (rets == 0 || !dev->hbuf_is_ready) { - cb->buf_idx = 0; - /* unseting complete will enqueue the cb for write */ - mei_hdr.msg_complete = 0; - cl->writing_state = MEI_WRITING; - rets = buf->size; - goto out; - } - - dev->hbuf_is_ready = false; - - /* Check for a maximum length */ - if (buf->size > mei_hbuf_max_len(dev)) { - mei_hdr.length = mei_hbuf_max_len(dev); - mei_hdr.msg_complete = 0; - } else { - mei_hdr.length = buf->size; - mei_hdr.msg_complete = 1; - } - - mei_hdr.host_addr = cl->host_client_id; - mei_hdr.me_addr = cl->me_client_id; - mei_hdr.reserved = 0; - - dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n", - MEI_HDR_PRM(&mei_hdr)); - - - if (mei_write_message(dev, &mei_hdr, buf->data)) { - rets = -EIO; - goto err; - } - - cl->writing_state = MEI_WRITING; - cb->buf_idx = mei_hdr.length; - - rets = buf->size; -out: - if (mei_hdr.msg_complete) { - if (mei_cl_flow_ctrl_reduce(cl)) { - rets = -ENODEV; - goto err; - } - list_add_tail(&cb->list, &dev->write_waiting_list.list); - } else { - list_add_tail(&cb->list, &dev->write_list.list); - } - - - if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { - - mutex_unlock(&dev->device_lock); - if (wait_event_interruptible(cl->tx_wait, - cl->writing_state == MEI_WRITE_COMPLETE)) { - if (signal_pending(current)) - rets = -EINTR; - else - rets = -ERESTARTSYS; - } - mutex_lock(&dev->device_lock); - } -err: - return rets; -} - - - /** * mei_cl_all_disconnect - disconnect forcefully all connected clients * diff --git a/trunk/drivers/misc/mei/client.h b/trunk/drivers/misc/mei/client.h index cfdb144526aa..214b2397ec3e 100644 --- a/trunk/drivers/misc/mei/client.h +++ b/trunk/drivers/misc/mei/client.h @@ -86,16 +86,17 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl); */ bool mei_cl_is_other_connecting(struct mei_cl *cl); int mei_cl_disconnect(struct mei_cl *cl); + +int mei_cl_read_start(struct mei_cl *cl); + int mei_cl_connect(struct mei_cl *cl, struct file *file); -int mei_cl_read_start(struct mei_cl *cl, size_t length); -int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking); void mei_host_client_init(struct work_struct *work); - void mei_cl_all_disconnect(struct mei_device *dev); void mei_cl_all_read_wakeup(struct mei_device *dev); void mei_cl_all_write_clear(struct mei_device *dev); + #endif /* _MEI_CLIENT_H_ */ diff --git a/trunk/drivers/misc/mei/debugfs.c b/trunk/drivers/misc/mei/debugfs.c deleted file mode 100644 index e3870f22d238..000000000000 --- a/trunk/drivers/misc/mei/debugfs.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2012-2013, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ -#include -#include -#include -#include -#include - -#include - -#include "mei_dev.h" -#include "hw.h" - -static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - struct mei_device *dev = fp->private_data; - struct mei_me_client *cl; - const size_t bufsz = 1024; - char *buf = kzalloc(bufsz, GFP_KERNEL); - int i; - int pos = 0; - int ret; - - if (!buf) - return -ENOMEM; - - pos += scnprintf(buf + pos, bufsz - pos, - " |id|addr| UUID |con|msg len|\n"); - - mutex_lock(&dev->device_lock); - - /* if the driver is not enabled the list won't b consitent */ - if (dev->dev_state != MEI_DEV_ENABLED) - goto out; - - for (i = 0; i < dev->me_clients_num; i++) { - cl = &dev->me_clients[i]; - - /* skip me clients that cannot be connected */ - if (cl->props.max_number_of_connections == 0) - continue; - - pos += scnprintf(buf + pos, bufsz - pos, - "%2d|%2d|%4d|%pUl|%3d|%7d|\n", - i, cl->client_id, - cl->props.fixed_address, - &cl->props.protocol_name, - cl->props.max_number_of_connections, - cl->props.max_msg_length); - } -out: - mutex_unlock(&dev->device_lock); - ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos); - kfree(buf); - return ret; -} - -static const struct file_operations mei_dbgfs_fops_meclients = { - .open = simple_open, - .read = mei_dbgfs_read_meclients, - .llseek = generic_file_llseek, -}; - -static ssize_t mei_dbgfs_read_devstate(struct file *fp, char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - struct mei_device *dev = fp->private_data; - const size_t bufsz = 1024; - char *buf = kzalloc(bufsz, GFP_KERNEL); - int pos = 0; - int ret; - - if (!buf) - return -ENOMEM; - - pos += scnprintf(buf + pos, bufsz - pos, "%s\n", - mei_dev_state_str(dev->dev_state)); - ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos); - kfree(buf); - return ret; -} -static const struct file_operations mei_dbgfs_fops_devstate = { - .open = simple_open, - .read = mei_dbgfs_read_devstate, - .llseek = generic_file_llseek, -}; - -/** - * mei_dbgfs_deregister - Remove the debugfs files and directories - * @mei - pointer to mei device private dat - */ -void mei_dbgfs_deregister(struct mei_device *dev) -{ - if (!dev->dbgfs_dir) - return; - debugfs_remove_recursive(dev->dbgfs_dir); - dev->dbgfs_dir = NULL; -} - -/** - * Add the debugfs files - * - */ -int mei_dbgfs_register(struct mei_device *dev, const char *name) -{ - struct dentry *dir, *f; - dir = debugfs_create_dir(name, NULL); - if (!dir) - return -ENOMEM; - - f = debugfs_create_file("meclients", S_IRUSR, dir, - dev, &mei_dbgfs_fops_meclients); - if (!f) { - dev_err(&dev->pdev->dev, "meclients: registration failed\n"); - goto err; - } - f = debugfs_create_file("devstate", S_IRUSR, dir, - dev, &mei_dbgfs_fops_devstate); - if (!f) { - dev_err(&dev->pdev->dev, "devstate: registration failed\n"); - goto err; - } - dev->dbgfs_dir = dir; - return 0; -err: - mei_dbgfs_deregister(dev); - return -ENODEV; -} - diff --git a/trunk/drivers/misc/mei/hbm.c b/trunk/drivers/misc/mei/hbm.c index db605f5cf187..fb9e63ba3bb1 100644 --- a/trunk/drivers/misc/mei/hbm.c +++ b/trunk/drivers/misc/mei/hbm.c @@ -52,7 +52,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev) sizeof(struct mei_me_client), GFP_KERNEL); if (!clients) { dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); - dev->dev_state = MEI_DEV_RESETTING; + dev->dev_state = MEI_DEV_RESETING; mei_reset(dev, 1); return; } @@ -123,33 +123,12 @@ static bool is_treat_specially_client(struct mei_cl *cl, return false; } -int mei_hbm_start_wait(struct mei_device *dev) -{ - int ret; - if (dev->hbm_state > MEI_HBM_START) - return 0; - - mutex_unlock(&dev->device_lock); - ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, - dev->hbm_state == MEI_HBM_IDLE || - dev->hbm_state > MEI_HBM_START, - mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); - mutex_lock(&dev->device_lock); - - if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) { - dev->hbm_state = MEI_HBM_IDLE; - dev_err(&dev->pdev->dev, "wating for mei start failed\n"); - return -ETIMEDOUT; - } - return 0; -} - /** * mei_hbm_start_req - sends start request message. * * @dev: the device structure */ -int mei_hbm_start_req(struct mei_device *dev) +void mei_hbm_start_req(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; struct hbm_host_version_request *start_req; @@ -164,19 +143,18 @@ int mei_hbm_start_req(struct mei_device *dev) start_req->host_version.major_version = HBM_MAJOR_VERSION; start_req->host_version.minor_version = HBM_MINOR_VERSION; - dev->hbm_state = MEI_HBM_IDLE; + dev->recvd_msg = false; if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { - dev_err(&dev->pdev->dev, "version message writet failed\n"); - dev->dev_state = MEI_DEV_RESETTING; + dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n"); + dev->dev_state = MEI_DEV_RESETING; mei_reset(dev, 1); - return -ENODEV; } - dev->hbm_state = MEI_HBM_START; + dev->init_clients_state = MEI_START_MESSAGE; dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; - return 0; + return ; } -/* +/** * mei_hbm_enum_clients_req - sends enumeration client request message. * * @dev: the device structure @@ -196,11 +174,11 @@ static void mei_hbm_enum_clients_req(struct mei_device *dev) enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { - dev->dev_state = MEI_DEV_RESETTING; - dev_err(&dev->pdev->dev, "enumeration request write failed.\n"); + dev->dev_state = MEI_DEV_RESETING; + dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); mei_reset(dev, 1); } - dev->hbm_state = MEI_HBM_ENUM_CLIENTS; + dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; return; } @@ -230,7 +208,6 @@ static int mei_hbm_prop_req(struct mei_device *dev) /* We got all client properties */ if (next_client_index == MEI_CLIENTS_MAX) { - dev->hbm_state = MEI_HBM_STARTED; schedule_work(&dev->init_work); return 0; @@ -249,8 +226,8 @@ static int mei_hbm_prop_req(struct mei_device *dev) prop_req->address = next_client_index; if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { - dev->dev_state = MEI_DEV_RESETTING; - dev_err(&dev->pdev->dev, "properties request write failed\n"); + dev->dev_state = MEI_DEV_RESETING; + dev_err(&dev->pdev->dev, "Properties request command failed\n"); mei_reset(dev, 1); return -EIO; @@ -565,28 +542,27 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev->version = version_res->me_max_version; dev_dbg(&dev->pdev->dev, "version mismatch.\n"); - dev->hbm_state = MEI_HBM_STOP; mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, dev->wr_msg.data); mei_write_message(dev, &dev->wr_msg.hdr, dev->wr_msg.data); - return; } dev->version.major_version = HBM_MAJOR_VERSION; dev->version.minor_version = HBM_MINOR_VERSION; if (dev->dev_state == MEI_DEV_INIT_CLIENTS && - dev->hbm_state == MEI_HBM_START) { + dev->init_clients_state == MEI_START_MESSAGE) { dev->init_clients_timer = 0; mei_hbm_enum_clients_req(dev); } else { - dev_err(&dev->pdev->dev, "reset: wrong host start response\n"); + dev->recvd_msg = false; + dev_dbg(&dev->pdev->dev, "reset due to received hbm: host start\n"); mei_reset(dev, 1); return; } - wake_up_interruptible(&dev->wait_recvd_msg); + dev->recvd_msg = true; dev_dbg(&dev->pdev->dev, "host start response message received.\n"); break; @@ -615,20 +591,23 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) me_client = &dev->me_clients[dev->me_client_presentation_num]; if (props_res->status || !dev->me_clients) { - dev_err(&dev->pdev->dev, "reset: properties response hbm wrong status.\n"); + dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); mei_reset(dev, 1); return; } if (me_client->client_id != props_res->address) { - dev_err(&dev->pdev->dev, "reset: host properties response address mismatch\n"); + dev_err(&dev->pdev->dev, + "Host client properties reply mismatch\n"); mei_reset(dev, 1); + return; } if (dev->dev_state != MEI_DEV_INIT_CLIENTS || - dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) { - dev_err(&dev->pdev->dev, "reset: unexpected properties response\n"); + dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) { + dev_err(&dev->pdev->dev, + "Unexpected client properties reply\n"); mei_reset(dev, 1); return; @@ -647,28 +626,26 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) enum_res = (struct hbm_host_enum_response *) mei_msg; memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); if (dev->dev_state == MEI_DEV_INIT_CLIENTS && - dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { + dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { dev->init_clients_timer = 0; dev->me_client_presentation_num = 0; dev->me_client_index = 0; mei_hbm_me_cl_allocate(dev); - dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; + dev->init_clients_state = + MEI_CLIENT_PROPERTIES_MESSAGE; /* first property reqeust */ mei_hbm_prop_req(dev); } else { - dev_err(&dev->pdev->dev, "reset: unexpected enumeration response hbm.\n"); + dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); mei_reset(dev, 1); return; } break; case HOST_STOP_RES_CMD: - - if (dev->hbm_state != MEI_HBM_STOP) - dev_err(&dev->pdev->dev, "unexpected stop response hbm.\n"); dev->dev_state = MEI_DEV_DISABLED; - dev_info(&dev->pdev->dev, "reset: FW stop response.\n"); + dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n"); mei_reset(dev, 1); break; @@ -680,7 +657,6 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) case ME_STOP_REQ_CMD: - dev->hbm_state = MEI_HBM_STOP; mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr, dev->wr_ext_msg.data); break; diff --git a/trunk/drivers/misc/mei/hbm.h b/trunk/drivers/misc/mei/hbm.h index e80dc24ef3e2..b552afbaf85c 100644 --- a/trunk/drivers/misc/mei/hbm.h +++ b/trunk/drivers/misc/mei/hbm.h @@ -17,27 +17,6 @@ #ifndef _MEI_HBM_H_ #define _MEI_HBM_H_ -struct mei_device; -struct mei_msg_hdr; -struct mei_cl; - -/** - * enum mei_hbm_state - host bus message protocol state - * - * @MEI_HBM_IDLE : protocol not started - * @MEI_HBM_START : start request message was sent - * @MEI_HBM_ENUM_CLIENTS : enumeration request was sent - * @MEI_HBM_CLIENT_PROPERTIES : acquiring clients properties - */ -enum mei_hbm_state { - MEI_HBM_IDLE = 0, - MEI_HBM_START, - MEI_HBM_ENUM_CLIENTS, - MEI_HBM_CLIENT_PROPERTIES, - MEI_HBM_STARTED, - MEI_HBM_STOP, -}; - void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr); static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) @@ -49,8 +28,8 @@ static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) hdr->reserved = 0; } -int mei_hbm_start_req(struct mei_device *dev); -int mei_hbm_start_wait(struct mei_device *dev); +void mei_hbm_start_req(struct mei_device *dev); + int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl); int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl); int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl); diff --git a/trunk/drivers/misc/mei/hw-me.c b/trunk/drivers/misc/mei/hw-me.c index fc032270916a..45ea7185c003 100644 --- a/trunk/drivers/misc/mei/hw-me.c +++ b/trunk/drivers/misc/mei/hw-me.c @@ -26,14 +26,14 @@ /** - * mei_me_reg_read - Reads 32bit data from the mei device + * mei_reg_read - Reads 32bit data from the mei device * * @dev: the device structure * @offset: offset from which to read the data * * returns register value (u32) */ -static inline u32 mei_me_reg_read(const struct mei_me_hw *hw, +static inline u32 mei_reg_read(const struct mei_me_hw *hw, unsigned long offset) { return ioread32(hw->mem_addr + offset); @@ -41,20 +41,20 @@ static inline u32 mei_me_reg_read(const struct mei_me_hw *hw, /** - * mei_me_reg_write - Writes 32bit data to the mei device + * mei_reg_write - Writes 32bit data to the mei device * * @dev: the device structure * @offset: offset from which to write the data * @value: register value to write (u32) */ -static inline void mei_me_reg_write(const struct mei_me_hw *hw, +static inline void mei_reg_write(const struct mei_me_hw *hw, unsigned long offset, u32 value) { iowrite32(value, hw->mem_addr + offset); } /** - * mei_me_mecbrw_read - Reads 32bit data from ME circular buffer + * mei_mecbrw_read - Reads 32bit data from ME circular buffer * read window register * * @dev: the device structure @@ -63,18 +63,18 @@ static inline void mei_me_reg_write(const struct mei_me_hw *hw, */ static u32 mei_me_mecbrw_read(const struct mei_device *dev) { - return mei_me_reg_read(to_me_hw(dev), ME_CB_RW); + return mei_reg_read(to_me_hw(dev), ME_CB_RW); } /** - * mei_me_mecsr_read - Reads 32bit data from the ME CSR + * mei_mecsr_read - Reads 32bit data from the ME CSR * * @dev: the device structure * * returns ME_CSR_HA register value (u32) */ -static inline u32 mei_me_mecsr_read(const struct mei_me_hw *hw) +static inline u32 mei_mecsr_read(const struct mei_me_hw *hw) { - return mei_me_reg_read(hw, ME_CSR_HA); + return mei_reg_read(hw, ME_CSR_HA); } /** @@ -86,7 +86,7 @@ static inline u32 mei_me_mecsr_read(const struct mei_me_hw *hw) */ static inline u32 mei_hcsr_read(const struct mei_me_hw *hw) { - return mei_me_reg_read(hw, H_CSR); + return mei_reg_read(hw, H_CSR); } /** @@ -98,7 +98,7 @@ static inline u32 mei_hcsr_read(const struct mei_me_hw *hw) static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) { hcsr &= ~H_IS; - mei_me_reg_write(hw, H_CSR, hcsr); + mei_reg_write(hw, H_CSR, hcsr); } @@ -123,7 +123,7 @@ static void mei_me_intr_clear(struct mei_device *dev) struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); if ((hcsr & H_IS) == H_IS) - mei_me_reg_write(hw, H_CSR, hcsr); + mei_reg_write(hw, H_CSR, hcsr); } /** * mei_me_intr_enable - enables mei device interrupts @@ -151,20 +151,6 @@ static void mei_me_intr_disable(struct mei_device *dev) mei_hcsr_set(hw, hcsr); } -/** - * mei_me_hw_reset_release - release device from the reset - * - * @dev: the device structure - */ -static void mei_me_hw_reset_release(struct mei_device *dev) -{ - struct mei_me_hw *hw = to_me_hw(dev); - u32 hcsr = mei_hcsr_read(hw); - - hcsr |= H_IG; - hcsr &= ~H_RST; - mei_hcsr_set(hw, hcsr); -} /** * mei_me_hw_reset - resets fw via mei csr register. * @@ -183,14 +169,18 @@ static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable) if (intr_enable) hcsr |= H_IE; else - hcsr |= ~H_IE; + hcsr &= ~H_IE; + + mei_hcsr_set(hw, hcsr); + + hcsr = mei_hcsr_read(hw) | H_IG; + hcsr &= ~H_RST; mei_hcsr_set(hw, hcsr); - if (dev->dev_state == MEI_DEV_POWER_DOWN) - mei_me_hw_reset_release(dev); + hcsr = mei_hcsr_read(hw); - dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", mei_hcsr_read(hw)); + dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", hcsr); } /** @@ -228,42 +218,10 @@ static bool mei_me_host_is_ready(struct mei_device *dev) static bool mei_me_hw_is_ready(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); - hw->me_hw_state = mei_me_mecsr_read(hw); + hw->me_hw_state = mei_mecsr_read(hw); return (hw->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA; } -static int mei_me_hw_ready_wait(struct mei_device *dev) -{ - int err; - if (mei_me_hw_is_ready(dev)) - return 0; - - mutex_unlock(&dev->device_lock); - err = wait_event_interruptible_timeout(dev->wait_hw_ready, - dev->recvd_hw_ready, MEI_INTEROP_TIMEOUT); - mutex_lock(&dev->device_lock); - if (!err && !dev->recvd_hw_ready) { - dev_err(&dev->pdev->dev, - "wait hw ready failed. status = 0x%x\n", err); - return -ETIMEDOUT; - } - - dev->recvd_hw_ready = false; - return 0; -} - -static int mei_me_hw_start(struct mei_device *dev) -{ - int ret = mei_me_hw_ready_wait(dev); - if (ret) - return ret; - dev_dbg(&dev->pdev->dev, "hw is ready\n"); - - mei_me_host_set_ready(dev); - return ret; -} - - /** * mei_hbuf_filled_slots - gets number of device filled buffer slots * @@ -337,11 +295,10 @@ static int mei_me_write_message(struct mei_device *dev, unsigned char *buf) { struct mei_me_hw *hw = to_me_hw(dev); - unsigned long rem; + unsigned long rem, dw_cnt; unsigned long length = header->length; u32 *reg_buf = (u32 *)buf; u32 hcsr; - u32 dw_cnt; int i; int empty_slots; @@ -354,16 +311,16 @@ static int mei_me_write_message(struct mei_device *dev, if (empty_slots < 0 || dw_cnt > empty_slots) return -EIO; - mei_me_reg_write(hw, H_CB_WW, *((u32 *) header)); + mei_reg_write(hw, H_CB_WW, *((u32 *) header)); for (i = 0; i < length / 4; i++) - mei_me_reg_write(hw, H_CB_WW, reg_buf[i]); + mei_reg_write(hw, H_CB_WW, reg_buf[i]); rem = length & 0x3; if (rem > 0) { u32 reg = 0; memcpy(®, &buf[length - rem], rem); - mei_me_reg_write(hw, H_CB_WW, reg); + mei_reg_write(hw, H_CB_WW, reg); } hcsr = mei_hcsr_read(hw) | H_IG; @@ -387,7 +344,7 @@ static int mei_me_count_full_read_slots(struct mei_device *dev) char read_ptr, write_ptr; unsigned char buffer_depth, filled_slots; - hw->me_hw_state = mei_me_mecsr_read(hw); + hw->me_hw_state = mei_mecsr_read(hw); buffer_depth = (unsigned char)((hw->me_hw_state & ME_CBD_HRA) >> 24); read_ptr = (char) ((hw->me_hw_state & ME_CBRP_HRA) >> 8); write_ptr = (char) ((hw->me_hw_state & ME_CBWP_HRA) >> 16); @@ -447,7 +404,7 @@ irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id) return IRQ_NONE; /* clear H_IS bit in H_CSR */ - mei_me_reg_write(hw, H_CSR, csr_reg); + mei_reg_write(hw, H_CSR, csr_reg); return IRQ_WAKE_THREAD; } @@ -466,8 +423,12 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) { struct mei_device *dev = (struct mei_device *) dev_id; struct mei_cl_cb complete_list; + struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; + struct mei_cl *cl; s32 slots; int rets; + bool bus_message_received; + dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); /* initialize our complete list */ @@ -481,7 +442,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) /* check if ME wants a reset */ if (!mei_hw_is_ready(dev) && - dev->dev_state != MEI_DEV_RESETTING && + dev->dev_state != MEI_DEV_RESETING && dev->dev_state != MEI_DEV_INITIALIZING) { dev_dbg(&dev->pdev->dev, "FW not ready.\n"); mei_reset(dev, 1); @@ -494,14 +455,18 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) if (mei_hw_is_ready(dev)) { dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); - dev->recvd_hw_ready = true; - wake_up_interruptible(&dev->wait_hw_ready); + mei_host_set_ready(dev); + + dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); + /* link is established * start sending messages. */ + + dev->dev_state = MEI_DEV_INIT_CLIENTS; + mei_hbm_start_req(dev); mutex_unlock(&dev->device_lock); return IRQ_HANDLED; } else { - dev_dbg(&dev->pdev->dev, "Reset Completed.\n"); - mei_me_hw_reset_release(dev); + dev_dbg(&dev->pdev->dev, "FW not ready.\n"); mutex_unlock(&dev->device_lock); return IRQ_HANDLED; } @@ -523,20 +488,44 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); dev->hbuf_is_ready = mei_hbuf_is_ready(dev); + bus_message_received = false; + if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { + dev_dbg(&dev->pdev->dev, "received waiting bus message\n"); + bus_message_received = true; + } mutex_unlock(&dev->device_lock); + if (bus_message_received) { + dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n"); + wake_up_interruptible(&dev->wait_recvd_msg); + bus_message_received = false; + } + if (list_empty(&complete_list.list)) + return IRQ_HANDLED; - mei_irq_compl_handler(dev, &complete_list); + list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) { + cl = cb_pos->cl; + list_del(&cb_pos->list); + if (cl) { + if (cl != &dev->iamthif_cl) { + dev_dbg(&dev->pdev->dev, "completing call back.\n"); + mei_irq_complete_handler(cl, cb_pos); + cb_pos = NULL; + } else if (cl == &dev->iamthif_cl) { + mei_amthif_complete(dev, cb_pos); + } + } + } return IRQ_HANDLED; } static const struct mei_hw_ops mei_me_hw_ops = { + .host_set_ready = mei_me_host_set_ready, .host_is_ready = mei_me_host_is_ready, .hw_is_ready = mei_me_hw_is_ready, .hw_reset = mei_me_hw_reset, - .hw_config = mei_me_hw_config, - .hw_start = mei_me_hw_start, + .hw_config = mei_me_hw_config, .intr_clear = mei_me_intr_clear, .intr_enable = mei_me_intr_enable, @@ -571,6 +560,14 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev) mei_device_init(dev); + INIT_LIST_HEAD(&dev->wd_cl.link); + INIT_LIST_HEAD(&dev->iamthif_cl.link); + mei_io_list_init(&dev->amthif_cmd_list); + mei_io_list_init(&dev->amthif_rd_complete_list); + + INIT_DELAYED_WORK(&dev->timer_work, mei_timer); + INIT_WORK(&dev->init_work, mei_host_client_init); + dev->ops = &mei_me_hw_ops; dev->pdev = pdev; diff --git a/trunk/drivers/misc/mei/hw-me.h b/trunk/drivers/misc/mei/hw-me.h index 80bd829fbd9a..8518d3eeb838 100644 --- a/trunk/drivers/misc/mei/hw-me.h +++ b/trunk/drivers/misc/mei/hw-me.h @@ -36,6 +36,12 @@ struct mei_me_hw { struct mei_device *mei_me_dev_init(struct pci_dev *pdev); +/* get slots (dwords) from a message length + header (bytes) */ +static inline unsigned char mei_data2slots(size_t length) +{ + return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); +} + irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id); irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id); diff --git a/trunk/drivers/misc/mei/init.c b/trunk/drivers/misc/mei/init.c index 713d89fedc46..6ec530168afb 100644 --- a/trunk/drivers/misc/mei/init.c +++ b/trunk/drivers/misc/mei/init.c @@ -14,7 +14,6 @@ * */ -#include #include #include #include @@ -23,7 +22,6 @@ #include #include "mei_dev.h" -#include "hbm.h" #include "client.h" const char *mei_dev_state_str(int state) @@ -33,8 +31,9 @@ const char *mei_dev_state_str(int state) MEI_DEV_STATE(INITIALIZING); MEI_DEV_STATE(INIT_CLIENTS); MEI_DEV_STATE(ENABLED); - MEI_DEV_STATE(RESETTING); + MEI_DEV_STATE(RESETING); MEI_DEV_STATE(DISABLED); + MEI_DEV_STATE(RECOVERING_FROM_RESET); MEI_DEV_STATE(POWER_DOWN); MEI_DEV_STATE(POWER_UP); default: @@ -47,9 +46,7 @@ void mei_device_init(struct mei_device *dev) { /* setup our list array */ INIT_LIST_HEAD(&dev->file_list); - INIT_LIST_HEAD(&dev->device_list); mutex_init(&dev->device_lock); - init_waitqueue_head(&dev->wait_hw_ready); init_waitqueue_head(&dev->wait_recvd_msg); init_waitqueue_head(&dev->wait_stop_wd); dev->dev_state = MEI_DEV_INITIALIZING; @@ -59,27 +56,19 @@ void mei_device_init(struct mei_device *dev) mei_io_list_init(&dev->write_waiting_list); mei_io_list_init(&dev->ctrl_wr_list); mei_io_list_init(&dev->ctrl_rd_list); - - INIT_DELAYED_WORK(&dev->timer_work, mei_timer); - INIT_WORK(&dev->init_work, mei_host_client_init); - - INIT_LIST_HEAD(&dev->wd_cl.link); - INIT_LIST_HEAD(&dev->iamthif_cl.link); - mei_io_list_init(&dev->amthif_cmd_list); - mei_io_list_init(&dev->amthif_rd_complete_list); - } -EXPORT_SYMBOL_GPL(mei_device_init); /** - * mei_start - initializes host and fw to start work. + * mei_hw_init - initializes host and fw to start work. * * @dev: the device structure * * returns 0 on success, <0 on failure. */ -int mei_start(struct mei_device *dev) +int mei_hw_init(struct mei_device *dev) { + int ret = 0; + mutex_lock(&dev->device_lock); /* acknowledge interrupt and stop interupts */ @@ -87,15 +76,29 @@ int mei_start(struct mei_device *dev) mei_hw_config(dev); + dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); mei_reset(dev, 1); - if (mei_hbm_start_wait(dev)) { - dev_err(&dev->pdev->dev, "HBM haven't started"); + /* wait for ME to turn on ME_RDY */ + if (!dev->recvd_msg) { + mutex_unlock(&dev->device_lock); + ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, + dev->recvd_msg, + mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); + mutex_lock(&dev->device_lock); + } + + if (ret <= 0 && !dev->recvd_msg) { + dev->dev_state = MEI_DEV_DISABLED; + dev_dbg(&dev->pdev->dev, + "wait_event_interruptible_timeout failed" + "on wait for ME to turn on ME_RDY.\n"); goto err; } + if (!mei_host_is_ready(dev)) { dev_err(&dev->pdev->dev, "host is not ready.\n"); goto err; @@ -112,6 +115,7 @@ int mei_start(struct mei_device *dev) goto err; } + dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); mutex_unlock(&dev->device_lock); @@ -122,7 +126,6 @@ int mei_start(struct mei_device *dev) mutex_unlock(&dev->device_lock); return -ENODEV; } -EXPORT_SYMBOL_GPL(mei_start); /** * mei_reset - resets host and fw. @@ -134,6 +137,9 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) { bool unexpected; + if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) + return; + unexpected = (dev->dev_state != MEI_DEV_INITIALIZING && dev->dev_state != MEI_DEV_DISABLED && dev->dev_state != MEI_DEV_POWER_DOWN && @@ -141,12 +147,11 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) mei_hw_reset(dev, interrupts_enabled); - dev->hbm_state = MEI_HBM_IDLE; if (dev->dev_state != MEI_DEV_INITIALIZING) { if (dev->dev_state != MEI_DEV_DISABLED && dev->dev_state != MEI_DEV_POWER_DOWN) - dev->dev_state = MEI_DEV_RESETTING; + dev->dev_state = MEI_DEV_RESETING; mei_cl_all_disconnect(dev); @@ -171,50 +176,13 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n", mei_dev_state_str(dev->dev_state)); - if (!interrupts_enabled) { - dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n"); - return; - } - - mei_hw_start(dev); - - dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); - /* link is established * start sending messages. */ - - dev->dev_state = MEI_DEV_INIT_CLIENTS; - - mei_hbm_start_req(dev); - /* wake up all readings so they can be interrupted */ mei_cl_all_read_wakeup(dev); /* remove all waiting requests */ mei_cl_all_write_clear(dev); } -EXPORT_SYMBOL_GPL(mei_reset); - -void mei_stop(struct mei_device *dev) -{ - dev_dbg(&dev->pdev->dev, "stopping the device.\n"); - - mutex_lock(&dev->device_lock); - - cancel_delayed_work(&dev->timer_work); - mei_wd_stop(dev); - - mei_nfc_host_exit(); - - dev->dev_state = MEI_DEV_POWER_DOWN; - mei_reset(dev, 0); - - mutex_unlock(&dev->device_lock); - - flush_scheduled_work(); - - mei_watchdog_unregister(dev); -} -EXPORT_SYMBOL_GPL(mei_stop); diff --git a/trunk/drivers/misc/mei/interrupt.c b/trunk/drivers/misc/mei/interrupt.c index 1473cfdbc426..3535b2676c97 100644 --- a/trunk/drivers/misc/mei/interrupt.c +++ b/trunk/drivers/misc/mei/interrupt.c @@ -15,7 +15,6 @@ */ -#include #include #include #include @@ -31,153 +30,103 @@ /** - * mei_cl_complete_handler - processes completed operation for a client + * mei_complete_handler - processes completed operation. * * @cl: private data of the file object. - * @cb: callback block. + * @cb_pos: callback block. */ -static void mei_cl_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb) +void mei_irq_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb_pos) { - if (cb->fop_type == MEI_FOP_WRITE) { - mei_io_cb_free(cb); - cb = NULL; + if (cb_pos->fop_type == MEI_FOP_WRITE) { + mei_io_cb_free(cb_pos); + cb_pos = NULL; cl->writing_state = MEI_WRITE_COMPLETE; if (waitqueue_active(&cl->tx_wait)) wake_up_interruptible(&cl->tx_wait); - } else if (cb->fop_type == MEI_FOP_READ && + } else if (cb_pos->fop_type == MEI_FOP_READ && MEI_READING == cl->reading_state) { cl->reading_state = MEI_READ_COMPLETE; if (waitqueue_active(&cl->rx_wait)) wake_up_interruptible(&cl->rx_wait); - else - mei_cl_bus_rx_event(cl); - - } -} - -/** - * mei_irq_compl_handler - dispatch complete handelers - * for the completed callbacks - * - * @dev - mei device - * @compl_list - list of completed cbs - */ -void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list) -{ - struct mei_cl_cb *cb, *next; - struct mei_cl *cl; - - list_for_each_entry_safe(cb, next, &compl_list->list, list) { - cl = cb->cl; - list_del(&cb->list); - if (!cl) - continue; - dev_dbg(&dev->pdev->dev, "completing call back.\n"); - if (cl == &dev->iamthif_cl) - mei_amthif_complete(dev, cb); - else - mei_cl_complete_handler(cl, cb); } } -EXPORT_SYMBOL_GPL(mei_irq_compl_handler); /** - * mei_cl_hbm_equal - check if hbm is addressed to the client + * _mei_irq_thread_state_ok - checks if mei header matches file private data * - * @cl: host client + * @cl: private data of the file object * @mei_hdr: header of mei client message * - * returns true if matches, false otherwise - */ -static inline int mei_cl_hbm_equal(struct mei_cl *cl, - struct mei_msg_hdr *mei_hdr) -{ - return cl->host_client_id == mei_hdr->host_addr && - cl->me_client_id == mei_hdr->me_addr; -} -/** - * mei_cl_is_reading - checks if the client - is the one to read this message - * - * @cl: mei client - * @mei_hdr: header of mei message - * - * returns true on match and false otherwise + * returns !=0 if matches, 0 if no match. */ -static bool mei_cl_is_reading(struct mei_cl *cl, struct mei_msg_hdr *mei_hdr) +static int _mei_irq_thread_state_ok(struct mei_cl *cl, + struct mei_msg_hdr *mei_hdr) { - return mei_cl_hbm_equal(cl, mei_hdr) && + return (cl->host_client_id == mei_hdr->host_addr && + cl->me_client_id == mei_hdr->me_addr && cl->state == MEI_FILE_CONNECTED && - cl->reading_state != MEI_READ_COMPLETE; + MEI_READ_COMPLETE != cl->reading_state); } /** - * mei_irq_read_client_message - process client message + * mei_irq_thread_read_client_message - bottom half read routine after ISR to + * handle the read mei client message data processing. * + * @complete_list: An instance of our list structure * @dev: the device structure * @mei_hdr: header of mei client message - * @complete_list: An instance of our list structure * * returns 0 on success, <0 on failure. */ -static int mei_cl_irq_read_msg(struct mei_device *dev, - struct mei_msg_hdr *mei_hdr, - struct mei_cl_cb *complete_list) +static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list, + struct mei_device *dev, + struct mei_msg_hdr *mei_hdr) { struct mei_cl *cl; - struct mei_cl_cb *cb, *next; + struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; unsigned char *buffer = NULL; - list_for_each_entry_safe(cb, next, &dev->read_list.list, list) { - cl = cb->cl; - if (!cl || !mei_cl_is_reading(cl, mei_hdr)) - continue; + dev_dbg(&dev->pdev->dev, "start client msg\n"); + if (list_empty(&dev->read_list.list)) + goto quit; - cl->reading_state = MEI_READING; + list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) { + cl = cb_pos->cl; + if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { + cl->reading_state = MEI_READING; + buffer = cb_pos->response_buffer.data + cb_pos->buf_idx; - if (cb->response_buffer.size == 0 || - cb->response_buffer.data == NULL) { - dev_err(&dev->pdev->dev, "response buffer is not allocated.\n"); - list_del(&cb->list); - return -ENOMEM; - } - - if (cb->response_buffer.size < mei_hdr->length + cb->buf_idx) { - dev_dbg(&dev->pdev->dev, "message overflow. size %d len %d idx %ld\n", - cb->response_buffer.size, - mei_hdr->length, cb->buf_idx); - buffer = krealloc(cb->response_buffer.data, - mei_hdr->length + cb->buf_idx, - GFP_KERNEL); - - if (!buffer) { - dev_err(&dev->pdev->dev, "allocation failed.\n"); - list_del(&cb->list); + if (cb_pos->response_buffer.size < + mei_hdr->length + cb_pos->buf_idx) { + dev_dbg(&dev->pdev->dev, "message overflow.\n"); + list_del(&cb_pos->list); return -ENOMEM; } - cb->response_buffer.data = buffer; - cb->response_buffer.size = - mei_hdr->length + cb->buf_idx; - } + if (buffer) + mei_read_slots(dev, buffer, mei_hdr->length); + + cb_pos->buf_idx += mei_hdr->length; + if (mei_hdr->msg_complete) { + cl->status = 0; + list_del(&cb_pos->list); + dev_dbg(&dev->pdev->dev, + "completed read H cl = %d, ME cl = %d, length = %lu\n", + cl->host_client_id, + cl->me_client_id, + cb_pos->buf_idx); + + list_add_tail(&cb_pos->list, + &complete_list->list); + } - buffer = cb->response_buffer.data + cb->buf_idx; - mei_read_slots(dev, buffer, mei_hdr->length); - - cb->buf_idx += mei_hdr->length; - if (mei_hdr->msg_complete) { - cl->status = 0; - list_del(&cb->list); - dev_dbg(&dev->pdev->dev, "completed read H cl = %d, ME cl = %d, length = %lu\n", - cl->host_client_id, - cl->me_client_id, - cb->buf_idx); - list_add_tail(&cb->list, &complete_list->list); + break; } - break; + } +quit: dev_dbg(&dev->pdev->dev, "message read\n"); if (!buffer) { mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); @@ -204,27 +153,25 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_cl_cb *cmpl_list) { - u32 msg_slots = - mei_data2slots(sizeof(struct hbm_client_connect_request)); + if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_client_connect_request))) + return -EBADMSG; - if (*slots < msg_slots) - return -EMSGSIZE; - - *slots -= msg_slots; + *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); if (mei_hbm_cl_disconnect_req(dev, cl)) { cl->status = 0; cb_pos->buf_idx = 0; list_move_tail(&cb_pos->list, &cmpl_list->list); - return -EIO; + return -EMSGSIZE; + } else { + cl->state = MEI_FILE_DISCONNECTING; + cl->status = 0; + cb_pos->buf_idx = 0; + list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); + cl->timer_count = MEI_CONNECT_TIMEOUT; } - cl->state = MEI_FILE_DISCONNECTING; - cl->status = 0; - cb_pos->buf_idx = 0; - list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); - cl->timer_count = MEI_CONNECT_TIMEOUT; - return 0; } @@ -245,15 +192,14 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_cl_cb *cmpl_list) { - u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); - - if (*slots < msg_slots) { + if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control))) { /* return the cancel routine */ list_del(&cb_pos->list); - return -EMSGSIZE; + return -EBADMSG; } - *slots -= msg_slots; + *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); if (mei_hbm_cl_flow_control_req(dev, cl)) { cl->status = -ENODEV; @@ -283,19 +229,15 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_cl_cb *cmpl_list) { - u32 msg_slots = - mei_data2slots(sizeof(struct hbm_client_connect_request)); - - if (*slots < msg_slots) { + if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_client_connect_request))) { /* return the cancel routine */ list_del(&cb_pos->list); - return -EMSGSIZE; + return -EBADMSG; } - *slots -= msg_slots; - cl->state = MEI_FILE_CONNECTING; - + *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); if (mei_hbm_cl_connect_req(dev, cl)) { cl->status = -ENODEV; cb_pos->buf_idx = 0; @@ -324,7 +266,7 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, struct mei_msg_hdr mei_hdr; struct mei_cl *cl = cb->cl; size_t len = cb->request_buffer.size - cb->buf_idx; - u32 msg_slots = mei_data2slots(len); + size_t msg_slots = mei_data2slots(len); mei_hdr.host_addr = cl->host_client_id; mei_hdr.me_addr = cl->me_client_id; @@ -356,14 +298,13 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, return -ENODEV; } + if (mei_cl_flow_ctrl_reduce(cl)) + return -ENODEV; cl->status = 0; cb->buf_idx += mei_hdr.length; - if (mei_hdr.msg_complete) { - if (mei_cl_flow_ctrl_reduce(cl)) - return -ENODEV; + if (mei_hdr.msg_complete) list_move_tail(&cb->list, &dev->write_waiting_list.list); - } return 0; } @@ -409,7 +350,8 @@ int mei_irq_read_handler(struct mei_device *dev, " client = %d, ME client = %d\n", cl_pos->host_client_id, cl_pos->me_client_id); - if (mei_cl_hbm_equal(cl_pos, mei_hdr)) + if (cl_pos->host_client_id == mei_hdr->host_addr && + cl_pos->me_client_id == mei_hdr->me_addr) break; } @@ -420,7 +362,7 @@ int mei_irq_read_handler(struct mei_device *dev, } } if (((*slots) * sizeof(u32)) < mei_hdr->length) { - dev_err(&dev->pdev->dev, + dev_dbg(&dev->pdev->dev, "we can't read the message slots =%08x.\n", *slots); /* we can't read the message */ @@ -436,19 +378,20 @@ int mei_irq_read_handler(struct mei_device *dev, } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && (dev->iamthif_state == MEI_IAMTHIF_READING)) { - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); - ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list); + ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr); if (ret) goto end; } else { - dev_dbg(&dev->pdev->dev, "call mei_cl_irq_read_msg.\n"); - dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); - ret = mei_cl_irq_read_msg(dev, mei_hdr, cmpl_list); + dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); + ret = mei_irq_thread_read_client_message(cmpl_list, + dev, mei_hdr); if (ret) goto end; + } /* reset the number of slots and header */ @@ -457,7 +400,7 @@ int mei_irq_read_handler(struct mei_device *dev, if (*slots == -EOVERFLOW) { /* overflow - reset */ - dev_err(&dev->pdev->dev, "resetting due to slots overflow.\n"); + dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n"); /* set the event since message has been read */ ret = -ERANGE; goto end; @@ -465,7 +408,6 @@ int mei_irq_read_handler(struct mei_device *dev, end: return ret; } -EXPORT_SYMBOL_GPL(mei_irq_read_handler); /** @@ -477,7 +419,8 @@ EXPORT_SYMBOL_GPL(mei_irq_read_handler); * * returns 0 on success, <0 on failure. */ -int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) +int mei_irq_write_handler(struct mei_device *dev, + struct mei_cl_cb *cmpl_list) { struct mei_cl *cl; @@ -616,7 +559,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) } return 0; } -EXPORT_SYMBOL_GPL(mei_irq_write_handler); @@ -644,8 +586,8 @@ void mei_timer(struct work_struct *work) if (dev->dev_state == MEI_DEV_INIT_CLIENTS) { if (dev->init_clients_timer) { if (--dev->init_clients_timer == 0) { - dev_err(&dev->pdev->dev, "reset: init clients timeout hbm_state = %d.\n", - dev->hbm_state); + dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n", + dev->init_clients_state); mei_reset(dev, 1); } } @@ -656,7 +598,7 @@ void mei_timer(struct work_struct *work) list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { if (cl_pos->timer_count) { if (--cl_pos->timer_count == 0) { - dev_err(&dev->pdev->dev, "reset: connect/disconnect timeout.\n"); + dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n"); mei_reset(dev, 1); goto out; } @@ -665,7 +607,7 @@ void mei_timer(struct work_struct *work) if (dev->iamthif_stall_timer) { if (--dev->iamthif_stall_timer == 0) { - dev_err(&dev->pdev->dev, "reset: amthif hanged.\n"); + dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n"); mei_reset(dev, 1); dev->iamthif_msg_buf_size = 0; dev->iamthif_msg_buf_index = 0; diff --git a/trunk/drivers/misc/mei/main.c b/trunk/drivers/misc/mei/main.c index 7c44c8dbae42..903f809b21f7 100644 --- a/trunk/drivers/misc/mei/main.c +++ b/trunk/drivers/misc/mei/main.c @@ -48,7 +48,7 @@ * * @inode: pointer to inode structure * @file: pointer to file structure - e + * * returns 0 on success, <0 on error */ static int mei_open(struct inode *inode, struct file *file) @@ -244,7 +244,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, goto out; } - err = mei_cl_read_start(cl, length); + err = mei_cl_read_start(cl); if (err && err != -EBUSY) { dev_dbg(&dev->pdev->dev, "mei start read failure with status = %d\n", err); @@ -292,8 +292,9 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, } /* now copy the data to user space */ copy_buffer: - dev_dbg(&dev->pdev->dev, "buf.size = %d buf.idx= %ld\n", - cb->response_buffer.size, cb->buf_idx); + dev_dbg(&dev->pdev->dev, "cb->response_buffer size - %d\n", + cb->response_buffer.size); + dev_dbg(&dev->pdev->dev, "cb->buf_idx - %lu\n", cb->buf_idx); if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) { rets = -EMSGSIZE; goto free; @@ -341,10 +342,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, { struct mei_cl *cl = file->private_data; struct mei_cl_cb *write_cb = NULL; + struct mei_msg_hdr mei_hdr; struct mei_device *dev; unsigned long timeout = 0; int rets; - int id; + int i; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -355,24 +357,24 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (dev->dev_state != MEI_DEV_ENABLED) { rets = -ENODEV; - goto out; + goto err; } - id = mei_me_cl_by_id(dev, cl->me_client_id); - if (id < 0) { + i = mei_me_cl_by_id(dev, cl->me_client_id); + if (i < 0) { rets = -ENODEV; - goto out; + goto err; } - if (length > dev->me_clients[id].props.max_msg_length || length <= 0) { + if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { rets = -EMSGSIZE; - goto out; + goto err; } if (cl->state != MEI_FILE_CONNECTED) { + rets = -ENODEV; dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", cl->host_client_id, cl->me_client_id); - rets = -ENODEV; - goto out; + goto err; } if (cl == &dev->iamthif_cl) { write_cb = mei_amthif_find_read_list_entry(dev, file); @@ -410,15 +412,17 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (!write_cb) { dev_err(&dev->pdev->dev, "write cb allocation failed\n"); rets = -ENOMEM; - goto out; + goto err; } rets = mei_io_cb_alloc_req_buf(write_cb, length); if (rets) - goto out; + goto err; + + dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length); rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); if (rets) - goto out; + goto err; cl->sm_state = 0; if (length == 4 && @@ -436,17 +440,65 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (rets) { dev_err(&dev->pdev->dev, "amthif write failed with status = %d\n", rets); - goto out; + goto err; } mutex_unlock(&dev->device_lock); return length; } - rets = mei_cl_write(cl, write_cb, false); + write_cb->fop_type = MEI_FOP_WRITE; + + dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", + cl->host_client_id, cl->me_client_id); + rets = mei_cl_flow_ctrl_creds(cl); + if (rets < 0) + goto err; + + if (rets == 0 || !dev->hbuf_is_ready) { + write_cb->buf_idx = 0; + mei_hdr.msg_complete = 0; + cl->writing_state = MEI_WRITING; + goto out; + } + + dev->hbuf_is_ready = false; + if (length > mei_hbuf_max_len(dev)) { + mei_hdr.length = mei_hbuf_max_len(dev); + mei_hdr.msg_complete = 0; + } else { + mei_hdr.length = length; + mei_hdr.msg_complete = 1; + } + mei_hdr.host_addr = cl->host_client_id; + mei_hdr.me_addr = cl->me_client_id; + mei_hdr.reserved = 0; + + dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n", + MEI_HDR_PRM(&mei_hdr)); + if (mei_write_message(dev, &mei_hdr, write_cb->request_buffer.data)) { + rets = -ENODEV; + goto err; + } + cl->writing_state = MEI_WRITING; + write_cb->buf_idx = mei_hdr.length; + out: + if (mei_hdr.msg_complete) { + if (mei_cl_flow_ctrl_reduce(cl)) { + rets = -ENODEV; + goto err; + } + list_add_tail(&write_cb->list, &dev->write_waiting_list.list); + } else { + list_add_tail(&write_cb->list, &dev->write_list.list); + } + mutex_unlock(&dev->device_lock); - if (rets < 0) - mei_io_cb_free(write_cb); + return length; + +err: + mutex_unlock(&dev->device_lock); + mei_io_cb_free(write_cb); return rets; } @@ -701,44 +753,17 @@ static struct miscdevice mei_misc_device = { .minor = MISC_DYNAMIC_MINOR, }; - -int mei_register(struct mei_device *dev) +int mei_register(struct device *dev) { - int ret; - mei_misc_device.parent = &dev->pdev->dev; - ret = misc_register(&mei_misc_device); - if (ret) - return ret; - - if (mei_dbgfs_register(dev, mei_misc_device.name)) - dev_err(&dev->pdev->dev, "cannot register debugfs\n"); - - return 0; + mei_misc_device.parent = dev; + return misc_register(&mei_misc_device); } -EXPORT_SYMBOL_GPL(mei_register); -void mei_deregister(struct mei_device *dev) +void mei_deregister(void) { - mei_dbgfs_deregister(dev); misc_deregister(&mei_misc_device); mei_misc_device.parent = NULL; } -EXPORT_SYMBOL_GPL(mei_deregister); - -static int __init mei_init(void) -{ - return mei_cl_bus_init(); -} - -static void __exit mei_exit(void) -{ - mei_cl_bus_exit(); -} - -module_init(mei_init); -module_exit(mei_exit); -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) Management Engine Interface"); MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/misc/mei/mei_dev.h b/trunk/drivers/misc/mei/mei_dev.h index 4de5140e7379..cb80166161f0 100644 --- a/trunk/drivers/misc/mei/mei_dev.h +++ b/trunk/drivers/misc/mei/mei_dev.h @@ -21,11 +21,9 @@ #include #include #include -#include #include "hw.h" #include "hw-me-regs.h" -#include "hbm.h" /* * watch dog definition @@ -97,14 +95,22 @@ enum mei_dev_state { MEI_DEV_INITIALIZING = 0, MEI_DEV_INIT_CLIENTS, MEI_DEV_ENABLED, - MEI_DEV_RESETTING, + MEI_DEV_RESETING, MEI_DEV_DISABLED, + MEI_DEV_RECOVERING_FROM_RESET, MEI_DEV_POWER_DOWN, MEI_DEV_POWER_UP }; const char *mei_dev_state_str(int state); +/* init clients states*/ +enum mei_init_clients_states { + MEI_START_MESSAGE = 0, + MEI_ENUM_CLIENTS_MESSAGE, + MEI_CLIENT_PROPERTIES_MESSAGE +}; + enum iamthif_states { MEI_IAMTHIF_IDLE, MEI_IAMTHIF_WRITING, @@ -147,7 +153,7 @@ enum mei_cb_file_ops { /* * Intel MEI message data struct */ -struct mei_msg_data { +struct mei_message_data { u32 size; unsigned char *data; }; @@ -178,8 +184,8 @@ struct mei_cl_cb { struct list_head list; struct mei_cl *cl; enum mei_cb_file_ops fop_type; - struct mei_msg_data request_buffer; - struct mei_msg_data response_buffer; + struct mei_message_data request_buffer; + struct mei_message_data response_buffer; unsigned long buf_idx; unsigned long read_time; struct file *file_object; @@ -203,20 +209,15 @@ struct mei_cl { enum mei_file_transaction_states writing_state; int sm_state; struct mei_cl_cb *read_cb; - - /* MEI CL bus data */ - struct mei_cl_device *device; - struct list_head device_link; - uuid_le device_uuid; }; /** struct mei_hw_ops * + * @host_set_ready - notify FW that host side is ready * @host_is_ready - query for host readiness * @hw_is_ready - query if hw is ready * @hw_reset - reset hw - * @hw_start - start hw after reset * @hw_config - configure hw * @intr_clear - clear pending interrupts @@ -236,11 +237,11 @@ struct mei_cl { */ struct mei_hw_ops { + void (*host_set_ready) (struct mei_device *dev); bool (*host_is_ready) (struct mei_device *dev); bool (*hw_is_ready) (struct mei_device *dev); void (*hw_reset) (struct mei_device *dev, bool enable); - int (*hw_start) (struct mei_device *dev); void (*hw_config) (struct mei_device *dev); void (*intr_clear) (struct mei_device *dev); @@ -262,77 +263,9 @@ struct mei_hw_ops { unsigned char *buf, unsigned long len); }; -/* MEI bus API*/ - -/** - * struct mei_cl_ops - MEI CL device ops - * This structure allows ME host clients to implement technology - * specific operations. - * - * @enable: Enable an MEI CL device. Some devices require specific - * HECI commands to initialize completely. - * @disable: Disable an MEI CL device. - * @send: Tx hook for the device. This allows ME host clients to trap - * the device driver buffers before actually physically - * pushing it to the ME. - * @recv: Rx hook for the device. This allows ME host clients to trap the - * ME buffers before forwarding them to the device driver. - */ -struct mei_cl_ops { - int (*enable)(struct mei_cl_device *device); - int (*disable)(struct mei_cl_device *device); - int (*send)(struct mei_cl_device *device, u8 *buf, size_t length); - int (*recv)(struct mei_cl_device *device, u8 *buf, size_t length); -}; - -struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, - uuid_le uuid, char *name, - struct mei_cl_ops *ops); -void mei_cl_remove_device(struct mei_cl_device *device); - -int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length); -int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length); -int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); -void mei_cl_bus_rx_event(struct mei_cl *cl); -int mei_cl_bus_init(void); -void mei_cl_bus_exit(void); - - -/** - * struct mei_cl_device - MEI device handle - * An mei_cl_device pointer is returned from mei_add_device() - * and links MEI bus clients to their actual ME host client pointer. - * Drivers for MEI devices will get an mei_cl_device pointer - * when being probed and shall use it for doing ME bus I/O. - * - * @dev: linux driver model device pointer - * @uuid: me client uuid - * @cl: mei client - * @ops: ME transport ops - * @event_cb: Drivers register this callback to get asynchronous ME - * events (e.g. Rx buffer pending) notifications. - * @events: Events bitmask sent to the driver. - * @priv_data: client private data - */ -struct mei_cl_device { - struct device dev; - - struct mei_cl *cl; - - const struct mei_cl_ops *ops; - - struct work_struct event_work; - mei_cl_event_cb_t event_cb; - void *event_context; - unsigned long events; - - void *priv_data; -}; - /** * struct mei_device - MEI private device struct - * @hbm_state - state of host bus message protocol * @mem_addr - mem mapped base register address * @hbuf_depth - depth of hardware host/write buffer is slots @@ -363,12 +296,11 @@ struct mei_device { */ struct mutex device_lock; /* device lock */ struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ + bool recvd_msg; - bool recvd_hw_ready; /* * waiting queue for receive message from FW */ - wait_queue_head_t wait_hw_ready; wait_queue_head_t wait_recvd_msg; wait_queue_head_t wait_stop_wd; @@ -376,7 +308,7 @@ struct mei_device { * mei device states */ enum mei_dev_state dev_state; - enum mei_hbm_state hbm_state; + enum mei_init_clients_states init_clients_state; u16 init_clients_timer; unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ @@ -433,14 +365,6 @@ struct mei_device { struct work_struct init_work; - /* List of bus devices */ - struct list_head device_list; - -#if IS_ENABLED(CONFIG_DEBUG_FS) - struct dentry *dbgfs_dir; -#endif /* CONFIG_DEBUG_FS */ - - const struct mei_hw_ops *ops; char hw[0] __aligned(sizeof(void *)); }; @@ -450,24 +374,13 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec) return msecs_to_jiffies(sec * MSEC_PER_SEC); } -/** - * mei_data2slots - get slots - number of (dwords) from a message length - * + size of the mei header - * @length - size of the messages in bytes - * returns - number of slots - */ -static inline u32 mei_data2slots(size_t length) -{ - return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); -} /* * mei init function prototypes */ void mei_device_init(struct mei_device *dev); void mei_reset(struct mei_device *dev, int interrupts); -int mei_start(struct mei_device *dev); -void mei_stop(struct mei_device *dev); +int mei_hw_init(struct mei_device *dev); /* * MEI interrupt functions prototype @@ -478,7 +391,8 @@ int mei_irq_read_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list, s32 *slots); int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list); -void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list); + +void mei_irq_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb_pos); /* * AMTHIF - AMT Host Interface Functions @@ -502,25 +416,6 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, void mei_amthif_run_next_cmd(struct mei_device *dev); -int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); - -void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb); -int mei_amthif_irq_read_msg(struct mei_device *dev, - struct mei_msg_hdr *mei_hdr, - struct mei_cl_cb *complete_list); -int mei_amthif_irq_read(struct mei_device *dev, s32 *slots); - -/* - * NFC functions - */ -int mei_nfc_host_init(struct mei_device *dev); -void mei_nfc_host_exit(void); - -/* - * NFC Client UUID - */ -extern const uuid_le mei_nfc_guid; int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); @@ -559,11 +454,6 @@ static inline void mei_hw_reset(struct mei_device *dev, bool enable) dev->ops->hw_reset(dev, enable); } -static inline void mei_hw_start(struct mei_device *dev) -{ - dev->ops->hw_start(dev); -} - static inline void mei_clear_interrupts(struct mei_device *dev) { dev->ops->intr_clear(dev); @@ -579,6 +469,10 @@ static inline void mei_disable_interrupts(struct mei_device *dev) dev->ops->intr_disable(dev); } +static inline void mei_host_set_ready(struct mei_device *dev) +{ + dev->ops->host_set_ready(dev); +} static inline bool mei_host_is_ready(struct mei_device *dev) { return dev->ops->host_is_ready(dev); @@ -626,19 +520,8 @@ static inline int mei_count_full_read_slots(struct mei_device *dev) return dev->ops->rdbuf_full_slots(dev); } -#if IS_ENABLED(CONFIG_DEBUG_FS) -int mei_dbgfs_register(struct mei_device *dev, const char *name); -void mei_dbgfs_deregister(struct mei_device *dev); -#else -static inline int mei_dbgfs_register(struct mei_device *dev, const char *name) -{ - return 0; -} -static inline void mei_dbgfs_deregister(struct mei_device *dev) {} -#endif /* CONFIG_DEBUG_FS */ - -int mei_register(struct mei_device *dev); -void mei_deregister(struct mei_device *dev); +int mei_register(struct device *dev); +void mei_deregister(void); #define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d comp=%1d" #define MEI_HDR_PRM(hdr) \ diff --git a/trunk/drivers/misc/mei/nfc.c b/trunk/drivers/misc/mei/nfc.c deleted file mode 100644 index 3adf8a70f26e..000000000000 --- a/trunk/drivers/misc/mei/nfc.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2013, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "mei_dev.h" -#include "client.h" - -struct mei_nfc_cmd { - u8 command; - u8 status; - u16 req_id; - u32 reserved; - u16 data_size; - u8 sub_command; - u8 data[]; -} __packed; - -struct mei_nfc_reply { - u8 command; - u8 status; - u16 req_id; - u32 reserved; - u16 data_size; - u8 sub_command; - u8 reply_status; - u8 data[]; -} __packed; - -struct mei_nfc_if_version { - u8 radio_version_sw[3]; - u8 reserved[3]; - u8 radio_version_hw[3]; - u8 i2c_addr; - u8 fw_ivn; - u8 vendor_id; - u8 radio_type; -} __packed; - -struct mei_nfc_connect { - u8 fw_ivn; - u8 vendor_id; -} __packed; - -struct mei_nfc_connect_resp { - u8 fw_ivn; - u8 vendor_id; - u16 me_major; - u16 me_minor; - u16 me_hotfix; - u16 me_build; -} __packed; - -struct mei_nfc_hci_hdr { - u8 cmd; - u8 status; - u16 req_id; - u32 reserved; - u16 data_size; -} __packed; - -#define MEI_NFC_CMD_MAINTENANCE 0x00 -#define MEI_NFC_CMD_HCI_SEND 0x01 -#define MEI_NFC_CMD_HCI_RECV 0x02 - -#define MEI_NFC_SUBCMD_CONNECT 0x00 -#define MEI_NFC_SUBCMD_IF_VERSION 0x01 - -#define MEI_NFC_HEADER_SIZE 10 - -/** mei_nfc_dev - NFC mei device - * - * @cl: NFC host client - * @cl_info: NFC info host client - * @init_work: perform connection to the info client - * @fw_ivn: NFC Intervace Version Number - * @vendor_id: NFC manufacturer ID - * @radio_type: NFC radio type - */ -struct mei_nfc_dev { - struct mei_cl *cl; - struct mei_cl *cl_info; - struct work_struct init_work; - wait_queue_head_t send_wq; - u8 fw_ivn; - u8 vendor_id; - u8 radio_type; - char *bus_name; - - u16 req_id; - u16 recv_req_id; -}; - -static struct mei_nfc_dev nfc_dev; - -/* UUIDs for NFC F/W clients */ -const uuid_le mei_nfc_guid = UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, - 0x94, 0xd4, 0x50, 0x26, - 0x67, 0x23, 0x77, 0x5c); - -static const uuid_le mei_nfc_info_guid = UUID_LE(0xd2de1625, 0x382d, 0x417d, - 0x48, 0xa4, 0xef, 0xab, - 0xba, 0x8a, 0x12, 0x06); - -/* Vendors */ -#define MEI_NFC_VENDOR_INSIDE 0x00 -#define MEI_NFC_VENDOR_NXP 0x01 - -/* Radio types */ -#define MEI_NFC_VENDOR_INSIDE_UREAD 0x00 -#define MEI_NFC_VENDOR_NXP_PN544 0x01 - -static void mei_nfc_free(struct mei_nfc_dev *ndev) -{ - if (ndev->cl) { - list_del(&ndev->cl->device_link); - mei_cl_unlink(ndev->cl); - kfree(ndev->cl); - } - - if (ndev->cl_info) { - list_del(&ndev->cl_info->device_link); - mei_cl_unlink(ndev->cl_info); - kfree(ndev->cl_info); - } -} - -static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev) -{ - struct mei_device *dev; - - if (!ndev->cl) - return -ENODEV; - - dev = ndev->cl->dev; - - switch (ndev->vendor_id) { - case MEI_NFC_VENDOR_INSIDE: - switch (ndev->radio_type) { - case MEI_NFC_VENDOR_INSIDE_UREAD: - ndev->bus_name = "microread"; - return 0; - - default: - dev_err(&dev->pdev->dev, "Unknow radio type 0x%x\n", - ndev->radio_type); - - return -EINVAL; - } - - case MEI_NFC_VENDOR_NXP: - switch (ndev->radio_type) { - case MEI_NFC_VENDOR_NXP_PN544: - ndev->bus_name = "pn544"; - return 0; - default: - dev_err(&dev->pdev->dev, "Unknow radio type 0x%x\n", - ndev->radio_type); - - return -EINVAL; - } - - default: - dev_err(&dev->pdev->dev, "Unknow vendor ID 0x%x\n", - ndev->vendor_id); - - return -EINVAL; - } - - return 0; -} - -static int mei_nfc_connect(struct mei_nfc_dev *ndev) -{ - struct mei_device *dev; - struct mei_cl *cl; - struct mei_nfc_cmd *cmd, *reply; - struct mei_nfc_connect *connect; - struct mei_nfc_connect_resp *connect_resp; - size_t connect_length, connect_resp_length; - int bytes_recv, ret; - - cl = ndev->cl; - dev = cl->dev; - - connect_length = sizeof(struct mei_nfc_cmd) + - sizeof(struct mei_nfc_connect); - - connect_resp_length = sizeof(struct mei_nfc_cmd) + - sizeof(struct mei_nfc_connect_resp); - - cmd = kzalloc(connect_length, GFP_KERNEL); - if (!cmd) - return -ENOMEM; - connect = (struct mei_nfc_connect *)cmd->data; - - reply = kzalloc(connect_resp_length, GFP_KERNEL); - if (!reply) { - kfree(cmd); - return -ENOMEM; - } - - connect_resp = (struct mei_nfc_connect_resp *)reply->data; - - cmd->command = MEI_NFC_CMD_MAINTENANCE; - cmd->data_size = 3; - cmd->sub_command = MEI_NFC_SUBCMD_CONNECT; - connect->fw_ivn = ndev->fw_ivn; - connect->vendor_id = ndev->vendor_id; - - ret = __mei_cl_send(cl, (u8 *)cmd, connect_length); - if (ret < 0) { - dev_err(&dev->pdev->dev, "Could not send connect cmd\n"); - goto err; - } - - bytes_recv = __mei_cl_recv(cl, (u8 *)reply, connect_resp_length); - if (bytes_recv < 0) { - dev_err(&dev->pdev->dev, "Could not read connect response\n"); - ret = bytes_recv; - goto err; - } - - dev_info(&dev->pdev->dev, "IVN 0x%x Vendor ID 0x%x\n", - connect_resp->fw_ivn, connect_resp->vendor_id); - - dev_info(&dev->pdev->dev, "ME FW %d.%d.%d.%d\n", - connect_resp->me_major, connect_resp->me_minor, - connect_resp->me_hotfix, connect_resp->me_build); - - ret = 0; - -err: - kfree(reply); - kfree(cmd); - - return ret; -} - -static int mei_nfc_if_version(struct mei_nfc_dev *ndev) -{ - struct mei_device *dev; - struct mei_cl *cl; - - struct mei_nfc_cmd cmd; - struct mei_nfc_reply *reply = NULL; - struct mei_nfc_if_version *version; - size_t if_version_length; - int bytes_recv, ret; - - cl = ndev->cl_info; - dev = cl->dev; - - memset(&cmd, 0, sizeof(struct mei_nfc_cmd)); - cmd.command = MEI_NFC_CMD_MAINTENANCE; - cmd.data_size = 1; - cmd.sub_command = MEI_NFC_SUBCMD_IF_VERSION; - - ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd)); - if (ret < 0) { - dev_err(&dev->pdev->dev, "Could not send IF version cmd\n"); - return ret; - } - - /* to be sure on the stack we alloc memory */ - if_version_length = sizeof(struct mei_nfc_reply) + - sizeof(struct mei_nfc_if_version); - - reply = kzalloc(if_version_length, GFP_KERNEL); - if (!reply) - return -ENOMEM; - - bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length); - if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) { - dev_err(&dev->pdev->dev, "Could not read IF version\n"); - ret = -EIO; - goto err; - } - - version = (struct mei_nfc_if_version *)reply->data; - - ndev->fw_ivn = version->fw_ivn; - ndev->vendor_id = version->vendor_id; - ndev->radio_type = version->radio_type; - -err: - kfree(reply); - return ret; -} - -static int mei_nfc_enable(struct mei_cl_device *cldev) -{ - struct mei_device *dev; - struct mei_nfc_dev *ndev = &nfc_dev; - int ret; - - dev = ndev->cl->dev; - - ret = mei_nfc_connect(ndev); - if (ret < 0) { - dev_err(&dev->pdev->dev, "Could not connect to NFC"); - return ret; - } - - return 0; -} - -static int mei_nfc_disable(struct mei_cl_device *cldev) -{ - return 0; -} - -static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) -{ - struct mei_device *dev; - struct mei_nfc_dev *ndev; - struct mei_nfc_hci_hdr *hdr; - u8 *mei_buf; - int err; - - ndev = (struct mei_nfc_dev *) cldev->priv_data; - dev = ndev->cl->dev; - - mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL); - if (!mei_buf) - return -ENOMEM; - - hdr = (struct mei_nfc_hci_hdr *) mei_buf; - hdr->cmd = MEI_NFC_CMD_HCI_SEND; - hdr->status = 0; - hdr->req_id = ndev->req_id; - hdr->reserved = 0; - hdr->data_size = length; - - memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length); - - err = __mei_cl_send(ndev->cl, mei_buf, length + MEI_NFC_HEADER_SIZE); - if (err < 0) - return err; - - kfree(mei_buf); - - if (!wait_event_interruptible_timeout(ndev->send_wq, - ndev->recv_req_id == ndev->req_id, HZ)) { - dev_err(&dev->pdev->dev, "NFC MEI command timeout\n"); - err = -ETIMEDOUT; - } else { - ndev->req_id++; - } - - return err; -} - -static int mei_nfc_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) -{ - struct mei_nfc_dev *ndev; - struct mei_nfc_hci_hdr *hci_hdr; - int received_length; - - ndev = (struct mei_nfc_dev *)cldev->priv_data; - - received_length = __mei_cl_recv(ndev->cl, buf, length); - if (received_length < 0) - return received_length; - - hci_hdr = (struct mei_nfc_hci_hdr *) buf; - - if (hci_hdr->cmd == MEI_NFC_CMD_HCI_SEND) { - ndev->recv_req_id = hci_hdr->req_id; - wake_up(&ndev->send_wq); - - return 0; - } - - return received_length; -} - -static struct mei_cl_ops nfc_ops = { - .enable = mei_nfc_enable, - .disable = mei_nfc_disable, - .send = mei_nfc_send, - .recv = mei_nfc_recv, -}; - -static void mei_nfc_init(struct work_struct *work) -{ - struct mei_device *dev; - struct mei_cl_device *cldev; - struct mei_nfc_dev *ndev; - struct mei_cl *cl_info; - - ndev = container_of(work, struct mei_nfc_dev, init_work); - - cl_info = ndev->cl_info; - dev = cl_info->dev; - - mutex_lock(&dev->device_lock); - - if (mei_cl_connect(cl_info, NULL) < 0) { - mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, - "Could not connect to the NFC INFO ME client"); - - goto err; - } - - mutex_unlock(&dev->device_lock); - - if (mei_nfc_if_version(ndev) < 0) { - dev_err(&dev->pdev->dev, "Could not get the NFC interfave version"); - - goto err; - } - - dev_info(&dev->pdev->dev, - "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n", - ndev->fw_ivn, ndev->vendor_id, ndev->radio_type); - - mutex_lock(&dev->device_lock); - - if (mei_cl_disconnect(cl_info) < 0) { - mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, - "Could not disconnect the NFC INFO ME client"); - - goto err; - } - - mutex_unlock(&dev->device_lock); - - if (mei_nfc_build_bus_name(ndev) < 0) { - dev_err(&dev->pdev->dev, - "Could not build the bus ID name\n"); - return; - } - - cldev = mei_cl_add_device(dev, mei_nfc_guid, ndev->bus_name, &nfc_ops); - if (!cldev) { - dev_err(&dev->pdev->dev, - "Could not add the NFC device to the MEI bus\n"); - - goto err; - } - - cldev->priv_data = ndev; - - - return; - -err: - mei_nfc_free(ndev); - - return; -} - - -int mei_nfc_host_init(struct mei_device *dev) -{ - struct mei_nfc_dev *ndev = &nfc_dev; - struct mei_cl *cl_info, *cl = NULL; - int i, ret; - - /* already initialzed */ - if (ndev->cl_info) - return 0; - - cl_info = mei_cl_allocate(dev); - cl = mei_cl_allocate(dev); - - if (!cl || !cl_info) { - ret = -ENOMEM; - goto err; - } - - /* check for valid client id */ - i = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); - if (i < 0) { - dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); - ret = -ENOENT; - goto err; - } - - cl_info->me_client_id = dev->me_clients[i].client_id; - - ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY); - if (ret) - goto err; - - cl_info->device_uuid = mei_nfc_info_guid; - - list_add_tail(&cl_info->device_link, &dev->device_list); - - /* check for valid client id */ - i = mei_me_cl_by_uuid(dev, &mei_nfc_guid); - if (i < 0) { - dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); - ret = -ENOENT; - goto err; - } - - cl->me_client_id = dev->me_clients[i].client_id; - - ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); - if (ret) - goto err; - - cl->device_uuid = mei_nfc_guid; - - list_add_tail(&cl->device_link, &dev->device_list); - - ndev->cl_info = cl_info; - ndev->cl = cl; - ndev->req_id = 1; - - INIT_WORK(&ndev->init_work, mei_nfc_init); - init_waitqueue_head(&ndev->send_wq); - schedule_work(&ndev->init_work); - - return 0; - -err: - mei_nfc_free(ndev); - - return ret; -} - -void mei_nfc_host_exit(void) -{ - struct mei_nfc_dev *ndev = &nfc_dev; - - if (ndev->cl && ndev->cl->device) - mei_cl_remove_device(ndev->cl->device); - - mei_nfc_free(ndev); -} diff --git a/trunk/drivers/misc/mei/pci-me.c b/trunk/drivers/misc/mei/pci-me.c index 88aec6a90ff4..b40ec0601ab0 100644 --- a/trunk/drivers/misc/mei/pci-me.c +++ b/trunk/drivers/misc/mei/pci-me.c @@ -47,7 +47,7 @@ static struct pci_dev *mei_pdev; /* mei_pci_tbl - PCI Device ID Table */ -static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = { +static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)}, @@ -86,7 +86,7 @@ static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = { {0, } }; -MODULE_DEVICE_TABLE(pci, mei_me_pci_tbl); +MODULE_DEVICE_TABLE(pci, mei_pci_tbl); static DEFINE_MUTEX(mei_mutex); @@ -97,7 +97,7 @@ static DEFINE_MUTEX(mei_mutex); * * returns true if ME Interface is valid, false otherwise */ -static bool mei_me_quirk_probe(struct pci_dev *pdev, +static bool mei_quirk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { u32 reg; @@ -119,7 +119,7 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev, * * returns 0 on success, <0 on failure. */ -static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int mei_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct mei_device *dev; struct mei_me_hw *hw; @@ -127,7 +127,7 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mutex_lock(&mei_mutex); - if (!mei_me_quirk_probe(pdev, ent)) { + if (!mei_quirk_probe(pdev, ent)) { err = -ENODEV; goto end; } @@ -184,19 +184,20 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto disable_msi; } - if (mei_start(dev)) { + if (mei_hw_init(dev)) { dev_err(&pdev->dev, "init hw failure.\n"); err = -ENODEV; goto release_irq; } - err = mei_register(dev); + err = mei_register(&pdev->dev); if (err) goto release_irq; mei_pdev = pdev; pci_set_drvdata(pdev, dev); + schedule_delayed_work(&dev->timer_work, HZ); mutex_unlock(&mei_mutex); @@ -232,7 +233,7 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * mei_remove is called by the PCI subsystem to alert the driver * that it should release a PCI device. */ -static void mei_me_remove(struct pci_dev *pdev) +static void mei_remove(struct pci_dev *pdev) { struct mei_device *dev; struct mei_me_hw *hw; @@ -246,12 +247,44 @@ static void mei_me_remove(struct pci_dev *pdev) hw = to_me_hw(dev); + mutex_lock(&dev->device_lock); + + cancel_delayed_work(&dev->timer_work); - dev_err(&pdev->dev, "stop\n"); - mei_stop(dev); + mei_wd_stop(dev); mei_pdev = NULL; + if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) { + dev->iamthif_cl.state = MEI_FILE_DISCONNECTING; + mei_cl_disconnect(&dev->iamthif_cl); + } + if (dev->wd_cl.state == MEI_FILE_CONNECTED) { + dev->wd_cl.state = MEI_FILE_DISCONNECTING; + mei_cl_disconnect(&dev->wd_cl); + } + + /* Unregistering watchdog device */ + mei_watchdog_unregister(dev); + + /* remove entry if already in list */ + dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); + + if (dev->open_handle_count > 0) + dev->open_handle_count--; + mei_cl_unlink(&dev->wd_cl); + + if (dev->open_handle_count > 0) + dev->open_handle_count--; + mei_cl_unlink(&dev->iamthif_cl); + + dev->iamthif_current_cb = NULL; + dev->me_clients_num = 0; + + mutex_unlock(&dev->device_lock); + + flush_scheduled_work(); + /* disable interrupts */ mei_disable_interrupts(dev); @@ -262,37 +295,44 @@ static void mei_me_remove(struct pci_dev *pdev) if (hw->mem_addr) pci_iounmap(pdev, hw->mem_addr); - mei_deregister(dev); - kfree(dev); pci_release_regions(pdev); pci_disable_device(pdev); + mei_deregister(); } #ifdef CONFIG_PM -static int mei_me_pci_suspend(struct device *device) +static int mei_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mei_device *dev = pci_get_drvdata(pdev); + int err; if (!dev) return -ENODEV; + mutex_lock(&dev->device_lock); - dev_err(&pdev->dev, "suspend\n"); - - mei_stop(dev); + cancel_delayed_work(&dev->timer_work); - mei_disable_interrupts(dev); + /* Stop watchdog if exists */ + err = mei_wd_stop(dev); + /* Set new mei state */ + if (dev->dev_state == MEI_DEV_ENABLED || + dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) { + dev->dev_state = MEI_DEV_POWER_DOWN; + mei_reset(dev, 0); + } + mutex_unlock(&dev->device_lock); free_irq(pdev->irq, dev); pci_disable_msi(pdev); - return 0; + return err; } -static int mei_me_pci_resume(struct device *device) +static int mei_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mei_device *dev; @@ -332,24 +372,24 @@ static int mei_me_pci_resume(struct device *device) return err; } -static SIMPLE_DEV_PM_OPS(mei_me_pm_ops, mei_me_pci_suspend, mei_me_pci_resume); -#define MEI_ME_PM_OPS (&mei_me_pm_ops) +static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume); +#define MEI_PM_OPS (&mei_pm_ops) #else -#define MEI_ME_PM_OPS NULL +#define MEI_PM_OPS NULL #endif /* CONFIG_PM */ /* * PCI driver structure */ -static struct pci_driver mei_me_driver = { +static struct pci_driver mei_driver = { .name = KBUILD_MODNAME, - .id_table = mei_me_pci_tbl, - .probe = mei_me_probe, - .remove = mei_me_remove, - .shutdown = mei_me_remove, - .driver.pm = MEI_ME_PM_OPS, + .id_table = mei_pci_tbl, + .probe = mei_probe, + .remove = mei_remove, + .shutdown = mei_remove, + .driver.pm = MEI_PM_OPS, }; -module_pci_driver(mei_me_driver); +module_pci_driver(mei_driver); MODULE_AUTHOR("Intel Corporation"); MODULE_DESCRIPTION("Intel(R) Management Engine Interface"); diff --git a/trunk/drivers/misc/mei/wd.c b/trunk/drivers/misc/mei/wd.c index eb3f05c8d7d0..2413247fc392 100644 --- a/trunk/drivers/misc/mei/wd.c +++ b/trunk/drivers/misc/mei/wd.c @@ -317,8 +317,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) * * returns 0 if success, negative errno code for failure */ -static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, - unsigned int timeout) +static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, unsigned int timeout) { struct mei_device *dev; diff --git a/trunk/drivers/misc/tsl2550.c b/trunk/drivers/misc/tsl2550.c index 1dfde4d543db..1e7bc0eb081e 100644 --- a/trunk/drivers/misc/tsl2550.c +++ b/trunk/drivers/misc/tsl2550.c @@ -417,26 +417,24 @@ static int tsl2550_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM -static int tsl2550_suspend(struct device *dev) +static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg) { - return tsl2550_set_power_state(to_i2c_client(dev), 0); + return tsl2550_set_power_state(client, 0); } -static int tsl2550_resume(struct device *dev) +static int tsl2550_resume(struct i2c_client *client) { - return tsl2550_set_power_state(to_i2c_client(dev), 1); + return tsl2550_set_power_state(client, 1); } -static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops, tsl2550_suspend, tsl2550_resume); -#define TSL2550_PM_OPS (&tsl2550_pm_ops) - #else -#define TSL2550_PM_OPS NULL +#define tsl2550_suspend NULL +#define tsl2550_resume NULL -#endif /* CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM */ static const struct i2c_device_id tsl2550_id[] = { { "tsl2550", 0 }, @@ -448,8 +446,9 @@ static struct i2c_driver tsl2550_driver = { .driver = { .name = TSL2550_DRV_NAME, .owner = THIS_MODULE, - .pm = TSL2550_PM_OPS, }, + .suspend = tsl2550_suspend, + .resume = tsl2550_resume, .probe = tsl2550_probe, .remove = tsl2550_remove, .id_table = tsl2550_id, diff --git a/trunk/drivers/misc/vmw_vmci/Kconfig b/trunk/drivers/misc/vmw_vmci/Kconfig index ea98f7e9ccd1..39c2ecadb273 100644 --- a/trunk/drivers/misc/vmw_vmci/Kconfig +++ b/trunk/drivers/misc/vmw_vmci/Kconfig @@ -4,7 +4,7 @@ config VMWARE_VMCI tristate "VMware VMCI Driver" - depends on X86 && PCI && NET + depends on X86 && PCI help This is VMware's Virtual Machine Communication Interface. It enables high-speed communication between host and guest in a virtual diff --git a/trunk/drivers/misc/vmw_vmci/vmci_datagram.c b/trunk/drivers/misc/vmw_vmci/vmci_datagram.c index f3cdd904fe4d..ed5c433cd493 100644 --- a/trunk/drivers/misc/vmw_vmci/vmci_datagram.c +++ b/trunk/drivers/misc/vmw_vmci/vmci_datagram.c @@ -42,11 +42,9 @@ struct datagram_entry { struct delayed_datagram_info { struct datagram_entry *entry; + struct vmci_datagram msg; struct work_struct work; bool in_dg_host_queue; - /* msg and msg_payload must be together. */ - struct vmci_datagram msg; - u8 msg_payload[]; }; /* Number of in-flight host->host datagrams */ diff --git a/trunk/drivers/mmc/host/sdricoh_cs.c b/trunk/drivers/mmc/host/sdricoh_cs.c index 50adbd155f35..7009f17ad6cd 100644 --- a/trunk/drivers/mmc/host/sdricoh_cs.c +++ b/trunk/drivers/mmc/host/sdricoh_cs.c @@ -543,7 +543,25 @@ static struct pcmcia_driver sdricoh_driver = { .suspend = sdricoh_pcmcia_suspend, .resume = sdricoh_pcmcia_resume, }; -module_pcmcia_driver(sdricoh_driver); + +/*****************************************************************************\ + * * + * Driver init/exit * + * * +\*****************************************************************************/ + +static int __init sdricoh_drv_init(void) +{ + return pcmcia_register_driver(&sdricoh_driver); +} + +static void __exit sdricoh_drv_exit(void) +{ + pcmcia_unregister_driver(&sdricoh_driver); +} + +module_init(sdricoh_drv_init); +module_exit(sdricoh_drv_exit); module_param(switchlocked, uint, 0444); diff --git a/trunk/drivers/mtd/bcm47xxpart.c b/trunk/drivers/mtd/bcm47xxpart.c index 9279a9174f84..63feb75cc8e0 100644 --- a/trunk/drivers/mtd/bcm47xxpart.c +++ b/trunk/drivers/mtd/bcm47xxpart.c @@ -19,12 +19,6 @@ /* 10 parts were found on sflash on Netgear WNDR4500 */ #define BCM47XXPART_MAX_PARTS 12 -/* - * Amount of bytes we read when analyzing each block of flash memory. - * Set it big enough to allow detecting partition and reading important data. - */ -#define BCM47XXPART_BYTES_TO_READ 0x404 - /* Magics */ #define BOARD_DATA_MAGIC 0x5246504D /* MPFR */ #define POT_MAGIC1 0x54544f50 /* POTT */ @@ -63,15 +57,17 @@ static int bcm47xxpart_parse(struct mtd_info *master, struct trx_header *trx; int trx_part = -1; int last_trx_part = -1; - int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; + int max_bytes_to_read = 0x8004; if (blocksize <= 0x10000) blocksize = 0x10000; + if (blocksize == 0x20000) + max_bytes_to_read = 0x18004; /* Alloc */ parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS, GFP_KERNEL); - buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL); + buf = kzalloc(max_bytes_to_read, GFP_KERNEL); /* Parse block by block looking for magics */ for (offset = 0; offset <= master->size - blocksize; @@ -86,7 +82,7 @@ static int bcm47xxpart_parse(struct mtd_info *master, } /* Read beginning of the block */ - if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ, + if (mtd_read(master, offset, max_bytes_to_read, &bytes_read, (uint8_t *)buf) < 0) { pr_err("mtd_read error while parsing (offset: 0x%X)!\n", offset); @@ -100,6 +96,20 @@ static int bcm47xxpart_parse(struct mtd_info *master, continue; } + /* Standard NVRAM */ + if (buf[0x000 / 4] == NVRAM_HEADER || + buf[0x1000 / 4] == NVRAM_HEADER || + buf[0x8000 / 4] == NVRAM_HEADER || + (blocksize == 0x20000 && ( + buf[0x10000 / 4] == NVRAM_HEADER || + buf[0x11000 / 4] == NVRAM_HEADER || + buf[0x18000 / 4] == NVRAM_HEADER))) { + bcm47xxpart_add_part(&parts[curr_part++], "nvram", + offset, 0); + offset = rounddown(offset, blocksize); + continue; + } + /* * board_data starts with board_id which differs across boards, * but we can use 'MPFR' (hopefully) magic at 0x100 @@ -168,30 +178,6 @@ static int bcm47xxpart_parse(struct mtd_info *master, continue; } } - - /* Look for NVRAM at the end of the last block. */ - for (i = 0; i < ARRAY_SIZE(possible_nvram_sizes); i++) { - if (curr_part > BCM47XXPART_MAX_PARTS) { - pr_warn("Reached maximum number of partitions, scanning stopped!\n"); - break; - } - - offset = master->size - possible_nvram_sizes[i]; - if (mtd_read(master, offset, 0x4, &bytes_read, - (uint8_t *)buf) < 0) { - pr_err("mtd_read error while reading at offset 0x%X!\n", - offset); - continue; - } - - /* Standard NVRAM */ - if (buf[0] == NVRAM_HEADER) { - bcm47xxpart_add_part(&parts[curr_part++], "nvram", - master->size - blocksize, 0); - break; - } - } - kfree(buf); /* diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index dc571ebc1aa0..82c06165d3d2 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -1123,6 +1123,33 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file, } #endif +static inline unsigned long get_vm_size(struct vm_area_struct *vma) +{ + return vma->vm_end - vma->vm_start; +} + +static inline resource_size_t get_vm_offset(struct vm_area_struct *vma) +{ + return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT; +} + +/* + * Set a new vm offset. + * + * Verify that the incoming offset really works as a page offset, + * and that the offset and size fit in a resource_size_t. + */ +static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off) +{ + pgoff_t pgoff = off >> PAGE_SHIFT; + if (off != (resource_size_t) pgoff << PAGE_SHIFT) + return -EINVAL; + if (off + get_vm_size(vma) - 1 < off) + return -EINVAL; + vma->vm_pgoff = pgoff; + return 0; +} + /* * set up a mapping for shared memory segments */ @@ -1132,17 +1159,45 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma) struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; struct map_info *map = mtd->priv; + resource_size_t start, off; + unsigned long len, vma_len; /* This is broken because it assumes the MTD device is map-based and that mtd->priv is a valid struct map_info. It should be replaced with something that uses the mtd_get_unmapped_area() operation properly. */ if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { + off = get_vm_offset(vma); + start = map->phys; + len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); + start &= PAGE_MASK; + vma_len = get_vm_size(vma); + + /* Overflow in off+len? */ + if (vma_len + off < off) + return -EINVAL; + /* Does it fit in the mapping? */ + if (vma_len + off > len) + return -EINVAL; + + off += start; + /* Did that overflow? */ + if (off < start) + return -EINVAL; + if (set_vm_offset(vma, off) < 0) + return -EINVAL; + vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; + #ifdef pgprot_noncached - if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory)) + if (file->f_flags & O_DSYNC || off >= __pa(high_memory)) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); #endif - return vm_iomap_memory(vma, map->phys, map->size); + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) + return -EAGAIN; + + return 0; } return -ENOSYS; #else @@ -1183,7 +1238,6 @@ static struct file_system_type mtd_inodefs_type = { .mount = mtd_inodefs_mount, .kill_sb = kill_anon_super, }; -MODULE_ALIAS_FS("mtd_inodefs"); static int __init init_mtdchar(void) { diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 42c63927609d..43214151b882 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -1523,14 +1523,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, oobreadlen -= toread; } } - - if (chip->options & NAND_NEED_READRDY) { - /* Apply delay or wait for ready/busy pin */ - if (!chip->dev_ready) - udelay(chip->chip_delay); - else - nand_wait_ready(mtd); - } } else { memcpy(buf, chip->buffers->databuf + col, bytes); buf += bytes; @@ -1795,14 +1787,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, len = min(len, readlen); buf = nand_transfer_oob(chip, buf, ops, len); - if (chip->options & NAND_NEED_READRDY) { - /* Apply delay or wait for ready/busy pin */ - if (!chip->dev_ready) - udelay(chip->chip_delay); - else - nand_wait_ready(mtd); - } - readlen -= len; if (!readlen) break; diff --git a/trunk/drivers/mtd/nand/nand_ids.c b/trunk/drivers/mtd/nand/nand_ids.c index 9c612388e5de..e3aa2748a6e7 100644 --- a/trunk/drivers/mtd/nand/nand_ids.c +++ b/trunk/drivers/mtd/nand/nand_ids.c @@ -22,51 +22,49 @@ * 512 512 Byte page size */ struct nand_flash_dev nand_flash_ids[] = { -#define SP_OPTIONS NAND_NEED_READRDY -#define SP_OPTIONS16 (SP_OPTIONS | NAND_BUSWIDTH_16) #ifdef CONFIG_MTD_NAND_MUSEUM_IDS - {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, SP_OPTIONS}, - {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, SP_OPTIONS}, - {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, SP_OPTIONS}, - {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, SP_OPTIONS}, - {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, SP_OPTIONS}, - {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, SP_OPTIONS}, - {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, SP_OPTIONS}, - {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, SP_OPTIONS}, - {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, SP_OPTIONS}, - {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, SP_OPTIONS}, - - {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, SP_OPTIONS}, - {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, SP_OPTIONS}, - {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, SP_OPTIONS16}, - {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, SP_OPTIONS16}, + {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, + {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0}, + {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0}, + {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0}, + {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0}, + {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, + {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, + + {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, + {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, + {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, + {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, #endif - {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, SP_OPTIONS}, - {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, SP_OPTIONS}, - {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, SP_OPTIONS16}, - {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, SP_OPTIONS16}, - - {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, SP_OPTIONS}, - {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, SP_OPTIONS}, - {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, SP_OPTIONS16}, - {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, SP_OPTIONS16}, - - {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, SP_OPTIONS}, - {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, SP_OPTIONS}, - {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, SP_OPTIONS16}, - {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, SP_OPTIONS16}, - - {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, SP_OPTIONS}, - {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, SP_OPTIONS}, - {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, SP_OPTIONS}, - {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, SP_OPTIONS16}, - {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, SP_OPTIONS16}, - {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, SP_OPTIONS16}, - {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, SP_OPTIONS16}, - - {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, SP_OPTIONS}, + {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, + {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, + {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, + {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, + {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, + {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, + {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, + {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, + {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, + {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + + {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, /* * These are the new chips with large page size. The pagesize and the diff --git a/trunk/drivers/net/arcnet/com20020_cs.c b/trunk/drivers/net/arcnet/com20020_cs.c index 74dc1875f9cd..5bed4c4e2508 100644 --- a/trunk/drivers/net/arcnet/com20020_cs.c +++ b/trunk/drivers/net/arcnet/com20020_cs.c @@ -333,4 +333,16 @@ static struct pcmcia_driver com20020_cs_driver = { .suspend = com20020_suspend, .resume = com20020_resume, }; -module_pcmcia_driver(com20020_cs_driver); + +static int __init init_com20020_cs(void) +{ + return pcmcia_register_driver(&com20020_cs_driver); +} + +static void __exit exit_com20020_cs(void) +{ + pcmcia_unregister_driver(&com20020_cs_driver); +} + +module_init(init_com20020_cs); +module_exit(exit_com20020_cs); diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index dbbea0eec134..11d01d67b3f5 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -846,10 +846,8 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, if (bond->dev->flags & IFF_ALLMULTI) dev_set_allmulti(old_active->dev, -1); - netif_addr_lock_bh(bond->dev); netdev_for_each_mc_addr(ha, bond->dev) dev_mc_del(old_active->dev, ha->addr); - netif_addr_unlock_bh(bond->dev); } if (new_active) { @@ -860,10 +858,8 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, if (bond->dev->flags & IFF_ALLMULTI) dev_set_allmulti(new_active->dev, 1); - netif_addr_lock_bh(bond->dev); netdev_for_each_mc_addr(ha, bond->dev) dev_mc_add(new_active->dev, ha->addr); - netif_addr_unlock_bh(bond->dev); } } @@ -1633,7 +1629,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* If this is the first slave, then we need to set the master's hardware * address to be the same as the slave's. */ - if (bond->slave_cnt == 0 && bond->dev_addr_from_first) + if (bond->dev_addr_from_first) bond_set_dev_addr(bond->dev, slave_dev); new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); @@ -1750,8 +1746,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) bond_compute_features(bond); - bond_update_speed_duplex(new_slave); - read_lock(&bond->lock); new_slave->last_arp_rx = jiffies - @@ -1804,6 +1798,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) new_slave->link == BOND_LINK_DOWN ? "DOWN" : (new_slave->link == BOND_LINK_UP ? "UP" : "BACK")); + bond_update_speed_duplex(new_slave); + if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) { /* if there is a primary slave, remember it */ if (strcmp(bond->params.primary, new_slave->dev->name) == 0) { @@ -1905,29 +1901,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) bond_destroy_slave_symlinks(bond_dev, slave_dev); err_detach: - if (!USES_PRIMARY(bond->params.mode)) { - netif_addr_lock_bh(bond_dev); - bond_mc_list_flush(bond_dev, slave_dev); - netif_addr_unlock_bh(bond_dev); - } - bond_del_vlans_from_slave(bond, slave_dev); write_lock_bh(&bond->lock); bond_detach_slave(bond, new_slave); - if (bond->primary_slave == new_slave) - bond->primary_slave = NULL; write_unlock_bh(&bond->lock); - if (bond->curr_active_slave == new_slave) { - read_lock(&bond->lock); - write_lock_bh(&bond->curr_slave_lock); - bond_change_active_slave(bond, NULL); - bond_select_active_slave(bond); - write_unlock_bh(&bond->curr_slave_lock); - read_unlock(&bond->lock); - } - slave_disable_netpoll(new_slave); err_close: - slave_dev->priv_flags &= ~IFF_BONDING; dev_close(slave_dev); err_unset_master: @@ -1986,6 +1964,7 @@ static int __bond_release_one(struct net_device *bond_dev, } block_netpoll_tx(); + call_netdevice_notifiers(NETDEV_RELEASE, bond_dev); write_lock_bh(&bond->lock); slave = bond_get_slave_by_dev(bond, slave_dev); @@ -1998,11 +1977,12 @@ static int __bond_release_one(struct net_device *bond_dev, return -EINVAL; } - write_unlock_bh(&bond->lock); /* unregister rx_handler early so bond_handle_frame wouldn't be called * for this slave anymore. */ netdev_rx_handler_unregister(slave_dev); + write_unlock_bh(&bond->lock); + synchronize_net(); write_lock_bh(&bond->lock); if (!all && !bond->params.fail_over_mac) { @@ -2086,10 +2066,8 @@ static int __bond_release_one(struct net_device *bond_dev, write_unlock_bh(&bond->lock); unblock_netpoll_tx(); - if (bond->slave_cnt == 0) { + if (bond->slave_cnt == 0) call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); - call_netdevice_notifiers(NETDEV_RELEASE, bond->dev); - } bond_compute_features(bond); if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) && @@ -2395,6 +2373,8 @@ static void bond_miimon_commit(struct bonding *bond) bond_set_backup_slave(slave); } + bond_update_speed_duplex(slave); + pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", bond->dev->name, slave->dev->name, slave->speed, slave->duplex ? "full" : "half"); @@ -3190,20 +3170,11 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) { struct slave *slave = bond_slave_get_rtnl(slave_dev); - struct bonding *bond; - struct net_device *bond_dev; + struct bonding *bond = slave->bond; + struct net_device *bond_dev = slave->bond->dev; u32 old_speed; u8 old_duplex; - /* A netdev event can be generated while enslaving a device - * before netdev_rx_handler_register is called in which case - * slave will be NULL - */ - if (!slave) - return NOTIFY_DONE; - bond_dev = slave->bond->dev; - bond = slave->bond; - switch (event) { case NETDEV_UNREGISTER: if (bond->setup_by_slave) @@ -3317,22 +3288,20 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count) */ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) { - const struct ethhdr *data; - const struct iphdr *iph; - const struct ipv6hdr *ipv6h; + struct ethhdr *data = (struct ethhdr *)skb->data; + struct iphdr *iph; + struct ipv6hdr *ipv6h; u32 v6hash; - const __be32 *s, *d; + __be32 *s, *d; if (skb->protocol == htons(ETH_P_IP) && - pskb_network_may_pull(skb, sizeof(*iph))) { + skb_network_header_len(skb) >= sizeof(*iph)) { iph = ip_hdr(skb); - data = (struct ethhdr *)skb->data; return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ (data->h_dest[5] ^ data->h_source[5])) % count; } else if (skb->protocol == htons(ETH_P_IPV6) && - pskb_network_may_pull(skb, sizeof(*ipv6h))) { + skb_network_header_len(skb) >= sizeof(*ipv6h)) { ipv6h = ipv6_hdr(skb); - data = (struct ethhdr *)skb->data; s = &ipv6h->saddr.s6_addr32[0]; d = &ipv6h->daddr.s6_addr32[0]; v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]); @@ -3351,36 +3320,33 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) { u32 layer4_xor = 0; - const struct iphdr *iph; - const struct ipv6hdr *ipv6h; - const __be32 *s, *d; - const __be16 *l4 = NULL; - __be16 _l4[2]; - int noff = skb_network_offset(skb); - int poff; + struct iphdr *iph; + struct ipv6hdr *ipv6h; + __be32 *s, *d; + __be16 *layer4hdr; if (skb->protocol == htons(ETH_P_IP) && - pskb_may_pull(skb, noff + sizeof(*iph))) { + skb_network_header_len(skb) >= sizeof(*iph)) { iph = ip_hdr(skb); - poff = proto_ports_offset(iph->protocol); - - if (!ip_is_fragment(iph) && poff >= 0) { - l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff, - sizeof(_l4), &_l4); - if (l4) - layer4_xor = ntohs(l4[0] ^ l4[1]); + if (!ip_is_fragment(iph) && + (iph->protocol == IPPROTO_TCP || + iph->protocol == IPPROTO_UDP) && + (skb_headlen(skb) - skb_network_offset(skb) >= + iph->ihl * sizeof(u32) + sizeof(*layer4hdr) * 2)) { + layer4hdr = (__be16 *)((u32 *)iph + iph->ihl); + layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1)); } return (layer4_xor ^ ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count; } else if (skb->protocol == htons(ETH_P_IPV6) && - pskb_may_pull(skb, noff + sizeof(*ipv6h))) { + skb_network_header_len(skb) >= sizeof(*ipv6h)) { ipv6h = ipv6_hdr(skb); - poff = proto_ports_offset(ipv6h->nexthdr); - if (poff >= 0) { - l4 = skb_header_pointer(skb, noff + sizeof(*ipv6h) + poff, - sizeof(_l4), &_l4); - if (l4) - layer4_xor = ntohs(l4[0] ^ l4[1]); + if ((ipv6h->nexthdr == IPPROTO_TCP || + ipv6h->nexthdr == IPPROTO_UDP) && + (skb_headlen(skb) - skb_network_offset(skb) >= + sizeof(*ipv6h) + sizeof(*layer4hdr) * 2)) { + layer4hdr = (__be16 *)(ipv6h + 1); + layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1)); } s = &ipv6h->saddr.s6_addr32[0]; d = &ipv6h->daddr.s6_addr32[0]; @@ -4882,18 +4848,9 @@ static int __net_init bond_net_init(struct net *net) static void __net_exit bond_net_exit(struct net *net) { struct bond_net *bn = net_generic(net, bond_net_id); - struct bonding *bond, *tmp_bond; - LIST_HEAD(list); bond_destroy_sysfs(bn); bond_destroy_proc_dir(bn); - - /* Kill off any bonds created after unregistering bond rtnl ops */ - rtnl_lock(); - list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list) - unregister_netdevice_queue(bond->dev, &list); - unregister_netdevice_many(&list); - rtnl_unlock(); } static struct pernet_operations bond_net_ops = { diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index ea7a388f4843..1c9e09fbdff8 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -183,11 +183,6 @@ int bond_create_slave_symlinks(struct net_device *master, sprintf(linkname, "slave_%s", slave->name); ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj), linkname); - - /* free the master link created earlier in case of error */ - if (ret) - sysfs_remove_link(&(slave->dev.kobj), "master"); - return ret; } @@ -527,7 +522,7 @@ static ssize_t bonding_store_arp_interval(struct device *d, goto out; } if (new_value < 0) { - pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n", + pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n", bond->dev->name, new_value, INT_MAX); ret = -EINVAL; goto out; @@ -542,15 +537,14 @@ static ssize_t bonding_store_arp_interval(struct device *d, pr_info("%s: Setting ARP monitoring interval to %d.\n", bond->dev->name, new_value); bond->params.arp_interval = new_value; - if (new_value) { - if (bond->params.miimon) { - pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", - bond->dev->name, bond->dev->name); - bond->params.miimon = 0; - } - if (!bond->params.arp_targets[0]) - pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", - bond->dev->name); + if (bond->params.miimon) { + pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", + bond->dev->name, bond->dev->name); + bond->params.miimon = 0; + } + if (!bond->params.arp_targets[0]) { + pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", + bond->dev->name); } if (bond->dev->flags & IFF_UP) { /* If the interface is up, we may need to fire off @@ -558,13 +552,10 @@ static ssize_t bonding_store_arp_interval(struct device *d, * timer will get fired off when the open function * is called. */ - if (!new_value) { - cancel_delayed_work_sync(&bond->arp_work); - } else { - cancel_delayed_work_sync(&bond->mii_work); - queue_delayed_work(bond->wq, &bond->arp_work, 0); - } + cancel_delayed_work_sync(&bond->mii_work); + queue_delayed_work(bond->wq, &bond->arp_work, 0); } + out: rtnl_unlock(); return ret; @@ -706,7 +697,7 @@ static ssize_t bonding_store_downdelay(struct device *d, } if (new_value < 0) { pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 0, INT_MAX); + bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; } else { @@ -761,8 +752,8 @@ static ssize_t bonding_store_updelay(struct device *d, goto out; } if (new_value < 0) { - pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 0, INT_MAX); + pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", + bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; } else { @@ -972,37 +963,37 @@ static ssize_t bonding_store_miimon(struct device *d, } if (new_value < 0) { pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 0, INT_MAX); + bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; - } - pr_info("%s: Setting MII monitoring interval to %d.\n", - bond->dev->name, new_value); - bond->params.miimon = new_value; - if (bond->params.updelay) - pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", - bond->dev->name, - bond->params.updelay * bond->params.miimon); - if (bond->params.downdelay) - pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", - bond->dev->name, - bond->params.downdelay * bond->params.miimon); - if (new_value && bond->params.arp_interval) { - pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", - bond->dev->name); - bond->params.arp_interval = 0; - if (bond->params.arp_validate) - bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; - } - if (bond->dev->flags & IFF_UP) { - /* If the interface is up, we may need to fire off - * the MII timer. If the interface is down, the - * timer will get fired off when the open function - * is called. - */ - if (!new_value) { - cancel_delayed_work_sync(&bond->mii_work); - } else { + } else { + pr_info("%s: Setting MII monitoring interval to %d.\n", + bond->dev->name, new_value); + bond->params.miimon = new_value; + if (bond->params.updelay) + pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", + bond->dev->name, + bond->params.updelay * bond->params.miimon); + if (bond->params.downdelay) + pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", + bond->dev->name, + bond->params.downdelay * bond->params.miimon); + if (bond->params.arp_interval) { + pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", + bond->dev->name); + bond->params.arp_interval = 0; + if (bond->params.arp_validate) { + bond->params.arp_validate = + BOND_ARP_VALIDATE_NONE; + } + } + + if (bond->dev->flags & IFF_UP) { + /* If the interface is up, we may need to fire off + * the MII timer. If the interface is down, the + * timer will get fired off when the open function + * is called. + */ cancel_delayed_work_sync(&bond->arp_work); queue_delayed_work(bond->wq, &bond->mii_work, 0); } diff --git a/trunk/drivers/net/can/mcp251x.c b/trunk/drivers/net/can/mcp251x.c index 9aa0c64c33c8..f32b9fc6a983 100644 --- a/trunk/drivers/net/can/mcp251x.c +++ b/trunk/drivers/net/can/mcp251x.c @@ -929,7 +929,6 @@ static int mcp251x_open(struct net_device *net) struct mcp251x_priv *priv = netdev_priv(net); struct spi_device *spi = priv->spi; struct mcp251x_platform_data *pdata = spi->dev.platform_data; - unsigned long flags; int ret; ret = open_candev(net); @@ -946,14 +945,9 @@ static int mcp251x_open(struct net_device *net) priv->tx_skb = NULL; priv->tx_len = 0; - flags = IRQF_ONESHOT; - if (pdata->irq_flags) - flags |= pdata->irq_flags; - else - flags |= IRQF_TRIGGER_FALLING; - ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist, - flags, DEVICE_NAME, priv); + pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING, + DEVICE_NAME, priv); if (ret) { dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq); if (pdata->transceiver_enable) diff --git a/trunk/drivers/net/can/sja1000/Kconfig b/trunk/drivers/net/can/sja1000/Kconfig index ff2ba86cd4a4..b39ca5b3ea7f 100644 --- a/trunk/drivers/net/can/sja1000/Kconfig +++ b/trunk/drivers/net/can/sja1000/Kconfig @@ -46,7 +46,6 @@ config CAN_EMS_PCI config CAN_PEAK_PCMCIA tristate "PEAK PCAN-PC Card" depends on PCMCIA - depends on HAS_IOPORT ---help--- This driver is for the PCAN-PC Card PCMCIA adapter (1 or 2 channels) from PEAK-System (http://www.peak-system.com). To compile this diff --git a/trunk/drivers/net/can/sja1000/ems_pcmcia.c b/trunk/drivers/net/can/sja1000/ems_pcmcia.c index 321c27e1c7fc..5c2f3fbbf5ae 100644 --- a/trunk/drivers/net/can/sja1000/ems_pcmcia.c +++ b/trunk/drivers/net/can/sja1000/ems_pcmcia.c @@ -316,4 +316,15 @@ static struct pcmcia_driver ems_pcmcia_driver = { .remove = ems_pcmcia_remove, .id_table = ems_pcmcia_tbl, }; -module_pcmcia_driver(ems_pcmcia_driver); + +static int __init ems_pcmcia_init(void) +{ + return pcmcia_register_driver(&ems_pcmcia_driver); +} +module_init(ems_pcmcia_init); + +static void __exit ems_pcmcia_exit(void) +{ + pcmcia_unregister_driver(&ems_pcmcia_driver); +} +module_exit(ems_pcmcia_exit); diff --git a/trunk/drivers/net/can/sja1000/peak_pcmcia.c b/trunk/drivers/net/can/sja1000/peak_pcmcia.c index 0a707f70661c..1a7020ba37f5 100644 --- a/trunk/drivers/net/can/sja1000/peak_pcmcia.c +++ b/trunk/drivers/net/can/sja1000/peak_pcmcia.c @@ -740,4 +740,15 @@ static struct pcmcia_driver pcan_driver = { .remove = pcan_remove, .id_table = pcan_table, }; -module_pcmcia_driver(pcan_driver); + +static int __init pcan_init(void) +{ + return pcmcia_register_driver(&pcan_driver); +} +module_init(pcan_init); + +static void __exit pcan_exit(void) +{ + pcmcia_unregister_driver(&pcan_driver); +} +module_exit(pcan_exit); diff --git a/trunk/drivers/net/can/sja1000/plx_pci.c b/trunk/drivers/net/can/sja1000/plx_pci.c index 3c18d7d000ed..a042cdc260dc 100644 --- a/trunk/drivers/net/can/sja1000/plx_pci.c +++ b/trunk/drivers/net/can/sja1000/plx_pci.c @@ -348,7 +348,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) */ if ((priv->read_reg(priv, REG_CR) & REG_CR_BASICCAN_INITIAL_MASK) == REG_CR_BASICCAN_INITIAL && - (priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_BASICCAN_INITIAL) && + (priv->read_reg(priv, REG_SR) == REG_SR_BASICCAN_INITIAL) && (priv->read_reg(priv, REG_IR) == REG_IR_BASICCAN_INITIAL)) flag = 1; @@ -360,7 +360,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) * See states on p. 23 of the Datasheet. */ if (priv->read_reg(priv, REG_MOD) == REG_MOD_PELICAN_INITIAL && - priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_PELICAN_INITIAL && + priv->read_reg(priv, REG_SR) == REG_SR_PELICAN_INITIAL && priv->read_reg(priv, REG_IR) == REG_IR_PELICAN_INITIAL) return flag; diff --git a/trunk/drivers/net/can/sja1000/sja1000.c b/trunk/drivers/net/can/sja1000/sja1000.c index e4df307eaa90..daf4013a8fc7 100644 --- a/trunk/drivers/net/can/sja1000/sja1000.c +++ b/trunk/drivers/net/can/sja1000/sja1000.c @@ -92,7 +92,7 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val) */ spin_lock_irqsave(&priv->cmdreg_lock, flags); priv->write_reg(priv, REG_CMR, val); - priv->read_reg(priv, SJA1000_REG_SR); + priv->read_reg(priv, REG_SR); spin_unlock_irqrestore(&priv->cmdreg_lock, flags); } @@ -502,7 +502,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) { n++; - status = priv->read_reg(priv, SJA1000_REG_SR); + status = priv->read_reg(priv, REG_SR); /* check for absent controller due to hw unplug */ if (status == 0xFF && sja1000_is_absent(priv)) return IRQ_NONE; @@ -530,7 +530,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) /* receive interrupt */ while (status & SR_RBS) { sja1000_rx(dev); - status = priv->read_reg(priv, SJA1000_REG_SR); + status = priv->read_reg(priv, REG_SR); /* check for absent controller */ if (status == 0xFF && sja1000_is_absent(priv)) return IRQ_NONE; diff --git a/trunk/drivers/net/can/sja1000/sja1000.h b/trunk/drivers/net/can/sja1000/sja1000.h index aa48e053da27..afa99847a510 100644 --- a/trunk/drivers/net/can/sja1000/sja1000.h +++ b/trunk/drivers/net/can/sja1000/sja1000.h @@ -56,7 +56,7 @@ /* SJA1000 registers - manual section 6.4 (Pelican Mode) */ #define REG_MOD 0x00 #define REG_CMR 0x01 -#define SJA1000_REG_SR 0x02 +#define REG_SR 0x02 #define REG_IR 0x03 #define REG_IER 0x04 #define REG_ALC 0x0B diff --git a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c index 8e0c4a001939..6433b81256cd 100644 --- a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c @@ -96,8 +96,8 @@ static int sja1000_ofp_probe(struct platform_device *ofdev) struct net_device *dev; struct sja1000_priv *priv; struct resource res; - u32 prop; - int err, irq, res_size; + const u32 *prop; + int err, irq, res_size, prop_size; void __iomem *base; err = of_address_to_resource(np, 0, &res); @@ -138,27 +138,27 @@ static int sja1000_ofp_probe(struct platform_device *ofdev) priv->read_reg = sja1000_ofp_read_reg; priv->write_reg = sja1000_ofp_write_reg; - err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop); - if (!err) - priv->can.clock.freq = prop / 2; + prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->can.clock.freq = *prop / 2; else priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ - err = of_property_read_u32(np, "nxp,tx-output-mode", &prop); - if (!err) - priv->ocr |= prop & OCR_MODE_MASK; + prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->ocr |= *prop & OCR_MODE_MASK; else priv->ocr |= OCR_MODE_NORMAL; /* default */ - err = of_property_read_u32(np, "nxp,tx-output-config", &prop); - if (!err) - priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; + prop = of_get_property(np, "nxp,tx-output-config", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; else priv->ocr |= OCR_TX0_PULLDOWN; /* default */ - err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop); - if (!err && prop) { - u32 divider = priv->can.clock.freq * 2 / prop; + prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); + if (prop && (prop_size == sizeof(u32)) && *prop) { + u32 divider = priv->can.clock.freq * 2 / *prop; if (divider > 1) priv->cdr |= divider / 2 - 1; @@ -168,7 +168,8 @@ static int sja1000_ofp_probe(struct platform_device *ofdev) priv->cdr |= CDR_CLK_OFF; /* default */ } - if (!of_property_read_bool(np, "nxp,no-comparator-bypass")) + prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); + if (!prop) priv->cdr |= CDR_CBP; /* default */ priv->irq_flags = IRQF_SHARED; diff --git a/trunk/drivers/net/can/softing/softing_cs.c b/trunk/drivers/net/can/softing/softing_cs.c index 498605f833dd..c2c0a5bb0b21 100644 --- a/trunk/drivers/net/can/softing/softing_cs.c +++ b/trunk/drivers/net/can/softing/softing_cs.c @@ -27,7 +27,7 @@ #include "softing_platform.h" static int softingcs_index; -static DEFINE_SPINLOCK(softingcs_index_lock); +static spinlock_t softingcs_index_lock; static int softingcs_reset(struct platform_device *pdev, int v); static int softingcs_enable_irq(struct platform_device *pdev, int v); @@ -340,7 +340,19 @@ static struct pcmcia_driver softingcs_driver = { .remove = softingcs_remove, }; -module_pcmcia_driver(softingcs_driver); +static int __init softingcs_start(void) +{ + spin_lock_init(&softingcs_index_lock); + return pcmcia_register_driver(&softingcs_driver); +} + +static void __exit softingcs_stop(void) +{ + pcmcia_unregister_driver(&softingcs_driver); +} + +module_init(softingcs_start); +module_exit(softingcs_stop); MODULE_DESCRIPTION("softing CANcard driver" ", links PCMCIA card to softing driver"); diff --git a/trunk/drivers/net/ethernet/3com/3c574_cs.c b/trunk/drivers/net/ethernet/3com/3c574_cs.c index 6fc994fa4abe..ffd8de28a76a 100644 --- a/trunk/drivers/net/ethernet/3com/3c574_cs.c +++ b/trunk/drivers/net/ethernet/3com/3c574_cs.c @@ -1165,4 +1165,16 @@ static struct pcmcia_driver tc574_driver = { .suspend = tc574_suspend, .resume = tc574_resume, }; -module_pcmcia_driver(tc574_driver); + +static int __init init_tc574(void) +{ + return pcmcia_register_driver(&tc574_driver); +} + +static void __exit exit_tc574(void) +{ + pcmcia_unregister_driver(&tc574_driver); +} + +module_init(init_tc574); +module_exit(exit_tc574); diff --git a/trunk/drivers/net/ethernet/3com/3c589_cs.c b/trunk/drivers/net/ethernet/3com/3c589_cs.c index 078480aaa168..a556c01e011b 100644 --- a/trunk/drivers/net/ethernet/3com/3c589_cs.c +++ b/trunk/drivers/net/ethernet/3com/3c589_cs.c @@ -928,4 +928,16 @@ static struct pcmcia_driver tc589_driver = { .suspend = tc589_suspend, .resume = tc589_resume, }; -module_pcmcia_driver(tc589_driver); + +static int __init init_tc589(void) +{ + return pcmcia_register_driver(&tc589_driver); +} + +static void __exit exit_tc589(void) +{ + pcmcia_unregister_driver(&tc589_driver); +} + +module_init(init_tc589); +module_exit(exit_tc589); diff --git a/trunk/drivers/net/ethernet/8390/ax88796.c b/trunk/drivers/net/ethernet/8390/ax88796.c index e1d26433d619..cab306a9888e 100644 --- a/trunk/drivers/net/ethernet/8390/ax88796.c +++ b/trunk/drivers/net/ethernet/8390/ax88796.c @@ -828,7 +828,7 @@ static int ax_probe(struct platform_device *pdev) struct ei_device *ei_local; struct ax_device *ax; struct resource *irq, *mem, *mem2; - unsigned long mem_size, mem2_size = 0; + resource_size_t mem_size, mem2_size = 0; int ret = 0; dev = ax__alloc_ei_netdev(sizeof(struct ax_device)); diff --git a/trunk/drivers/net/ethernet/8390/axnet_cs.c b/trunk/drivers/net/ethernet/8390/axnet_cs.c index d801c1410fb0..e1b3941bd149 100644 --- a/trunk/drivers/net/ethernet/8390/axnet_cs.c +++ b/trunk/drivers/net/ethernet/8390/axnet_cs.c @@ -728,7 +728,19 @@ static struct pcmcia_driver axnet_cs_driver = { .suspend = axnet_suspend, .resume = axnet_resume, }; -module_pcmcia_driver(axnet_cs_driver); + +static int __init init_axnet_cs(void) +{ + return pcmcia_register_driver(&axnet_cs_driver); +} + +static void __exit exit_axnet_cs(void) +{ + pcmcia_unregister_driver(&axnet_cs_driver); +} + +module_init(init_axnet_cs); +module_exit(exit_axnet_cs); /*====================================================================*/ diff --git a/trunk/drivers/net/ethernet/8390/pcnet_cs.c b/trunk/drivers/net/ethernet/8390/pcnet_cs.c index 46c5aadaca8e..de1af0bfed4c 100644 --- a/trunk/drivers/net/ethernet/8390/pcnet_cs.c +++ b/trunk/drivers/net/ethernet/8390/pcnet_cs.c @@ -1694,4 +1694,16 @@ static struct pcmcia_driver pcnet_driver = { .suspend = pcnet_suspend, .resume = pcnet_resume, }; -module_pcmcia_driver(pcnet_driver); + +static int __init init_pcnet_cs(void) +{ + return pcmcia_register_driver(&pcnet_driver); +} + +static void __exit exit_pcnet_cs(void) +{ + pcmcia_unregister_driver(&pcnet_driver); +} + +module_init(init_pcnet_cs); +module_exit(exit_pcnet_cs); diff --git a/trunk/drivers/net/ethernet/amd/nmclan_cs.c b/trunk/drivers/net/ethernet/amd/nmclan_cs.c index d4ed89130c52..9f59bf63514b 100644 --- a/trunk/drivers/net/ethernet/amd/nmclan_cs.c +++ b/trunk/drivers/net/ethernet/amd/nmclan_cs.c @@ -1508,4 +1508,16 @@ static struct pcmcia_driver nmclan_cs_driver = { .suspend = nmclan_suspend, .resume = nmclan_resume, }; -module_pcmcia_driver(nmclan_cs_driver); + +static int __init init_nmclan_cs(void) +{ + return pcmcia_register_driver(&nmclan_cs_driver); +} + +static void __exit exit_nmclan_cs(void) +{ + pcmcia_unregister_driver(&nmclan_cs_driver); +} + +module_init(init_nmclan_cs); +module_exit(exit_nmclan_cs); diff --git a/trunk/drivers/net/ethernet/atheros/atl1e/atl1e.h b/trunk/drivers/net/ethernet/atheros/atl1e/atl1e.h index b5fd934585e9..829b5ad71d0d 100644 --- a/trunk/drivers/net/ethernet/atheros/atl1e/atl1e.h +++ b/trunk/drivers/net/ethernet/atheros/atl1e/atl1e.h @@ -186,7 +186,7 @@ struct atl1e_tpd_desc { /* how about 0x2000 */ #define MAX_TX_BUF_LEN 0x2000 #define MAX_TX_BUF_SHIFT 13 -#define MAX_TSO_SEG_SIZE 0x3c00 +/*#define MAX_TX_BUF_LEN 0x3000 */ /* rrs word 1 bit 0:31 */ #define RRS_RX_CSUM_MASK 0xFFFF @@ -438,6 +438,7 @@ struct atl1e_adapter { struct atl1e_hw hw; struct atl1e_hw_stats hw_stats; + bool have_msi; u32 wol; u16 link_speed; u16 link_duplex; diff --git a/trunk/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/trunk/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index ac25f05ff68f..92f4734f860d 100644 --- a/trunk/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/trunk/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -1849,19 +1849,34 @@ static void atl1e_free_irq(struct atl1e_adapter *adapter) struct net_device *netdev = adapter->netdev; free_irq(adapter->pdev->irq, netdev); + + if (adapter->have_msi) + pci_disable_msi(adapter->pdev); } static int atl1e_request_irq(struct atl1e_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; + int flags = 0; int err = 0; - err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, netdev->name, - netdev); + adapter->have_msi = true; + err = pci_enable_msi(pdev); + if (err) { + netdev_dbg(netdev, + "Unable to allocate MSI interrupt Error: %d\n", err); + adapter->have_msi = false; + } + + if (!adapter->have_msi) + flags |= IRQF_SHARED; + err = request_irq(pdev->irq, atl1e_intr, flags, netdev->name, netdev); if (err) { netdev_dbg(adapter->netdev, "Unable to allocate interrupt Error: %d\n", err); + if (adapter->have_msi) + pci_disable_msi(pdev); return err; } netdev_dbg(netdev, "atl1e_request_irq OK\n"); @@ -2329,7 +2344,6 @@ static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) INIT_WORK(&adapter->reset_task, atl1e_reset_task); INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task); - netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE); err = register_netdev(netdev); if (err) { netdev_err(netdev, "register netdevice failed\n"); diff --git a/trunk/drivers/net/ethernet/broadcom/bgmac.c b/trunk/drivers/net/ethernet/broadcom/bgmac.c index da5f4397f87c..639049d7e92d 100644 --- a/trunk/drivers/net/ethernet/broadcom/bgmac.c +++ b/trunk/drivers/net/ethernet/broadcom/bgmac.c @@ -301,16 +301,12 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", ring->start); } else { - /* Omit CRC. */ - len -= ETH_FCS_LEN; - new_skb = netdev_alloc_skb_ip_align(bgmac->net_dev, len); if (new_skb) { skb_put(new_skb, len); skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET, new_skb->data, len); - skb_checksum_none_assert(skb); new_skb->protocol = eth_type_trans(new_skb, bgmac->net_dev); netif_receive_skb(new_skb); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 57619dd4a92b..ecac04a3687c 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2614,9 +2614,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } - /* initialize FW coalescing state machines in RAM */ - bnx2x_update_coalesce(bp); - /* setup the leading queue */ rc = bnx2x_setup_leading(bp); if (rc) { @@ -2763,7 +2760,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->port.pmf = 0; load_error1: bnx2x_napi_disable(bp); - bnx2x_del_all_napi(bp); /* clear pf_load status, as it was already set */ if (IS_PF(bp)) @@ -3146,7 +3142,7 @@ static inline __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix) tsum = ~csum_fold(csum_add((__force __wsum) csum, csum_partial(t_header, -fix, 0))); - return bswab16(tsum); + return bswab16(csum); } static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) @@ -4583,11 +4579,11 @@ static void storm_memset_hc_disable(struct bnx2x *bp, u8 port, u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(fw_sb_id, sb_index); - u8 flags = REG_RD8(bp, addr); + u16 flags = REG_RD16(bp, addr); /* clear and set */ flags &= ~HC_INDEX_DATA_HC_ENABLED; flags |= enable_flag; - REG_WR8(bp, addr, flags); + REG_WR16(bp, addr, flags); DP(NETIF_MSG_IFUP, "port %x fw_sb_id %d sb_index %d disable %d\n", port, fw_sb_id, sb_index, disable); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index 91ecd6a00d05..568205436a15 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c @@ -2139,12 +2139,12 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap) break; default: BNX2X_ERR("Non valid capability ID\n"); - rval = 1; + rval = -EINVAL; break; } } else { DP(BNX2X_MSG_DCB, "DCB disabled\n"); - rval = 1; + rval = -EINVAL; } DP(BNX2X_MSG_DCB, "capid %d:%x\n", capid, *cap); @@ -2170,12 +2170,12 @@ static int bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num) break; default: BNX2X_ERR("Non valid TC-ID\n"); - rval = 1; + rval = -EINVAL; break; } } else { DP(BNX2X_MSG_DCB, "DCB disabled\n"); - rval = 1; + rval = -EINVAL; } return rval; @@ -2188,7 +2188,7 @@ static int bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num) return -EINVAL; } -static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev) +static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev) { struct bnx2x *bp = netdev_priv(netdev); DP(BNX2X_MSG_DCB, "state = %d\n", bp->dcbx_local_feat.pfc.enabled); @@ -2390,12 +2390,12 @@ static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid, break; default: BNX2X_ERR("Non valid featrue-ID\n"); - rval = 1; + rval = -EINVAL; break; } } else { DP(BNX2X_MSG_DCB, "DCB disabled\n"); - rval = 1; + rval = -EINVAL; } return rval; @@ -2431,12 +2431,12 @@ static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid, break; default: BNX2X_ERR("Non valid featrue-ID\n"); - rval = 1; + rval = -EINVAL; break; } } else { DP(BNX2X_MSG_DCB, "dcbnl call not valid\n"); - rval = 1; + rval = -EINVAL; } return rval; diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index edfa67adf2f9..9a674b14b403 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -281,8 +281,6 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->lp_advertising |= ADVERTISED_2500baseX_Full; if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE) cmd->lp_advertising |= ADVERTISED_10000baseT_Full; - if (status & LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE) - cmd->lp_advertising |= ADVERTISED_20000baseKR2_Full; } cmd->maxtxpkt = 0; @@ -465,10 +463,6 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ADVERTISED_10000baseKR_Full)) bp->link_params.speed_cap_mask[cfg_idx] |= PORT_HW_CFG_SPEED_CAPABILITY_D0_10G; - - if (cmd->advertising & ADVERTISED_20000baseKR2_Full) - bp->link_params.speed_cap_mask[cfg_idx] |= - PORT_HW_CFG_SPEED_CAPABILITY_D0_20G; } } else { /* forced speed */ /* advertise the requested speed and duplex if supported */ diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 0283f343b0d1..1663e0b6b5a0 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -8647,9 +8647,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC6, &rx_tx_in_reset); - if ((!rx_tx_in_reset) && - (params->link_flags & - PHY_INITIALIZED)) { + if (!rx_tx_in_reset) { bnx2x_warpcore_reset_lane(bp, phy, 1); bnx2x_warpcore_config_sfi(phy, params); bnx2x_warpcore_reset_lane(bp, phy, 0); @@ -10424,28 +10422,6 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x0); - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) { - /* Disable MI_INT interrupt before setting LED4 - * source to constant off. - */ - if (REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + - params->port*4) & - NIG_MASK_MI_INT) { - params->link_flags |= - LINK_FLAGS_INT_DISABLED; - - bnx2x_bits_dis( - bp, - NIG_REG_MASK_INTERRUPT_PORT0 + - params->port*4, - NIG_MASK_MI_INT); - } - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_SIGNAL_MASK, - 0x0); - } } break; case LED_MODE_ON: @@ -10492,28 +10468,6 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x20); - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) { - /* Disable MI_INT interrupt before setting LED4 - * source to constant on. - */ - if (REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + - params->port*4) & - NIG_MASK_MI_INT) { - params->link_flags |= - LINK_FLAGS_INT_DISABLED; - - bnx2x_bits_dis( - bp, - NIG_REG_MASK_INTERRUPT_PORT0 + - params->port*4, - NIG_MASK_MI_INT); - } - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_SIGNAL_MASK, - 0x20); - } } break; @@ -10578,22 +10532,6 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LINK_SIGNAL, val); - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) { - /* Restore LED4 source to external link, - * and re-enable interrupts. - */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_SIGNAL_MASK, - 0x40); - if (params->link_flags & - LINK_FLAGS_INT_DISABLED) { - bnx2x_link_int_enable(params); - params->link_flags &= - ~LINK_FLAGS_INT_DISABLED; - } - } } break; } @@ -11853,8 +11791,6 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, phy->media_type = ETH_PHY_KR; phy->flags |= FLAGS_WC_DUAL_MODE; phy->supported &= (SUPPORTED_20000baseKR2_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE | SUPPORTED_Pause | @@ -12529,8 +12465,6 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; vars->mac_type = MAC_TYPE_NONE; vars->phy_flags = 0; - vars->check_kr2_recovery_cnt = 0; - params->link_flags = PHY_INITIALIZED; /* Driver opens NIG-BRB filters */ bnx2x_set_rx_filter(params, 1); /* Check if link flap can be avoided */ @@ -12695,7 +12629,6 @@ int bnx2x_lfa_reset(struct link_params *params, struct bnx2x *bp = params->bp; vars->link_up = 0; vars->phy_flags = 0; - params->link_flags &= ~PHY_INITIALIZED; if (!params->lfa_base) return bnx2x_link_reset(params, vars, 1); /* @@ -13416,7 +13349,6 @@ static void bnx2x_disable_kr2(struct link_params *params, vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE; bnx2x_update_link_attr(params, vars->link_attr_sync); - vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT; /* Restart AN on leading lane */ bnx2x_warpcore_restart_AN_KR(phy, params); } @@ -13437,24 +13369,11 @@ static void bnx2x_check_kr2_wa(struct link_params *params, { struct bnx2x *bp = params->bp; u16 base_page, next_page, not_kr2_device, lane; - int sigdet; + int sigdet = bnx2x_warpcore_get_sigdet(phy, params); - /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery - * since some switches tend to reinit the AN process and clear the - * advertised BP/NP after ~2 seconds causing the KR2 to be disabled - * and recovered many times - */ - if (vars->check_kr2_recovery_cnt > 0) { - vars->check_kr2_recovery_cnt--; - return; - } - - sigdet = bnx2x_warpcore_get_sigdet(phy, params); if (!sigdet) { - if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { + if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) bnx2x_kr2_recovery(params, vars, phy); - DP(NETIF_MSG_LINK, "No sigdet\n"); - } return; } @@ -13518,7 +13437,7 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars) struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; bnx2x_set_aer_mmd(params, phy); if ((phy->supported & SUPPORTED_20000baseKR2_Full) && - (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) + (phy->speed_cap_mask & SPEED_20000)) bnx2x_check_kr2_wa(params, vars, phy); bnx2x_check_over_curr(params, vars); if (vars->rx_tx_asic_rst) diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index 56c2aae4e2c8..d25c7d79787a 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -307,9 +307,7 @@ struct link_params { struct bnx2x *bp; u16 req_fc_auto_adv; /* Should be set to TX / BOTH when req_flow_ctrl is set to AUTO */ - u16 link_flags; -#define LINK_FLAGS_INT_DISABLED (1<<0) -#define PHY_INITIALIZED (1<<1) + u16 rsrv1; u32 lfa_base; }; @@ -343,8 +341,7 @@ struct link_vars { u32 link_status; u32 eee_status; u8 fault_detected; - u8 check_kr2_recovery_cnt; -#define CHECK_KR2_RECOVERY_CNT 5 + u8 rsrv1; u16 periodic_flags; #define PERIODIC_FLAGS_LINK_EVENT 0x0001 diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c50696b396f1..e81a747ea8ce 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -4947,7 +4947,7 @@ static void bnx2x_after_function_update(struct bnx2x *bp) q); } - if (!NO_FCOE(bp) && CNIC_ENABLED(bp)) { + if (!NO_FCOE(bp)) { fp = &bp->fp[FCOE_IDX(bp)]; queue_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; @@ -9878,10 +9878,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) REG_RD(bp, NIG_REG_NIG_INT_STS_CLR_0); } } - if (!CHIP_IS_E1x(bp)) - /* block FW from writing to host */ - REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0); - /* wait until BRB is empty */ tmp_reg = REG_RD(bp, BRB1_REG_NUM_OF_FULL_BLOCKS); while (timer_count) { @@ -13358,7 +13354,6 @@ static int bnx2x_unregister_cnic(struct net_device *dev) RCU_INIT_POINTER(bp->cnic_ops, NULL); mutex_unlock(&bp->cnic_mutex); synchronize_rcu(); - bp->cnic_enabled = false; kfree(bp->cnic_kwq); bp->cnic_kwq = NULL; diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 198f6f1c9ad5..364e37ecbc5c 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -459,9 +459,8 @@ struct bnx2x_fw_port_stats_old { #define UPDATE_QSTAT(s, t) \ do { \ + qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi); \ qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \ - qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi) \ - + ((qstats->t##_lo < qstats_old->t##_lo) ? 1 : 0); \ } while (0) #define UPDATE_QSTAT_OLD(f) \ diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index 17a972734ba7..fdb9b5655414 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -1869,8 +1869,6 @@ static void tg3_link_report(struct tg3 *tp) tg3_ump_link_report(tp); } - - tp->link_up = netif_carrier_ok(tp->dev); } static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl) @@ -2524,6 +2522,12 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) return err; } +static void tg3_carrier_on(struct tg3 *tp) +{ + netif_carrier_on(tp->dev); + tp->link_up = true; +} + static void tg3_carrier_off(struct tg3 *tp) { netif_carrier_off(tp->dev); @@ -2549,7 +2553,7 @@ static int tg3_phy_reset(struct tg3 *tp) return -EBUSY; if (netif_running(tp->dev) && tp->link_up) { - netif_carrier_off(tp->dev); + tg3_carrier_off(tp); tg3_link_report(tp); } @@ -4130,14 +4134,6 @@ static void tg3_phy_copper_begin(struct tg3 *tp) tp->link_config.active_speed = tp->link_config.speed; tp->link_config.active_duplex = tp->link_config.duplex; - if (tg3_asic_rev(tp) == ASIC_REV_5714) { - /* With autoneg disabled, 5715 only links up when the - * advertisement register has the configured speed - * enabled. - */ - tg3_writephy(tp, MII_ADVERTISE, ADVERTISE_ALL); - } - bmcr = 0; switch (tp->link_config.speed) { default: @@ -4266,9 +4262,9 @@ static bool tg3_test_and_report_link_chg(struct tg3 *tp, int curr_link_up) { if (curr_link_up != tp->link_up) { if (curr_link_up) { - netif_carrier_on(tp->dev); + tg3_carrier_on(tp); } else { - netif_carrier_off(tp->dev); + tg3_carrier_off(tp); if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; } @@ -14604,11 +14600,8 @@ static void tg3_read_vpd(struct tg3 *tp) if (j + len > block_end) goto partno; - if (len >= sizeof(tp->fw_ver)) - len = sizeof(tp->fw_ver) - 1; - memset(tp->fw_ver, 0, sizeof(tp->fw_ver)); - snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len, - &vpd_data[j]); + memcpy(tp->fw_ver, &vpd_data[j], len); + strncat(tp->fw_ver, " bc ", vpdlen - len - 1); } partno: diff --git a/trunk/drivers/net/ethernet/calxeda/xgmac.c b/trunk/drivers/net/ethernet/calxeda/xgmac.c index b0ebc9f6d55e..a170065b5973 100644 --- a/trunk/drivers/net/ethernet/calxeda/xgmac.c +++ b/trunk/drivers/net/ethernet/calxeda/xgmac.c @@ -163,7 +163,6 @@ #define XGMAC_FLOW_CTRL_FCB_BPA 0x00000001 /* Flow Control Busy ... */ /* XGMAC_INT_STAT reg */ -#define XGMAC_INT_STAT_PMTIM 0x00800000 /* PMT Interrupt Mask */ #define XGMAC_INT_STAT_PMT 0x0080 /* PMT Interrupt Status */ #define XGMAC_INT_STAT_LPI 0x0040 /* LPI Interrupt Status */ @@ -961,9 +960,6 @@ static int xgmac_hw_init(struct net_device *dev) writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA); - /* Mask power mgt interrupt */ - writel(XGMAC_INT_STAT_PMTIM, ioaddr + XGMAC_INT_STAT); - /* XGMAC requires AXI bus init. This is a 'magic number' for now */ writel(0x0077000E, ioaddr + XGMAC_DMA_AXI_BUS); @@ -1145,9 +1141,6 @@ static int xgmac_rx(struct xgmac_priv *priv, int limit) struct sk_buff *skb; int frame_len; - if (!dma_ring_cnt(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ)) - break; - entry = priv->rx_tail; p = priv->dma_rx + entry; if (desc_get_owner(p)) @@ -1832,7 +1825,7 @@ static void xgmac_pmt(void __iomem *ioaddr, unsigned long mode) unsigned int pmt = 0; if (mode & WAKE_MAGIC) - pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT_EN; + pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT; if (mode & WAKE_UCAST) pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_GLBL_UNICAST; diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 8049268ce0f2..4ce62031f62f 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -497,9 +497,8 @@ int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len, } #define EEPROM_STAT_ADDR 0x7bfc +#define VPD_BASE 0 #define VPD_LEN 512 -#define VPD_BASE 0x400 -#define VPD_BASE_OLD 0 /** * t4_seeprom_wp - enable/disable EEPROM write protection @@ -525,7 +524,7 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable) int get_vpd_params(struct adapter *adapter, struct vpd_params *p) { u32 cclk_param, cclk_val; - int i, ret, addr; + int i, ret; int ec, sn; u8 *vpd, csum; unsigned int vpdr_len, kw_offset, id_len; @@ -534,12 +533,7 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) if (!vpd) return -ENOMEM; - ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd); - if (ret < 0) - goto out; - addr = *vpd == 0x82 ? VPD_BASE : VPD_BASE_OLD; - - ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd); + ret = pci_read_vpd(adapter->pdev, VPD_BASE, VPD_LEN, vpd); if (ret < 0) goto out; diff --git a/trunk/drivers/net/ethernet/davicom/dm9000.c b/trunk/drivers/net/ethernet/davicom/dm9000.c index 9eada8e86078..8cdf02503d13 100644 --- a/trunk/drivers/net/ethernet/davicom/dm9000.c +++ b/trunk/drivers/net/ethernet/davicom/dm9000.c @@ -257,107 +257,6 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count) tmp = readl(reg); } -/* - * Sleep, either by using msleep() or if we are suspending, then - * use mdelay() to sleep. - */ -static void dm9000_msleep(board_info_t *db, unsigned int ms) -{ - if (db->in_suspend) - mdelay(ms); - else - msleep(ms); -} - -/* Read a word from phyxcer */ -static int -dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) -{ - board_info_t *db = netdev_priv(dev); - unsigned long flags; - unsigned int reg_save; - int ret; - - mutex_lock(&db->addr_lock); - - spin_lock_irqsave(&db->lock, flags); - - /* Save previous register address */ - reg_save = readb(db->io_addr); - - /* Fill the phyxcer register into REG_0C */ - iow(db, DM9000_EPAR, DM9000_PHY | reg); - - /* Issue phyxcer read command */ - iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); - - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - - dm9000_msleep(db, 1); /* Wait read complete */ - - spin_lock_irqsave(&db->lock, flags); - reg_save = readb(db->io_addr); - - iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ - - /* The read data keeps on REG_0D & REG_0E */ - ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); - - /* restore the previous address */ - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - - mutex_unlock(&db->addr_lock); - - dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); - return ret; -} - -/* Write a word to phyxcer */ -static void -dm9000_phy_write(struct net_device *dev, - int phyaddr_unused, int reg, int value) -{ - board_info_t *db = netdev_priv(dev); - unsigned long flags; - unsigned long reg_save; - - dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); - mutex_lock(&db->addr_lock); - - spin_lock_irqsave(&db->lock, flags); - - /* Save previous register address */ - reg_save = readb(db->io_addr); - - /* Fill the phyxcer register into REG_0C */ - iow(db, DM9000_EPAR, DM9000_PHY | reg); - - /* Fill the written data into REG_0D & REG_0E */ - iow(db, DM9000_EPDRL, value); - iow(db, DM9000_EPDRH, value >> 8); - - /* Issue phyxcer write command */ - iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); - - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - - dm9000_msleep(db, 1); /* Wait write complete */ - - spin_lock_irqsave(&db->lock, flags); - reg_save = readb(db->io_addr); - - iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ - - /* restore the previous address */ - writeb(reg_save, db->io_addr); - - spin_unlock_irqrestore(&db->lock, flags); - mutex_unlock(&db->addr_lock); -} - /* dm9000_set_io * * select the specified set of io routines to use with the @@ -896,9 +795,6 @@ dm9000_init_dm9000(struct net_device *dev) iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ - dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */ - dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */ - ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0; /* if wol is needed, then always set NCR_WAKEEN otherwise we end @@ -1305,6 +1201,109 @@ dm9000_open(struct net_device *dev) return 0; } +/* + * Sleep, either by using msleep() or if we are suspending, then + * use mdelay() to sleep. + */ +static void dm9000_msleep(board_info_t *db, unsigned int ms) +{ + if (db->in_suspend) + mdelay(ms); + else + msleep(ms); +} + +/* + * Read a word from phyxcer + */ +static int +dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) +{ + board_info_t *db = netdev_priv(dev); + unsigned long flags; + unsigned int reg_save; + int ret; + + mutex_lock(&db->addr_lock); + + spin_lock_irqsave(&db->lock,flags); + + /* Save previous register address */ + reg_save = readb(db->io_addr); + + /* Fill the phyxcer register into REG_0C */ + iow(db, DM9000_EPAR, DM9000_PHY | reg); + + iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); /* Issue phyxcer read command */ + + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock,flags); + + dm9000_msleep(db, 1); /* Wait read complete */ + + spin_lock_irqsave(&db->lock,flags); + reg_save = readb(db->io_addr); + + iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ + + /* The read data keeps on REG_0D & REG_0E */ + ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); + + /* restore the previous address */ + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock,flags); + + mutex_unlock(&db->addr_lock); + + dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); + return ret; +} + +/* + * Write a word to phyxcer + */ +static void +dm9000_phy_write(struct net_device *dev, + int phyaddr_unused, int reg, int value) +{ + board_info_t *db = netdev_priv(dev); + unsigned long flags; + unsigned long reg_save; + + dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); + mutex_lock(&db->addr_lock); + + spin_lock_irqsave(&db->lock,flags); + + /* Save previous register address */ + reg_save = readb(db->io_addr); + + /* Fill the phyxcer register into REG_0C */ + iow(db, DM9000_EPAR, DM9000_PHY | reg); + + /* Fill the written data into REG_0D & REG_0E */ + iow(db, DM9000_EPDRL, value); + iow(db, DM9000_EPDRH, value >> 8); + + iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); /* Issue phyxcer write command */ + + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock, flags); + + dm9000_msleep(db, 1); /* Wait write complete */ + + spin_lock_irqsave(&db->lock,flags); + reg_save = readb(db->io_addr); + + iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ + + /* restore the previous address */ + writeb(reg_save, db->io_addr); + + spin_unlock_irqrestore(&db->lock, flags); + mutex_unlock(&db->addr_lock); +} + static void dm9000_shutdown(struct net_device *dev) { @@ -1503,12 +1502,7 @@ dm9000_probe(struct platform_device *pdev) db->flags |= DM9000_PLATF_SIMPLE_PHY; #endif - /* Fixing bug on dm9000_probe, takeover dm9000_reset(db), - * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo - * while probe stage. - */ - - iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST); + dm9000_reset(db); /* try multiple times, DM9000 sometimes gets the read wrong */ for (i = 0; i < 8; i++) { diff --git a/trunk/drivers/net/ethernet/davicom/dm9000.h b/trunk/drivers/net/ethernet/davicom/dm9000.h index 9ce058adabab..55688bd1a3ef 100644 --- a/trunk/drivers/net/ethernet/davicom/dm9000.h +++ b/trunk/drivers/net/ethernet/davicom/dm9000.h @@ -69,9 +69,7 @@ #define NCR_WAKEEN (1<<6) #define NCR_FCOL (1<<4) #define NCR_FDX (1<<3) - -#define NCR_RESERVED (3<<1) -#define NCR_MAC_LBK (1<<1) +#define NCR_LBK (3<<1) #define NCR_RST (1<<0) #define NSR_SPEED (1<<7) @@ -169,12 +167,5 @@ #define ISR_LNKCHNG (1<<5) #define ISR_UNDERRUN (1<<4) -/* Davicom MII registers. - */ - -#define MII_DM_DSPCR 0x1b /* DSP Control Register */ - -#define DSPCR_INIT_PARAM 0xE100 /* DSP init parameter */ - #endif /* _DM9000X_H_ */ diff --git a/trunk/drivers/net/ethernet/dec/tulip/Kconfig b/trunk/drivers/net/ethernet/dec/tulip/Kconfig index 1df33c799c00..0c37fb2cc867 100644 --- a/trunk/drivers/net/ethernet/dec/tulip/Kconfig +++ b/trunk/drivers/net/ethernet/dec/tulip/Kconfig @@ -108,7 +108,6 @@ config TULIP_DM910X config DE4X5 tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" depends on (PCI || EISA) - depends on VIRT_TO_BUS || ALPHA || PPC || SPARC select CRC32 ---help--- This is support for the DIGITAL series of PCI/EISA Ethernet cards. diff --git a/trunk/drivers/net/ethernet/emulex/benet/be.h b/trunk/drivers/net/ethernet/emulex/benet/be.h index 29aff55f2eea..28ceb8414185 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be.h @@ -349,7 +349,6 @@ struct be_adapter { struct pci_dev *pdev; struct net_device *netdev; - u8 __iomem *csr; /* CSR BAR used only for BE2/3 */ u8 __iomem *db; /* Door Bell */ struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c index 3c9b4f12e3e5..071aea79d218 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -473,17 +473,19 @@ static int be_mbox_notify_wait(struct be_adapter *adapter) return 0; } -static u16 be_POST_stage_get(struct be_adapter *adapter) +static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) { u32 sem; + u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH : + SLIPORT_SEMAPHORE_OFFSET_BE; - if (BEx_chip(adapter)) - sem = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx); - else - pci_read_config_dword(adapter->pdev, - SLIPORT_SEMAPHORE_OFFSET_SH, &sem); + pci_read_config_dword(adapter->pdev, reg, &sem); + *stage = sem & POST_STAGE_MASK; - return sem & POST_STAGE_MASK; + if ((sem >> POST_ERR_SHIFT) & POST_ERR_MASK) + return -1; + else + return 0; } int lancer_wait_ready(struct be_adapter *adapter) @@ -577,17 +579,19 @@ int be_fw_wait_ready(struct be_adapter *adapter) } do { - stage = be_POST_stage_get(adapter); - if (stage == POST_STAGE_ARMFW_RDY) + status = be_POST_stage_get(adapter, &stage); + if (status) { + dev_err(dev, "POST error; stage=0x%x\n", stage); + return -1; + } else if (stage != POST_STAGE_ARMFW_RDY) { + if (msleep_interruptible(2000)) { + dev_err(dev, "Waiting for POST aborted\n"); + return -EINTR; + } + timeout += 2; + } else { return 0; - - dev_info(dev, "Waiting for POST, %ds elapsed\n", - timeout); - if (msleep_interruptible(2000)) { - dev_err(dev, "Waiting for POST aborted\n"); - return -EINTR; } - timeout += 2; } while (timeout < 60); dev_err(dev, "POST timeout; stage=0x%x\n", stage); diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_hw.h b/trunk/drivers/net/ethernet/emulex/benet/be_hw.h index 62dc220695f7..541d4530d5bf 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be_hw.h @@ -32,8 +32,8 @@ #define MPU_EP_CONTROL 0 /********** MPU semphore: used for SH & BE *************/ -#define SLIPORT_SEMAPHORE_OFFSET_BEx 0xac /* CSR BAR offset */ -#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 /* PCI-CFG offset */ +#define SLIPORT_SEMAPHORE_OFFSET_BE 0x7c +#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 #define POST_STAGE_MASK 0x0000FFFF #define POST_ERR_MASK 0x1 #define POST_ERR_SHIFT 31 diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index 2886c9b63f90..3860888ac711 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -759,9 +759,8 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, if (vlan_tx_tag_present(skb)) { vlan_tag = be_get_tx_vlan_tag(adapter, skb); - skb = __vlan_put_tag(skb, vlan_tag); - if (skb) - skb->vlan_tci = 0; + __vlan_put_tag(skb, vlan_tag); + skb->vlan_tci = 0; } return skb; @@ -3689,8 +3688,6 @@ static void be_netdev_init(struct net_device *netdev) static void be_unmap_pci_bars(struct be_adapter *adapter) { - if (adapter->csr) - pci_iounmap(adapter->pdev, adapter->csr); if (adapter->db) pci_iounmap(adapter->pdev, adapter->db); } @@ -3724,12 +3721,6 @@ static int be_map_pci_bars(struct be_adapter *adapter) adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> SLI_INTF_IF_TYPE_SHIFT; - if (BEx_chip(adapter) && be_physfn(adapter)) { - adapter->csr = pci_iomap(adapter->pdev, 2, 0); - if (adapter->csr == NULL) - return -ENOMEM; - } - addr = pci_iomap(adapter->pdev, db_bar(adapter), 0); if (addr == NULL) goto pci_map_err; @@ -4338,8 +4329,6 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) pci_restore_state(pdev); /* Check if card is ok and fw is ready */ - dev_info(&adapter->pdev->dev, - "Waiting for FW to be ready after EEH reset\n"); status = be_fw_wait_ready(adapter); if (status) return PCI_ERS_RESULT_DISCONNECT; diff --git a/trunk/drivers/net/ethernet/freescale/fec.c b/trunk/drivers/net/ethernet/freescale/fec.c index 73195f643c9c..fccc3bf2141d 100644 --- a/trunk/drivers/net/ethernet/freescale/fec.c +++ b/trunk/drivers/net/ethernet/freescale/fec.c @@ -246,13 +246,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) struct bufdesc *bdp; void *bufaddr; unsigned short status; - unsigned int index; + unsigned long flags; if (!fep->link) { /* Link is down or autonegotiation is in progress. */ return NETDEV_TX_BUSY; } + spin_lock_irqsave(&fep->hw_lock, flags); /* Fill in a Tx ring entry */ bdp = fep->cur_tx; @@ -263,6 +264,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) * This should not happen, since ndev->tbusy should be set. */ printk("%s: tx queue full!.\n", ndev->name); + spin_unlock_irqrestore(&fep->hw_lock, flags); return NETDEV_TX_BUSY; } @@ -278,13 +280,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) * 4-byte boundaries. Use bounce buffers to copy data * and get it aligned. Ugh. */ - if (fep->bufdesc_ex) - index = (struct bufdesc_ex *)bdp - - (struct bufdesc_ex *)fep->tx_bd_base; - else - index = bdp - fep->tx_bd_base; - if (((unsigned long) bufaddr) & FEC_ALIGNMENT) { + unsigned int index; + if (fep->bufdesc_ex) + index = (struct bufdesc_ex *)bdp - + (struct bufdesc_ex *)fep->tx_bd_base; + else + index = bdp - fep->tx_bd_base; memcpy(fep->tx_bounce[index], skb->data, skb->len); bufaddr = fep->tx_bounce[index]; } @@ -298,7 +300,10 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) swap_buffer(bufaddr, skb->len); /* Save skb pointer */ - fep->tx_skbuff[index] = skb; + fep->tx_skbuff[fep->skb_cur] = skb; + + ndev->stats.tx_bytes += skb->len; + fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; /* Push the data cache so the CPM does not get stale memory * data. @@ -326,70 +331,27 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) ebdp->cbd_esc = BD_ENET_TX_INT; } } + /* Trigger transmission start */ + writel(0, fep->hwp + FEC_X_DES_ACTIVE); + /* If this was the last BD in the ring, start at the beginning again. */ if (status & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; else bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - fep->cur_tx = bdp; - - if (fep->cur_tx == fep->dirty_tx) + if (bdp == fep->dirty_tx) { + fep->tx_full = 1; netif_stop_queue(ndev); - - /* Trigger transmission start */ - writel(0, fep->hwp + FEC_X_DES_ACTIVE); - - skb_tx_timestamp(skb); - - return NETDEV_TX_OK; -} - -/* Init RX & TX buffer descriptors - */ -static void fec_enet_bd_init(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - struct bufdesc *bdp; - unsigned int i; - - /* Initialize the receive buffer descriptors. */ - bdp = fep->rx_bd_base; - for (i = 0; i < RX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - if (bdp->cbd_bufaddr) - bdp->cbd_sc = BD_ENET_RX_EMPTY; - else - bdp->cbd_sc = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); } - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - - fep->cur_rx = fep->rx_bd_base; - - /* ...and the same for transmit */ - bdp = fep->tx_bd_base; fep->cur_tx = bdp; - for (i = 0; i < TX_RING_SIZE; i++) { - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) { - dev_kfree_skb_any(fep->tx_skbuff[i]); - fep->tx_skbuff[i] = NULL; - } - bdp->cbd_bufaddr = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } + skb_tx_timestamp(skb); - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - fep->dirty_tx = bdp; + spin_unlock_irqrestore(&fep->hw_lock, flags); + + return NETDEV_TX_OK; } /* This function is called to start or restart the FEC during a link @@ -435,8 +397,6 @@ fec_restart(struct net_device *ndev, int duplex) /* Set maximum receive buffer size. */ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); - fec_enet_bd_init(ndev); - /* Set receive and transmit descriptor base. */ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); if (fep->bufdesc_ex) @@ -446,7 +406,11 @@ fec_restart(struct net_device *ndev, int duplex) writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->cur_rx = fep->rx_bd_base; + /* Reset SKB transmit buffers. */ + fep->skb_cur = fep->skb_dirty = 0; for (i = 0; i <= TX_RING_MOD_MASK; i++) { if (fep->tx_skbuff[i]) { dev_kfree_skb_any(fep->tx_skbuff[i]); @@ -609,35 +573,20 @@ fec_enet_tx(struct net_device *ndev) struct bufdesc *bdp; unsigned short status; struct sk_buff *skb; - int index = 0; fep = netdev_priv(ndev); + spin_lock(&fep->hw_lock); bdp = fep->dirty_tx; - /* get next bdp of dirty_tx */ - if (bdp->cbd_sc & BD_ENET_TX_WRAP) - bdp = fep->tx_bd_base; - else - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { - - /* current queue is empty */ - if (bdp == fep->cur_tx) + if (bdp == fep->cur_tx && fep->tx_full == 0) break; - if (fep->bufdesc_ex) - index = (struct bufdesc_ex *)bdp - - (struct bufdesc_ex *)fep->tx_bd_base; - else - index = bdp - fep->tx_bd_base; - dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); bdp->cbd_bufaddr = 0; - skb = fep->tx_skbuff[index]; - + skb = fep->tx_skbuff[fep->skb_dirty]; /* Check for errors. */ if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN | @@ -682,9 +631,8 @@ fec_enet_tx(struct net_device *ndev) /* Free the sk buffer associated with this last transmit */ dev_kfree_skb_any(skb); - fep->tx_skbuff[index] = NULL; - - fep->dirty_tx = bdp; + fep->tx_skbuff[fep->skb_dirty] = NULL; + fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; /* Update pointer to next buffer descriptor to be transmitted */ if (status & BD_ENET_TX_WRAP) @@ -694,12 +642,14 @@ fec_enet_tx(struct net_device *ndev) /* Since we have freed up a buffer, the ring is no longer full */ - if (fep->dirty_tx != fep->cur_tx) { + if (fep->tx_full) { + fep->tx_full = 0; if (netif_queue_stopped(ndev)) netif_wake_queue(ndev); } } - return; + fep->dirty_tx = bdp; + spin_unlock(&fep->hw_lock); } @@ -866,7 +816,7 @@ fec_enet_interrupt(int irq, void *dev_id) int_events = readl(fep->hwp + FEC_IEVENT); writel(int_events, fep->hwp + FEC_IEVENT); - if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) { + if (int_events & FEC_ENET_RXF) { ret = IRQ_HANDLED; /* Disable the RX interrupt */ @@ -877,6 +827,15 @@ fec_enet_interrupt(int irq, void *dev_id) } } + /* Transmit OK, or non-fatal error. Update the buffer + * descriptors. FEC handles all errors, we just discover + * them as part of the transmit process. + */ + if (int_events & FEC_ENET_TXF) { + ret = IRQ_HANDLED; + fec_enet_tx(ndev); + } + if (int_events & FEC_ENET_MII) { ret = IRQ_HANDLED; complete(&fep->mdio_done); @@ -892,8 +851,6 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget) int pkts = fec_enet_rx(ndev, budget); struct fec_enet_private *fep = netdev_priv(ndev); - fec_enet_tx(ndev); - if (pkts < budget) { napi_complete(napi); writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); @@ -982,29 +939,24 @@ static void fec_enet_adjust_link(struct net_device *ndev) goto spin_unlock; } + /* Duplex link change */ if (phy_dev->link) { - if (!fep->link) { + if (fep->full_duplex != phy_dev->duplex) { + fec_restart(ndev, phy_dev->duplex); + /* prevent unnecessary second fec_restart() below */ fep->link = phy_dev->link; status_change = 1; } + } - if (fep->full_duplex != phy_dev->duplex) - status_change = 1; - - if (phy_dev->speed != fep->speed) { - fep->speed = phy_dev->speed; - status_change = 1; - } - - /* if any of the above changed restart the FEC */ - if (status_change) + /* Link on or off change */ + if (phy_dev->link != fep->link) { + fep->link = phy_dev->link; + if (phy_dev->link) fec_restart(ndev, phy_dev->duplex); - } else { - if (fep->link) { + else fec_stop(ndev); - fep->link = phy_dev->link; - status_change = 1; - } + status_change = 1; } spin_unlock: @@ -1381,7 +1333,7 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) static void fec_enet_free_buffers(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - unsigned int i; + int i; struct sk_buff *skb; struct bufdesc *bdp; @@ -1405,7 +1357,7 @@ static void fec_enet_free_buffers(struct net_device *ndev) static int fec_enet_alloc_buffers(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - unsigned int i; + int i; struct sk_buff *skb; struct bufdesc *bdp; @@ -1490,7 +1442,6 @@ fec_enet_close(struct net_device *ndev) struct fec_enet_private *fep = netdev_priv(ndev); /* Don't know what to do yet. */ - napi_disable(&fep->napi); fep->opened = 0; netif_stop_queue(ndev); fec_stop(ndev); @@ -1646,6 +1597,8 @@ static int fec_enet_init(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); struct bufdesc *cbd_base; + struct bufdesc *bdp; + int i; /* Allocate memory for buffer descriptors. */ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, @@ -1655,7 +1608,6 @@ static int fec_enet_init(struct net_device *ndev) return -ENOMEM; } - memset(cbd_base, 0, PAGE_SIZE); spin_lock_init(&fep->hw_lock); fep->netdev = ndev; @@ -1679,6 +1631,33 @@ static int fec_enet_init(struct net_device *ndev) writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK); netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT); + /* Initialize the receive buffer descriptors. */ + bdp = fep->rx_bd_base; + for (i = 0; i < RX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + + /* ...and the same for transmit */ + bdp = fep->tx_bd_base; + for (i = 0; i < TX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + bdp->cbd_bufaddr = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + fec_restart(ndev, 0); return 0; diff --git a/trunk/drivers/net/ethernet/freescale/fec.h b/trunk/drivers/net/ethernet/freescale/fec.h index eb4372962839..01579b8e37c4 100644 --- a/trunk/drivers/net/ethernet/freescale/fec.h +++ b/trunk/drivers/net/ethernet/freescale/fec.h @@ -97,13 +97,6 @@ struct bufdesc { unsigned short cbd_sc; /* Control and status info */ unsigned long cbd_bufaddr; /* Buffer address */ }; -#else -struct bufdesc { - unsigned short cbd_sc; /* Control and status info */ - unsigned short cbd_datlen; /* Data length */ - unsigned long cbd_bufaddr; /* Buffer address */ -}; -#endif struct bufdesc_ex { struct bufdesc desc; @@ -114,6 +107,14 @@ struct bufdesc_ex { unsigned short res0[4]; }; +#else +struct bufdesc { + unsigned short cbd_sc; /* Control and status info */ + unsigned short cbd_datlen; /* Data length */ + unsigned long cbd_bufaddr; /* Buffer address */ +}; +#endif + /* * The following definitions courtesy of commproc.h, which where * Copyright (c) 1997 Dan Malek (dmalek@jlc.net). @@ -213,6 +214,8 @@ struct fec_enet_private { unsigned char *tx_bounce[TX_RING_SIZE]; struct sk_buff *tx_skbuff[TX_RING_SIZE]; struct sk_buff *rx_skbuff[RX_RING_SIZE]; + ushort skb_cur; + ushort skb_dirty; /* CPM dual port RAM relative addresses */ dma_addr_t bd_dma; @@ -224,6 +227,7 @@ struct fec_enet_private { /* The ring entries to be free()ed */ struct bufdesc *dirty_tx; + uint tx_full; /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ spinlock_t hw_lock; @@ -240,7 +244,6 @@ struct fec_enet_private { phy_interface_t phy_interface; int link; int full_duplex; - int speed; struct completion mdio_done; int irq[FEC_IRQ_NUM]; int bufdesc_ex; diff --git a/trunk/drivers/net/ethernet/freescale/fec_ptp.c b/trunk/drivers/net/ethernet/freescale/fec_ptp.c index 0d8df400a479..1f17ca0f2201 100644 --- a/trunk/drivers/net/ethernet/freescale/fec_ptp.c +++ b/trunk/drivers/net/ethernet/freescale/fec_ptp.c @@ -128,7 +128,6 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev) spin_unlock_irqrestore(&fep->tmreg_lock, flags); } -EXPORT_SYMBOL(fec_ptp_start_cyclecounter); /** * fec_ptp_adjfreq - adjust ptp cycle frequency @@ -319,7 +318,6 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; } -EXPORT_SYMBOL(fec_ptp_ioctl); /** * fec_time_keep - call timecounter_read every second to avoid timer overrun @@ -385,4 +383,3 @@ void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev) pr_info("registered PHC device on %s\n", ndev->name); } } -EXPORT_SYMBOL(fec_ptp_init); diff --git a/trunk/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/trunk/drivers/net/ethernet/fujitsu/fmvj18x_cs.c index ab98b77df309..2418faf2251a 100644 --- a/trunk/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +++ b/trunk/drivers/net/ethernet/fujitsu/fmvj18x_cs.c @@ -705,7 +705,19 @@ static struct pcmcia_driver fmvj18x_cs_driver = { .suspend = fmvj18x_suspend, .resume = fmvj18x_resume, }; -module_pcmcia_driver(fmvj18x_cs_driver); + +static int __init init_fmvj18x_cs(void) +{ + return pcmcia_register_driver(&fmvj18x_cs_driver); +} + +static void __exit exit_fmvj18x_cs(void) +{ + pcmcia_unregister_driver(&fmvj18x_cs_driver); +} + +module_init(init_fmvj18x_cs); +module_exit(exit_fmvj18x_cs); /*====================================================================*/ diff --git a/trunk/drivers/net/ethernet/intel/e100.c b/trunk/drivers/net/ethernet/intel/e100.c index d2bea3f07c73..ec800b093e7e 100644 --- a/trunk/drivers/net/ethernet/intel/e100.c +++ b/trunk/drivers/net/ethernet/intel/e100.c @@ -870,7 +870,7 @@ static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr) } static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, - int (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *)) + void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *)) { struct cb *cb; unsigned long flags; @@ -888,13 +888,10 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, nic->cbs_avail--; cb->skb = skb; - err = cb_prepare(nic, cb, skb); - if (err) - goto err_unlock; - if (unlikely(!nic->cbs_avail)) err = -ENOSPC; + cb_prepare(nic, cb, skb); /* Order is important otherwise we'll be in a race with h/w: * set S-bit in current first, then clear S-bit in previous. */ @@ -1094,7 +1091,7 @@ static void e100_get_defaults(struct nic *nic) nic->mii.mdio_write = mdio_write; } -static int e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) +static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) { struct config *config = &cb->u.config; u8 *c = (u8 *)config; @@ -1184,7 +1181,6 @@ static int e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) netif_printk(nic, hw, KERN_DEBUG, nic->netdev, "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); - return 0; } /************************************************************************* @@ -1335,7 +1331,7 @@ static const struct firmware *e100_request_firmware(struct nic *nic) return fw; } -static int e100_setup_ucode(struct nic *nic, struct cb *cb, +static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) { const struct firmware *fw = (void *)skb; @@ -1362,7 +1358,6 @@ static int e100_setup_ucode(struct nic *nic, struct cb *cb, cb->u.ucode[min_size] |= cpu_to_le32((BUNDLESMALL) ? 0xFFFF : 0xFF80); cb->command = cpu_to_le16(cb_ucode | cb_el); - return 0; } static inline int e100_load_ucode_wait(struct nic *nic) @@ -1405,20 +1400,18 @@ static inline int e100_load_ucode_wait(struct nic *nic) return err; } -static int e100_setup_iaaddr(struct nic *nic, struct cb *cb, +static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, struct sk_buff *skb) { cb->command = cpu_to_le16(cb_iaaddr); memcpy(cb->u.iaaddr, nic->netdev->dev_addr, ETH_ALEN); - return 0; } -static int e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb) +static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb) { cb->command = cpu_to_le16(cb_dump); cb->u.dump_buffer_addr = cpu_to_le32(nic->dma_addr + offsetof(struct mem, dump_buf)); - return 0; } static int e100_phy_check_without_mii(struct nic *nic) @@ -1588,7 +1581,7 @@ static int e100_hw_init(struct nic *nic) return 0; } -static int e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) +static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) { struct net_device *netdev = nic->netdev; struct netdev_hw_addr *ha; @@ -1603,7 +1596,6 @@ static int e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) memcpy(&cb->u.multi.addr[i++ * ETH_ALEN], &ha->addr, ETH_ALEN); } - return 0; } static void e100_set_multicast_list(struct net_device *netdev) @@ -1764,18 +1756,11 @@ static void e100_watchdog(unsigned long data) round_jiffies(jiffies + E100_WATCHDOG_PERIOD)); } -static int e100_xmit_prepare(struct nic *nic, struct cb *cb, +static void e100_xmit_prepare(struct nic *nic, struct cb *cb, struct sk_buff *skb) { - dma_addr_t dma_addr; cb->command = nic->tx_command; - dma_addr = pci_map_single(nic->pdev, - skb->data, skb->len, PCI_DMA_TODEVICE); - /* If we can't map the skb, have the upper layer try later */ - if (pci_dma_mapping_error(nic->pdev, dma_addr)) - return -ENOMEM; - /* * Use the last 4 bytes of the SKB payload packet as the CRC, used for * testing, ie sending frames with bad CRC. @@ -1792,10 +1777,11 @@ static int e100_xmit_prepare(struct nic *nic, struct cb *cb, cb->u.tcb.tcb_byte_count = 0; cb->u.tcb.threshold = nic->tx_threshold; cb->u.tcb.tbd_count = 1; - cb->u.tcb.tbd.buf_addr = cpu_to_le32(dma_addr); + cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev, + skb->data, skb->len, PCI_DMA_TODEVICE)); + /* check for mapping failure? */ cb->u.tcb.tbd.size = cpu_to_le16(skb->len); skb_tx_timestamp(skb); - return 0; } static netdev_tx_t e100_xmit_frame(struct sk_buff *skb, diff --git a/trunk/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/trunk/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index ffd287196bf8..43462d596a4e 100644 --- a/trunk/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -1053,10 +1053,6 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) txdr->buffer_info[i].dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(&pdev->dev, txdr->buffer_info[i].dma)) { - ret_val = 4; - goto err_nomem; - } tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma); tx_desc->lower.data = cpu_to_le32(skb->len); tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP | @@ -1073,7 +1069,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_buffer), GFP_KERNEL); if (!rxdr->buffer_info) { - ret_val = 5; + ret_val = 4; goto err_nomem; } @@ -1081,7 +1077,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma, GFP_KERNEL); if (!rxdr->desc) { - ret_val = 6; + ret_val = 5; goto err_nomem; } memset(rxdr->desc, 0, rxdr->size); @@ -1105,7 +1101,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL); if (!skb) { - ret_val = 7; + ret_val = 6; goto err_nomem; } skb_reserve(skb, NET_IP_ALIGN); @@ -1114,10 +1110,6 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->buffer_info[i].dma = dma_map_single(&pdev->dev, skb->data, E1000_RXBUFFER_2048, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, rxdr->buffer_info[i].dma)) { - ret_val = 8; - goto err_nomem; - } rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma); memset(skb->data, 0x00, skb->len); } diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c b/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c index f91a8f3f9d48..2c1813737f6d 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "e1000.h" @@ -2230,19 +2229,7 @@ static int e1000e_get_ts_info(struct net_device *netdev, return 0; } -static int e1000e_ethtool_begin(struct net_device *netdev) -{ - return pm_runtime_get_sync(netdev->dev.parent); -} - -static void e1000e_ethtool_complete(struct net_device *netdev) -{ - pm_runtime_put_sync(netdev->dev.parent); -} - static const struct ethtool_ops e1000_ethtool_ops = { - .begin = e1000e_ethtool_begin, - .complete = e1000e_ethtool_complete, .get_settings = e1000_get_settings, .set_settings = e1000_set_settings, .get_drvinfo = e1000_get_drvinfo, diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c index 121a865c7fbd..dff7bff8b8e0 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -781,59 +781,6 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw) return ret_val; } -/** - * e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP - * @hw: pointer to the HW structure - * @link: link up bool flag - * - * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications - * preventing further DMA write requests. Workaround the issue by disabling - * the de-assertion of the clock request when in 1Gpbs mode. - **/ -static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) -{ - u32 fextnvm6 = er32(FEXTNVM6); - s32 ret_val = 0; - - if (link && (er32(STATUS) & E1000_STATUS_SPEED_1000)) { - u16 kmrn_reg; - - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - return ret_val; - - ret_val = - e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, - &kmrn_reg); - if (ret_val) - goto release; - - ret_val = - e1000e_write_kmrn_reg_locked(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - kmrn_reg & - ~E1000_KMRNCTRLSTA_K1_ENABLE); - if (ret_val) - goto release; - - usleep_range(10, 20); - - ew32(FEXTNVM6, fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK); - - ret_val = - e1000e_write_kmrn_reg_locked(hw, - E1000_KMRNCTRLSTA_K1_CONFIG, - kmrn_reg); -release: - hw->phy.ops.release(hw); - } else { - /* clear FEXTNVM6 bit 8 on link down or 10/100 */ - ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); - } - - return ret_val; -} - /** * e1000_check_for_copper_link_ich8lan - Check for link (Copper) * @hw: pointer to the HW structure @@ -871,14 +818,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) return ret_val; } - /* Work-around I218 hang issue */ - if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) || - (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V)) { - ret_val = e1000_k1_workaround_lpt_lp(hw, link); - if (ret_val) - return ret_val; - } - /* Clear link partner's EEE ability */ hw->dev_spec.ich8lan.eee_lp_ability = 0; @@ -4015,16 +3954,8 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) phy_ctrl = er32(PHY_CTRL); phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; - if (hw->phy.type == e1000_phy_i217) { - u16 phy_reg, device_id = hw->adapter->pdev->device; - - if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) || - (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) { - u32 fextnvm6 = er32(FEXTNVM6); - - ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); - } + u16 phy_reg; ret_val = hw->phy.ops.acquire(hw); if (ret_val) diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.h b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.h index 8bf4655c2e17..b6d3174d7d2d 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.h @@ -92,8 +92,6 @@ #define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7 #define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3 -#define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100 - #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL #define E1000_ICH_RAR_ENTRIES 7 diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 7e615e2bf7e6..a177b8b65c44 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -848,16 +848,11 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring, } } - if (!buffer_info->dma) { + if (!buffer_info->dma) buffer_info->dma = dma_map_page(&pdev->dev, buffer_info->page, 0, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { - adapter->alloc_rx_buff_failed++; - break; - } - } rx_desc = E1000_RX_DESC_EXT(*rx_ring, i); rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma); @@ -4308,7 +4303,6 @@ static int e1000_open(struct net_device *netdev) netif_start_queue(netdev); adapter->idle_check = true; - hw->mac.get_link_status = true; pm_runtime_put(&pdev->dev); /* fire a link status change interrupt to start the watchdog */ @@ -4668,7 +4662,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) (adapter->hw.phy.media_type == e1000_media_type_copper)) { int ret_val; - pm_runtime_get_sync(&adapter->pdev->dev); ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr); ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr); ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise); @@ -4679,7 +4672,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus); if (ret_val) e_warn("Error reading PHY register\n"); - pm_runtime_put_sync(&adapter->pdev->dev); } else { /* Do not read PHY registers if link is not up * Set values to typical power-on defaults @@ -5895,7 +5887,8 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) return retval; } -static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) +static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, + bool runtime) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); @@ -5919,6 +5912,10 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) } e1000e_reset_interrupt_capability(adapter); + retval = pci_save_state(pdev); + if (retval) + return retval; + status = er32(STATUS); if (status & E1000_STATUS_LU) wufc &= ~E1000_WUFC_LNKC; @@ -5974,6 +5971,13 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) ew32(WUFC, 0); } + *enable_wake = !!wufc; + + /* make sure adapter isn't asleep if manageability is enabled */ + if ((adapter->flags & FLAG_MNG_PT_ENABLED) || + (hw->mac.ops.check_mng_mode(hw))) + *enable_wake = true; + if (adapter->hw.phy.type == e1000_phy_igp_3) e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); @@ -5982,7 +5986,27 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) */ e1000e_release_hw_control(adapter); - pci_clear_master(pdev); + pci_disable_device(pdev); + + return 0; +} + +static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake) +{ + if (sleep && wake) { + pci_prepare_to_sleep(pdev); + return; + } + + pci_wake_from_d3(pdev, wake); + pci_set_power_state(pdev, PCI_D3hot); +} + +static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, + bool wake) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev_priv(netdev); /* The pci-e switch on some quad port adapters will report a * correctable error when the MAC transitions from D0 to D3. To @@ -5997,13 +6021,12 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, (devctl & ~PCI_EXP_DEVCTL_CERE)); - pci_save_state(pdev); - pci_prepare_to_sleep(pdev); + e1000_power_off(pdev, sleep, wake); pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl); + } else { + e1000_power_off(pdev, sleep, wake); } - - return 0; } #ifdef CONFIG_PCIEASPM @@ -6061,7 +6084,9 @@ static int __e1000_resume(struct pci_dev *pdev) if (aspm_disable_flag) e1000e_disable_aspm(pdev, aspm_disable_flag); - pci_set_master(pdev); + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_save_state(pdev); e1000e_set_interrupt_capability(adapter); if (netif_running(netdev)) { @@ -6127,8 +6152,14 @@ static int __e1000_resume(struct pci_dev *pdev) static int e1000_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); + int retval; + bool wake; - return __e1000_shutdown(pdev, false); + retval = __e1000_shutdown(pdev, &wake, false); + if (!retval) + e1000_complete_shutdown(pdev, true, wake); + + return retval; } static int e1000_resume(struct device *dev) @@ -6151,10 +6182,13 @@ static int e1000_runtime_suspend(struct device *dev) struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - if (!e1000e_pm_ready(adapter)) - return 0; + if (e1000e_pm_ready(adapter)) { + bool wake; + + __e1000_shutdown(pdev, &wake, true); + } - return __e1000_shutdown(pdev, true); + return 0; } static int e1000_idle(struct device *dev) @@ -6192,7 +6226,12 @@ static int e1000_runtime_resume(struct device *dev) static void e1000_shutdown(struct pci_dev *pdev) { - __e1000_shutdown(pdev, false); + bool wake = false; + + __e1000_shutdown(pdev, &wake, false); + + if (system_state == SYSTEM_POWER_OFF) + e1000_complete_shutdown(pdev, false, wake); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -6313,9 +6352,9 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) "Cannot re-enable PCI device after reset.\n"); result = PCI_ERS_RESULT_DISCONNECT; } else { + pci_set_master(pdev); pdev->state_saved = true; pci_restore_state(pdev); - pci_set_master(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); @@ -6744,11 +6783,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* initialize the wol settings based on the eeprom settings */ adapter->wol = adapter->eeprom_wol; - - /* make sure adapter isn't asleep if manageability is enabled */ - if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) || - (hw->mac.ops.check_mng_mode(hw))) - device_wakeup_enable(&pdev->dev); + device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); /* save off EEPROM version number */ e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/regs.h b/trunk/drivers/net/ethernet/intel/e1000e/regs.h index a7e6a3e37257..794fe1497666 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/regs.h +++ b/trunk/drivers/net/ethernet/intel/e1000e/regs.h @@ -42,7 +42,6 @@ #define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ #define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */ #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ -#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */ #define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */ #define E1000_FCT 0x00030 /* Flow Control Type - RW */ #define E1000_VET 0x00038 /* VLAN Ether Type - RW */ diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c index 12b1d8480808..84e7e0909def 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1361,16 +1361,11 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) switch (hw->phy.type) { case e1000_phy_i210: case e1000_phy_m88: - switch (hw->phy.id) { - case I347AT4_E_PHY_ID: - case M88E1112_E_PHY_ID: - case I210_I_PHY_ID: + if (hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) ret_val = igb_copper_link_setup_m88_gen2(hw); - break; - default: + else ret_val = igb_copper_link_setup_m88(hw); - break; - } break; case e1000_phy_igp_3: ret_val = igb_copper_link_setup_igp(hw); @@ -1818,32 +1813,27 @@ static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw) **/ void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf) { - u32 reg_val, reg_offset; + u32 dtxswc; switch (hw->mac.type) { case e1000_82576: - reg_offset = E1000_DTXSWC; - break; case e1000_i350: - reg_offset = E1000_TXSWC; + dtxswc = rd32(E1000_DTXSWC); + if (enable) { + dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK | + E1000_DTXSWC_VLAN_SPOOF_MASK); + /* The PF can spoof - it has to in order to + * support emulation mode NICs */ + dtxswc ^= (1 << pf | 1 << (pf + MAX_NUM_VFS)); + } else { + dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK | + E1000_DTXSWC_VLAN_SPOOF_MASK); + } + wr32(E1000_DTXSWC, dtxswc); break; default: - return; - } - - reg_val = rd32(reg_offset); - if (enable) { - reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK | - E1000_DTXSWC_VLAN_SPOOF_MASK); - /* The PF can spoof - it has to in order to - * support emulation mode NICs - */ - reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS)); - } else { - reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK | - E1000_DTXSWC_VLAN_SPOOF_MASK); + break; } - wr32(reg_offset, reg_val); } /** diff --git a/trunk/drivers/net/ethernet/intel/igb/igb.h b/trunk/drivers/net/ethernet/intel/igb/igb.h index ab577a763a20..d27edbc63923 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb.h +++ b/trunk/drivers/net/ethernet/intel/igb/igb.h @@ -284,10 +284,18 @@ struct igb_q_vector { enum e1000_ring_flags_t { IGB_RING_FLAG_RX_SCTP_CSUM, IGB_RING_FLAG_RX_LB_VLAN_BSWAP, + IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, IGB_RING_FLAG_TX_CTX_IDX, IGB_RING_FLAG_TX_DETECT_HANG }; +#define ring_uses_build_skb(ring) \ + test_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags) +#define set_ring_build_skb_enabled(ring) \ + set_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags) +#define clear_ring_build_skb_enabled(ring) \ + clear_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags) + #define IGB_TXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS) #define IGB_RX_DESC(R, i) \ @@ -439,7 +447,7 @@ struct igb_adapter { #endif struct i2c_algo_bit_data i2c_algo; struct i2c_adapter i2c_adap; - struct i2c_client *i2c_client; + struct igb_i2c_client_list *i2c_clients; }; #define IGB_FLAG_HAS_MSI (1 << 0) diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_hwmon.c b/trunk/drivers/net/ethernet/intel/igb/igb_hwmon.c index 0478a1abe541..0a9b073d0b03 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_hwmon.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_hwmon.c @@ -39,10 +39,6 @@ #include #ifdef CONFIG_IGB_HWMON -static struct i2c_board_info i350_sensor_info = { - I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)), -}; - /* hwmon callback functions */ static ssize_t igb_hwmon_show_location(struct device *dev, struct device_attribute *attr, @@ -192,7 +188,6 @@ int igb_sysfs_init(struct igb_adapter *adapter) unsigned int i; int n_attrs; int rc = 0; - struct i2c_client *client = NULL; /* If this method isn't defined we don't support thermals */ if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) @@ -203,15 +198,6 @@ int igb_sysfs_init(struct igb_adapter *adapter) if (rc) goto exit; - /* init i2c_client */ - client = i2c_new_device(&adapter->i2c_adap, &i350_sensor_info); - if (client == NULL) { - dev_info(&adapter->pdev->dev, - "Failed to create new i2c device..\n"); - goto exit; - } - adapter->i2c_client = client; - /* Allocation space for max attributes * max num sensors * values (loc, temp, max, caution) */ diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_main.c b/trunk/drivers/net/ethernet/intel/igb/igb_main.c index 64f75291e3a5..ed79a1c53b59 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_main.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_main.c @@ -1923,6 +1923,10 @@ void igb_set_fw_version(struct igb_adapter *adapter) return; } +static const struct i2c_board_info i350_sensor_info = { + I2C_BOARD_INFO("i350bb", 0Xf8), +}; + /* igb_init_i2c - Init I2C interface * @adapter: pointer to adapter structure * @@ -2542,8 +2546,8 @@ static void igb_probe_vfs(struct igb_adapter *adapter) if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) return; - pci_sriov_set_totalvfs(pdev, 7); igb_enable_sriov(pdev, max_vfs); + pci_sriov_set_totalvfs(pdev, 7); #endif /* CONFIG_PCI_IOV */ } @@ -2652,7 +2656,7 @@ static int igb_sw_init(struct igb_adapter *adapter) if (max_vfs > 7) { dev_warn(&pdev->dev, "Maximum of 7 VFs per PF, using max\n"); - max_vfs = adapter->vfs_allocated_count = 7; + adapter->vfs_allocated_count = 7; } else adapter->vfs_allocated_count = max_vfs; if (adapter->vfs_allocated_count) @@ -3350,6 +3354,20 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, wr32(E1000_RXDCTL(reg_idx), rxdctl); } +static void igb_set_rx_buffer_len(struct igb_adapter *adapter, + struct igb_ring *rx_ring) +{ +#define IGB_MAX_BUILD_SKB_SIZE \ + (SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) - \ + (NET_SKB_PAD + NET_IP_ALIGN + IGB_TS_HDR_LEN)) + + /* set build_skb flag */ + if (adapter->max_frame_size <= IGB_MAX_BUILD_SKB_SIZE) + set_ring_build_skb_enabled(rx_ring); + else + clear_ring_build_skb_enabled(rx_ring); +} + /** * igb_configure_rx - Configure receive Unit after Reset * @adapter: board private structure @@ -3369,8 +3387,11 @@ static void igb_configure_rx(struct igb_adapter *adapter) /* Setup the HW Rx Head and Tail Descriptor Pointers and * the Base and Length of the Rx Descriptor Ring */ - for (i = 0; i < adapter->num_rx_queues; i++) - igb_configure_rx_ring(adapter, adapter->rx_ring[i]); + for (i = 0; i < adapter->num_rx_queues; i++) { + struct igb_ring *rx_ring = adapter->rx_ring[i]; + igb_set_rx_buffer_len(adapter, rx_ring); + igb_configure_rx_ring(adapter, rx_ring); + } } /** @@ -6186,6 +6207,85 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring, return igb_can_reuse_rx_page(rx_buffer, page, truesize); } +static struct sk_buff *igb_build_rx_buffer(struct igb_ring *rx_ring, + union e1000_adv_rx_desc *rx_desc) +{ + struct igb_rx_buffer *rx_buffer; + struct sk_buff *skb; + struct page *page; + void *page_addr; + unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); +#if (PAGE_SIZE < 8192) + unsigned int truesize = IGB_RX_BUFSZ; +#else + unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + + SKB_DATA_ALIGN(NET_SKB_PAD + + NET_IP_ALIGN + + size); +#endif + + /* If we spanned a buffer we have a huge mess so test for it */ + BUG_ON(unlikely(!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP))); + + /* Guarantee this function can be used by verifying buffer sizes */ + BUILD_BUG_ON(SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) < (NET_SKB_PAD + + NET_IP_ALIGN + + IGB_TS_HDR_LEN + + ETH_FRAME_LEN + + ETH_FCS_LEN)); + + rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; + page = rx_buffer->page; + prefetchw(page); + + page_addr = page_address(page) + rx_buffer->page_offset; + + /* prefetch first cache line of first page */ + prefetch(page_addr + NET_SKB_PAD + NET_IP_ALIGN); +#if L1_CACHE_BYTES < 128 + prefetch(page_addr + L1_CACHE_BYTES + NET_SKB_PAD + NET_IP_ALIGN); +#endif + + /* build an skb to around the page buffer */ + skb = build_skb(page_addr, truesize); + if (unlikely(!skb)) { + rx_ring->rx_stats.alloc_failed++; + return NULL; + } + + /* we are reusing so sync this buffer for CPU use */ + dma_sync_single_range_for_cpu(rx_ring->dev, + rx_buffer->dma, + rx_buffer->page_offset, + IGB_RX_BUFSZ, + DMA_FROM_DEVICE); + + /* update pointers within the skb to store the data */ + skb_reserve(skb, NET_IP_ALIGN + NET_SKB_PAD); + __skb_put(skb, size); + + /* pull timestamp out of packet data */ + if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { + igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb); + __skb_pull(skb, IGB_TS_HDR_LEN); + } + + if (igb_can_reuse_rx_page(rx_buffer, page, truesize)) { + /* hand second half of page back to the ring */ + igb_reuse_rx_page(rx_ring, rx_buffer); + } else { + /* we are not reusing the buffer so unmap it */ + dma_unmap_page(rx_ring->dev, rx_buffer->dma, + PAGE_SIZE, DMA_FROM_DEVICE); + } + + /* clear contents of buffer_info */ + rx_buffer->dma = 0; + rx_buffer->page = NULL; + + return skb; +} + static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring, union e1000_adv_rx_desc *rx_desc, struct sk_buff *skb) @@ -6601,7 +6701,10 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) rmb(); /* retrieve a buffer from the ring */ - skb = igb_fetch_rx_buffer(rx_ring, rx_desc, skb); + if (ring_uses_build_skb(rx_ring)) + skb = igb_build_rx_buffer(rx_ring, rx_desc); + else + skb = igb_fetch_rx_buffer(rx_ring, rx_desc, skb); /* exit if we failed to retrieve a buffer */ if (!skb) @@ -6688,6 +6791,14 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, return true; } +static inline unsigned int igb_rx_offset(struct igb_ring *rx_ring) +{ + if (ring_uses_build_skb(rx_ring)) + return NET_SKB_PAD + NET_IP_ALIGN; + else + return 0; +} + /** * igb_alloc_rx_buffers - Replace used receive buffers; packet split * @adapter: address of board private structure @@ -6714,7 +6825,9 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count) * Refresh the desc even if buffer_addrs didn't change * because each write-back erases this info. */ - rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset); + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + + bi->page_offset + + igb_rx_offset(rx_ring)); rx_desc++; bi++; @@ -7611,6 +7724,67 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) } } +static DEFINE_SPINLOCK(i2c_clients_lock); + +/* igb_get_i2c_client - returns matching client + * in adapters's client list. + * @adapter: adapter struct + * @dev_addr: device address of i2c needed. + */ +static struct i2c_client * +igb_get_i2c_client(struct igb_adapter *adapter, u8 dev_addr) +{ + ulong flags; + struct igb_i2c_client_list *client_list; + struct i2c_client *client = NULL; + struct i2c_board_info client_info = { + I2C_BOARD_INFO("igb", 0x00), + }; + + spin_lock_irqsave(&i2c_clients_lock, flags); + client_list = adapter->i2c_clients; + + /* See if we already have an i2c_client */ + while (client_list) { + if (client_list->client->addr == (dev_addr >> 1)) { + client = client_list->client; + goto exit; + } else { + client_list = client_list->next; + } + } + + /* no client_list found, create a new one */ + client_list = kzalloc(sizeof(*client_list), GFP_ATOMIC); + if (client_list == NULL) + goto exit; + + /* dev_addr passed to us is left-shifted by 1 bit + * i2c_new_device call expects it to be flush to the right. + */ + client_info.addr = dev_addr >> 1; + client_info.platform_data = adapter; + client_list->client = i2c_new_device(&adapter->i2c_adap, &client_info); + if (client_list->client == NULL) { + dev_info(&adapter->pdev->dev, + "Failed to create new i2c device..\n"); + goto err_no_client; + } + + /* insert new client at head of list */ + client_list->next = adapter->i2c_clients; + adapter->i2c_clients = client_list; + + client = client_list->client; + goto exit; + +err_no_client: + kfree(client_list); +exit: + spin_unlock_irqrestore(&i2c_clients_lock, flags); + return client; +} + /* igb_read_i2c_byte - Reads 8 bit word over I2C * @hw: pointer to hardware structure * @byte_offset: byte offset to read @@ -7624,7 +7798,7 @@ s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data) { struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw); - struct i2c_client *this_client = adapter->i2c_client; + struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr); s32 status; u16 swfw_mask = 0; @@ -7661,7 +7835,7 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr, u8 data) { struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw); - struct i2c_client *this_client = adapter->i2c_client; + struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr); s32 status; u16 swfw_mask = E1000_SWFW_PHY0_SM; diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_ptp.c b/trunk/drivers/net/ethernet/intel/igb/igb_ptp.c index 0a237507ee85..0987822359f0 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -740,7 +740,7 @@ void igb_ptp_init(struct igb_adapter *adapter) case e1000_82576: snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); adapter->ptp_caps.owner = THIS_MODULE; - adapter->ptp_caps.max_adj = 999999881; + adapter->ptp_caps.max_adj = 1000000000; adapter->ptp_caps.n_ext_ts = 0; adapter->ptp_caps.pps = 0; adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82576; diff --git a/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c index b5f94abe3cff..ea4808373435 100644 --- a/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -2159,10 +2159,6 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count) skb->data, adapter->rx_buffer_len, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { - adapter->alloc_rx_buff_failed++; - break; - } rx_desc = IXGB_RX_DESC(*rx_ring, i); rx_desc->buff_addr = cpu_to_le64(buffer_info->dma); @@ -2172,8 +2168,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count) rx_desc->status = 0; - if (++i == rx_ring->count) - i = 0; + if (++i == rx_ring->count) i = 0; buffer_info = &rx_ring->buffer_info[i]; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 79f4a26ea6cc..db5611ae407e 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7922,19 +7922,12 @@ static int __init ixgbe_init_module(void) ixgbe_dbg_init(); #endif /* CONFIG_DEBUG_FS */ - ret = pci_register_driver(&ixgbe_driver); - if (ret) { -#ifdef CONFIG_DEBUG_FS - ixgbe_dbg_exit(); -#endif /* CONFIG_DEBUG_FS */ - return ret; - } - #ifdef CONFIG_IXGBE_DCA dca_register_notify(&dca_notifier); #endif - return 0; + ret = pci_register_driver(&ixgbe_driver); + return ret; } module_init(ixgbe_init_module); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 97e33669c0b9..d44b4d21268c 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -1049,12 +1049,6 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) return -EINVAL; if (vlan || qos) { - if (adapter->vfinfo[vf].pf_vlan) - err = ixgbe_set_vf_vlan(adapter, false, - adapter->vfinfo[vf].pf_vlan, - vf); - if (err) - goto out; err = ixgbe_set_vf_vlan(adapter, true, vlan, vf); if (err) goto out; diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 2b6cb5ca48ee..c3db6cd69b68 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -944,17 +944,9 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter) free_irq(adapter->msix_entries[vector].vector, adapter->q_vector[vector]); } - /* This failure is non-recoverable - it indicates the system is - * out of MSIX vector resources and the VF driver cannot run - * without them. Set the number of msix vectors to zero - * indicating that not enough can be allocated. The error - * will be returned to the user indicating device open failed. - * Any further attempts to force the driver to open will also - * fail. The only way to recover is to unload the driver and - * reload it again. If the system has recovered some MSIX - * vectors then it may succeed. - */ - adapter->num_msix_vectors = 0; + pci_disable_msix(adapter->pdev); + kfree(adapter->msix_entries); + adapter->msix_entries = NULL; return err; } @@ -2580,15 +2572,6 @@ static int ixgbevf_open(struct net_device *netdev) struct ixgbe_hw *hw = &adapter->hw; int err; - /* A previous failure to open the device because of a lack of - * available MSIX vector resources may have reset the number - * of msix vectors variable to zero. The only way to recover - * is to unload/reload the driver and hope that the system has - * been able to recover some MSIX vector resources. - */ - if (!adapter->num_msix_vectors) - return -ENOMEM; - /* disallow open during test */ if (test_bit(__IXGBEVF_TESTING, &adapter->state)) return -EBUSY; @@ -2645,6 +2628,7 @@ static int ixgbevf_open(struct net_device *netdev) err_req_irq: ixgbevf_down(adapter); + ixgbevf_free_irq(adapter); err_setup_rx: ixgbevf_free_all_rx_resources(adapter); err_setup_tx: diff --git a/trunk/drivers/net/ethernet/lantiq_etop.c b/trunk/drivers/net/ethernet/lantiq_etop.c index bfdb06860397..6a2127489af7 100644 --- a/trunk/drivers/net/ethernet/lantiq_etop.c +++ b/trunk/drivers/net/ethernet/lantiq_etop.c @@ -769,7 +769,7 @@ ltq_etop_probe(struct platform_device *pdev) return 0; err_free: - free_netdev(dev); + kfree(dev); err_out: return err; } diff --git a/trunk/drivers/net/ethernet/marvell/Kconfig b/trunk/drivers/net/ethernet/marvell/Kconfig index 434e33c527df..edfba9370922 100644 --- a/trunk/drivers/net/ethernet/marvell/Kconfig +++ b/trunk/drivers/net/ethernet/marvell/Kconfig @@ -33,7 +33,6 @@ config MV643XX_ETH config MVMDIO tristate "Marvell MDIO interface support" - select PHYLIB ---help--- This driver supports the MDIO interface found in the network interface units of the Marvell EBU SoCs (Kirkwood, Orion5x, @@ -46,6 +45,7 @@ config MVMDIO config MVNETA tristate "Marvell Armada 370/XP network interface support" depends on MACH_ARMADA_370_XP + select PHYLIB select MVMDIO ---help--- This driver supports the network interface units in the diff --git a/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c b/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c index 6562c736a1d8..29140502b71a 100644 --- a/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -1081,45 +1081,6 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq) /* mii management interface *************************************************/ -static void mv643xx_adjust_pscr(struct mv643xx_eth_private *mp) -{ - u32 pscr = rdlp(mp, PORT_SERIAL_CONTROL); - u32 autoneg_disable = FORCE_LINK_PASS | - DISABLE_AUTO_NEG_SPEED_GMII | - DISABLE_AUTO_NEG_FOR_FLOW_CTRL | - DISABLE_AUTO_NEG_FOR_DUPLEX; - - if (mp->phy->autoneg == AUTONEG_ENABLE) { - /* enable auto negotiation */ - pscr &= ~autoneg_disable; - goto out_write; - } - - pscr |= autoneg_disable; - - if (mp->phy->speed == SPEED_1000) { - /* force gigabit, half duplex not supported */ - pscr |= SET_GMII_SPEED_TO_1000; - pscr |= SET_FULL_DUPLEX_MODE; - goto out_write; - } - - pscr &= ~SET_GMII_SPEED_TO_1000; - - if (mp->phy->speed == SPEED_100) - pscr |= SET_MII_SPEED_TO_100; - else - pscr &= ~SET_MII_SPEED_TO_100; - - if (mp->phy->duplex == DUPLEX_FULL) - pscr |= SET_FULL_DUPLEX_MODE; - else - pscr &= ~SET_FULL_DUPLEX_MODE; - -out_write: - wrlp(mp, PORT_SERIAL_CONTROL, pscr); -} - static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id) { struct mv643xx_eth_shared_private *msp = dev_id; @@ -1538,7 +1499,6 @@ static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct mv643xx_eth_private *mp = netdev_priv(dev); - int ret; if (mp->phy == NULL) return -EINVAL; @@ -1548,10 +1508,7 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) */ cmd->advertising &= ~ADVERTISED_1000baseT_Half; - ret = phy_ethtool_sset(mp->phy, cmd); - if (!ret) - mv643xx_adjust_pscr(mp); - return ret; + return phy_ethtool_sset(mp->phy, cmd); } static void mv643xx_eth_get_drvinfo(struct net_device *dev, @@ -2485,15 +2442,11 @@ static int mv643xx_eth_stop(struct net_device *dev) static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mv643xx_eth_private *mp = netdev_priv(dev); - int ret; - if (mp->phy == NULL) - return -ENOTSUPP; + if (mp->phy != NULL) + return phy_mii_ioctl(mp->phy, ifr, cmd); - ret = phy_mii_ioctl(mp->phy, ifr, cmd); - if (!ret) - mv643xx_adjust_pscr(mp); - return ret; + return -EOPNOTSUPP; } static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) diff --git a/trunk/drivers/net/ethernet/marvell/mvneta.c b/trunk/drivers/net/ethernet/marvell/mvneta.c index a47a097c21e1..cd345b8969bc 100644 --- a/trunk/drivers/net/ethernet/marvell/mvneta.c +++ b/trunk/drivers/net/ethernet/marvell/mvneta.c @@ -374,6 +374,7 @@ static int rxq_number = 8; static int txq_number = 8; static int rxq_def; +static int txq_def; #define MVNETA_DRIVER_NAME "mvneta" #define MVNETA_DRIVER_VERSION "1.0" @@ -1474,8 +1475,7 @@ static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb, static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) { struct mvneta_port *pp = netdev_priv(dev); - u16 txq_id = skb_get_queue_mapping(skb); - struct mvneta_tx_queue *txq = &pp->txqs[txq_id]; + struct mvneta_tx_queue *txq = &pp->txqs[txq_def]; struct mvneta_tx_desc *tx_desc; struct netdev_queue *nq; int frags = 0; @@ -1485,7 +1485,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) goto out; frags = skb_shinfo(skb)->nr_frags + 1; - nq = netdev_get_tx_queue(dev, txq_id); + nq = netdev_get_tx_queue(dev, txq_def); /* Get a descriptor for the first part of the packet */ tx_desc = mvneta_txq_next_desc_get(txq); @@ -2689,7 +2689,7 @@ static int mvneta_probe(struct platform_device *pdev) return -EINVAL; } - dev = alloc_etherdev_mqs(sizeof(struct mvneta_port), txq_number, rxq_number); + dev = alloc_etherdev_mq(sizeof(struct mvneta_port), 8); if (!dev) return -ENOMEM; @@ -2771,17 +2771,16 @@ static int mvneta_probe(struct platform_device *pdev) netif_napi_add(dev, &pp->napi, mvneta_poll, pp->weight); - dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; - dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM; - dev->vlan_features |= NETIF_F_SG | NETIF_F_IP_CSUM; - dev->priv_flags |= IFF_UNICAST_FLT; - err = register_netdev(dev); if (err < 0) { dev_err(&pdev->dev, "failed to register\n"); goto err_deinit; } + dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM; + dev->priv_flags |= IFF_UNICAST_FLT; + netdev_info(dev, "mac: %pM\n", dev->dev_addr); platform_set_drvdata(pdev, pp->dev); @@ -2844,3 +2843,4 @@ module_param(rxq_number, int, S_IRUGO); module_param(txq_number, int, S_IRUGO); module_param(rxq_def, int, S_IRUGO); +module_param(txq_def, int, S_IRUGO); diff --git a/trunk/drivers/net/ethernet/marvell/sky2.c b/trunk/drivers/net/ethernet/marvell/sky2.c index 6a0e671fcecd..fc07ca35721b 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.c +++ b/trunk/drivers/net/ethernet/marvell/sky2.c @@ -1067,7 +1067,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space) sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp); sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2); - tp = space - 8192/8; + tp = space - 2048/8; sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp); sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4); } else { diff --git a/trunk/drivers/net/ethernet/marvell/sky2.h b/trunk/drivers/net/ethernet/marvell/sky2.h index ec6dcd80152b..615ac63ea860 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.h +++ b/trunk/drivers/net/ethernet/marvell/sky2.h @@ -2074,7 +2074,7 @@ enum { GM_IS_RX_FF_OR = 1<<1, /* Receive FIFO Overrun */ GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */ -#define GMAC_DEF_MSK (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR) +#define GMAC_DEF_MSK GM_IS_TX_FF_UR }; /* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/cq.c b/trunk/drivers/net/ethernet/mellanox/mlx4/cq.c index 0706623cfb96..7e64033d7de3 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/cq.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/cq.c @@ -226,7 +226,7 @@ void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn) static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn) { - u64 in_param = 0; + u64 in_param; int err; if (mlx4_is_mfunc(dev)) { diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 30d78f806dc3..bb4d8d99f36d 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -411,8 +411,8 @@ static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) static void mlx4_en_u64_to_mac(unsigned char dst_mac[ETH_ALEN + 2], u64 src_mac) { - int i; - for (i = ETH_ALEN - 1; i >= 0; --i) { + unsigned int i; + for (i = ETH_ALEN - 1; i; --i) { dst_mac[i] = src_mac & 0xff; src_mac >>= 8; } @@ -565,38 +565,34 @@ static void mlx4_en_put_qp(struct mlx4_en_priv *priv) struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_dev *dev = mdev->dev; int qpn = priv->base_qpn; - u64 mac; + u64 mac = mlx4_en_mac_to_u64(priv->dev->dev_addr); - if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) { - mac = mlx4_en_mac_to_u64(priv->dev->dev_addr); - en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", - priv->dev->dev_addr); - mlx4_unregister_mac(dev, priv->port, mac); - } else { + en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", + priv->dev->dev_addr); + mlx4_unregister_mac(dev, priv->port, mac); + + if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) { struct mlx4_mac_entry *entry; struct hlist_node *tmp; struct hlist_head *bucket; - unsigned int i; + unsigned int mac_hash; - for (i = 0; i < MLX4_EN_MAC_HASH_SIZE; ++i) { - bucket = &priv->mac_hash[i]; - hlist_for_each_entry_safe(entry, tmp, bucket, hlist) { - mac = mlx4_en_mac_to_u64(entry->mac); - en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", - entry->mac); + mac_hash = priv->dev->dev_addr[MLX4_EN_MAC_HASH_IDX]; + bucket = &priv->mac_hash[mac_hash]; + hlist_for_each_entry_safe(entry, tmp, bucket, hlist) { + if (ether_addr_equal_64bits(entry->mac, + priv->dev->dev_addr)) { + en_dbg(DRV, priv, "Releasing qp: port %d, MAC %pM, qpn %d\n", + priv->port, priv->dev->dev_addr, qpn); mlx4_en_uc_steer_release(priv, entry->mac, qpn, entry->reg_id); + mlx4_qp_release_range(dev, qpn, 1); - mlx4_unregister_mac(dev, priv->port, mac); hlist_del_rcu(&entry->hlist); kfree_rcu(entry, rcu); + break; } } - - en_dbg(DRV, priv, "Releasing qp: port %d, qpn %d\n", - priv->port, qpn); - mlx4_qp_release_range(dev, qpn, 1); - priv->flags &= ~MLX4_EN_FLAG_FORCE_PROMISC; } } @@ -654,10 +650,28 @@ u64 mlx4_en_mac_to_u64(u8 *addr) return mac; } -static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv) +static int mlx4_en_set_mac(struct net_device *dev, void *addr) { + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + struct sockaddr *saddr = addr; + + if (!is_valid_ether_addr(saddr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); + queue_work(mdev->workqueue, &priv->mac_task); + return 0; +} + +static void mlx4_en_do_set_mac(struct work_struct *work) +{ + struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, + mac_task); + struct mlx4_en_dev *mdev = priv->mdev; int err = 0; + mutex_lock(&mdev->state_lock); if (priv->port_up) { /* Remove old MAC and insert the new one */ err = mlx4_en_replace_mac(priv, priv->base_qpn, @@ -669,26 +683,7 @@ static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv) } else en_dbg(HW, priv, "Port is down while registering mac, exiting...\n"); - return err; -} - -static int mlx4_en_set_mac(struct net_device *dev, void *addr) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - struct sockaddr *saddr = addr; - int err; - - if (!is_valid_ether_addr(saddr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); - - mutex_lock(&mdev->state_lock); - err = mlx4_en_do_set_mac(priv); mutex_unlock(&mdev->state_lock); - - return err; } static void mlx4_en_clear_list(struct net_device *dev) @@ -1353,7 +1348,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work) queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); } if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) { - mlx4_en_do_set_mac(priv); + queue_work(mdev->workqueue, &priv->mac_task); mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0; } mutex_unlock(&mdev->state_lock); @@ -1637,17 +1632,6 @@ void mlx4_en_stop_port(struct net_device *dev, int detach) /* Flush multicast filter */ mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG); - /* Remove flow steering rules for the port*/ - if (mdev->dev->caps.steering_mode == - MLX4_STEERING_MODE_DEVICE_MANAGED) { - ASSERT_RTNL(); - list_for_each_entry_safe(flow, tmp_flow, - &priv->ethtool_list, list) { - mlx4_flow_detach(mdev->dev, flow->id); - list_del(&flow->list); - } - } - mlx4_en_destroy_drop_qp(priv); /* Free TX Rings */ @@ -1668,6 +1652,17 @@ void mlx4_en_stop_port(struct net_device *dev, int detach) if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN)) mdev->mac_removed[priv->port] = 1; + /* Remove flow steering rules for the port*/ + if (mdev->dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { + ASSERT_RTNL(); + list_for_each_entry_safe(flow, tmp_flow, + &priv->ethtool_list, list) { + mlx4_flow_detach(mdev->dev, flow->id); + list_del(&flow->list); + } + } + /* Free RX Rings */ for (i = 0; i < priv->rx_ring_num; i++) { mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]); @@ -1833,11 +1828,9 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) } #ifdef CONFIG_RFS_ACCEL - if (priv->mdev->dev->caps.comp_pool) { - priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool); - if (!priv->dev->rx_cpu_rmap) - goto err; - } + priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool); + if (!priv->dev->rx_cpu_rmap) + goto err; #endif return 0; @@ -2085,6 +2078,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv->msg_enable = MLX4_EN_MSG_LEVEL; spin_lock_init(&priv->stats_lock); INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); + INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac); INIT_WORK(&priv->watchdog_task, mlx4_en_restart); INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c b/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c index 8e3123a1df88..251ae2f93116 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -771,7 +771,7 @@ int mlx4_MAP_EQ_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_slave_event_eq_info *event_eq = priv->mfunc.master.slave_state[slave].event_eq; u32 in_modifier = vhcr->in_modifier; - u32 eqn = in_modifier & 0x3FF; + u32 eqn = in_modifier & 0x1FF; u64 in_param = vhcr->in_param; int err = 0; int i; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c index f6245579962d..50917eb3013e 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -787,14 +787,6 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); - /* turn off device-managed steering capability if not enabled */ - if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) { - MLX4_GET(field, outbox->buf, - QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); - field &= 0x7f; - MLX4_PUT(outbox->buf, field, - QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); - } return 0; } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c index 16abde20e1fc..d180bc46826a 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1555,7 +1555,7 @@ void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx) void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) { - u64 in_param = 0; + u64 in_param; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, idx); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h index d738454116a0..cf883345af88 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -1235,7 +1235,7 @@ int mlx4_get_qp_per_mgm(struct mlx4_dev *dev); static inline void set_param_l(u64 *arg, u32 val) { - *arg = (*arg & 0xffffffff00000000ULL) | (u64) val; + *((u32 *)arg) = val; } static inline void set_param_h(u64 *arg, u32 val) diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index f710b7ce0dcb..c313d7e943a9 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -509,6 +509,7 @@ struct mlx4_en_priv { struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; struct mlx4_qp drop_qp; struct work_struct rx_mode_task; + struct work_struct mac_task; struct work_struct watchdog_task; struct work_struct linkstate_task; struct delayed_work stats_task; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c b/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c index f91719a08cba..602ca9bf78e4 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -183,7 +183,7 @@ u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order) static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order) { - u64 in_param = 0; + u64 in_param; u64 out_param; int err; @@ -240,7 +240,7 @@ void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order) static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order) { - u64 in_param = 0; + u64 in_param; int err; if (mlx4_is_mfunc(dev)) { @@ -351,7 +351,7 @@ void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index) static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index) { - u64 in_param = 0; + u64 in_param; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, index); @@ -374,7 +374,7 @@ int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index) static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index) { - u64 param = 0; + u64 param; if (mlx4_is_mfunc(dev)) { set_param_l(¶m, index); @@ -395,7 +395,7 @@ void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index) static void mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index) { - u64 in_param = 0; + u64 in_param; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, index); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c b/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c index 00f223acada7..1ac88637ad9d 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c @@ -101,7 +101,7 @@ void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) { - u64 in_param = 0; + u64 in_param; int err; if (mlx4_is_mfunc(dev)) { diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/port.c b/trunk/drivers/net/ethernet/mellanox/mlx4/port.c index 10c57c86388b..719ead15e491 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/port.c @@ -175,7 +175,7 @@ EXPORT_SYMBOL_GPL(__mlx4_register_mac); int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac) { - u64 out_param = 0; + u64 out_param; int err; if (mlx4_is_mfunc(dev)) { @@ -222,7 +222,7 @@ EXPORT_SYMBOL_GPL(__mlx4_unregister_mac); void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac) { - u64 out_param = 0; + u64 out_param; if (mlx4_is_mfunc(dev)) { set_param_l(&out_param, port); @@ -361,7 +361,7 @@ static int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index) { - u64 out_param = 0; + u64 out_param; int err; if (mlx4_is_mfunc(dev)) { @@ -406,7 +406,7 @@ static void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) { - u64 in_param = 0; + u64 in_param; int err; if (mlx4_is_mfunc(dev)) { diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/qp.c b/trunk/drivers/net/ethernet/mellanox/mlx4/qp.c index e891b058c1be..81e2abe07bbb 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -222,7 +222,7 @@ int __mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base) { - u64 in_param = 0; + u64 in_param; u64 out_param; int err; @@ -255,7 +255,7 @@ void __mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt) void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt) { - u64 in_param = 0; + u64 in_param; int err; if (mlx4_is_mfunc(dev)) { @@ -319,7 +319,7 @@ int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn) static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn) { - u64 param = 0; + u64 param; if (mlx4_is_mfunc(dev)) { set_param_l(¶m, qpn); @@ -344,7 +344,7 @@ void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn) static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn) { - u64 in_param = 0; + u64 in_param; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, qpn); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 1391b52f443a..083fb48dc3d7 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -99,7 +99,6 @@ struct res_qp { struct list_head mcg_list; spinlock_t mcg_spl; int local_qpn; - atomic_t ref_count; }; enum res_mtt_states { @@ -198,7 +197,6 @@ enum res_fs_rule_states { struct res_fs_rule { struct res_common com; - int qpn; }; static void *res_tracker_lookup(struct rb_root *root, u64 res_id) @@ -357,7 +355,7 @@ static int mpt_mask(struct mlx4_dev *dev) return dev->caps.num_mpts - 1; } -static void *find_res(struct mlx4_dev *dev, u64 res_id, +static void *find_res(struct mlx4_dev *dev, int res_id, enum mlx4_resource type) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -449,7 +447,6 @@ static struct res_common *alloc_qp_tr(int id) ret->local_qpn = id; INIT_LIST_HEAD(&ret->mcg_list); spin_lock_init(&ret->mcg_spl); - atomic_set(&ret->ref_count, 0); return &ret->com; } @@ -557,7 +554,7 @@ static struct res_common *alloc_xrcdn_tr(int id) return &ret->com; } -static struct res_common *alloc_fs_rule_tr(u64 id, int qpn) +static struct res_common *alloc_fs_rule_tr(u64 id) { struct res_fs_rule *ret; @@ -567,7 +564,7 @@ static struct res_common *alloc_fs_rule_tr(u64 id, int qpn) ret->com.res_id = id; ret->com.state = RES_FS_RULE_ALLOCATED; - ret->qpn = qpn; + return &ret->com; } @@ -605,7 +602,7 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave, ret = alloc_xrcdn_tr(id); break; case RES_FS_RULE: - ret = alloc_fs_rule_tr(id, extra); + ret = alloc_fs_rule_tr(id); break; default: return NULL; @@ -674,14 +671,10 @@ static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count, static int remove_qp_ok(struct res_qp *res) { - if (res->com.state == RES_QP_BUSY || atomic_read(&res->ref_count) || - !list_empty(&res->mcg_list)) { - pr_err("resource tracker: fail to remove qp, state %d, ref_count %d\n", - res->com.state, atomic_read(&res->ref_count)); + if (res->com.state == RES_QP_BUSY) return -EBUSY; - } else if (res->com.state != RES_QP_RESERVED) { + else if (res->com.state != RES_QP_RESERVED) return -EPERM; - } return 0; } @@ -2997,9 +2990,6 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, u8 steer_type_mask = 2; enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1; - if (dev->caps.steering_mode != MLX4_STEERING_MODE_B0) - return -EINVAL; - qpn = vhcr->in_modifier & 0xffffff; err = get_res(dev, slave, qpn, RES_QP, &rqp); if (err) @@ -3131,7 +3121,6 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; int err; int qpn; - struct res_qp *rqp; struct mlx4_net_trans_rule_hw_ctrl *ctrl; struct _rule_hw *rule_header; int header_id; @@ -3142,7 +3131,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; qpn = be32_to_cpu(ctrl->qpn) & 0xffffff; - err = get_res(dev, slave, qpn, RES_QP, &rqp); + err = get_res(dev, slave, qpn, RES_QP, NULL); if (err) { pr_err("Steering rule with qpn 0x%x rejected.\n", qpn); return err; @@ -3183,16 +3172,14 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, if (err) goto err_put; - err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, qpn); + err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0); if (err) { mlx4_err(dev, "Fail to add flow steering resources.\n "); /* detach rule*/ mlx4_cmd(dev, vhcr->out_param, 0, 0, MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); - goto err_put; } - atomic_inc(&rqp->ref_count); err_put: put_res(dev, slave, qpn, RES_QP); return err; @@ -3205,35 +3192,20 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_info *cmd) { int err; - struct res_qp *rqp; - struct res_fs_rule *rrule; if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) return -EOPNOTSUPP; - err = get_res(dev, slave, vhcr->in_param, RES_FS_RULE, &rrule); - if (err) - return err; - /* Release the rule form busy state before removal */ - put_res(dev, slave, vhcr->in_param, RES_FS_RULE); - err = get_res(dev, slave, rrule->qpn, RES_QP, &rqp); - if (err) - return err; - err = rem_res_range(dev, slave, vhcr->in_param, 1, RES_FS_RULE, 0); if (err) { mlx4_err(dev, "Fail to remove flow steering resources.\n "); - goto out; + return err; } err = mlx4_cmd(dev, vhcr->in_param, 0, 0, MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); - if (!err) - atomic_dec(&rqp->ref_count); -out: - put_res(dev, slave, rrule->qpn, RES_QP); return err; } @@ -3831,7 +3803,6 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); /*VLAN*/ rem_slave_macs(dev, slave); - rem_slave_fs_rule(dev, slave); rem_slave_qps(dev, slave); rem_slave_srqs(dev, slave); rem_slave_cqs(dev, slave); @@ -3840,5 +3811,6 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) rem_slave_mtts(dev, slave); rem_slave_counters(dev, slave); rem_slave_xrcdns(dev, slave); + rem_slave_fs_rule(dev, slave); mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/srq.c b/trunk/drivers/net/ethernet/mellanox/mlx4/srq.c index e329fe1f11b7..feda6c00829f 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/srq.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/srq.c @@ -149,7 +149,7 @@ void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn) static void mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn) { - u64 in_param = 0; + u64 in_param; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, srqn); diff --git a/trunk/drivers/net/ethernet/micrel/ks8851.c b/trunk/drivers/net/ethernet/micrel/ks8851.c index 8fb481252e2c..33bcb63d56a2 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851.c @@ -528,7 +528,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) for (; rxfc != 0; rxfc--) { rxh = ks8851_rdreg32(ks, KS_RXFHSR); rxstat = rxh & 0xffff; - rxlen = (rxh >> 16) & 0xfff; + rxlen = rxh >> 16; netif_dbg(ks, rx_status, ks->netdev, "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen); diff --git a/trunk/drivers/net/ethernet/nxp/lpc_eth.c b/trunk/drivers/net/ethernet/nxp/lpc_eth.c index efa29b712d5f..c4122c86f829 100644 --- a/trunk/drivers/net/ethernet/nxp/lpc_eth.c +++ b/trunk/drivers/net/ethernet/nxp/lpc_eth.c @@ -1472,8 +1472,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, ndev); - ret = lpc_mii_init(pldat); - if (ret) + if (lpc_mii_init(pldat) != 0) goto err_out_unregister_netdev; netdev_info(ndev, "LPC mac at 0x%08x irq %d\n", diff --git a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 73ce7dd6b954..39ab4d09faaa 100644 --- a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -1726,9 +1726,9 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, skb->protocol = eth_type_trans(skb, netdev); if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else skb->ip_summed = CHECKSUM_NONE; + else + skb->ip_summed = CHECKSUM_UNNECESSARY; napi_gro_receive(&adapter->napi, skb); (*work_done)++; diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index edd63f1230f3..cd5ae8813cb3 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -1500,12 +1500,6 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode) } } while ((adapter->ahw->linkup && ahw->has_link_events) != 1); - /* Make sure carrier is off and queue is stopped during loopback */ - if (netif_running(netdev)) { - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - ret = qlcnic_do_lb_test(adapter, mode); qlcnic_83xx_clear_lb_mode(adapter, mode); @@ -2786,7 +2780,6 @@ static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter, void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data) { struct qlcnic_cmd_args cmd; - struct net_device *netdev = adapter->netdev; int ret = 0; qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS); @@ -2796,7 +2789,7 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data) data = qlcnic_83xx_fill_stats(adapter, &cmd, data, QLC_83XX_STAT_TX, &ret); if (ret) { - netdev_err(netdev, "Error getting Tx stats\n"); + dev_info(&adapter->pdev->dev, "Error getting MAC stats\n"); goto out; } /* Get MAC stats */ @@ -2806,7 +2799,8 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data) data = qlcnic_83xx_fill_stats(adapter, &cmd, data, QLC_83XX_STAT_MAC, &ret); if (ret) { - netdev_err(netdev, "Error getting MAC stats\n"); + dev_info(&adapter->pdev->dev, + "Error getting Rx stats\n"); goto out; } /* Get Rx stats */ @@ -2816,7 +2810,8 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data) data = qlcnic_83xx_fill_stats(adapter, &cmd, data, QLC_83XX_STAT_RX, &ret); if (ret) - netdev_err(netdev, "Error getting Rx stats\n"); + dev_info(&adapter->pdev->dev, + "Error getting Tx stats\n"); out: qlcnic_free_mbx_args(&cmd); } diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 5fa847fe388a..0e630061bff3 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -358,7 +358,8 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter, memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN); } opcode = TX_ETHER_PKT; - if (skb_is_gso(skb)) { + if ((adapter->netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && + skb_shinfo(skb)->gso_size > 0) { hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); first_desc->total_hdr_length = hdr_len; diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 5ef328af61d0..987fb6f8adc3 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -200,10 +200,10 @@ static ssize_t qlcnic_store_beacon(struct device *dev, } err = qlcnic_config_led(adapter, b_state, b_rate); - if (!err) { + if (!err) err = len; + else ahw->beacon_state = b_state; - } if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) qlcnic_diag_free_res(adapter->netdev, max_sds_rings); diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge.h b/trunk/drivers/net/ethernet/qlogic/qlge/qlge.h index 7e8d68263963..a131d7b5d2fe 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge.h +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge.h @@ -18,7 +18,7 @@ */ #define DRV_NAME "qlge" #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION "v1.00.00.32" +#define DRV_VERSION "v1.00.00.31" #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c index 0780e039b271..6f316ab23257 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c @@ -379,13 +379,13 @@ static int ql_get_settings(struct net_device *ndev, ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->advertising = ADVERTISED_10000baseT_Full; + ecmd->autoneg = AUTONEG_ENABLE; ecmd->transceiver = XCVR_EXTERNAL; if ((qdev->link_status & STS_LINK_TYPE_MASK) == STS_LINK_TYPE_10GBASET) { ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); ecmd->port = PORT_TP; - ecmd->autoneg = AUTONEG_ENABLE; } else { ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 8033555e53c2..b13ab544a7eb 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1434,13 +1434,11 @@ static int ql_map_send(struct ql_adapter *qdev, } /* Categorizing receive firmware frame errors */ -static void ql_categorize_rx_err(struct ql_adapter *qdev, u8 rx_err, - struct rx_ring *rx_ring) +static void ql_categorize_rx_err(struct ql_adapter *qdev, u8 rx_err) { struct nic_stats *stats = &qdev->nic_stats; stats->rx_err_count++; - rx_ring->rx_errors++; switch (rx_err & IB_MAC_IOCB_RSP_ERR_MASK) { case IB_MAC_IOCB_RSP_ERR_CODE_ERR: @@ -1476,12 +1474,6 @@ static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev, struct bq_desc *lbq_desc = ql_get_curr_lchunk(qdev, rx_ring); struct napi_struct *napi = &rx_ring->napi; - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - put_page(lbq_desc->p.pg_chunk.page); - return; - } napi->dev = qdev->ndev; skb = napi_get_frags(napi); @@ -1537,12 +1529,6 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, addr = lbq_desc->p.pg_chunk.va; prefetch(addr); - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - goto err_out; - } - /* The max framesize filter on this chip is set higher than * MTU since FCoE uses 2k frames. */ @@ -1628,13 +1614,6 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, memcpy(skb_put(new_skb, length), skb->data, length); skb = new_skb; - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - dev_kfree_skb_any(skb); - return; - } - /* loopback self test for ethtool */ if (test_bit(QL_SELFTEST, &qdev->flags)) { ql_check_lb_frame(qdev, skb); @@ -1940,13 +1919,6 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, return; } - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - dev_kfree_skb_any(skb); - return; - } - /* The max framesize filter on this chip is set higher than * MTU since FCoE uses 2k frames. */ @@ -2028,6 +2000,12 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev, QL_DUMP_IB_MAC_RSP(ib_mac_rsp); + /* Frame error, so drop the packet. */ + if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { + ql_categorize_rx_err(qdev, ib_mac_rsp->flags2); + return (unsigned long)length; + } + if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) { /* The data and headers are split into * separate buffers. diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 4ecbe64a758d..8900398ba103 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -3818,30 +3818,6 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) } } -static void rtl_speed_down(struct rtl8169_private *tp) -{ - u32 adv; - int lpa; - - rtl_writephy(tp, 0x1f, 0x0000); - lpa = rtl_readphy(tp, MII_LPA); - - if (lpa & (LPA_10HALF | LPA_10FULL)) - adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; - else if (lpa & (LPA_100HALF | LPA_100FULL)) - adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; - else - adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | - (tp->mii.supports_gmii ? - ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full : 0); - - rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL, - adv); -} - static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3872,7 +3848,9 @@ static bool rtl_wol_pll_power_down(struct rtl8169_private *tp) if (!(__rtl8169_get_wol(tp) & WAKE_ANY)) return false; - rtl_speed_down(tp); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, MII_BMCR, 0x0000); + rtl_wol_suspend_quirk(tp); return true; @@ -4787,10 +4765,8 @@ static void rtl_hw_start_8168bb(struct rtl8169_private *tp) RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); - if (tp->dev->mtu <= ETH_DATA_LEN) { - rtl_tx_performance_tweak(pdev, (0x5 << MAX_READ_REQUEST_SHIFT) | - PCI_EXP_DEVCTL_NOSNOOP_EN); - } + rtl_tx_performance_tweak(pdev, + (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); } static void rtl_hw_start_8168bef(struct rtl8169_private *tp) @@ -4813,8 +4789,7 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_disable_clock_request(pdev); @@ -4847,8 +4822,7 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } @@ -4867,8 +4841,7 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) RTL_W8(MaxTxPacketSize, TxPacketMax); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } @@ -4928,8 +4901,7 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp) RTL_W8(MaxTxPacketSize, TxPacketMax); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } @@ -4941,8 +4913,7 @@ static void rtl_hw_start_8168dp(struct rtl8169_private *tp) rtl_csi_access_enable_1(tp); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W8(MaxTxPacketSize, TxPacketMax); @@ -5001,8 +4972,7 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1)); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W8(MaxTxPacketSize, TxPacketMax); @@ -5028,8 +4998,7 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2)); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.c b/trunk/drivers/net/ethernet/renesas/sh_eth.c index 6ed333fe5c04..33e96176e4d8 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.c +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.c @@ -1216,7 +1216,10 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (felic_stat & ECSR_LCHNG) { /* Link Changed */ if (mdp->cd->no_psr || mdp->no_ether_link) { - goto ignore_link; + if (mdp->link == PHY_DOWN) + link_stat = 0; + else + link_stat = PHY_ST_LINK; } else { link_stat = (sh_eth_read(ndev, PSR)); if (mdp->ether_link_active_low) @@ -1239,7 +1242,6 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) } } -ignore_link: if (intr_status & EESR_TWB) { /* Write buck end. unused write back interrupt */ if (intr_status & EESR_TABT) /* Transmit Abort int */ @@ -1324,18 +1326,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_cpu_data *cd = mdp->cd; irqreturn_t ret = IRQ_NONE; - unsigned long intr_status; + u32 intr_status = 0; spin_lock(&mdp->lock); - /* Get interrupt status */ + /* Get interrpt stat */ intr_status = sh_eth_read(ndev, EESR); - /* Mask it with the interrupt mask, forcing ECI interrupt to be always - * enabled since it's the one that comes thru regardless of the mask, - * and we need to fully handle it in sh_eth_error() in order to quench - * it as it doesn't get cleared by just writing 1 to the ECI bit... - */ - intr_status &= sh_eth_read(ndev, EESIPR) | DMAC_M_ECI; /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | @@ -1377,7 +1373,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) struct phy_device *phydev = mdp->phydev; int new_state = 0; - if (phydev->link) { + if (phydev->link != PHY_DOWN) { if (phydev->duplex != mdp->duplex) { new_state = 1; mdp->duplex = phydev->duplex; @@ -1391,21 +1387,17 @@ static void sh_eth_adjust_link(struct net_device *ndev) if (mdp->cd->set_rate) mdp->cd->set_rate(ndev); } - if (!mdp->link) { + if (mdp->link == PHY_DOWN) { sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR); new_state = 1; mdp->link = phydev->link; - if (mdp->cd->no_psr || mdp->no_ether_link) - sh_eth_rcv_snd_enable(ndev); } } else if (mdp->link) { new_state = 1; - mdp->link = 0; + mdp->link = PHY_DOWN; mdp->speed = 0; mdp->duplex = -1; - if (mdp->cd->no_psr || mdp->no_ether_link) - sh_eth_rcv_snd_disable(ndev); } if (new_state && netif_msg_link(mdp)) @@ -1422,7 +1414,7 @@ static int sh_eth_phy_init(struct net_device *ndev) snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, mdp->mii_bus->id , mdp->phy_id); - mdp->link = 0; + mdp->link = PHY_DOWN; mdp->speed = 0; mdp->duplex = -1; @@ -2228,7 +2220,6 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp) /* MDIO bus release function */ static int sh_mdio_release(struct net_device *ndev) { - struct sh_eth_private *mdp = netdev_priv(ndev); struct mii_bus *bus = dev_get_drvdata(&ndev->dev); /* unregister mdio bus */ @@ -2243,9 +2234,6 @@ static int sh_mdio_release(struct net_device *ndev) /* free bitbang info */ free_mdio_bitbang(bus); - /* free bitbang memory */ - kfree(mdp->bitbang); - return 0; } @@ -2274,7 +2262,6 @@ static int sh_mdio_init(struct net_device *ndev, int id, bitbang->ctrl.ops = &bb_ops; /* MII controller setting */ - mdp->bitbang = bitbang; mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl); if (!mdp->mii_bus) { ret = -ENOMEM; @@ -2454,11 +2441,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev) } mdp->tsu_addr = ioremap(rtsu->start, resource_size(rtsu)); - if (mdp->tsu_addr == NULL) { - ret = -ENOMEM; - dev_err(&pdev->dev, "TSU ioremap failed.\n"); - goto out_release; - } mdp->port = devno % 2; ndev->features = NETIF_F_HW_VLAN_FILTER; } diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.h b/trunk/drivers/net/ethernet/renesas/sh_eth.h index 828be4515008..bae84fd2e73a 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.h +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.h @@ -705,7 +705,6 @@ struct sh_eth_private { const u16 *reg_offset; void __iomem *addr; void __iomem *tsu_addr; - struct bb_info *bitbang; u32 num_rx_ring; u32 num_tx_ring; dma_addr_t rx_desc_dma; @@ -723,7 +722,7 @@ struct sh_eth_private { u32 phy_id; /* PHY ID */ struct mii_bus *mii_bus; /* MDIO bus control */ struct phy_device *phydev; /* PHY device control */ - int link; + enum phy_state link; phy_interface_t phy_interface; int msg_enable; int speed; diff --git a/trunk/drivers/net/ethernet/sfc/efx.c b/trunk/drivers/net/ethernet/sfc/efx.c index 0bc00991d310..bf57b3cb16ab 100644 --- a/trunk/drivers/net/ethernet/sfc/efx.c +++ b/trunk/drivers/net/ethernet/sfc/efx.c @@ -779,7 +779,6 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) tx_queue->txd.entries); } - efx_device_detach_sync(efx); efx_stop_all(efx); efx_stop_interrupts(efx, true); @@ -833,7 +832,6 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) efx_start_interrupts(efx, true); efx_start_all(efx); - netif_device_attach(efx->net_dev); return rc; rollback: @@ -1643,12 +1641,8 @@ static void efx_stop_all(struct efx_nic *efx) /* Flush efx_mac_work(), refill_workqueue, monitor_work */ efx_flush_all(efx); - /* Stop the kernel transmit interface. This is only valid if - * the device is stopped or detached; otherwise the watchdog - * may fire immediately. - */ - WARN_ON(netif_running(efx->net_dev) && - netif_device_present(efx->net_dev)); + /* Stop the kernel transmit interface late, so the watchdog + * timer isn't ticking over the flush */ netif_tx_disable(efx->net_dev); efx_stop_datapath(efx); @@ -1969,18 +1963,16 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) if (new_mtu > EFX_MAX_MTU) return -EINVAL; - netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu); - - efx_device_detach_sync(efx); efx_stop_all(efx); + netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu); + mutex_lock(&efx->mac_lock); net_dev->mtu = new_mtu; efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); efx_start_all(efx); - netif_device_attach(efx->net_dev); return 0; } diff --git a/trunk/drivers/net/ethernet/sfc/efx.h b/trunk/drivers/net/ethernet/sfc/efx.h index d2f790df6dcb..50247dfe8f57 100644 --- a/trunk/drivers/net/ethernet/sfc/efx.h +++ b/trunk/drivers/net/ethernet/sfc/efx.h @@ -171,9 +171,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx) * TX scheduler is stopped when we're done and before * netif_device_present() becomes false. */ - netif_tx_lock_bh(dev); + netif_tx_lock(dev); netif_device_detach(dev); - netif_tx_unlock_bh(dev); + netif_tx_unlock(dev); } #endif /* EFX_EFX_H */ diff --git a/trunk/drivers/net/ethernet/sfc/net_driver.h b/trunk/drivers/net/ethernet/sfc/net_driver.h index 0a90abd2421b..2d756c1d7142 100644 --- a/trunk/drivers/net/ethernet/sfc/net_driver.h +++ b/trunk/drivers/net/ethernet/sfc/net_driver.h @@ -210,7 +210,6 @@ struct efx_tx_queue { * Will be %NULL if the buffer slot is currently free. * @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE. * Will be %NULL if the buffer slot is currently free. - * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE. * @len: Buffer length, in bytes. * @flags: Flags for buffer and packet state. */ @@ -220,8 +219,7 @@ struct efx_rx_buffer { struct sk_buff *skb; struct page *page; } u; - u16 page_offset; - u16 len; + unsigned int len; u16 flags; }; #define EFX_RX_BUF_PAGE 0x0001 diff --git a/trunk/drivers/net/ethernet/sfc/nic.c b/trunk/drivers/net/ethernet/sfc/nic.c index eaa8e874a3cb..0ad790cc473c 100644 --- a/trunk/drivers/net/ethernet/sfc/nic.c +++ b/trunk/drivers/net/ethernet/sfc/nic.c @@ -376,8 +376,7 @@ efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count) return false; tx_queue->empty_read_count = 0; - return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0 - && tx_queue->write_count - write_count == 1; + return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0; } /* For each entry inserted into the software descriptor ring, create a diff --git a/trunk/drivers/net/ethernet/sfc/rx.c b/trunk/drivers/net/ethernet/sfc/rx.c index bb579a6128c8..d780a0d096b4 100644 --- a/trunk/drivers/net/ethernet/sfc/rx.c +++ b/trunk/drivers/net/ethernet/sfc/rx.c @@ -90,7 +90,11 @@ static unsigned int rx_refill_threshold; static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, struct efx_rx_buffer *buf) { - return buf->page_offset + efx->type->rx_buffer_hash_size; + /* Offset is always within one page, so we don't need to consider + * the page order. + */ + return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) + + efx->type->rx_buffer_hash_size; } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) { @@ -183,7 +187,6 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) struct efx_nic *efx = rx_queue->efx; struct efx_rx_buffer *rx_buf; struct page *page; - unsigned int page_offset; struct efx_rx_page_state *state; dma_addr_t dma_addr; unsigned index, count; @@ -208,14 +211,12 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) state->dma_addr = dma_addr; dma_addr += sizeof(struct efx_rx_page_state); - page_offset = sizeof(struct efx_rx_page_state); split: index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->u.page = page; - rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; rx_buf->flags = EFX_RX_BUF_PAGE; ++rx_queue->added_count; @@ -226,7 +227,6 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) /* Use the second half of the page */ get_page(page); dma_addr += (PAGE_SIZE >> 1); - page_offset += (PAGE_SIZE >> 1); ++count; goto split; } @@ -236,8 +236,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) } static void efx_unmap_rx_buffer(struct efx_nic *efx, - struct efx_rx_buffer *rx_buf, - unsigned int used_len) + struct efx_rx_buffer *rx_buf) { if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { struct efx_rx_page_state *state; @@ -248,10 +247,6 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, state->dma_addr, efx_rx_buf_size(efx), DMA_FROM_DEVICE); - } else if (used_len) { - dma_sync_single_for_cpu(&efx->pci_dev->dev, - rx_buf->dma_addr, used_len, - DMA_FROM_DEVICE); } } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { dma_unmap_single(&efx->pci_dev->dev, rx_buf->dma_addr, @@ -274,7 +269,7 @@ static void efx_free_rx_buffer(struct efx_nic *efx, static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf) { - efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0); + efx_unmap_rx_buffer(rx_queue->efx, rx_buf); efx_free_rx_buffer(rx_queue->efx, rx_buf); } @@ -540,10 +535,10 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, goto out; } - /* Release and/or sync DMA mapping - assumes all RX buffers - * consumed in-order per RX queue + /* Release card resources - assumes all RX buffers consumed in-order + * per RX queue */ - efx_unmap_rx_buffer(efx, rx_buf, len); + efx_unmap_rx_buffer(efx, rx_buf); /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. diff --git a/trunk/drivers/net/ethernet/smsc/smc91c92_cs.c b/trunk/drivers/net/ethernet/smsc/smc91c92_cs.c index 656d2e2ebfc9..04393b5fef71 100644 --- a/trunk/drivers/net/ethernet/smsc/smc91c92_cs.c +++ b/trunk/drivers/net/ethernet/smsc/smc91c92_cs.c @@ -2054,4 +2054,16 @@ static struct pcmcia_driver smc91c92_cs_driver = { .suspend = smc91c92_suspend, .resume = smc91c92_resume, }; -module_pcmcia_driver(smc91c92_cs_driver); + +static int __init init_smc91c92_cs(void) +{ + return pcmcia_register_driver(&smc91c92_cs_driver); +} + +static void __exit exit_smc91c92_cs(void) +{ + pcmcia_unregister_driver(&smc91c92_cs_driver); +} + +module_init(init_smc91c92_cs); +module_exit(exit_smc91c92_cs); diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index 50617c5a0bdb..0c74a702d461 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c @@ -149,7 +149,6 @@ void dwmac_mmc_intr_all_mask(void __iomem *ioaddr) { writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_INTR_MASK); writel(MMC_DEFAULT_MASK, ioaddr + MMC_TX_INTR_MASK); - writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_IPC_INTR_MASK); } /* This reads the MAC core counters (if actaully supported). diff --git a/trunk/drivers/net/ethernet/ti/cpsw.c b/trunk/drivers/net/ethernet/ti/cpsw.c index 4781d3d8e182..7e93df6585e7 100644 --- a/trunk/drivers/net/ethernet/ti/cpsw.c +++ b/trunk/drivers/net/ethernet/ti/cpsw.c @@ -436,7 +436,7 @@ void cpsw_tx_handler(void *token, int len, int status) * queue is stopped then start the queue as we have free desc for tx */ if (unlikely(netif_queue_stopped(ndev))) - netif_wake_queue(ndev); + netif_start_queue(ndev); cpts_tx_timestamp(priv->cpts, skb); priv->stats.tx_packets++; priv->stats.tx_bytes += len; @@ -731,7 +731,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) writel(vlan, &priv->host_port_regs->port_vlan); - for (i = 0; i < priv->data.slaves; i++) + for (i = 0; i < 2; i++) slave_write(priv->slaves + i, vlan, reg); cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port, @@ -905,7 +905,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, /* If there is no more tx desc left free then we need to * tell the kernel to stop sending us tx frames. */ - if (unlikely(!cpdma_check_free_tx_desc(priv->txch))) + if (unlikely(cpdma_check_free_tx_desc(priv->txch))) netif_stop_queue(ndev); return NETDEV_TX_OK; @@ -1364,7 +1364,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, struct platform_device *mdio; parp = of_get_property(slave_node, "phy_id", &lenp); - if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) { + if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) { pr_err("Missing slave[%d] phy_id property\n", i); ret = -EINVAL; goto error_ret; @@ -1380,7 +1380,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); if (data->dual_emac) { - if (of_property_read_u32(slave_node, "dual_emac_res_vlan", + if (of_property_read_u32(node, "dual_emac_res_vlan", &prop)) { pr_err("Missing dual_emac_res_vlan in DT.\n"); slave_data->dual_emac_res_vlan = i+1; diff --git a/trunk/drivers/net/ethernet/ti/davinci_emac.c b/trunk/drivers/net/ethernet/ti/davinci_emac.c index 72300bc9e378..52c05366599a 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_emac.c +++ b/trunk/drivers/net/ethernet/ti/davinci_emac.c @@ -1053,7 +1053,7 @@ static void emac_tx_handler(void *token, int len, int status) * queue is stopped then start the queue as we have free desc for tx */ if (unlikely(netif_queue_stopped(ndev))) - netif_wake_queue(ndev); + netif_start_queue(ndev); ndev->stats.tx_packets++; ndev->stats.tx_bytes += len; dev_kfree_skb_any(skb); @@ -1102,7 +1102,7 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) /* If there is no more tx desc left free then we need to * tell the kernel to stop sending us tx frames. */ - if (unlikely(!cpdma_check_free_tx_desc(priv->txchan))) + if (unlikely(cpdma_check_free_tx_desc(priv->txchan))) netif_stop_queue(ndev); return NETDEV_TX_OK; diff --git a/trunk/drivers/net/ethernet/xircom/xirc2ps_cs.c b/trunk/drivers/net/ethernet/xircom/xirc2ps_cs.c index 1025b4e937d2..98e09d0d3ce2 100644 --- a/trunk/drivers/net/ethernet/xircom/xirc2ps_cs.c +++ b/trunk/drivers/net/ethernet/xircom/xirc2ps_cs.c @@ -1775,7 +1775,21 @@ static struct pcmcia_driver xirc2ps_cs_driver = { .suspend = xirc2ps_suspend, .resume = xirc2ps_resume, }; -module_pcmcia_driver(xirc2ps_cs_driver); + +static int __init +init_xirc2ps_cs(void) +{ + return pcmcia_register_driver(&xirc2ps_cs_driver); +} + +static void __exit +exit_xirc2ps_cs(void) +{ + pcmcia_unregister_driver(&xirc2ps_cs_driver); +} + +module_init(init_xirc2ps_cs); +module_exit(exit_xirc2ps_cs); #ifndef MODULE static int __init setup_xirc2ps_cs(char *str) diff --git a/trunk/drivers/net/hippi/rrunner.c b/trunk/drivers/net/hippi/rrunner.c index 3c4d6274bb9b..e5b19b056909 100644 --- a/trunk/drivers/net/hippi/rrunner.c +++ b/trunk/drivers/net/hippi/rrunner.c @@ -202,9 +202,6 @@ static int rr_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; out: - if (rrpriv->evt_ring) - pci_free_consistent(pdev, EVT_RING_SIZE, rrpriv->evt_ring, - rrpriv->evt_ring_dma); if (rrpriv->rx_ring) pci_free_consistent(pdev, RX_TOTAL_SIZE, rrpriv->rx_ring, rrpriv->rx_ring_dma); diff --git a/trunk/drivers/net/hyperv/netvsc.c b/trunk/drivers/net/hyperv/netvsc.c index f5f0f09e4cc5..1cd77483da50 100644 --- a/trunk/drivers/net/hyperv/netvsc.c +++ b/trunk/drivers/net/hyperv/netvsc.c @@ -470,10 +470,8 @@ static void netvsc_send_completion(struct hv_device *device, packet->trans_id; /* Notify the layer above us */ - if (nvsc_packet) - nvsc_packet->completion.send.send_completion( - nvsc_packet->completion.send. - send_completion_ctx); + nvsc_packet->completion.send.send_completion( + nvsc_packet->completion.send.send_completion_ctx); num_outstanding_sends = atomic_dec_return(&net_device->num_outstanding_sends); @@ -500,7 +498,6 @@ int netvsc_send(struct hv_device *device, int ret = 0; struct nvsp_message sendMessage; struct net_device *ndev; - u64 req_id; net_device = get_outbound_net_device(device); if (!net_device) @@ -521,24 +518,20 @@ int netvsc_send(struct hv_device *device, 0xFFFFFFFF; sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0; - if (packet->completion.send.send_completion) - req_id = (u64)packet; - else - req_id = 0; - if (packet->page_buf_cnt) { ret = vmbus_sendpacket_pagebuffer(device->channel, packet->page_buf, packet->page_buf_cnt, &sendMessage, sizeof(struct nvsp_message), - req_id); + (unsigned long)packet); } else { ret = vmbus_sendpacket(device->channel, &sendMessage, sizeof(struct nvsp_message), - req_id, + (unsigned long)packet, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + } if (ret == 0) { diff --git a/trunk/drivers/net/hyperv/netvsc_drv.c b/trunk/drivers/net/hyperv/netvsc_drv.c index 8341b62e5521..5f85205cd12b 100644 --- a/trunk/drivers/net/hyperv/netvsc_drv.c +++ b/trunk/drivers/net/hyperv/netvsc_drv.c @@ -241,11 +241,13 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, if (status == 1) { netif_carrier_on(net); + netif_wake_queue(net); ndev_ctx = netdev_priv(net); schedule_delayed_work(&ndev_ctx->dwork, 0); schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); } else { netif_carrier_off(net); + netif_tx_disable(net); } } diff --git a/trunk/drivers/net/hyperv/rndis_filter.c b/trunk/drivers/net/hyperv/rndis_filter.c index 0775f0aefd1e..2b657d4d63a8 100644 --- a/trunk/drivers/net/hyperv/rndis_filter.c +++ b/trunk/drivers/net/hyperv/rndis_filter.c @@ -61,6 +61,9 @@ struct rndis_request { static void rndis_filter_send_completion(void *ctx); +static void rndis_filter_send_request_completion(void *ctx); + + static struct rndis_device *get_rndis_device(void) { @@ -238,7 +241,10 @@ static int rndis_filter_send_request(struct rndis_device *dev, packet->page_buf[0].len; } - packet->completion.send.send_completion = NULL; + packet->completion.send.send_completion_ctx = req;/* packet; */ + packet->completion.send.send_completion = + rndis_filter_send_request_completion; + packet->completion.send.send_completion_tid = (unsigned long)dev; ret = netvsc_send(dev->net_dev->dev, packet); return ret; @@ -993,3 +999,9 @@ static void rndis_filter_send_completion(void *ctx) /* Pass it back to the original handler */ filter_pkt->completion(filter_pkt->completion_ctx); } + + +static void rndis_filter_send_request_completion(void *ctx) +{ + /* Noop */ +} diff --git a/trunk/drivers/net/macvlan.c b/trunk/drivers/net/macvlan.c index 73abbc1655d5..417b2af1aa80 100644 --- a/trunk/drivers/net/macvlan.c +++ b/trunk/drivers/net/macvlan.c @@ -660,7 +660,6 @@ void macvlan_common_setup(struct net_device *dev) ether_setup(dev); dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); - dev->priv_flags |= IFF_UNICAST_FLT; dev->netdev_ops = &macvlan_netdev_ops; dev->destructor = free_netdev; dev->header_ops = &macvlan_hard_header_ops, diff --git a/trunk/drivers/net/netconsole.c b/trunk/drivers/net/netconsole.c index 59ac143dec25..37add21a3d7d 100644 --- a/trunk/drivers/net/netconsole.c +++ b/trunk/drivers/net/netconsole.c @@ -666,7 +666,6 @@ static int netconsole_netdev_event(struct notifier_block *this, goto done; spin_lock_irqsave(&target_list_lock, flags); -restart: list_for_each_entry(nt, &target_list, list) { netconsole_target_get(nt); if (nt->np.dev == dev) { @@ -679,17 +678,15 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_UNREGISTER: /* * rtnl_lock already held - * we might sleep in __netpoll_cleanup() */ - 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; + if (nt->np.dev) { + __netpoll_cleanup(&nt->np); + dev_put(nt->np.dev); + nt->np.dev = NULL; + } nt->enabled = 0; stopped = true; - netconsole_target_put(nt); - goto restart; + break; } } netconsole_target_put(nt); diff --git a/trunk/drivers/net/phy/micrel.c b/trunk/drivers/net/phy/micrel.c index abf7b6153d00..29934446436a 100644 --- a/trunk/drivers/net/phy/micrel.c +++ b/trunk/drivers/net/phy/micrel.c @@ -257,7 +257,8 @@ static struct phy_driver ksphy_driver[] = { .phy_id = PHY_ID_KSZ9021, .phy_id_mask = 0x000ffffe, .name = "Micrel KSZ9021 Gigabit PHY", - .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), + .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause + | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, diff --git a/trunk/drivers/net/phy/phy_device.c b/trunk/drivers/net/phy/phy_device.c index 3657b4a29124..9930f9999561 100644 --- a/trunk/drivers/net/phy/phy_device.c +++ b/trunk/drivers/net/phy/phy_device.c @@ -44,13 +44,13 @@ MODULE_LICENSE("GPL"); void phy_device_free(struct phy_device *phydev) { - put_device(&phydev->dev); + kfree(phydev); } EXPORT_SYMBOL(phy_device_free); static void phy_device_release(struct device *dev) { - kfree(to_phy_device(dev)); + phy_device_free(to_phy_device(dev)); } static struct phy_driver genphy_driver; @@ -201,8 +201,6 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, there's no driver _already_ loaded. */ request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id)); - device_initialize(&dev->dev); - return dev; } EXPORT_SYMBOL(phy_device_create); @@ -365,9 +363,9 @@ int phy_device_register(struct phy_device *phydev) /* Run all of the fixups for this PHY */ phy_scan_fixups(phydev); - err = device_add(&phydev->dev); + err = device_register(&phydev->dev); if (err) { - pr_err("PHY %d failed to add\n", phydev->addr); + pr_err("phy %d failed to register\n", phydev->addr); goto out; } diff --git a/trunk/drivers/net/team/team.c b/trunk/drivers/net/team/team.c index bf3419297875..05c5efe84591 100644 --- a/trunk/drivers/net/team/team.c +++ b/trunk/drivers/net/team/team.c @@ -1138,8 +1138,6 @@ static int team_port_del(struct team *team, struct net_device *port_dev) netdev_upper_dev_unlink(port_dev, dev); team_port_disable_netpoll(port); vlan_vids_del_by_dev(port_dev, dev); - dev_uc_unsync(port_dev, dev); - dev_mc_unsync(port_dev, dev); dev_close(port_dev); team_port_leave(team, port); diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 729ed533bb33..2c6a22e278ea 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -747,8 +747,6 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; skb_orphan(skb); - nf_reset(skb); - /* Enqueue packet */ skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb); @@ -1594,7 +1592,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (tun->flags & TUN_TAP_MQ && (tun->numqueues + tun->numdisabled > 1)) - return -EBUSY; + return err; } else { char *name; diff --git a/trunk/drivers/net/usb/Kconfig b/trunk/drivers/net/usb/Kconfig index 7c769d8e25ad..da92ed3797aa 100644 --- a/trunk/drivers/net/usb/Kconfig +++ b/trunk/drivers/net/usb/Kconfig @@ -156,24 +156,6 @@ config USB_NET_AX8817X This driver creates an interface named "ethX", where X depends on what other networking devices you have in use. -config USB_NET_AX88179_178A - tristate "ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet" - depends on USB_USBNET - select CRC32 - select PHYLIB - default y - help - This option adds support for ASIX AX88179 based USB 3.0/2.0 - to Gigabit Ethernet adapters. - - This driver should work with at least the following devices: - * ASIX AX88179 - * ASIX AX88178A - * Sitcomm LN-032 - - This driver creates an interface named "ethX", where X depends on - what other networking devices you have in use. - config USB_NET_CDCETHER tristate "CDC Ethernet support (smart devices such as cable modems)" depends on USB_USBNET @@ -268,7 +250,7 @@ config USB_NET_SMSC75XX select CRC16 select CRC32 help - This option adds support for SMSC LAN75XX based USB 2.0 + This option adds support for SMSC LAN95XX based USB 2.0 Gigabit Ethernet adapters. config USB_NET_SMSC95XX diff --git a/trunk/drivers/net/usb/Makefile b/trunk/drivers/net/usb/Makefile index 119b06c9aa16..478691326f37 100644 --- a/trunk/drivers/net/usb/Makefile +++ b/trunk/drivers/net/usb/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_USB_RTL8150) += rtl8150.o obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o asix-y := asix_devices.o asix_common.o ax88172a.o -obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o diff --git a/trunk/drivers/net/usb/asix_devices.c b/trunk/drivers/net/usb/asix_devices.c index 709753469099..2205dbc8d32f 100644 --- a/trunk/drivers/net/usb/asix_devices.c +++ b/trunk/drivers/net/usb/asix_devices.c @@ -924,29 +924,6 @@ static const struct driver_info ax88178_info = { .tx_fixup = asix_tx_fixup, }; -/* - * USBLINK 20F9 "USB 2.0 LAN" USB ethernet adapter, typically found in - * no-name packaging. - * USB device strings are: - * 1: Manufacturer: USBLINK - * 2: Product: HG20F9 USB2.0 - * 3: Serial: 000003 - * Appears to be compatible with Asix 88772B. - */ -static const struct driver_info hg20f9_info = { - .description = "HG20F9 USB 2.0 Ethernet", - .bind = ax88772_bind, - .unbind = ax88772_unbind, - .status = asix_status, - .link_reset = ax88772_link_reset, - .reset = ax88772_reset, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | - FLAG_MULTI_PACKET, - .rx_fixup = asix_rx_fixup_common, - .tx_fixup = asix_tx_fixup, - .data = FLAG_EEPROM_MAC, -}; - extern const struct driver_info ax88172a_info; static const struct usb_device_id products [] = { @@ -1086,14 +1063,6 @@ static const struct usb_device_id products [] = { /* ASIX 88172a demo board */ USB_DEVICE(0x0b95, 0x172a), .driver_info = (unsigned long) &ax88172a_info, -}, { - /* - * USBLINK HG20F9 "USB 2.0 LAN" - * Appears to have gazumped Linksys's manufacturer ID but - * doesn't (yet) conflict with any known Linksys product. - */ - USB_DEVICE(0x066b, 0x20f9), - .driver_info = (unsigned long) &hg20f9_info, }, { }, // END }; diff --git a/trunk/drivers/net/usb/ax88179_178a.c b/trunk/drivers/net/usb/ax88179_178a.c deleted file mode 100644 index 71c27d8d214f..000000000000 --- a/trunk/drivers/net/usb/ax88179_178a.c +++ /dev/null @@ -1,1448 +0,0 @@ -/* - * ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet Devices - * - * Copyright (C) 2011-2013 ASIX - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include - -#define AX88179_PHY_ID 0x03 -#define AX_EEPROM_LEN 0x100 -#define AX88179_EEPROM_MAGIC 0x17900b95 -#define AX_MCAST_FLTSIZE 8 -#define AX_MAX_MCAST 64 -#define AX_INT_PPLS_LINK ((u32)BIT(16)) -#define AX_RXHDR_L4_TYPE_MASK 0x1c -#define AX_RXHDR_L4_TYPE_UDP 4 -#define AX_RXHDR_L4_TYPE_TCP 16 -#define AX_RXHDR_L3CSUM_ERR 2 -#define AX_RXHDR_L4CSUM_ERR 1 -#define AX_RXHDR_CRC_ERR ((u32)BIT(31)) -#define AX_RXHDR_DROP_ERR ((u32)BIT(30)) -#define AX_ACCESS_MAC 0x01 -#define AX_ACCESS_PHY 0x02 -#define AX_ACCESS_EEPROM 0x04 -#define AX_ACCESS_EFUS 0x05 -#define AX_PAUSE_WATERLVL_HIGH 0x54 -#define AX_PAUSE_WATERLVL_LOW 0x55 - -#define PHYSICAL_LINK_STATUS 0x02 - #define AX_USB_SS 0x04 - #define AX_USB_HS 0x02 - -#define GENERAL_STATUS 0x03 -/* Check AX88179 version. UA1:Bit2 = 0, UA2:Bit2 = 1 */ - #define AX_SECLD 0x04 - -#define AX_SROM_ADDR 0x07 -#define AX_SROM_CMD 0x0a - #define EEP_RD 0x04 - #define EEP_BUSY 0x10 - -#define AX_SROM_DATA_LOW 0x08 -#define AX_SROM_DATA_HIGH 0x09 - -#define AX_RX_CTL 0x0b - #define AX_RX_CTL_DROPCRCERR 0x0100 - #define AX_RX_CTL_IPE 0x0200 - #define AX_RX_CTL_START 0x0080 - #define AX_RX_CTL_AP 0x0020 - #define AX_RX_CTL_AM 0x0010 - #define AX_RX_CTL_AB 0x0008 - #define AX_RX_CTL_AMALL 0x0002 - #define AX_RX_CTL_PRO 0x0001 - #define AX_RX_CTL_STOP 0x0000 - -#define AX_NODE_ID 0x10 -#define AX_MULFLTARY 0x16 - -#define AX_MEDIUM_STATUS_MODE 0x22 - #define AX_MEDIUM_GIGAMODE 0x01 - #define AX_MEDIUM_FULL_DUPLEX 0x02 - #define AX_MEDIUM_ALWAYS_ONE 0x04 - #define AX_MEDIUM_EN_125MHZ 0x08 - #define AX_MEDIUM_RXFLOW_CTRLEN 0x10 - #define AX_MEDIUM_TXFLOW_CTRLEN 0x20 - #define AX_MEDIUM_RECEIVE_EN 0x100 - #define AX_MEDIUM_PS 0x200 - #define AX_MEDIUM_JUMBO_EN 0x8040 - -#define AX_MONITOR_MOD 0x24 - #define AX_MONITOR_MODE_RWLC 0x02 - #define AX_MONITOR_MODE_RWMP 0x04 - #define AX_MONITOR_MODE_PMEPOL 0x20 - #define AX_MONITOR_MODE_PMETYPE 0x40 - -#define AX_GPIO_CTRL 0x25 - #define AX_GPIO_CTRL_GPIO3EN 0x80 - #define AX_GPIO_CTRL_GPIO2EN 0x40 - #define AX_GPIO_CTRL_GPIO1EN 0x20 - -#define AX_PHYPWR_RSTCTL 0x26 - #define AX_PHYPWR_RSTCTL_BZ 0x0010 - #define AX_PHYPWR_RSTCTL_IPRL 0x0020 - #define AX_PHYPWR_RSTCTL_AT 0x1000 - -#define AX_RX_BULKIN_QCTRL 0x2e -#define AX_CLK_SELECT 0x33 - #define AX_CLK_SELECT_BCS 0x01 - #define AX_CLK_SELECT_ACS 0x02 - #define AX_CLK_SELECT_ULR 0x08 - -#define AX_RXCOE_CTL 0x34 - #define AX_RXCOE_IP 0x01 - #define AX_RXCOE_TCP 0x02 - #define AX_RXCOE_UDP 0x04 - #define AX_RXCOE_TCPV6 0x20 - #define AX_RXCOE_UDPV6 0x40 - -#define AX_TXCOE_CTL 0x35 - #define AX_TXCOE_IP 0x01 - #define AX_TXCOE_TCP 0x02 - #define AX_TXCOE_UDP 0x04 - #define AX_TXCOE_TCPV6 0x20 - #define AX_TXCOE_UDPV6 0x40 - -#define AX_LEDCTRL 0x73 - -#define GMII_PHY_PHYSR 0x11 - #define GMII_PHY_PHYSR_SMASK 0xc000 - #define GMII_PHY_PHYSR_GIGA 0x8000 - #define GMII_PHY_PHYSR_100 0x4000 - #define GMII_PHY_PHYSR_FULL 0x2000 - #define GMII_PHY_PHYSR_LINK 0x400 - -#define GMII_LED_ACT 0x1a - #define GMII_LED_ACTIVE_MASK 0xff8f - #define GMII_LED0_ACTIVE BIT(4) - #define GMII_LED1_ACTIVE BIT(5) - #define GMII_LED2_ACTIVE BIT(6) - -#define GMII_LED_LINK 0x1c - #define GMII_LED_LINK_MASK 0xf888 - #define GMII_LED0_LINK_10 BIT(0) - #define GMII_LED0_LINK_100 BIT(1) - #define GMII_LED0_LINK_1000 BIT(2) - #define GMII_LED1_LINK_10 BIT(4) - #define GMII_LED1_LINK_100 BIT(5) - #define GMII_LED1_LINK_1000 BIT(6) - #define GMII_LED2_LINK_10 BIT(8) - #define GMII_LED2_LINK_100 BIT(9) - #define GMII_LED2_LINK_1000 BIT(10) - #define LED0_ACTIVE BIT(0) - #define LED0_LINK_10 BIT(1) - #define LED0_LINK_100 BIT(2) - #define LED0_LINK_1000 BIT(3) - #define LED0_FD BIT(4) - #define LED0_USB3_MASK 0x001f - #define LED1_ACTIVE BIT(5) - #define LED1_LINK_10 BIT(6) - #define LED1_LINK_100 BIT(7) - #define LED1_LINK_1000 BIT(8) - #define LED1_FD BIT(9) - #define LED1_USB3_MASK 0x03e0 - #define LED2_ACTIVE BIT(10) - #define LED2_LINK_1000 BIT(13) - #define LED2_LINK_100 BIT(12) - #define LED2_LINK_10 BIT(11) - #define LED2_FD BIT(14) - #define LED_VALID BIT(15) - #define LED2_USB3_MASK 0x7c00 - -#define GMII_PHYPAGE 0x1e -#define GMII_PHY_PAGE_SELECT 0x1f - #define GMII_PHY_PGSEL_EXT 0x0007 - #define GMII_PHY_PGSEL_PAGE0 0x0000 - -struct ax88179_data { - u16 rxctl; - u16 reserved; -}; - -struct ax88179_int_data { - __le32 intdata1; - __le32 intdata2; -}; - -static const struct { - unsigned char ctrl, timer_l, timer_h, size, ifg; -} AX88179_BULKIN_SIZE[] = { - {7, 0x4f, 0, 0x12, 0xff}, - {7, 0x20, 3, 0x16, 0xff}, - {7, 0xae, 7, 0x18, 0xff}, - {7, 0xcc, 0x4c, 0x18, 8}, -}; - -static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data, int in_pm) -{ - int ret; - int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); - - BUG_ON(!dev); - - if (!in_pm) - fn = usbnet_read_cmd; - else - fn = usbnet_read_cmd_nopm; - - ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, data, size); - - if (unlikely(ret < 0)) - netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n", - index, ret); - - return ret; -} - -static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data, int in_pm) -{ - int ret; - int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); - - BUG_ON(!dev); - - if (!in_pm) - fn = usbnet_write_cmd; - else - fn = usbnet_write_cmd_nopm; - - ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, data, size); - - if (unlikely(ret < 0)) - netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n", - index, ret); - - return ret; -} - -static void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, - u16 index, u16 size, void *data) -{ - u16 buf; - - if (2 == size) { - buf = *((u16 *)data); - cpu_to_le16s(&buf); - usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, value, index, &buf, - size); - } else { - usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, value, index, data, - size); - } -} - -static int ax88179_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, - u16 index, u16 size, void *data) -{ - int ret; - - if (2 == size) { - u16 buf; - ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1); - le16_to_cpus(&buf); - *((u16 *)data) = buf; - } else if (4 == size) { - u32 buf; - ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1); - le32_to_cpus(&buf); - *((u32 *)data) = buf; - } else { - ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 1); - } - - return ret; -} - -static int ax88179_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, - u16 index, u16 size, void *data) -{ - int ret; - - if (2 == size) { - u16 buf; - buf = *((u16 *)data); - cpu_to_le16s(&buf); - ret = __ax88179_write_cmd(dev, cmd, value, index, - size, &buf, 1); - } else { - ret = __ax88179_write_cmd(dev, cmd, value, index, - size, data, 1); - } - - return ret; -} - -static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data) -{ - int ret; - - if (2 == size) { - u16 buf; - ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0); - le16_to_cpus(&buf); - *((u16 *)data) = buf; - } else if (4 == size) { - u32 buf; - ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0); - le32_to_cpus(&buf); - *((u32 *)data) = buf; - } else { - ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 0); - } - - return ret; -} - -static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data) -{ - int ret; - - if (2 == size) { - u16 buf; - buf = *((u16 *)data); - cpu_to_le16s(&buf); - ret = __ax88179_write_cmd(dev, cmd, value, index, - size, &buf, 0); - } else { - ret = __ax88179_write_cmd(dev, cmd, value, index, - size, data, 0); - } - - return ret; -} - -static void ax88179_status(struct usbnet *dev, struct urb *urb) -{ - struct ax88179_int_data *event; - u32 link; - - if (urb->actual_length < 8) - return; - - event = urb->transfer_buffer; - le32_to_cpus((void *)&event->intdata1); - - link = (((__force u32)event->intdata1) & AX_INT_PPLS_LINK) >> 16; - - if (netif_carrier_ok(dev->net) != link) { - if (link) - usbnet_defer_kevent(dev, EVENT_LINK_RESET); - else - netif_carrier_off(dev->net); - - netdev_info(dev->net, "ax88179 - Link status is: %d\n", link); - } -} - -static int ax88179_mdio_read(struct net_device *netdev, int phy_id, int loc) -{ - struct usbnet *dev = netdev_priv(netdev); - u16 res; - - ax88179_read_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res); - return res; -} - -static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc, - int val) -{ - struct usbnet *dev = netdev_priv(netdev); - u16 res = (u16) val; - - ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res); -} - -static int ax88179_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct usbnet *dev = usb_get_intfdata(intf); - u16 tmp16; - u8 tmp8; - - usbnet_suspend(intf, message); - - /* Disable RX path */ - ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &tmp16); - tmp16 &= ~AX_MEDIUM_RECEIVE_EN; - ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &tmp16); - - /* Force bulk-in zero length */ - ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, - 2, 2, &tmp16); - - tmp16 |= AX_PHYPWR_RSTCTL_BZ | AX_PHYPWR_RSTCTL_IPRL; - ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, - 2, 2, &tmp16); - - /* change clock */ - tmp8 = 0; - ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); - - /* Configure RX control register => stop operation */ - tmp16 = AX_RX_CTL_STOP; - ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); - - return 0; -} - -/* This function is used to enable the autodetach function. */ -/* This function is determined by offset 0x43 of EEPROM */ -static int ax88179_auto_detach(struct usbnet *dev, int in_pm) -{ - u16 tmp16; - u8 tmp8; - int (*fnr)(struct usbnet *, u8, u16, u16, u16, void *); - int (*fnw)(struct usbnet *, u8, u16, u16, u16, void *); - - if (!in_pm) { - fnr = ax88179_read_cmd; - fnw = ax88179_write_cmd; - } else { - fnr = ax88179_read_cmd_nopm; - fnw = ax88179_write_cmd_nopm; - } - - if (fnr(dev, AX_ACCESS_EEPROM, 0x43, 1, 2, &tmp16) < 0) - return 0; - - if ((tmp16 == 0xFFFF) || (!(tmp16 & 0x0100))) - return 0; - - /* Enable Auto Detach bit */ - tmp8 = 0; - fnr(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); - tmp8 |= AX_CLK_SELECT_ULR; - fnw(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); - - fnr(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); - tmp16 |= AX_PHYPWR_RSTCTL_AT; - fnw(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); - - return 0; -} - -static int ax88179_resume(struct usb_interface *intf) -{ - struct usbnet *dev = usb_get_intfdata(intf); - u16 tmp16; - u8 tmp8; - - netif_carrier_off(dev->net); - - /* Power up ethernet PHY */ - tmp16 = 0; - ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, - 2, 2, &tmp16); - udelay(1000); - - tmp16 = AX_PHYPWR_RSTCTL_IPRL; - ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, - 2, 2, &tmp16); - msleep(200); - - /* Ethernet PHY Auto Detach*/ - ax88179_auto_detach(dev, 1); - - /* Enable clock */ - ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); - tmp8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; - ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); - msleep(100); - - /* Configure RX control register => start operation */ - tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | - AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; - ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); - - return usbnet_resume(intf); -} - -static void -ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) -{ - struct usbnet *dev = netdev_priv(net); - u8 opt; - - if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, - 1, 1, &opt) < 0) { - wolinfo->supported = 0; - wolinfo->wolopts = 0; - return; - } - - wolinfo->supported = WAKE_PHY | WAKE_MAGIC; - wolinfo->wolopts = 0; - if (opt & AX_MONITOR_MODE_RWLC) - wolinfo->wolopts |= WAKE_PHY; - if (opt & AX_MONITOR_MODE_RWMP) - wolinfo->wolopts |= WAKE_MAGIC; -} - -static int -ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) -{ - struct usbnet *dev = netdev_priv(net); - u8 opt = 0; - - if (wolinfo->wolopts & WAKE_PHY) - opt |= AX_MONITOR_MODE_RWLC; - if (wolinfo->wolopts & WAKE_MAGIC) - opt |= AX_MONITOR_MODE_RWMP; - - if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, - 1, 1, &opt) < 0) - return -EINVAL; - - return 0; -} - -static int ax88179_get_eeprom_len(struct net_device *net) -{ - return AX_EEPROM_LEN; -} - -static int -ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, - u8 *data) -{ - struct usbnet *dev = netdev_priv(net); - u16 *eeprom_buff; - int first_word, last_word; - int i, ret; - - if (eeprom->len == 0) - return -EINVAL; - - eeprom->magic = AX88179_EEPROM_MAGIC; - - first_word = eeprom->offset >> 1; - last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), - GFP_KERNEL); - if (!eeprom_buff) - return -ENOMEM; - - /* ax88179/178A returns 2 bytes from eeprom on read */ - for (i = first_word; i <= last_word; i++) { - ret = __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2, - &eeprom_buff[i - first_word], - 0); - if (ret < 0) { - kfree(eeprom_buff); - return -EIO; - } - } - - memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); - kfree(eeprom_buff); - return 0; -} - -static int ax88179_get_settings(struct net_device *net, struct ethtool_cmd *cmd) -{ - struct usbnet *dev = netdev_priv(net); - return mii_ethtool_gset(&dev->mii, cmd); -} - -static int ax88179_set_settings(struct net_device *net, struct ethtool_cmd *cmd) -{ - struct usbnet *dev = netdev_priv(net); - return mii_ethtool_sset(&dev->mii, cmd); -} - - -static int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd) -{ - struct usbnet *dev = netdev_priv(net); - return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); -} - -static const struct ethtool_ops ax88179_ethtool_ops = { - .get_link = ethtool_op_get_link, - .get_msglevel = usbnet_get_msglevel, - .set_msglevel = usbnet_set_msglevel, - .get_wol = ax88179_get_wol, - .set_wol = ax88179_set_wol, - .get_eeprom_len = ax88179_get_eeprom_len, - .get_eeprom = ax88179_get_eeprom, - .get_settings = ax88179_get_settings, - .set_settings = ax88179_set_settings, - .nway_reset = usbnet_nway_reset, -}; - -static void ax88179_set_multicast(struct net_device *net) -{ - struct usbnet *dev = netdev_priv(net); - struct ax88179_data *data = (struct ax88179_data *)dev->data; - u8 *m_filter = ((u8 *)dev->data) + 12; - - data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE); - - if (net->flags & IFF_PROMISC) { - data->rxctl |= AX_RX_CTL_PRO; - } else if (net->flags & IFF_ALLMULTI || - netdev_mc_count(net) > AX_MAX_MCAST) { - data->rxctl |= AX_RX_CTL_AMALL; - } else if (netdev_mc_empty(net)) { - /* just broadcast and directed */ - } else { - /* We use the 20 byte dev->data for our 8 byte filter buffer - * to avoid allocating memory that is tricky to free later - */ - u32 crc_bits; - struct netdev_hw_addr *ha; - - memset(m_filter, 0, AX_MCAST_FLTSIZE); - - netdev_for_each_mc_addr(ha, net) { - crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; - *(m_filter + (crc_bits >> 3)) |= (1 << (crc_bits & 7)); - } - - ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_MULFLTARY, - AX_MCAST_FLTSIZE, AX_MCAST_FLTSIZE, - m_filter); - - data->rxctl |= AX_RX_CTL_AM; - } - - ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_RX_CTL, - 2, 2, &data->rxctl); -} - -static int -ax88179_set_features(struct net_device *net, netdev_features_t features) -{ - u8 tmp; - struct usbnet *dev = netdev_priv(net); - netdev_features_t changed = net->features ^ features; - - if (changed & NETIF_F_IP_CSUM) { - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); - tmp ^= AX_TXCOE_TCP | AX_TXCOE_UDP; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); - } - - if (changed & NETIF_F_IPV6_CSUM) { - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); - tmp ^= AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); - } - - if (changed & NETIF_F_RXCSUM) { - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp); - tmp ^= AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | - AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp); - } - - return 0; -} - -static int ax88179_change_mtu(struct net_device *net, int new_mtu) -{ - struct usbnet *dev = netdev_priv(net); - u16 tmp16; - - if (new_mtu <= 0 || new_mtu > 4088) - return -EINVAL; - - net->mtu = new_mtu; - dev->hard_mtu = net->mtu + net->hard_header_len; - - if (net->mtu > 1500) { - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &tmp16); - tmp16 |= AX_MEDIUM_JUMBO_EN; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &tmp16); - } else { - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &tmp16); - tmp16 &= ~AX_MEDIUM_JUMBO_EN; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &tmp16); - } - - return 0; -} - -static int ax88179_set_mac_addr(struct net_device *net, void *p) -{ - struct usbnet *dev = netdev_priv(net); - struct sockaddr *addr = p; - - if (netif_running(net)) - return -EBUSY; - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); - - /* Set the MAC address */ - return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, - ETH_ALEN, net->dev_addr); -} - -static const struct net_device_ops ax88179_netdev_ops = { - .ndo_open = usbnet_open, - .ndo_stop = usbnet_stop, - .ndo_start_xmit = usbnet_start_xmit, - .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_change_mtu = ax88179_change_mtu, - .ndo_set_mac_address = ax88179_set_mac_addr, - .ndo_validate_addr = eth_validate_addr, - .ndo_do_ioctl = ax88179_ioctl, - .ndo_set_rx_mode = ax88179_set_multicast, - .ndo_set_features = ax88179_set_features, -}; - -static int ax88179_check_eeprom(struct usbnet *dev) -{ - u8 i, buf, eeprom[20]; - u16 csum, delay = HZ / 10; - unsigned long jtimeout; - - /* Read EEPROM content */ - for (i = 0; i < 6; i++) { - buf = i; - if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR, - 1, 1, &buf) < 0) - return -EINVAL; - - buf = EEP_RD; - if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, - 1, 1, &buf) < 0) - return -EINVAL; - - jtimeout = jiffies + delay; - do { - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, - 1, 1, &buf); - - if (time_after(jiffies, jtimeout)) - return -EINVAL; - - } while (buf & EEP_BUSY); - - __ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW, - 2, 2, &eeprom[i * 2], 0); - - if ((i == 0) && (eeprom[0] == 0xFF)) - return -EINVAL; - } - - csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9]; - csum = (csum >> 8) + (csum & 0xff); - if ((csum + eeprom[10]) != 0xff) - return -EINVAL; - - return 0; -} - -static int ax88179_check_efuse(struct usbnet *dev, u16 *ledmode) -{ - u8 i; - u8 efuse[64]; - u16 csum = 0; - - if (ax88179_read_cmd(dev, AX_ACCESS_EFUS, 0, 64, 64, efuse) < 0) - return -EINVAL; - - if (*efuse == 0xFF) - return -EINVAL; - - for (i = 0; i < 64; i++) - csum = csum + efuse[i]; - - while (csum > 255) - csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF); - - if (csum != 0xFF) - return -EINVAL; - - *ledmode = (efuse[51] << 8) | efuse[52]; - - return 0; -} - -static int ax88179_convert_old_led(struct usbnet *dev, u16 *ledvalue) -{ - u16 led; - - /* Loaded the old eFuse LED Mode */ - if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x3C, 1, 2, &led) < 0) - return -EINVAL; - - led >>= 8; - switch (led) { - case 0xFF: - led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 | - LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 | - LED2_LINK_100 | LED2_LINK_1000 | LED_VALID; - break; - case 0xFE: - led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | LED_VALID; - break; - case 0xFD: - led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | - LED2_LINK_10 | LED_VALID; - break; - case 0xFC: - led = LED0_ACTIVE | LED1_ACTIVE | LED1_LINK_1000 | LED2_ACTIVE | - LED2_LINK_100 | LED2_LINK_10 | LED_VALID; - break; - default: - led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 | - LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 | - LED2_LINK_100 | LED2_LINK_1000 | LED_VALID; - break; - } - - *ledvalue = led; - - return 0; -} - -static int ax88179_led_setting(struct usbnet *dev) -{ - u8 ledfd, value = 0; - u16 tmp, ledact, ledlink, ledvalue = 0, delay = HZ / 10; - unsigned long jtimeout; - - /* Check AX88179 version. UA1 or UA2*/ - ax88179_read_cmd(dev, AX_ACCESS_MAC, GENERAL_STATUS, 1, 1, &value); - - if (!(value & AX_SECLD)) { /* UA1 */ - value = AX_GPIO_CTRL_GPIO3EN | AX_GPIO_CTRL_GPIO2EN | - AX_GPIO_CTRL_GPIO1EN; - if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_GPIO_CTRL, - 1, 1, &value) < 0) - return -EINVAL; - } - - /* Check EEPROM */ - if (!ax88179_check_eeprom(dev)) { - value = 0x42; - if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR, - 1, 1, &value) < 0) - return -EINVAL; - - value = EEP_RD; - if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, - 1, 1, &value) < 0) - return -EINVAL; - - jtimeout = jiffies + delay; - do { - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, - 1, 1, &value); - - if (time_after(jiffies, jtimeout)) - return -EINVAL; - - } while (value & EEP_BUSY); - - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_HIGH, - 1, 1, &value); - ledvalue = (value << 8); - - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW, - 1, 1, &value); - ledvalue |= value; - - /* load internal ROM for defaule setting */ - if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0)) - ax88179_convert_old_led(dev, &ledvalue); - - } else if (!ax88179_check_efuse(dev, &ledvalue)) { - if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0)) - ax88179_convert_old_led(dev, &ledvalue); - } else { - ax88179_convert_old_led(dev, &ledvalue); - } - - tmp = GMII_PHY_PGSEL_EXT; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHY_PAGE_SELECT, 2, &tmp); - - tmp = 0x2c; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHYPAGE, 2, &tmp); - - ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_LED_ACT, 2, &ledact); - - ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_LED_LINK, 2, &ledlink); - - ledact &= GMII_LED_ACTIVE_MASK; - ledlink &= GMII_LED_LINK_MASK; - - if (ledvalue & LED0_ACTIVE) - ledact |= GMII_LED0_ACTIVE; - - if (ledvalue & LED1_ACTIVE) - ledact |= GMII_LED1_ACTIVE; - - if (ledvalue & LED2_ACTIVE) - ledact |= GMII_LED2_ACTIVE; - - if (ledvalue & LED0_LINK_10) - ledlink |= GMII_LED0_LINK_10; - - if (ledvalue & LED1_LINK_10) - ledlink |= GMII_LED1_LINK_10; - - if (ledvalue & LED2_LINK_10) - ledlink |= GMII_LED2_LINK_10; - - if (ledvalue & LED0_LINK_100) - ledlink |= GMII_LED0_LINK_100; - - if (ledvalue & LED1_LINK_100) - ledlink |= GMII_LED1_LINK_100; - - if (ledvalue & LED2_LINK_100) - ledlink |= GMII_LED2_LINK_100; - - if (ledvalue & LED0_LINK_1000) - ledlink |= GMII_LED0_LINK_1000; - - if (ledvalue & LED1_LINK_1000) - ledlink |= GMII_LED1_LINK_1000; - - if (ledvalue & LED2_LINK_1000) - ledlink |= GMII_LED2_LINK_1000; - - tmp = ledact; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_LED_ACT, 2, &tmp); - - tmp = ledlink; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_LED_LINK, 2, &tmp); - - tmp = GMII_PHY_PGSEL_PAGE0; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHY_PAGE_SELECT, 2, &tmp); - - /* LED full duplex setting */ - ledfd = 0; - if (ledvalue & LED0_FD) - ledfd |= 0x01; - else if ((ledvalue & LED0_USB3_MASK) == 0) - ledfd |= 0x02; - - if (ledvalue & LED1_FD) - ledfd |= 0x04; - else if ((ledvalue & LED1_USB3_MASK) == 0) - ledfd |= 0x08; - - if (ledvalue & LED2_FD) - ledfd |= 0x10; - else if ((ledvalue & LED2_USB3_MASK) == 0) - ledfd |= 0x20; - - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_LEDCTRL, 1, 1, &ledfd); - - return 0; -} - -static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) -{ - u8 buf[5]; - u16 *tmp16; - u8 *tmp; - struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; - - usbnet_get_endpoints(dev, intf); - - tmp16 = (u16 *)buf; - tmp = (u8 *)buf; - - memset(ax179_data, 0, sizeof(*ax179_data)); - - /* Power up ethernet PHY */ - *tmp16 = 0; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); - *tmp16 = AX_PHYPWR_RSTCTL_IPRL; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); - msleep(200); - - *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); - msleep(100); - - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, - ETH_ALEN, dev->net->dev_addr); - memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); - - /* RX bulk configuration */ - memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); - - dev->rx_urb_size = 1024 * 20; - - *tmp = 0x34; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); - - *tmp = 0x52; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, - 1, 1, tmp); - - dev->net->netdev_ops = &ax88179_netdev_ops; - dev->net->ethtool_ops = &ax88179_ethtool_ops; - dev->net->needed_headroom = 8; - - /* Initialize MII structure */ - dev->mii.dev = dev->net; - dev->mii.mdio_read = ax88179_mdio_read; - dev->mii.mdio_write = ax88179_mdio_write; - dev->mii.phy_id_mask = 0xff; - dev->mii.reg_num_mask = 0xff; - dev->mii.phy_id = 0x03; - dev->mii.supports_gmii = 1; - - dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; - - dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; - - /* Enable checksum offload */ - *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | - AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp); - - *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP | - AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp); - - /* Configure RX control register => start operation */ - *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | - AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); - - *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | - AX_MONITOR_MODE_RWMP; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp); - - /* Configure default medium type => giga */ - *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | - AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE | - AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, tmp16); - - ax88179_led_setting(dev); - - /* Restart autoneg */ - mii_nway_restart(&dev->mii); - - netif_carrier_off(dev->net); - - return 0; -} - -static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf) -{ - u16 tmp16; - - /* Configure RX control register => stop operation */ - tmp16 = AX_RX_CTL_STOP; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); - - tmp16 = 0; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16); - - /* Power down ethernet PHY */ - tmp16 = 0; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); -} - -static void -ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hdr) -{ - skb->ip_summed = CHECKSUM_NONE; - - /* checksum error bit is set */ - if ((*pkt_hdr & AX_RXHDR_L3CSUM_ERR) || - (*pkt_hdr & AX_RXHDR_L4CSUM_ERR)) - return; - - /* It must be a TCP or UDP packet with a valid checksum */ - if (((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_TCP) || - ((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_UDP)) - skb->ip_summed = CHECKSUM_UNNECESSARY; -} - -static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -{ - struct sk_buff *ax_skb; - int pkt_cnt; - u32 rx_hdr; - u16 hdr_off; - u32 *pkt_hdr; - - skb_trim(skb, skb->len - 4); - memcpy(&rx_hdr, skb_tail_pointer(skb), 4); - le32_to_cpus(&rx_hdr); - - pkt_cnt = (u16)rx_hdr; - hdr_off = (u16)(rx_hdr >> 16); - pkt_hdr = (u32 *)(skb->data + hdr_off); - - while (pkt_cnt--) { - u16 pkt_len; - - le32_to_cpus(pkt_hdr); - pkt_len = (*pkt_hdr >> 16) & 0x1fff; - - /* Check CRC or runt packet */ - if ((*pkt_hdr & AX_RXHDR_CRC_ERR) || - (*pkt_hdr & AX_RXHDR_DROP_ERR)) { - skb_pull(skb, (pkt_len + 7) & 0xFFF8); - pkt_hdr++; - continue; - } - - if (pkt_cnt == 0) { - /* Skip IP alignment psudo header */ - skb_pull(skb, 2); - skb->len = pkt_len; - skb_set_tail_pointer(skb, pkt_len); - skb->truesize = pkt_len + sizeof(struct sk_buff); - ax88179_rx_checksum(skb, pkt_hdr); - return 1; - } - - ax_skb = skb_clone(skb, GFP_ATOMIC); - if (ax_skb) { - ax_skb->len = pkt_len; - ax_skb->data = skb->data + 2; - skb_set_tail_pointer(ax_skb, pkt_len); - ax_skb->truesize = pkt_len + sizeof(struct sk_buff); - ax88179_rx_checksum(ax_skb, pkt_hdr); - usbnet_skb_return(dev, ax_skb); - } else { - return 0; - } - - skb_pull(skb, (pkt_len + 7) & 0xFFF8); - pkt_hdr++; - } - return 1; -} - -static struct sk_buff * -ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) -{ - u32 tx_hdr1, tx_hdr2; - int frame_size = dev->maxpacket; - int mss = skb_shinfo(skb)->gso_size; - int headroom; - int tailroom; - - tx_hdr1 = skb->len; - tx_hdr2 = mss; - if (((skb->len + 8) % frame_size) == 0) - tx_hdr2 |= 0x80008000; /* Enable padding */ - - skb_linearize(skb); - headroom = skb_headroom(skb); - tailroom = skb_tailroom(skb); - - if (!skb_header_cloned(skb) && - !skb_cloned(skb) && - (headroom + tailroom) >= 8) { - if (headroom < 8) { - skb->data = memmove(skb->head + 8, skb->data, skb->len); - skb_set_tail_pointer(skb, skb->len); - } - } else { - struct sk_buff *skb2; - - skb2 = skb_copy_expand(skb, 8, 0, flags); - dev_kfree_skb_any(skb); - skb = skb2; - if (!skb) - return NULL; - } - - skb_push(skb, 4); - cpu_to_le32s(&tx_hdr2); - skb_copy_to_linear_data(skb, &tx_hdr2, 4); - - skb_push(skb, 4); - cpu_to_le32s(&tx_hdr1); - skb_copy_to_linear_data(skb, &tx_hdr1, 4); - - return skb; -} - -static int ax88179_link_reset(struct usbnet *dev) -{ - struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; - u8 tmp[5], link_sts; - u16 mode, tmp16, delay = HZ / 10; - u32 tmp32 = 0x40000000; - unsigned long jtimeout; - - jtimeout = jiffies + delay; - while (tmp32 & 0x40000000) { - mode = 0; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &mode); - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, - &ax179_data->rxctl); - - /*link up, check the usb device control TX FIFO full or empty*/ - ax88179_read_cmd(dev, 0x81, 0x8c, 0, 4, &tmp32); - - if (time_after(jiffies, jtimeout)) - return 0; - } - - mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | - AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE; - - ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS, - 1, 1, &link_sts); - - ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHY_PHYSR, 2, &tmp16); - - if (!(tmp16 & GMII_PHY_PHYSR_LINK)) { - return 0; - } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) { - mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ; - if (dev->net->mtu > 1500) - mode |= AX_MEDIUM_JUMBO_EN; - - if (link_sts & AX_USB_SS) - memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); - else if (link_sts & AX_USB_HS) - memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5); - else - memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); - } else if (GMII_PHY_PHYSR_100 == (tmp16 & GMII_PHY_PHYSR_SMASK)) { - mode |= AX_MEDIUM_PS; - - if (link_sts & (AX_USB_SS | AX_USB_HS)) - memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5); - else - memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); - } else { - memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); - } - - /* RX bulk configuration */ - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); - - dev->rx_urb_size = (1024 * (tmp[3] + 2)); - - if (tmp16 & GMII_PHY_PHYSR_FULL) - mode |= AX_MEDIUM_FULL_DUPLEX; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &mode); - - netif_carrier_on(dev->net); - - return 0; -} - -static int ax88179_reset(struct usbnet *dev) -{ - u8 buf[5]; - u16 *tmp16; - u8 *tmp; - - tmp16 = (u16 *)buf; - tmp = (u8 *)buf; - - /* Power up ethernet PHY */ - *tmp16 = 0; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); - - *tmp16 = AX_PHYPWR_RSTCTL_IPRL; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); - msleep(200); - - *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); - msleep(100); - - /* Ethernet PHY Auto Detach*/ - ax88179_auto_detach(dev, 0); - - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN, - dev->net->dev_addr); - memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); - - /* RX bulk configuration */ - memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); - - dev->rx_urb_size = 1024 * 20; - - *tmp = 0x34; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); - - *tmp = 0x52; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, - 1, 1, tmp); - - dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; - - dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; - - /* Enable checksum offload */ - *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | - AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp); - - *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP | - AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp); - - /* Configure RX control register => start operation */ - *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | - AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); - - *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | - AX_MONITOR_MODE_RWMP; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp); - - /* Configure default medium type => giga */ - *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | - AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE | - AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, tmp16); - - ax88179_led_setting(dev); - - /* Restart autoneg */ - mii_nway_restart(&dev->mii); - - netif_carrier_off(dev->net); - - return 0; -} - -static int ax88179_stop(struct usbnet *dev) -{ - u16 tmp16; - - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &tmp16); - tmp16 &= ~AX_MEDIUM_RECEIVE_EN; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, &tmp16); - - return 0; -} - -static const struct driver_info ax88179_info = { - .description = "ASIX AX88179 USB 3.0 Gigibit Ethernet", - .bind = ax88179_bind, - .unbind = ax88179_unbind, - .status = ax88179_status, - .link_reset = ax88179_link_reset, - .reset = ax88179_reset, - .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, - .rx_fixup = ax88179_rx_fixup, - .tx_fixup = ax88179_tx_fixup, -}; - -static const struct driver_info ax88178a_info = { - .description = "ASIX AX88178A USB 2.0 Gigibit Ethernet", - .bind = ax88179_bind, - .unbind = ax88179_unbind, - .status = ax88179_status, - .link_reset = ax88179_link_reset, - .reset = ax88179_reset, - .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, - .rx_fixup = ax88179_rx_fixup, - .tx_fixup = ax88179_tx_fixup, -}; - -static const struct driver_info sitecom_info = { - .description = "Sitecom USB 3.0 to Gigabit Adapter", - .bind = ax88179_bind, - .unbind = ax88179_unbind, - .status = ax88179_status, - .link_reset = ax88179_link_reset, - .reset = ax88179_reset, - .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, - .rx_fixup = ax88179_rx_fixup, - .tx_fixup = ax88179_tx_fixup, -}; - -static const struct usb_device_id products[] = { -{ - /* ASIX AX88179 10/100/1000 */ - USB_DEVICE(0x0b95, 0x1790), - .driver_info = (unsigned long)&ax88179_info, -}, { - /* ASIX AX88178A 10/100/1000 */ - USB_DEVICE(0x0b95, 0x178a), - .driver_info = (unsigned long)&ax88178a_info, -}, { - /* Sitecom USB 3.0 to Gigabit Adapter */ - USB_DEVICE(0x0df6, 0x0072), - .driver_info = (unsigned long) &sitecom_info, -}, - { }, -}; -MODULE_DEVICE_TABLE(usb, products); - -static struct usb_driver ax88179_178a_driver = { - .name = "ax88179_178a", - .id_table = products, - .probe = usbnet_probe, - .suspend = ax88179_suspend, - .resume = ax88179_resume, - .disconnect = usbnet_disconnect, - .supports_autosuspend = 1, - .disable_hub_initiated_lpm = 1, -}; - -module_usb_driver(ax88179_178a_driver); - -MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/usb/cdc_mbim.c b/trunk/drivers/net/usb/cdc_mbim.c index 6bd91676d2cb..248d2dc765a5 100644 --- a/trunk/drivers/net/usb/cdc_mbim.c +++ b/trunk/drivers/net/usb/cdc_mbim.c @@ -68,9 +68,18 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf) struct cdc_ncm_ctx *ctx; struct usb_driver *subdriver = ERR_PTR(-ENODEV); int ret = -ENODEV; - u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf); + u8 data_altsetting = CDC_NCM_DATA_ALTSETTING_NCM; struct cdc_mbim_state *info = (void *)&dev->data; + /* see if interface supports MBIM alternate setting */ + if (intf->num_altsetting == 2) { + if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) + usb_set_interface(dev->udev, + intf->cur_altsetting->desc.bInterfaceNumber, + CDC_NCM_COMM_ALTSETTING_MBIM); + data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM; + } + /* Probably NCM, defer for cdc_ncm_bind */ if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) goto err; @@ -134,7 +143,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb goto error; if (skb) { - if (skb->len <= ETH_HLEN) + if (skb->len <= sizeof(ETH_HLEN)) goto error; /* mapping VLANs to MBIM sessions: diff --git a/trunk/drivers/net/usb/cdc_ncm.c b/trunk/drivers/net/usb/cdc_ncm.c index 4709fa3497cf..4a8c25a22294 100644 --- a/trunk/drivers/net/usb/cdc_ncm.c +++ b/trunk/drivers/net/usb/cdc_ncm.c @@ -55,14 +55,6 @@ #define DRIVER_VERSION "14-Mar-2012" -#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) -static bool prefer_mbim = true; -#else -static bool prefer_mbim; -#endif -module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions"); - static void cdc_ncm_txpath_bh(unsigned long param); static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx); static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); @@ -558,12 +550,9 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) } EXPORT_SYMBOL_GPL(cdc_ncm_unbind); -/* Select the MBIM altsetting iff it is preferred and available, - * returning the number of the corresponding data interface altsetting - */ -u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf) +static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) { - struct usb_host_interface *alt; + int ret; /* The MBIM spec defines a NCM compatible default altsetting, * which we may have matched: @@ -579,27 +568,23 @@ u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf) * endpoint descriptors, shall be constructed according to * the rules given in section 6 (USB Device Model) of this * specification." + * + * Do not bind to such interfaces, allowing cdc_mbim to handle + * them */ - if (prefer_mbim && intf->num_altsetting == 2) { - alt = usb_altnum_to_altsetting(intf, CDC_NCM_COMM_ALTSETTING_MBIM); - if (alt && cdc_ncm_comm_intf_is_mbim(alt) && - !usb_set_interface(dev->udev, - intf->cur_altsetting->desc.bInterfaceNumber, - CDC_NCM_COMM_ALTSETTING_MBIM)) - return CDC_NCM_DATA_ALTSETTING_MBIM; +#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) + if ((intf->num_altsetting == 2) && + !usb_set_interface(dev->udev, + intf->cur_altsetting->desc.bInterfaceNumber, + CDC_NCM_COMM_ALTSETTING_MBIM)) { + if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) + return -ENODEV; + else + usb_set_interface(dev->udev, + intf->cur_altsetting->desc.bInterfaceNumber, + CDC_NCM_COMM_ALTSETTING_NCM); } - return CDC_NCM_DATA_ALTSETTING_NCM; -} -EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting); - -static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) -{ - int ret; - - /* MBIM backwards compatible function? */ - cdc_ncm_select_altsetting(dev, intf); - if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) - return -ENODEV; +#endif /* NCM data altsetting is always 1 */ ret = cdc_ncm_bind_common(dev, intf, 1); @@ -1228,14 +1213,6 @@ static const struct usb_device_id cdc_devs[] = { .driver_info = (unsigned long) &wwan_info, }, - /* tag Huawei devices as wwan */ - { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, - USB_CLASS_COMM, - USB_CDC_SUBCLASS_NCM, - USB_CDC_PROTO_NONE), - .driver_info = (unsigned long)&wwan_info, - }, - /* Huawei NCM devices disguised as vendor specific */ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), .driver_info = (unsigned long)&wwan_info, diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index 2a3579f67910..efb5c7c33a28 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -53,96 +52,6 @@ struct qmi_wwan_state { struct usb_interface *data; }; -/* default ethernet address used by the modem */ -static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; - -/* Make up an ethernet header if the packet doesn't have one. - * - * A firmware bug common among several devices cause them to send raw - * IP packets under some circumstances. There is no way for the - * driver/host to know when this will happen. And even when the bug - * hits, some packets will still arrive with an intact header. - * - * The supported devices are only capably of sending IPv4, IPv6 and - * ARP packets on a point-to-point link. Any packet with an ethernet - * header will have either our address or a broadcast/multicast - * address as destination. ARP packets will always have a header. - * - * This means that this function will reliably add the appropriate - * header iff necessary, provided our hardware address does not start - * with 4 or 6. - * - * Another common firmware bug results in all packets being addressed - * to 00:a0:c6:00:00:00 despite the host address being different. - * This function will also fixup such packets. - */ -static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -{ - __be16 proto; - - /* usbnet rx_complete guarantees that skb->len is at least - * hard_header_len, so we can inspect the dest address without - * checking skb->len - */ - switch (skb->data[0] & 0xf0) { - case 0x40: - proto = htons(ETH_P_IP); - break; - case 0x60: - proto = htons(ETH_P_IPV6); - break; - case 0x00: - if (is_multicast_ether_addr(skb->data)) - return 1; - /* possibly bogus destination - rewrite just in case */ - skb_reset_mac_header(skb); - goto fix_dest; - default: - /* pass along other packets without modifications */ - return 1; - } - if (skb_headroom(skb) < ETH_HLEN) - return 0; - skb_push(skb, ETH_HLEN); - skb_reset_mac_header(skb); - eth_hdr(skb)->h_proto = proto; - memset(eth_hdr(skb)->h_source, 0, ETH_ALEN); -fix_dest: - memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN); - return 1; -} - -/* very simplistic detection of IPv4 or IPv6 headers */ -static bool possibly_iphdr(const char *data) -{ - return (data[0] & 0xd0) == 0x40; -} - -/* disallow addresses which may be confused with IP headers */ -static int qmi_wwan_mac_addr(struct net_device *dev, void *p) -{ - int ret; - struct sockaddr *addr = p; - - ret = eth_prepare_mac_addr_change(dev, p); - if (ret < 0) - return ret; - if (possibly_iphdr(addr->sa_data)) - return -EADDRNOTAVAIL; - eth_commit_mac_addr_change(dev, p); - return 0; -} - -static const struct net_device_ops qmi_wwan_netdev_ops = { - .ndo_open = usbnet_open, - .ndo_stop = usbnet_stop, - .ndo_start_xmit = usbnet_start_xmit, - .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_change_mtu = usbnet_change_mtu, - .ndo_set_mac_address = qmi_wwan_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - /* using a counter to merge subdriver requests with our own into a combined state */ static int qmi_wwan_manage_power(struct usbnet *dev, int on) { @@ -230,9 +139,16 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state))); - /* set up initial state */ - info->control = intf; - info->data = intf; + /* control and data is shared? */ + if (intf->cur_altsetting->desc.bNumEndpoints == 3) { + info->control = intf; + info->data = intf; + goto shared; + } + + /* else require a single interrupt status endpoint on control intf */ + if (intf->cur_altsetting->desc.bNumEndpoints != 1) + goto err; /* and a number of CDC descriptors */ while (len > 3) { @@ -291,14 +207,25 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) buf += h->bLength; } - /* Use separate control and data interfaces if we found a CDC Union */ - if (cdc_union) { - info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0); - if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) { - dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n", - cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0); - goto err; - } + /* did we find all the required ones? */ + if (!(found & (1 << USB_CDC_HEADER_TYPE)) || + !(found & (1 << USB_CDC_UNION_TYPE))) { + dev_err(&intf->dev, "CDC functional descriptors missing\n"); + goto err; + } + + /* verify CDC Union */ + if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) { + dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0); + goto err; + } + + /* need to save these for unbind */ + info->control = intf; + info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0); + if (!info->data) { + dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0); + goto err; } /* errors aren't fatal - we can live with the dynamic address */ @@ -308,30 +235,17 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) } /* claim data interface and set it up */ - if (info->control != info->data) { - status = usb_driver_claim_interface(driver, info->data, dev); - if (status < 0) - goto err; - } + status = usb_driver_claim_interface(driver, info->data, dev); + if (status < 0) + goto err; +shared: status = qmi_wwan_register_subdriver(dev); if (status < 0 && info->control != info->data) { usb_set_intfdata(info->data, NULL); usb_driver_release_interface(driver, info->data); } - /* Never use the same address on both ends of the link, even - * if the buggy firmware told us to. - */ - if (!compare_ether_addr(dev->net->dev_addr, default_modem_addr)) - eth_hw_addr_random(dev->net); - - /* make MAC addr easily distinguishable from an IP header */ - if (possibly_iphdr(dev->net->dev_addr)) { - dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */ - dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */ - } - dev->net->netdev_ops = &qmi_wwan_netdev_ops; err: return status; } @@ -410,7 +324,6 @@ static const struct driver_info qmi_wwan_info = { .bind = qmi_wwan_bind, .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, - .rx_fixup = qmi_wwan_rx_fixup, }; #define HUAWEI_VENDOR_ID 0x12D1 diff --git a/trunk/drivers/net/usb/smsc75xx.c b/trunk/drivers/net/usb/smsc75xx.c index 1a15ec14c386..9abe51710f22 100644 --- a/trunk/drivers/net/usb/smsc75xx.c +++ b/trunk/drivers/net/usb/smsc75xx.c @@ -914,12 +914,8 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) { struct usbnet *dev = netdev_priv(netdev); - int ret; - - if (new_mtu > MAX_SINGLE_PACKET_SIZE) - return -EINVAL; - ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); + int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu); if (ret < 0) { netdev_warn(dev->net, "Failed to set mac rx frame length\n"); return ret; @@ -1328,7 +1324,7 @@ static int smsc75xx_reset(struct usbnet *dev) netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x\n", buf); - ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN); + ret = smsc75xx_set_rx_max_frame_length(dev, 1514); if (ret < 0) { netdev_warn(dev->net, "Failed to set max rx frame length\n"); return ret; @@ -2138,8 +2134,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) dev->net->stats.rx_frame_errors++; } else { - /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */ - if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) { + /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ + if (unlikely(size > (ETH_FRAME_LEN + 12))) { netif_dbg(dev, rx_err, dev->net, "size err rx_cmd_a=0x%08x\n", rx_cmd_a); diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c index eae7a03d4f9b..4aad350e4dae 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2958,7 +2958,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, adapter->num_rx_queues = num_rx_queues; adapter->num_tx_queues = num_tx_queues; - adapter->rx_buf_per_pkt = 1; size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues; size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues; diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c index 63a124340cbe..a0feb17a0238 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -472,12 +472,6 @@ vmxnet3_set_ringparam(struct net_device *netdev, VMXNET3_RX_RING_MAX_SIZE) return -EINVAL; - /* if adapter not yet initialized, do nothing */ - if (adapter->rx_buf_per_pkt == 0) { - netdev_err(netdev, "adapter not completely initialized, " - "ring size cannot be changed yet\n"); - return -EOPNOTSUPP; - } /* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */ new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) & diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_int.h b/trunk/drivers/net/vmxnet3/vmxnet3_int.h index 35418146fa17..3198384689d9 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_int.h +++ b/trunk/drivers/net/vmxnet3/vmxnet3_int.h @@ -70,10 +70,10 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.1.30.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.1.29.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01011E00 +#define VMXNET3_DRIVER_VERSION_NUM 0x01011D00 #if defined(CONFIG_PCI_MSI) /* RSS only makes sense if MSI-X is supported. */ diff --git a/trunk/drivers/net/vxlan.c b/trunk/drivers/net/vxlan.c index 7cee7a3068ec..f10e58ac9c1b 100644 --- a/trunk/drivers/net/vxlan.c +++ b/trunk/drivers/net/vxlan.c @@ -961,8 +961,6 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); tunnel_ip_select_ident(skb, old_iph, &rt->dst); - nf_reset(skb); - vxlan_set_owner(dev, skb); /* See iptunnel_xmit() */ @@ -1506,14 +1504,6 @@ static __net_init int vxlan_init_net(struct net *net) static __net_exit void vxlan_exit_net(struct net *net) { struct vxlan_net *vn = net_generic(net, vxlan_net_id); - struct vxlan_dev *vxlan; - unsigned h; - - rtnl_lock(); - for (h = 0; h < VNI_HASH_SIZE; ++h) - hlist_for_each_entry(vxlan, &vn->vni_list[h], hlist) - dev_close(vxlan->dev); - rtnl_unlock(); if (vn->sock) { sk_release_kernel(vn->sock->sk); diff --git a/trunk/drivers/net/wireless/airo_cs.c b/trunk/drivers/net/wireless/airo_cs.c index 14128fd265ac..956024a636e6 100644 --- a/trunk/drivers/net/wireless/airo_cs.c +++ b/trunk/drivers/net/wireless/airo_cs.c @@ -180,7 +180,16 @@ static struct pcmcia_driver airo_driver = { .suspend = airo_suspend, .resume = airo_resume, }; -module_pcmcia_driver(airo_driver); + +static int __init airo_cs_init(void) +{ + return pcmcia_register_driver(&airo_driver); +} + +static void __exit airo_cs_cleanup(void) +{ + pcmcia_unregister_driver(&airo_driver); +} /* This program is free software; you can redistribute it and/or @@ -220,3 +229,6 @@ module_pcmcia_driver(airo_driver); IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +module_init(airo_cs_init); +module_exit(airo_cs_cleanup); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c index f76c3ca07a45..4cc13940c895 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -1023,7 +1023,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, AR_PHY_AGC_CONTROL_FLTR_CAL | AR_PHY_AGC_CONTROL_PKDET_CAL; - /* Use chip chainmask only for calibration */ ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); if (rtt) { @@ -1151,9 +1150,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ar9003_hw_rtt_disable(ah); } - /* Revert chainmask to runtime parameters */ - ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); - /* Initialize list pointers */ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h index bdee2ed67219..28fd99203f64 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h @@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2] = { {0x00008258, 0x00000000}, {0x0000825c, 0x40000000}, {0x00008260, 0x00080922}, - {0x00008264, 0x9d400010}, + {0x00008264, 0x9bc00010}, {0x00008268, 0xffffffff}, {0x0000826c, 0x0000ffff}, {0x00008270, 0x00000000}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/common.h b/trunk/drivers/net/wireless/ath/ath9k/common.h index 050ca4a4850d..5f845beeb18b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/common.h +++ b/trunk/drivers/net/wireless/ath/ath9k/common.h @@ -27,7 +27,7 @@ #define WME_MAX_BA WME_BA_BMP_SIZE #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) -#define ATH_RSSI_DUMMY_MARKER 127 +#define ATH_RSSI_DUMMY_MARKER 0x127 #define ATH_RSSI_LPF_LEN 10 #define RSSI_LPF_THRESHOLD -20 #define ATH_RSSI_EP_MULTIPLIER (1<<7) diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index 73fe8d6db566..467b60014b7b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c @@ -143,14 +143,14 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) u32 sz, i; struct channel_detector *cd; - cd = kmalloc(sizeof(*cd), GFP_ATOMIC); + cd = kmalloc(sizeof(*cd), GFP_KERNEL); if (cd == NULL) goto fail; INIT_LIST_HEAD(&cd->head); cd->freq = freq; sz = sizeof(cd->detectors) * dpd->num_radar_types; - cd->detectors = kzalloc(sz, GFP_ATOMIC); + cd->detectors = kzalloc(sz, GFP_KERNEL); if (cd->detectors == NULL) goto fail; diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c b/trunk/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c index 5e48c5515b8c..91b8dceeadb1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c @@ -218,7 +218,7 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) { struct pulse_elem *p = pool_get_pulse_elem(); if (p == NULL) { - p = kmalloc(sizeof(*p), GFP_ATOMIC); + p = kmalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) { DFS_POOL_STAT_INC(pulse_alloc_error); return false; @@ -299,7 +299,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde, ps.deadline_ts = ps.first_ts + ps.dur; new_ps = pool_get_pseq_elem(); if (new_ps == NULL) { - new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC); + new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL); if (new_ps == NULL) { DFS_POOL_STAT_INC(pseq_alloc_error); return false; diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc.h b/trunk/drivers/net/wireless/ath/ath9k/htc.h index d3b099d7898b..96bfb18078fa 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/htc.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c index a47f5e05fc04..716058b67557 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -796,7 +796,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) * required version. */ if (priv->fw_version_major != MAJOR_VERSION_REQ || - priv->fw_version_minor < MINOR_VERSION_REQ) { + priv->fw_version_minor != MINOR_VERSION_REQ) { dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", MAJOR_VERSION_REQ, MINOR_VERSION_REQ); return -EINVAL; diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index bd8251c1c749..3ad1fd05c5e7 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -1067,19 +1067,15 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, last_rssi = priv->rx.last_rssi; - if (ieee80211_is_beacon(hdr->frame_control) && - !is_zero_ether_addr(common->curbssid) && - ether_addr_equal(hdr->addr3, common->curbssid)) { - s8 rssi = rxbuf->rxstatus.rs_rssi; + if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) + rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi, + ATH_RSSI_EP_MULTIPLIER); - if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) - rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); + if (rxbuf->rxstatus.rs_rssi < 0) + rxbuf->rxstatus.rs_rssi = 0; - if (rssi < 0) - rssi = 0; - - priv->ah->stats.avgbrssi = rssi; - } + if (ieee80211_is_beacon(fc)) + priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); rx_status->band = hw->conf.channel->band; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 07e25260c31d..2a2ae403e0e5 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -1463,9 +1463,7 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah, reset_type = ATH9K_RESET_POWER_ON; else reset_type = ATH9K_RESET_COLD; - } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) || - (REG_READ(ah, AR_CR) & AR_CR_RXE)) - reset_type = ATH9K_RESET_COLD; + } if (!ath9k_hw_set_reset_reg(ah, reset_type)) return false; diff --git a/trunk/drivers/net/wireless/ath/ath9k/link.c b/trunk/drivers/net/wireless/ath/ath9k/link.c index 7fdac6c7b3ea..ade3afb21f91 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/link.c +++ b/trunk/drivers/net/wireless/ath/ath9k/link.c @@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct work_struct *work) int i; bool needreset = false; - for (i = 0; i < IEEE80211_NUM_ACS; i++) { - txq = sc->tx.txq_map[i]; - - ath_txq_lock(sc, txq); - if (txq->axq_depth) { - if (txq->axq_tx_inprogress) { - needreset = true; - ath_txq_unlock(sc, txq); - break; - } else { - txq->axq_tx_inprogress = true; + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) + if (ATH_TXQ_SETUP(sc, i)) { + txq = &sc->tx.txq[i]; + ath_txq_lock(sc, txq); + if (txq->axq_depth) { + if (txq->axq_tx_inprogress) { + needreset = true; + ath_txq_unlock(sc, txq); + break; + } else { + txq->axq_tx_inprogress = true; + } } + ath_txq_unlock_complete(sc, txq); } - ath_txq_unlock_complete(sc, txq); - } if (needreset) { ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, @@ -170,8 +170,7 @@ void ath_rx_poll(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; - if (!test_bit(SC_OP_INVALID, &sc->sc_flags)) - ieee80211_queue_work(sc->hw, &sc->hw_check_work); + ieee80211_queue_work(sc->hw, &sc->hw_check_work); } /* diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 988372d218a4..6e66f9c6782b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -280,10 +280,6 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) if (r) { ath_err(common, "Unable to reset channel, reset status %d\n", r); - - ath9k_hw_enable_interrupts(ah); - ath9k_queue_reset(sc, RESET_TYPE_BB_HANG); - goto out; } diff --git a/trunk/drivers/net/wireless/atmel_cs.c b/trunk/drivers/net/wireless/atmel_cs.c index 522572219217..b42930f457c2 100644 --- a/trunk/drivers/net/wireless/atmel_cs.c +++ b/trunk/drivers/net/wireless/atmel_cs.c @@ -245,7 +245,16 @@ static struct pcmcia_driver atmel_driver = { .suspend = atmel_suspend, .resume = atmel_resume, }; -module_pcmcia_driver(atmel_driver); + +static int __init atmel_cs_init(void) +{ + return pcmcia_register_driver(&atmel_driver); +} + +static void __exit atmel_cs_cleanup(void) +{ + pcmcia_unregister_driver(&atmel_driver); +} /* This program is free software; you can redistribute it and/or @@ -285,3 +294,6 @@ module_pcmcia_driver(atmel_driver); IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +module_init(atmel_cs_init); +module_exit(atmel_cs_cleanup); diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index 122146943bf2..38bc5a7997ff 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -1487,12 +1487,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_dma_ops *ops; struct b43_dmaring *ring; struct b43_dmadesc_meta *meta; - static const struct b43_txstatus fake; /* filled with 0 */ - const struct b43_txstatus *txstat; int slot, firstused; bool frame_succeed; - int skip; - static u8 err_out1, err_out2; ring = parse_cookie(dev, status->cookie, &slot); if (unlikely(!ring)) @@ -1505,36 +1501,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, firstused = ring->current_slot - ring->used_slots + 1; if (firstused < 0) firstused = ring->nr_slots + firstused; - - skip = 0; if (unlikely(slot != firstused)) { /* This possibly is a firmware bug and will result in - * malfunction, memory leaks and/or stall of DMA functionality. - */ - if (slot == next_slot(ring, next_slot(ring, firstused))) { - /* If a single header/data pair was missed, skip over - * the first two slots in an attempt to recover. - */ - slot = firstused; - skip = 2; - if (!err_out1) { - /* Report the error once. */ - b43dbg(dev->wl, - "Skip on DMA ring %d slot %d.\n", - ring->index, slot); - err_out1 = 1; - } - } else { - /* More than a single header/data pair were missed. - * Report this error once. - */ - if (!err_out2) - b43dbg(dev->wl, - "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n", - ring->index, firstused, slot); - err_out2 = 1; - return; - } + * malfunction, memory leaks and/or stall of DMA functionality. */ + b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. " + "Expected %d, but got %d\n", + ring->index, firstused, slot); + return; } ops = ring->ops; @@ -1549,13 +1522,11 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, slot, firstused, ring->index); break; } - if (meta->skb) { struct b43_private_tx_info *priv_info = - b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); + b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); - unmap_descbuffer(ring, meta->dmaaddr, - meta->skb->len, 1); + unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); kfree(priv_info->bouncebuffer); priv_info->bouncebuffer = NULL; } else { @@ -1567,9 +1538,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, struct ieee80211_tx_info *info; if (unlikely(!meta->skb)) { - /* This is a scatter-gather fragment of a frame, - * so the skb pointer must not be NULL. - */ + /* This is a scatter-gather fragment of a frame, so + * the skb pointer must not be NULL. */ b43dbg(dev->wl, "TX status unexpected NULL skb " "at slot %d (first=%d) on ring %d\n", slot, firstused, ring->index); @@ -1580,18 +1550,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, /* * Call back to inform the ieee80211 subsystem about - * the status of the transmission. When skipping over - * a missed TX status report, use a status structure - * filled with zeros to indicate that the frame was not - * sent (frame_count 0) and not acknowledged + * the status of the transmission. */ - if (unlikely(skip)) - txstat = &fake; - else - txstat = status; - - frame_succeed = b43_fill_txstatus_report(dev, info, - txstat); + frame_succeed = b43_fill_txstatus_report(dev, info, status); #ifdef CONFIG_B43_DEBUG if (frame_succeed) ring->nr_succeed_tx_packets++; @@ -1619,14 +1580,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, /* Everything unmapped and free'd. So it's not used anymore. */ ring->used_slots--; - if (meta->is_last_fragment && !skip) { + if (meta->is_last_fragment) { /* This is the last scatter-gather * fragment of the frame. We are done. */ break; } slot = next_slot(ring, slot); - if (skip > 0) - --skip; } if (ring->stopped) { B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME); diff --git a/trunk/drivers/net/wireless/b43/pcmcia.c b/trunk/drivers/net/wireless/b43/pcmcia.c index 55f2bd7f8f74..f2ea2ceec8a9 100644 --- a/trunk/drivers/net/wireless/b43/pcmcia.c +++ b/trunk/drivers/net/wireless/b43/pcmcia.c @@ -130,10 +130,6 @@ static struct pcmcia_driver b43_pcmcia_driver = { .resume = b43_pcmcia_resume, }; -/* - * These are not module init/exit functions! - * The module_pcmcia_driver() helper cannot be used here. - */ int b43_pcmcia_init(void) { return pcmcia_register_driver(&b43_pcmcia_driver); diff --git a/trunk/drivers/net/wireless/b43/phy_n.c b/trunk/drivers/net/wireless/b43/phy_n.c index b70f220bc4b3..3c35382ee6c2 100644 --- a/trunk/drivers/net/wireless/b43/phy_n.c +++ b/trunk/drivers/net/wireless/b43/phy_n.c @@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) u16 clip_off[2] = { 0xFFFF, 0xFFFF }; u8 vcm_final = 0; - s32 offset[4]; + s8 offset[4]; s32 results[8][4] = { }; s32 results_min[4] = { }; s32 poll_results[4] = { }; @@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) } for (i = 0; i < 4; i += 2) { s32 curr; - s32 mind = 0x100000; + s32 mind = 40; s32 minpoll = 249; u8 minvcm = 0; if (2 * core != i) @@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) u8 regs_save_radio[2]; u16 regs_save_phy[2]; - s32 offset[4]; + s8 offset[4]; u8 core; u8 rail; @@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) } for (i = 0; i < 4; i++) { - s32 mind = 0x100000; + s32 mind = 40; u8 minvcm = 0; s32 minpoll = 249; s32 curr; @@ -5165,8 +5165,7 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) #endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: - ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco, - avoid); + /* FIXME */ break; #endif } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 35fc68be158d..4469321c0eb3 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3317,15 +3317,15 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) goto err; } + /* External image takes precedence if specified */ if (brcmf_sdbrcm_download_code_file(bus)) { brcmf_err("dongle image file download failed\n"); goto err; } - if (brcmf_sdbrcm_download_nvram(bus)) { + /* External nvram takes precedence if specified */ + if (brcmf_sdbrcm_download_nvram(bus)) brcmf_err("dongle nvram file download failed\n"); - goto err; - } /* Take arm out of reset */ if (brcmf_sdbrcm_download_state(bus, false)) { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 78da3eff75e8..2af9c0f0798d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -1891,10 +1891,8 @@ static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, const u8 *mac_addr, struct key_params *params) { - struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_wsec_key key; s32 err = 0; - u8 keybuf[8]; memset(&key, 0, sizeof(key)); key.index = (u32) key_idx; @@ -1918,9 +1916,8 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, brcmf_dbg(CONN, "Setting the key index %d\n", key.index); memcpy(key.data, params->key, key.len); - if ((ifp->vif->mode != WL_MODE_AP) && - (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { - brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); + if (params->cipher == WLAN_CIPHER_SUITE_TKIP) { + u8 keybuf[8]; memcpy(keybuf, &key.data[24], sizeof(keybuf)); memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); memcpy(&key.data[16], keybuf, sizeof(keybuf)); @@ -2016,7 +2013,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, break; case WLAN_CIPHER_SUITE_TKIP: if (ifp->vif->mode != WL_MODE_AP) { - brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); + brcmf_dbg(CONN, "Swapping key\n"); memcpy(keybuf, &key.data[24], sizeof(keybuf)); memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); memcpy(&key.data[16], keybuf, sizeof(keybuf)); @@ -2121,7 +2118,8 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, err = -EAGAIN; goto done; } - if (wsec & WEP_ENABLED) { + switch (wsec & ~SES_OW_ENABLED) { + case WEP_ENABLED: sec = &profile->sec; if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { params.cipher = WLAN_CIPHER_SUITE_WEP40; @@ -2130,13 +2128,16 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, params.cipher = WLAN_CIPHER_SUITE_WEP104; brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); } - } else if (wsec & TKIP_ENABLED) { + break; + case TKIP_ENABLED: params.cipher = WLAN_CIPHER_SUITE_TKIP; brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); - } else if (wsec & AES_ENABLED) { + break; + case AES_ENABLED: params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); - } else { + break; + default: brcmf_err("Invalid algo (0x%x)\n", wsec); err = -EINVAL; goto done; @@ -3823,9 +3824,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); - s32 err; + s32 err = -EPERM; struct brcmf_fil_bss_enable_le bss_enable; - struct brcmf_join_params join_params; brcmf_dbg(TRACE, "Enter\n"); @@ -3833,21 +3833,16 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) /* Due to most likely deauths outstanding we sleep */ /* first to make sure they get processed by fw. */ msleep(400); - - memset(&join_params, 0, sizeof(join_params)); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, - &join_params, sizeof(join_params)); - if (err < 0) - brcmf_err("SET SSID error (%d)\n", err); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); - if (err < 0) - brcmf_err("BRCMF_C_UP error %d\n", err); err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); - if (err < 0) + if (err < 0) { brcmf_err("setting AP mode failed %d\n", err); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0); - if (err < 0) - brcmf_err("setting INFRA mode failed %d\n", err); + goto exit; + } + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); + if (err < 0) { + brcmf_err("BRCMF_C_UP error %d\n", err); + goto exit; + } } else { bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx); bss_enable.enable = cpu_to_le32(0); @@ -3860,6 +3855,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); +exit: return err; } @@ -4126,6 +4122,10 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = { BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE) + }, { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | @@ -4183,7 +4183,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO); + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_DEVICE); wiphy->iface_combinations = brcmf_iface_combos; wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index e2340b231aa1..c6451c61407a 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -274,130 +274,6 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br) } } -/** - * This function frees the WL per-device resources. - * - * This function frees resources owned by the WL device pointed to - * by the wl parameter. - * - * precondition: can both be called locked and unlocked - * - */ -static void brcms_free(struct brcms_info *wl) -{ - struct brcms_timer *t, *next; - - /* free ucode data */ - if (wl->fw.fw_cnt) - brcms_ucode_data_free(&wl->ucode); - if (wl->irq) - free_irq(wl->irq, wl); - - /* kill dpc */ - tasklet_kill(&wl->tasklet); - - if (wl->pub) { - brcms_debugfs_detach(wl->pub); - brcms_c_module_unregister(wl->pub, "linux", wl); - } - - /* free common resources */ - if (wl->wlc) { - brcms_c_detach(wl->wlc); - wl->wlc = NULL; - wl->pub = NULL; - } - - /* virtual interface deletion is deferred so we cannot spinwait */ - - /* wait for all pending callbacks to complete */ - while (atomic_read(&wl->callbacks) > 0) - schedule(); - - /* free timers */ - for (t = wl->timers; t; t = next) { - next = t->next; -#ifdef DEBUG - kfree(t->name); -#endif - kfree(t); - } -} - -/* -* called from both kernel as from this kernel module (error flow on attach) -* precondition: perimeter lock is not acquired. -*/ -static void brcms_remove(struct bcma_device *pdev) -{ - struct ieee80211_hw *hw = bcma_get_drvdata(pdev); - struct brcms_info *wl = hw->priv; - - if (wl->wlc) { - wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); - wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); - ieee80211_unregister_hw(hw); - } - - brcms_free(wl); - - bcma_set_drvdata(pdev, NULL); - ieee80211_free_hw(hw); -} - -/* - * Precondition: Since this function is called in brcms_pci_probe() context, - * no locking is required. - */ -static void brcms_release_fw(struct brcms_info *wl) -{ - int i; - for (i = 0; i < MAX_FW_IMAGES; i++) { - release_firmware(wl->fw.fw_bin[i]); - release_firmware(wl->fw.fw_hdr[i]); - } -} - -/* - * Precondition: Since this function is called in brcms_pci_probe() context, - * no locking is required. - */ -static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) -{ - int status; - struct device *device = &pdev->dev; - char fw_name[100]; - int i; - - memset(&wl->fw, 0, sizeof(struct brcms_firmware)); - for (i = 0; i < MAX_FW_IMAGES; i++) { - if (brcms_firmwares[i] == NULL) - break; - sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], - UCODE_LOADER_API_VER); - status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); - if (status) { - wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); - return status; - } - sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], - UCODE_LOADER_API_VER); - status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); - if (status) { - wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); - return status; - } - wl->fw.hdr_num_entries[i] = - wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); - } - wl->fw.fw_cnt = i; - status = brcms_ucode_data_init(wl, &wl->ucode); - brcms_release_fw(wl); - return status; -} - static void brcms_ops_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) @@ -430,14 +306,6 @@ static int brcms_ops_start(struct ieee80211_hw *hw) if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); - if (!wl->ucode.bcm43xx_bomminor) { - err = brcms_request_fw(wl, wl->wlc->hw->d11core); - if (err) { - brcms_remove(wl->wlc->hw->d11core); - return -ENOENT; - } - } - spin_lock_bh(&wl->lock); /* avoid acknowledging frames before a non-monitor device is added */ wl->mute_tx = true; @@ -925,6 +793,128 @@ void brcms_dpc(unsigned long data) wake_up(&wl->tx_flush_wq); } +/* + * Precondition: Since this function is called in brcms_pci_probe() context, + * no locking is required. + */ +static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) +{ + int status; + struct device *device = &pdev->dev; + char fw_name[100]; + int i; + + memset(&wl->fw, 0, sizeof(struct brcms_firmware)); + for (i = 0; i < MAX_FW_IMAGES; i++) { + if (brcms_firmwares[i] == NULL) + break; + sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); + if (status) { + wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); + return status; + } + sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); + if (status) { + wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); + return status; + } + wl->fw.hdr_num_entries[i] = + wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); + } + wl->fw.fw_cnt = i; + return brcms_ucode_data_init(wl, &wl->ucode); +} + +/* + * Precondition: Since this function is called in brcms_pci_probe() context, + * no locking is required. + */ +static void brcms_release_fw(struct brcms_info *wl) +{ + int i; + for (i = 0; i < MAX_FW_IMAGES; i++) { + release_firmware(wl->fw.fw_bin[i]); + release_firmware(wl->fw.fw_hdr[i]); + } +} + +/** + * This function frees the WL per-device resources. + * + * This function frees resources owned by the WL device pointed to + * by the wl parameter. + * + * precondition: can both be called locked and unlocked + * + */ +static void brcms_free(struct brcms_info *wl) +{ + struct brcms_timer *t, *next; + + /* free ucode data */ + if (wl->fw.fw_cnt) + brcms_ucode_data_free(&wl->ucode); + if (wl->irq) + free_irq(wl->irq, wl); + + /* kill dpc */ + tasklet_kill(&wl->tasklet); + + if (wl->pub) { + brcms_debugfs_detach(wl->pub); + brcms_c_module_unregister(wl->pub, "linux", wl); + } + + /* free common resources */ + if (wl->wlc) { + brcms_c_detach(wl->wlc); + wl->wlc = NULL; + wl->pub = NULL; + } + + /* virtual interface deletion is deferred so we cannot spinwait */ + + /* wait for all pending callbacks to complete */ + while (atomic_read(&wl->callbacks) > 0) + schedule(); + + /* free timers */ + for (t = wl->timers; t; t = next) { + next = t->next; +#ifdef DEBUG + kfree(t->name); +#endif + kfree(t); + } +} + +/* +* called from both kernel as from this kernel module (error flow on attach) +* precondition: perimeter lock is not acquired. +*/ +static void brcms_remove(struct bcma_device *pdev) +{ + struct ieee80211_hw *hw = bcma_get_drvdata(pdev); + struct brcms_info *wl = hw->priv; + + if (wl->wlc) { + wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); + wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); + ieee80211_unregister_hw(hw); + } + + brcms_free(wl); + + bcma_set_drvdata(pdev, NULL); + ieee80211_free_hw(hw); +} + static irqreturn_t brcms_isr(int irq, void *dev_id) { struct brcms_info *wl; @@ -1057,8 +1047,18 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) spin_lock_init(&wl->lock); spin_lock_init(&wl->isr_lock); + /* prepare ucode */ + if (brcms_request_fw(wl, pdev) < 0) { + wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " + "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); + brcms_release_fw(wl); + brcms_remove(pdev); + return NULL; + } + /* common load-time initialization */ wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); + brcms_release_fw(wl); if (!wl->wlc) { wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", KBUILD_MODNAME, err); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c index 18d37645e2cd..21a824232478 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c @@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, gain0_15 = ((biq1 & 0xf) << 12) | ((tia & 0xf) << 8) | ((lna2 & 0x3) << 6) | - ((lna2 & - 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); + ((lna2 & 0x3) << 4) | + ((lna1 & 0x3) << 2) | + ((lna1 & 0x3) << 0); mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); @@ -1156,6 +1157,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, } mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); + mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); + mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3); } @@ -1328,6 +1331,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples) return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; } +static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain, + u16 tia_gain, u16 lna2_gain) +{ + u32 i_thresh_l, q_thresh_l; + u32 i_thresh_h, q_thresh_h; + struct lcnphy_iq_est iq_est_h, iq_est_l; + + wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain, + lna2_gain, 0); + + wlc_lcnphy_rx_gain_override_enable(pi, true); + wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0); + udelay(500); + write_radio_reg(pi, RADIO_2064_REG112, 0); + if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l)) + return false; + + wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0); + udelay(500); + write_radio_reg(pi, RADIO_2064_REG112, 0); + if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h)) + return false; + + i_thresh_l = (iq_est_l.i_pwr << 1); + i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr; + + q_thresh_l = (iq_est_l.q_pwr << 1); + q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr; + if ((iq_est_h.i_pwr > i_thresh_l) && + (iq_est_h.i_pwr < i_thresh_h) && + (iq_est_h.q_pwr > q_thresh_l) && + (iq_est_h.q_pwr < q_thresh_h)) + return true; + + return false; +} + static bool wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, const struct lcnphy_rx_iqcomp *iqcomp, @@ -1342,8 +1382,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, rfoverride3_old, rfoverride3val_old, rfoverride4_old, rfoverride4val_old, afectrlovr_old, afectrlovrval_old; - int tia_gain; - u32 received_power, rx_pwr_threshold; + int tia_gain, lna2_gain, biq1_gain; + bool set_gain; u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; u16 values_to_save[11]; s16 *ptr; @@ -1368,126 +1408,134 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, goto cal_done; } - if (module == 1) { + WARN_ON(module != 1); + tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + for (i = 0; i < 11; i++) + values_to_save[i] = + read_radio_reg(pi, rxiq_cal_rf_reg[i]); + Core1TxControl_old = read_phy_reg(pi, 0x631); + + or_phy_reg(pi, 0x631, 0x0015); + + RFOverride0_old = read_phy_reg(pi, 0x44c); + RFOverrideVal0_old = read_phy_reg(pi, 0x44d); + rfoverride2_old = read_phy_reg(pi, 0x4b0); + rfoverride2val_old = read_phy_reg(pi, 0x4b1); + rfoverride3_old = read_phy_reg(pi, 0x4f9); + rfoverride3val_old = read_phy_reg(pi, 0x4fa); + rfoverride4_old = read_phy_reg(pi, 0x938); + rfoverride4val_old = read_phy_reg(pi, 0x939); + afectrlovr_old = read_phy_reg(pi, 0x43b); + afectrlovrval_old = read_phy_reg(pi, 0x43c); + old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - for (i = 0; i < 11; i++) - values_to_save[i] = - read_radio_reg(pi, rxiq_cal_rf_reg[i]); - Core1TxControl_old = read_phy_reg(pi, 0x631); - - or_phy_reg(pi, 0x631, 0x0015); - - RFOverride0_old = read_phy_reg(pi, 0x44c); - RFOverrideVal0_old = read_phy_reg(pi, 0x44d); - rfoverride2_old = read_phy_reg(pi, 0x4b0); - rfoverride2val_old = read_phy_reg(pi, 0x4b1); - rfoverride3_old = read_phy_reg(pi, 0x4f9); - rfoverride3val_old = read_phy_reg(pi, 0x4fa); - rfoverride4_old = read_phy_reg(pi, 0x938); - rfoverride4val_old = read_phy_reg(pi, 0x939); - afectrlovr_old = read_phy_reg(pi, 0x43b); - afectrlovrval_old = read_phy_reg(pi, 0x43c); - old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - - tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); - if (tx_gain_override_old) { - wlc_lcnphy_get_tx_gain(pi, &old_gains); - tx_gain_index_old = pi_lcn->lcnphy_current_index; - } + tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); + if (tx_gain_override_old) { + wlc_lcnphy_get_tx_gain(pi, &old_gains); + tx_gain_index_old = pi_lcn->lcnphy_current_index; + } - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); - mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - write_radio_reg(pi, RADIO_2064_REG116, 0x06); - write_radio_reg(pi, RADIO_2064_REG12C, 0x07); - write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); - write_radio_reg(pi, RADIO_2064_REG098, 0x03); - write_radio_reg(pi, RADIO_2064_REG00B, 0x7); - mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); - write_radio_reg(pi, RADIO_2064_REG01D, 0x01); - write_radio_reg(pi, RADIO_2064_REG114, 0x01); - write_radio_reg(pi, RADIO_2064_REG02E, 0x10); - write_radio_reg(pi, RADIO_2064_REG12A, 0x08); - - mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); - mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); - mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); - - mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); - - wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0); - write_phy_reg(pi, 0x6da, 0xffff); - or_phy_reg(pi, 0x6db, 0x3); - wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); - wlc_lcnphy_rx_gain_override_enable(pi, true); - - tia_gain = 8; - rx_pwr_threshold = 950; - while (tia_gain > 0) { - tia_gain -= 1; - wlc_lcnphy_set_rx_gain_by_distribution(pi, - 0, 0, 2, 2, - (u16) - tia_gain, 1, 0); - udelay(500); + write_radio_reg(pi, RADIO_2064_REG116, 0x06); + write_radio_reg(pi, RADIO_2064_REG12C, 0x07); + write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); + write_radio_reg(pi, RADIO_2064_REG098, 0x03); + write_radio_reg(pi, RADIO_2064_REG00B, 0x7); + mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); + write_radio_reg(pi, RADIO_2064_REG01D, 0x01); + write_radio_reg(pi, RADIO_2064_REG114, 0x01); + write_radio_reg(pi, RADIO_2064_REG02E, 0x10); + write_radio_reg(pi, RADIO_2064_REG12A, 0x08); + + mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); + mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); - received_power = - wlc_lcnphy_measure_digital_power(pi, 2000); - if (received_power < rx_pwr_threshold) - break; + mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + + write_phy_reg(pi, 0x6da, 0xffff); + or_phy_reg(pi, 0x6db, 0x3); + + wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); + set_gain = false; + + lna2_gain = 3; + while ((lna2_gain >= 0) && !set_gain) { + tia_gain = 4; + + while ((tia_gain >= 0) && !set_gain) { + biq1_gain = 6; + + while ((biq1_gain >= 0) && !set_gain) { + set_gain = wlc_lcnphy_rx_iq_cal_gain(pi, + (u16) + biq1_gain, + (u16) + tia_gain, + (u16) + lna2_gain); + biq1_gain -= 1; + } + tia_gain -= 1; } - result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); + lna2_gain -= 1; + } - wlc_lcnphy_stop_tx_tone(pi); + if (set_gain) + result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024); + else + result = false; - write_phy_reg(pi, 0x631, Core1TxControl_old); + wlc_lcnphy_stop_tx_tone(pi); - write_phy_reg(pi, 0x44c, RFOverrideVal0_old); - write_phy_reg(pi, 0x44d, RFOverrideVal0_old); - write_phy_reg(pi, 0x4b0, rfoverride2_old); - write_phy_reg(pi, 0x4b1, rfoverride2val_old); - write_phy_reg(pi, 0x4f9, rfoverride3_old); - write_phy_reg(pi, 0x4fa, rfoverride3val_old); - write_phy_reg(pi, 0x938, rfoverride4_old); - write_phy_reg(pi, 0x939, rfoverride4val_old); - write_phy_reg(pi, 0x43b, afectrlovr_old); - write_phy_reg(pi, 0x43c, afectrlovrval_old); - write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); + write_phy_reg(pi, 0x631, Core1TxControl_old); + + write_phy_reg(pi, 0x44c, RFOverrideVal0_old); + write_phy_reg(pi, 0x44d, RFOverrideVal0_old); + write_phy_reg(pi, 0x4b0, rfoverride2_old); + write_phy_reg(pi, 0x4b1, rfoverride2val_old); + write_phy_reg(pi, 0x4f9, rfoverride3_old); + write_phy_reg(pi, 0x4fa, rfoverride3val_old); + write_phy_reg(pi, 0x938, rfoverride4_old); + write_phy_reg(pi, 0x939, rfoverride4val_old); + write_phy_reg(pi, 0x43b, afectrlovr_old); + write_phy_reg(pi, 0x43c, afectrlovrval_old); + write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); + write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); - wlc_lcnphy_clear_trsw_override(pi); + wlc_lcnphy_clear_trsw_override(pi); - mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); + mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); - for (i = 0; i < 11; i++) - write_radio_reg(pi, rxiq_cal_rf_reg[i], - values_to_save[i]); + for (i = 0; i < 11; i++) + write_radio_reg(pi, rxiq_cal_rf_reg[i], + values_to_save[i]); - if (tx_gain_override_old) - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); - else - wlc_lcnphy_disable_tx_gain_override(pi); + if (tx_gain_override_old) + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); + else + wlc_lcnphy_disable_tx_gain_override(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); - wlc_lcnphy_rx_gain_override_enable(pi, false); - } + wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); + wlc_lcnphy_rx_gain_override_enable(pi, false); cal_done: kfree(ptr); @@ -1781,6 +1829,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel) write_radio_reg(pi, RADIO_2064_REG038, 3); write_radio_reg(pi, RADIO_2064_REG091, 7); } + + if (!(pi->sh->boardflags & BFL_FEM)) { + u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc, + 0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0}; + + write_radio_reg(pi, RADIO_2064_REG02A, 0xf); + write_radio_reg(pi, RADIO_2064_REG091, 0x3); + write_radio_reg(pi, RADIO_2064_REG038, 0x3); + + write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]); + } } static int @@ -1975,6 +2034,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos) } else { mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); + mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2); + mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4); + mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0); + mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77); + mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1); + mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7); + mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1); + mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4); } } else { mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); @@ -2061,12 +2130,14 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi) (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); + mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0)); } static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) { struct phytbl_info tab; u32 rfseq, ind; + u8 tssi_sel; tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; @@ -2088,7 +2159,13 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); - wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); + if (pi->sh->boardflags & BFL_FEM) { + tssi_sel = 0x1; + wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); + } else { + tssi_sel = 0xe; + wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA); + } mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); @@ -2124,9 +2201,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); + mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel); mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); } else { + mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1); mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); } @@ -2173,6 +2251,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); + mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0); + mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); + wlc_lcnphy_pwrctrl_rssiparams(pi); } @@ -2791,6 +2873,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) read_radio_reg(pi, RADIO_2064_REG007) & 1; u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; + u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi); + idleTssi = read_phy_reg(pi, 0x4ab); suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)); @@ -2808,6 +2892,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); wlc_lcnphy_tssi_setup(pi); + + mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0)); + mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6)); + + wlc_lcnphy_set_bbmult(pi, 0x0); + wlc_phy_do_dummy_tx(pi, true, OFF); idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) >> 0); @@ -2829,6 +2919,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); + wlc_lcnphy_set_bbmult(pi, SAVE_bbmult); wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); wlc_lcnphy_set_tx_gain(pi, &old_gains); wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); @@ -3042,6 +3133,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi) wlc_lcnphy_write_table(pi, &tab); tab.tbl_offset++; } + mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0); + mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0); + mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8); + mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4); + mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2); mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); @@ -3843,7 +3939,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) target_gains.pad_gain = 21; target_gains.dac_gain = 0; wlc_lcnphy_set_tx_gain(pi, &target_gains); - wlc_lcnphy_set_tx_pwr_by_index(pi, 16); if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { @@ -3854,6 +3949,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) lcnphy_recal ? LCNPHY_CAL_RECAL : LCNPHY_CAL_FULL), false); } else { + wlc_lcnphy_set_tx_pwr_by_index(pi, 16); wlc_lcnphy_tx_iqlo_soft_cal_full(pi); } @@ -4278,17 +4374,22 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi, if (CHSPEC_IS5G(pi->radio_chanspec)) pa_gain = 0x70; else - pa_gain = 0x70; + pa_gain = 0x60; if (pi->sh->boardflags & BFL_FEM) pa_gain = 0x10; + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; tab.tbl_len = 1; tab.tbl_ptr = &val; for (j = 0; j < 128; j++) { - gm_gain = gain_table[j].gm; + if (pi->sh->boardflags & BFL_FEM) + gm_gain = gain_table[j].gm; + else + gm_gain = 15; + val = (((u32) pa_gain << 24) | (gain_table[j].pad << 16) | (gain_table[j].pga << 8) | gm_gain); @@ -4499,7 +4600,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi) write_phy_reg(pi, 0x4ea, 0x4688); - mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); + if (pi->sh->boardflags & BFL_FEM) + mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); + else + mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0); mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); @@ -4510,6 +4614,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi) wlc_lcnphy_rcal(pi); wlc_lcnphy_rc_cal(pi); + + if (!(pi->sh->boardflags & BFL_FEM)) { + write_radio_reg(pi, RADIO_2064_REG032, 0x6f); + write_radio_reg(pi, RADIO_2064_REG033, 0x19); + write_radio_reg(pi, RADIO_2064_REG039, 0xe); + } + } static void wlc_lcnphy_radio_init(struct brcms_phy *pi) @@ -4539,22 +4650,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) wlc_lcnphy_write_table(pi, &tab); } - tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; - tab.tbl_width = 16; - tab.tbl_ptr = &val; - tab.tbl_len = 1; - - val = 114; - tab.tbl_offset = 0; - wlc_lcnphy_write_table(pi, &tab); + if (!(pi->sh->boardflags & BFL_FEM)) { + tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; + tab.tbl_width = 16; + tab.tbl_ptr = &val; + tab.tbl_len = 1; - val = 130; - tab.tbl_offset = 1; - wlc_lcnphy_write_table(pi, &tab); + val = 150; + tab.tbl_offset = 0; + wlc_lcnphy_write_table(pi, &tab); - val = 6; - tab.tbl_offset = 8; - wlc_lcnphy_write_table(pi, &tab); + val = 220; + tab.tbl_offset = 1; + wlc_lcnphy_write_table(pi, &tab); + } if (CHSPEC_IS2G(pi->radio_chanspec)) { if (pi->sh->boardflags & BFL_FEM) @@ -4946,6 +5055,7 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec) wlc_lcnphy_load_tx_iir_filter(pi, true, 3); mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3); + wlc_lcnphy_tssi_setup(pi); } void wlc_phy_detach_lcnphy(struct brcms_phy *pi) @@ -4984,8 +5094,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) return false; - if ((pi->sh->boardflags & BFL_FEM) && - (LCNREV_IS(pi->pubpi.phy_rev, 1))) { + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { if (pi_lcn->lcnphy_tempsense_option == 3) { pi->hwpwrctrl = true; pi->hwpwrctrl_capable = true; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c index 622c01ca72c5..b7e95acc2084 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c @@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = { }; static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { - 0x000a, 0x0009, - 0x0006, - 0x0005, 0x000a, - 0x0009, - 0x0006, 0x0005, - 0x000a, - 0x0009, 0x0006, - 0x0005, - 0x000a, 0x0009, - 0x0006, - 0x0005, 0x000a, - 0x0009, - 0x0006, 0x0005, - 0x000a, - 0x0009, 0x0006, - 0x0005, - 0x000a, 0x0009, - 0x0006, - 0x0005, 0x000a, - 0x0009, - 0x0006, 0x0005, - 0x000a, - 0x0009, 0x0006, - 0x0005, - 0x000a, 0x0009, - 0x0006, - 0x0005, 0x000a, - 0x0009, - 0x0006, 0x0005, - 0x000a, - 0x0009, 0x0006, - 0x0005, + 0x0009, 0x000a, + 0x0005, + 0x0006, 0x0009, + 0x000a, + 0x0005, 0x0006, + 0x0009, + 0x000a, 0x0005, + 0x0006, + 0x0009, 0x000a, + 0x0005, + 0x0006, 0x0009, + 0x000a, + 0x0005, 0x0006, + 0x0009, + 0x000a, 0x0005, + 0x0006, + 0x0009, 0x000a, + 0x0005, + 0x0006, 0x0009, + 0x000a, + 0x0005, 0x0006, + 0x0009, + 0x000a, 0x0005, + 0x0006, + 0x0009, 0x000a, + 0x0005, + 0x0006, 0x0009, + 0x000a, + 0x0005, 0x0006, + 0x0009, + 0x000a, 0x0005, + 0x0006, }; static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { diff --git a/trunk/drivers/net/wireless/hostap/hostap_cs.c b/trunk/drivers/net/wireless/hostap/hostap_cs.c index 56cd01ca8ad0..89e9d3a78c3c 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_cs.c +++ b/trunk/drivers/net/wireless/hostap/hostap_cs.c @@ -709,4 +709,17 @@ static struct pcmcia_driver hostap_driver = { .suspend = hostap_cs_suspend, .resume = hostap_cs_resume, }; -module_pcmcia_driver(hostap_driver); + +static int __init init_prism2_pccard(void) +{ + return pcmcia_register_driver(&hostap_driver); +} + +static void __exit exit_prism2_pccard(void) +{ + pcmcia_unregister_driver(&hostap_driver); +} + + +module_init(init_prism2_pccard); +module_exit(exit_prism2_pccard); diff --git a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c index c353b5f19c8c..3630a41df50d 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c @@ -475,7 +475,6 @@ il3945_tx_skb(struct il_priv *il, dma_addr_t txcmd_phys; int txq_id = skb_get_queue_mapping(skb); u16 len, idx, hdr_len; - u16 firstlen, secondlen; u8 id; u8 unicast; u8 sta_id; @@ -590,22 +589,21 @@ il3945_tx_skb(struct il_priv *il, len = sizeof(struct il3945_tx_cmd) + sizeof(struct il_cmd_header) + hdr_len; - firstlen = (len + 3) & ~3; + len = (len + 3) & ~3; /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ txcmd_phys = - pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen, - PCI_DMA_TODEVICE); + pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE); if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys))) goto drop_unlock; /* Set up TFD's 2nd entry to point directly to remainder of skb, * if any (802.11 null frames have no payload). */ - secondlen = skb->len - hdr_len; - if (secondlen > 0) { + len = skb->len - hdr_len; + if (len) { phys_addr = - pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen, + pci_map_single(il->pci_dev, skb->data + hdr_len, len, PCI_DMA_TODEVICE); if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) goto drop_unlock; @@ -613,12 +611,12 @@ il3945_tx_skb(struct il_priv *il, /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ - il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0); + il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); dma_unmap_addr_set(out_meta, mapping, txcmd_phys); - dma_unmap_len_set(out_meta, len, firstlen); - if (secondlen > 0) - il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, 0, - U32_PAD(secondlen)); + dma_unmap_len_set(out_meta, len, len); + if (len) + il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, + U32_PAD(len)); if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-rs.c b/trunk/drivers/net/wireless/iwlegacy/4965-rs.c index 6c7493c2d698..e8324b5e5bfe 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-rs.c @@ -2152,7 +2152,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, int rate_idx; int i; u32 rate; - u8 use_green; + u8 use_green = il4965_rs_use_green(il, sta); u8 active_tbl = 0; u8 valid_tx_ant; struct il_station_priv *sta_priv; @@ -2160,7 +2160,6 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, if (!sta || !lq_sta) return; - use_green = il4965_rs_use_green(il, sta); sta_priv = (void *)sta->drv_priv; i = lq_sta->last_txrate_idx; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c b/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c index 44ca0e57f9f7..86ea5f4c3939 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -1261,15 +1261,6 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } - /* - * This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag - * in iwl_down but cancel the workers only later. - */ - if (!priv->ucode_loaded) { - IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id); - return -EIO; - } - /* * Synchronous commands from this op-mode must hold * the mutex, this ensures we don't try to send two diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c index a82b6b39d4ff..23be948cf162 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -1419,14 +1419,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (changes & BSS_CHANGED_IDLE && bss_conf->idle) { - /* - * If we go idle, then clearly no "passive-no-rx" - * workaround is needed any more, this is a reset. - */ - iwlagn_lift_passive_no_rx(priv); - } - if (unlikely(!iwl_is_ready(priv))) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); mutex_unlock(&priv->mutex); @@ -1458,6 +1450,16 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, priv->timestamp = bss_conf->sync_tsf; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { + /* + * If we disassociate while there are pending + * frames, just wake up the queues and let the + * frames "escape" ... This shouldn't really + * be happening to start with, but we should + * not get stuck in this case either since it + * can happen if userspace gets confused. + */ + iwlagn_lift_passive_no_rx(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; if (ctx->ctxid == IWL_RXON_CTX_BSS) diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/sta.c b/trunk/drivers/net/wireless/iwlwifi/dvm/sta.c index b775769f8322..94ef33838bc6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/sta.c @@ -151,7 +151,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); if (!(flags & CMD_ASYNC)) { - cmd.flags |= CMD_WANT_SKB; + cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD; might_sleep(); } diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c index d1a670d7b10c..6aec2df3bb27 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -1192,7 +1192,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, memset(&info->status, 0, sizeof(info->status)); if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && - ctx->vif && + iwl_is_associated_ctx(ctx) && ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) { /* block and stop all queues */ priv->passive_no_rx = true; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c index 1a4ac9236a44..736fe9bb140e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -367,8 +367,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return -EIO; } - priv->ucode_loaded = true; - if (ucode_type != IWL_UCODE_WOWLAN) { /* delay a bit to give rfkill time to run */ msleep(5); @@ -382,6 +380,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return ret; } + priv->ucode_loaded = true; + return 0; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/trunk/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 81aa91fab5aa..9a0f45ec9e01 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -349,23 +349,25 @@ TRACE_EVENT(iwlwifi_dev_rx_data, TRACE_EVENT(iwlwifi_dev_hcmd, TP_PROTO(const struct device *dev, struct iwl_host_cmd *cmd, u16 total_size, - struct iwl_cmd_header *hdr), - TP_ARGS(dev, cmd, total_size, hdr), + const void *hdr, size_t hdr_len), + TP_ARGS(dev, cmd, total_size, hdr, hdr_len), TP_STRUCT__entry( DEV_ENTRY __dynamic_array(u8, hcmd, total_size) __field(u32, flags) ), TP_fast_assign( - int i, offset = sizeof(*hdr); + int i, offset = hdr_len; DEV_ASSIGN; __entry->flags = cmd->flags; - memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr)); + memcpy(__get_dynamic_array(hcmd), hdr, hdr_len); - for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { if (!cmd->len[i]) continue; + if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) + continue; memcpy((u8 *)__get_dynamic_array(hcmd) + offset, cmd->data[i], cmd->len[i]); offset += cmd->len[i]; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c index fbfd2d137117..6f228bb2b844 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1102,6 +1102,7 @@ void iwl_drv_stop(struct iwl_drv *drv) /* shared module parameters */ struct iwl_mod_params iwlwifi_mod_params = { + .amsdu_size_8K = 1, .restart_fw = 1, .plcp_check = true, .bt_coex_active = true, @@ -1206,7 +1207,7 @@ MODULE_PARM_DESC(11n_disable, "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, int, S_IRUGO); -MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); +MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-modparams.h b/trunk/drivers/net/wireless/iwlwifi/iwl-modparams.h index 2c2a729092f5..e5e3a79eae2f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-modparams.h @@ -91,7 +91,7 @@ enum iwl_power_level { * @sw_crypto: using hardware encryption, default = 0 * @disable_11n: disable 11n capabilities, default = 0, * use IWL_DISABLE_HT_* constants - * @amsdu_size_8K: enable 8K amsdu size, default = 0 + * @amsdu_size_8K: enable 8K amsdu size, default = 1 * @restart_fw: restart firmware, default = 1 * @plcp_check: enable plcp health check, default = true * @wd_disable: enable stuck queue check, default = 0 diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 3392011a8768..14fc8d39fc28 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -136,6 +136,12 @@ struct iwl_calib_res_notif_phy_db { u8 data[]; } __packed; +#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587) +static inline void iwl_phy_db_test_pic(__le32 pic) +{ + WARN_ON(IWL_PHY_DB_STATIC_PIC != pic); +} + struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) { struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), @@ -254,6 +260,11 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; } + /* Test PIC */ + if (type != IWL_PHY_DB_CFG) + iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) + + (size / sizeof(__le32)) - 1)); + IWL_DEBUG_INFO(phy_db->trans, "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", __func__, __LINE__, type, size); @@ -361,6 +372,11 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, *size = entry->size; } + /* Test PIC */ + if (type != IWL_PHY_DB_CFG) + iwl_phy_db_test_pic(*(((__le32 *)*data) + + (*size / sizeof(__le32)) - 1)); + IWL_DEBUG_INFO(phy_db->trans, "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", __func__, __LINE__, type, *size); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h index 0cac2b7af78b..8c7bec6b9a0b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -186,13 +186,19 @@ struct iwl_rx_packet { * @CMD_ASYNC: Return right away and don't want for the response * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the * response. The caller needs to call iwl_free_resp when done. + * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the + * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be + * copied. The pointer passed to the response handler is in the transport + * ownership and don't need to be freed by the op_mode. This also means + * that the pointer is invalidated after the op_mode's handler returns. * @CMD_ON_DEMAND: This command is sent by the test mode pipe. */ enum CMD_MODE { CMD_SYNC = 0, CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), - CMD_ON_DEMAND = BIT(2), + CMD_WANT_HCMD = BIT(2), + CMD_ON_DEMAND = BIT(3), }; #define DEF_CMD_PAYLOAD_SIZE 320 @@ -211,11 +217,7 @@ struct iwl_device_cmd { #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) -/* - * number of transfer buffers (fragments) per transmit frame descriptor; - * this is just the driver's idea, the hardware supports 20 - */ -#define IWL_MAX_CMD_TBS_PER_TFD 2 +#define IWL_MAX_CMD_TFDS 2 /** * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command @@ -252,15 +254,15 @@ enum iwl_hcmd_dataflag { * @id: id of the host command */ struct iwl_host_cmd { - const void *data[IWL_MAX_CMD_TBS_PER_TFD]; + const void *data[IWL_MAX_CMD_TFDS]; struct iwl_rx_packet *resp_pkt; unsigned long _rx_page_addr; u32 _rx_page_order; int handler_status; u32 flags; - u16 len[IWL_MAX_CMD_TBS_PER_TFD]; - u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD]; + u16 len[IWL_MAX_CMD_TFDS]; + u8 dataflags[IWL_MAX_CMD_TFDS]; u8 id; }; diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/d3.c b/trunk/drivers/net/wireless/iwlwifi/mvm/d3.c index 994c8c263dc0..c64d864799cd 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -61,7 +61,6 @@ * *****************************************************************************/ -#include #include #include #include "iwl-modparams.h" @@ -193,11 +192,6 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, sizeof(wkc), &wkc); data->error = ret != 0; - mvm->ptk_ivlen = key->iv_len; - mvm->ptk_icvlen = key->icv_len; - mvm->gtk_ivlen = key->iv_len; - mvm->gtk_icvlen = key->icv_len; - /* don't upload key again */ goto out_unlock; } @@ -310,13 +304,9 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, */ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { key->hw_key_idx = 0; - mvm->ptk_ivlen = key->iv_len; - mvm->ptk_icvlen = key->icv_len; } else { data->gtk_key_idx++; key->hw_key_idx = data->gtk_key_idx; - mvm->gtk_ivlen = key->iv_len; - mvm->gtk_icvlen = key->icv_len; } ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); @@ -659,11 +649,6 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* We reprogram keys and shouldn't allocate new key indices */ memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); - mvm->ptk_ivlen = 0; - mvm->ptk_icvlen = 0; - mvm->ptk_ivlen = 0; - mvm->ptk_icvlen = 0; - /* * The D3 firmware still hardcodes the AP station ID for the * BSS we're associated with as 0. As a result, we have to move @@ -798,6 +783,7 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, struct iwl_wowlan_status *status; u32 reasons; int ret, len; + bool pkt8023 = false; struct sk_buff *pkt = NULL; iwl_trans_read_mem_bytes(mvm->trans, base, @@ -838,8 +824,7 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, status = (void *)cmd.resp_pkt->data; if (len - sizeof(struct iwl_cmd_header) != - sizeof(*status) + - ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) { + sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); goto out; } @@ -851,96 +836,61 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, goto report; } - if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) + if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { wakeup.magic_pkt = true; + pkt8023 = true; + } - if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) + if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { wakeup.pattern_idx = le16_to_cpu(status->pattern_number); + pkt8023 = true; + } if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) wakeup.disconnect = true; - if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) + if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { wakeup.gtk_rekey_failure = true; + pkt8023 = true; + } - if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) + if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { wakeup.rfkill_release = true; + pkt8023 = true; + } - if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) + if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { wakeup.eap_identity_req = true; + pkt8023 = true; + } - if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) + if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { wakeup.four_way_handshake = true; + pkt8023 = true; + } if (status->wake_packet_bufsize) { - int pktsize = le32_to_cpu(status->wake_packet_bufsize); - int pktlen = le32_to_cpu(status->wake_packet_length); - const u8 *pktdata = status->wake_packet; - struct ieee80211_hdr *hdr = (void *)pktdata; - int truncated = pktlen - pktsize; - - /* this would be a firmware bug */ - if (WARN_ON_ONCE(truncated < 0)) - truncated = 0; - - if (ieee80211_is_data(hdr->frame_control)) { - int hdrlen = ieee80211_hdrlen(hdr->frame_control); - int ivlen = 0, icvlen = 4; /* also FCS */ + u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); + u32 pktlen = le32_to_cpu(status->wake_packet_length); + if (pkt8023) { pkt = alloc_skb(pktsize, GFP_KERNEL); if (!pkt) goto report; - - memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen); - pktdata += hdrlen; - pktsize -= hdrlen; - - if (ieee80211_has_protected(hdr->frame_control)) { - if (is_multicast_ether_addr(hdr->addr1)) { - ivlen = mvm->gtk_ivlen; - icvlen += mvm->gtk_icvlen; - } else { - ivlen = mvm->ptk_ivlen; - icvlen += mvm->ptk_icvlen; - } - } - - /* if truncated, FCS/ICV is (partially) gone */ - if (truncated >= icvlen) { - icvlen = 0; - truncated -= icvlen; - } else { - icvlen -= truncated; - truncated = 0; - } - - pktsize -= ivlen + icvlen; - pktdata += ivlen; - - memcpy(skb_put(pkt, pktsize), pktdata, pktsize); - + memcpy(skb_put(pkt, pktsize), status->wake_packet, + pktsize); if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) goto report; wakeup.packet = pkt->data; wakeup.packet_present_len = pkt->len; - wakeup.packet_len = pkt->len - truncated; + wakeup.packet_len = pkt->len - (pktlen - pktsize); wakeup.packet_80211 = false; } else { - int fcslen = 4; - - if (truncated >= 4) { - truncated -= 4; - fcslen = 0; - } else { - fcslen -= truncated; - truncated = 0; - } - pktsize -= fcslen; wakeup.packet = status->wake_packet; wakeup.packet_present_len = pktsize; - wakeup.packet_len = pktlen - truncated; + wakeup.packet_len = pktlen; wakeup.packet_80211 = true; } } diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/trunk/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 2adb61f103f4..23eebda848b0 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -762,20 +762,18 @@ struct iwl_phy_context_cmd { #define IWL_RX_INFO_PHY_CNT 8 #define IWL_RX_INFO_AGC_IDX 1 #define IWL_RX_INFO_RSSI_AB_IDX 2 -#define IWL_OFDM_AGC_A_MSK 0x0000007f -#define IWL_OFDM_AGC_A_POS 0 -#define IWL_OFDM_AGC_B_MSK 0x00003f80 -#define IWL_OFDM_AGC_B_POS 7 -#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000 -#define IWL_OFDM_AGC_CODE_POS 20 +#define IWL_RX_INFO_RSSI_C_IDX 3 +#define IWL_OFDM_AGC_DB_MSK 0xfe00 +#define IWL_OFDM_AGC_DB_POS 9 #define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff -#define IWL_OFDM_RSSI_A_POS 0 #define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 -#define IWL_OFDM_RSSI_ALLBAND_A_POS 8 +#define IWL_OFDM_RSSI_A_POS 0 #define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 -#define IWL_OFDM_RSSI_B_POS 16 #define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 -#define IWL_OFDM_RSSI_ALLBAND_B_POS 24 +#define IWL_OFDM_RSSI_B_POS 16 +#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff +#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00 +#define IWL_OFDM_RSSI_C_POS 0 /** * struct iwl_rx_phy_info - phy info diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/fw.c b/trunk/drivers/net/wireless/iwlwifi/mvm/fw.c index 500f818dba04..d3d959db03a9 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -79,8 +79,17 @@ #define UCODE_VALID_OK cpu_to_le32(0x1) /* Default calibration values for WkP - set to INIT image w/o running */ +static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f, + 0x00, 0x18, 0x00 }; +static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f }; +static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 }; +static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00, + 0x00 }; +static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 }; static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 }; static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 }; +static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 }; struct iwl_calib_default_data { u16 size; @@ -90,7 +99,12 @@ struct iwl_calib_default_data { #define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf} static const struct iwl_calib_default_data wkp_calib_default_data[12] = { + [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc), + [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter), + [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo), + [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq), [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew), + [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq), [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew), }; @@ -227,6 +241,20 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, return 0; } +#define IWL_HW_REV_ID_RAINBOW 0x2 +#define IWL_PROJ_TYPE_LHP 0x5 + +static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm) +{ + struct iwl_nvm_data *data = mvm->nvm_data; + /* Temp calls to static definitions, will be changed to CSR calls */ + u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW; + u8 project_type = IWL_PROJ_TYPE_LHP; + + return data->radio_cfg_dash | (data->radio_cfg_step << 2) | + (hw_rev_id << 4) | ((project_type & 0x7f) << 6) | + (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20); +} static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) { @@ -234,7 +262,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) enum iwl_ucode_type ucode_type = mvm->cur_ucode; /* Set parameters */ - phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config); + phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm)); phy_cfg_cmd.calib_control.event_trigger = mvm->fw->default_calib[ucode_type].event_trigger; phy_cfg_cmd.calib_control.flow_trigger = @@ -247,6 +275,103 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) sizeof(phy_cfg_cmd), &phy_cfg_cmd); } +/* Starting with the new PHY DB implementation - New calibs are enabled */ +/* Value - 0x405e7 */ +#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\ + IWL_CALIB_CFG_TEMPERATURE_IDX |\ + IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ + IWL_CALIB_CFG_DC_IDX |\ + IWL_CALIB_CFG_BB_FILTER_IDX |\ + IWL_CALIB_CFG_LO_LEAKAGE_IDX |\ + IWL_CALIB_CFG_TX_IQ_IDX |\ + IWL_CALIB_CFG_RX_IQ_IDX |\ + IWL_CALIB_CFG_AGC_IDX) + +#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0 + +/* Value 0x41567 */ +#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\ + IWL_CALIB_CFG_TEMPERATURE_IDX |\ + IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ + IWL_CALIB_CFG_BB_FILTER_IDX |\ + IWL_CALIB_CFG_DC_IDX |\ + IWL_CALIB_CFG_TX_IQ_IDX |\ + IWL_CALIB_CFG_RX_IQ_IDX |\ + IWL_CALIB_CFG_SENSITIVITY_IDX |\ + IWL_CALIB_CFG_AGC_IDX) + +#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\ + IWL_CALIB_CFG_TEMPERATURE_IDX |\ + IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ + IWL_CALIB_CFG_TX_PWR_IDX |\ + IWL_CALIB_CFG_DC_IDX |\ + IWL_CALIB_CFG_TX_IQ_IDX |\ + IWL_CALIB_CFG_SENSITIVITY_IDX) + +/* + * Sets the calibrations trigger values that will be sent to the FW for runtime + * and init calibrations. + * The ones given in the FW TLV are not correct. + */ +static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm) +{ + struct iwl_tlv_calib_ctrl default_calib; + + /* + * WkP FW TLV calib bits are wrong, overwrite them. + * This defines the dynamic calibrations which are implemented in the + * uCode both for init(flow) calculation and event driven calibs. + */ + + /* Init Image */ + default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT); + default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT); + + if (default_calib.event_trigger != + mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger) + IWL_ERR(mvm, + "Updating the event calib for INIT image: 0x%x -> 0x%x\n", + mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger, + default_calib.event_trigger); + if (default_calib.flow_trigger != + mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger) + IWL_ERR(mvm, + "Updating the flow calib for INIT image: 0x%x -> 0x%x\n", + mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger, + default_calib.flow_trigger); + + memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT], + &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); + IWL_ERR(mvm, + "Setting uCode init calibrations event 0x%x, trigger 0x%x\n", + default_calib.event_trigger, + default_calib.flow_trigger); + + /* Run time image */ + default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN); + default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN); + + if (default_calib.event_trigger != + mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger) + IWL_ERR(mvm, + "Updating the event calib for RT image: 0x%x -> 0x%x\n", + mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger, + default_calib.event_trigger); + if (default_calib.flow_trigger != + mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger) + IWL_ERR(mvm, + "Updating the flow calib for RT image: 0x%x -> 0x%x\n", + mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger, + default_calib.flow_trigger); + + memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR], + &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); + IWL_ERR(mvm, + "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n", + default_calib.event_trigger, + default_calib.flow_trigger); +} + static int iwl_set_default_calibrations(struct iwl_mvm *mvm) { u8 cmd_raw[16]; /* holds the variable size commands */ @@ -321,10 +446,8 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); WARN_ON(ret); - /* Send TX valid antennas before triggering calibrations */ - ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); - if (ret) - goto error; + /* Override the calibrations from TLV and the const of fw */ + iwl_set_default_calib_trigger(mvm); /* WkP doesn't have all calibrations, need to set default values */ if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/trunk/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 7e169b085afe..e8264e11b12d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -557,9 +557,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, return ret; } -static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) +static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); u32 tfd_msk = 0, ac; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) @@ -592,21 +594,12 @@ static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, */ flush_work(&mvm->sta_drained_wk); } -} - -static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - - iwl_mvm_prepare_mac_removal(mvm, vif); mutex_lock(&mvm->mutex); /* * For AP/GO interface, the tear down of the resources allocated to the - * interface is be handled as part of the stop_ap flow. + * interface should be handled as part of the bss_info_changed flow. */ if (vif->type == NL80211_IFTYPE_AP) { iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); @@ -770,8 +763,6 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - iwl_mvm_prepare_mac_removal(mvm, vif); - mutex_lock(&mvm->mutex); mvmvif->ap_active = false; diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/mvm.h b/trunk/drivers/net/wireless/iwlwifi/mvm/mvm.h index bdae700c769e..4e339ccfa800 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -80,8 +80,7 @@ #define IWL_INVALID_MAC80211_QUEUE 0xff #define IWL_MVM_MAX_ADDRESSES 2 -/* RSSI offset for WkP */ -#define IWL_RSSI_OFFSET 50 +#define IWL_RSSI_OFFSET 44 enum iwl_mvm_tx_fifo { IWL_MVM_TX_FIFO_BK = 0, @@ -328,10 +327,6 @@ struct iwl_mvm { struct led_classdev led; struct ieee80211_vif *p2p_device_vif; - -#ifdef CONFIG_PM_SLEEP - int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; -#endif }; /* Extract MVM priv from op_mode and _hw */ diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/ops.c b/trunk/drivers/net/wireless/iwlwifi/mvm/ops.c index d0f9c1e0475e..aa59adf87db3 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -624,8 +624,12 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) ieee80211_free_txskb(mvm->hw, skb); } -static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) +static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) { + struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); + + iwl_mvm_dump_nic_error_log(mvm); + iwl_abort_notification_waits(&mvm->notif_wait); /* @@ -659,21 +663,9 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) } } -static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) -{ - struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - - iwl_mvm_dump_nic_error_log(mvm); - - iwl_mvm_nic_restart(mvm); -} - static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) { - struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - WARN_ON(1); - iwl_mvm_nic_restart(mvm); } static const struct iwl_op_mode_ops iwl_mvm_ops = { diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/rx.c b/trunk/drivers/net/wireless/iwlwifi/mvm/rx.c index b0b190d0ec23..3f40ab05bbd8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -131,42 +131,33 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, struct iwl_rx_phy_info *phy_info) { - int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm; - int rssi_all_band_a, rssi_all_band_b; - u32 agc_a, agc_b, max_agc; + u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db; u32 val; - /* Find max rssi among 2 possible receivers. + /* Find max rssi among 3 possible receivers. * These values are measured by the Digital Signal Processor (DSP). * They should stay fairly constant even as the signal strength varies, * if the radio's Automatic Gain Control (AGC) is working right. * AGC value (see below) will provide the "interesting" info. */ - val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); - agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS; - agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS; - max_agc = max_t(u32, agc_a, agc_b); - val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]); rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS; rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS; - rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >> - IWL_OFDM_RSSI_ALLBAND_A_POS; - rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >> - IWL_OFDM_RSSI_ALLBAND_B_POS; + val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]); + rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS; - /* - * dBm = rssi dB - agc dB - constant. - * Higher AGC (higher radio gain) means lower signal. - */ - rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a; - rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b; - max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm); + val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); + agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS; + + max_rssi = max_t(u32, rssi_a, rssi_b); + max_rssi = max_t(u32, max_rssi, rssi_c); - IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n", - rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b); + IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", + rssi_a, rssi_b, rssi_c, max_rssi, agc_db); - return max_rssi_dbm; + /* dBm = max_rssi dB - agc dB - constant. + * Higher AGC (higher radio gain) means lower signal. */ + return max_rssi - agc_db - IWL_RSSI_OFFSET; } /* diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/sta.c b/trunk/drivers/net/wireless/iwlwifi/mvm/sta.c index 274f44e2ef60..861a7f9f8e7f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -770,16 +770,6 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u16 txq_id; int err; - - /* - * If mac80211 is cleaning its state, then say that we finished since - * our state has been cleared anyway. - */ - if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - return 0; - } - spin_lock_bh(&mvmsta->lock); txq_id = tid_data->txq_id; diff --git a/trunk/drivers/net/wireless/iwlwifi/mvm/tx.c b/trunk/drivers/net/wireless/iwlwifi/mvm/tx.c index 6645efe5c03e..6b67ce3f679c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -607,8 +607,12 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, /* Single frame failure in an AMPDU queue => send BAR */ if (txq_id >= IWL_FIRST_AMPDU_QUEUE && - !(info->flags & IEEE80211_TX_STAT_ACK)) + !(info->flags & IEEE80211_TX_STAT_ACK)) { + /* there must be only one skb in the skb_list */ + WARN_ON_ONCE(skb_freed > 1 || + !skb_queue_empty(&skbs)); info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + } /* W/A FW bug: seq_ctl is wrong when the queue is flushed */ if (status == TX_STATUS_FAIL_FIFO_FLUSHED) { diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h index 148843e7f34f..aa2a39a637dd 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -137,6 +137,10 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd) struct iwl_cmd_meta { /* only for SYNC commands, iff the reply skb is wanted */ struct iwl_host_cmd *source; + + DEFINE_DMA_UNMAP_ADDR(mapping); + DEFINE_DMA_UNMAP_LEN(len); + u32 flags; }; @@ -178,39 +182,19 @@ struct iwl_queue { #define TFD_TX_CMD_SLOTS 256 #define TFD_CMD_SLOTS 32 -/* - * The FH will write back to the first TB only, so we need - * to copy some data into the buffer regardless of whether - * it should be mapped or not. This indicates how big the - * first TB must be to include the scratch buffer. Since - * the scratch is 4 bytes at offset 12, it's 16 now. If we - * make it bigger then allocations will be bigger and copy - * slower, so that's probably not useful. - */ -#define IWL_HCMD_SCRATCHBUF_SIZE 16 - struct iwl_pcie_txq_entry { struct iwl_device_cmd *cmd; + struct iwl_device_cmd *copy_cmd; struct sk_buff *skb; /* buffer to free after command completes */ const void *free_buf; struct iwl_cmd_meta meta; }; -struct iwl_pcie_txq_scratch_buf { - struct iwl_cmd_header hdr; - u8 buf[8]; - __le32 scratch; -}; - /** * struct iwl_txq - Tx Queue for DMA * @q: generic Rx/Tx queue descriptor * @tfds: transmit frame descriptors (DMA memory) - * @scratchbufs: start of command headers, including scratch buffers, for - * the writeback -- this is DMA memory and an array holding one buffer - * for each command on the queue - * @scratchbufs_dma: DMA address for the scratchbufs start * @entries: transmit entries (driver state) * @lock: queue lock * @stuck_timer: timer that fires if queue gets stuck @@ -224,8 +208,6 @@ struct iwl_pcie_txq_scratch_buf { struct iwl_txq { struct iwl_queue q; struct iwl_tfd *tfds; - struct iwl_pcie_txq_scratch_buf *scratchbufs; - dma_addr_t scratchbufs_dma; struct iwl_pcie_txq_entry *entries; spinlock_t lock; struct timer_list stuck_timer; @@ -234,13 +216,6 @@ struct iwl_txq { u8 active; }; -static inline dma_addr_t -iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) -{ - return txq->scratchbufs_dma + - sizeof(struct iwl_pcie_txq_scratch_buf) * idx; -} - /** * struct iwl_trans_pcie - PCIe transport specific data * @rxq: all the RX queue data diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c index 567e67ad1f61..b0ae06d2456f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -637,14 +637,22 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, index = SEQ_TO_INDEX(sequence); cmd_index = get_cmd_index(&txq->q, index); - if (reclaim) - cmd = txq->entries[cmd_index].cmd; - else + if (reclaim) { + struct iwl_pcie_txq_entry *ent; + ent = &txq->entries[cmd_index]; + cmd = ent->copy_cmd; + WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); + } else { cmd = NULL; + } err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); if (reclaim) { + /* The original command isn't needed any more */ + kfree(txq->entries[cmd_index].copy_cmd); + txq->entries[cmd_index].copy_cmd = NULL; + /* nor is the duplicated part of the command */ kfree(txq->entries[cmd_index].free_buf); txq->entries[cmd_index].free_buf = NULL; } diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c index 12c4f31ca8fb..17bedc50e753 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -475,10 +475,6 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, /* If platform's RF_KILL switch is NOT set to KILL */ hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans_pcie->status); - else - clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); if (hw_rfkill && !run_in_rfkill) return -ERFKILL; @@ -645,7 +641,6 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill; int err; @@ -661,10 +656,6 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_enable_rfkill_int(trans); hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans_pcie->status); - else - clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); return 0; @@ -703,10 +694,6 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, * op_mode. */ hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans_pcie->status); - else - clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); } } diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c index cb5c6792e3a8..8e9e3212fe78 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -191,9 +191,12 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) } for (i = q->read_ptr; i != q->write_ptr; - i = iwl_queue_inc_wrap(i, q->n_bd)) + i = iwl_queue_inc_wrap(i, q->n_bd)) { + struct iwl_tx_cmd *tx_cmd = + (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; IWL_ERR(trans, "scratch %d = 0x%08x\n", i, - le32_to_cpu(txq->scratchbufs[i].scratch)); + get_unaligned_le32(&tx_cmd->scratch)); + } iwl_op_mode_nic_error(trans->op_mode); } @@ -364,8 +367,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd) } static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, - struct iwl_cmd_meta *meta, - struct iwl_tfd *tfd) + struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, + enum dma_data_direction dma_dir) { int i; int num_tbs; @@ -379,12 +382,17 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, return; } - /* first TB is never freed - it's the scratchbuf data */ + /* Unmap tx_cmd */ + if (num_tbs) + dma_unmap_single(trans->dev, + dma_unmap_addr(meta, mapping), + dma_unmap_len(meta, len), + DMA_BIDIRECTIONAL); + /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), - iwl_pcie_tfd_tb_get_len(tfd, i), - DMA_TO_DEVICE); + iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); tfd->num_tbs = 0; } @@ -398,7 +406,8 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ -static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) +static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, + enum dma_data_direction dma_dir) { struct iwl_tfd *tfd_tmp = txq->tfds; @@ -409,7 +418,8 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) lockdep_assert_held(&txq->lock); /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ - iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]); + iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], + dma_dir); /* free SKB */ if (txq->entries) { @@ -469,7 +479,6 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; - size_t scratchbuf_sz; int i; if (WARN_ON(txq->entries || txq->tfds)) @@ -505,25 +514,9 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); goto error; } - - BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs)); - BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) != - sizeof(struct iwl_cmd_header) + - offsetof(struct iwl_tx_cmd, scratch)); - - scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num; - - txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz, - &txq->scratchbufs_dma, - GFP_KERNEL); - if (!txq->scratchbufs) - goto err_free_tfds; - txq->q.id = txq_id; return 0; -err_free_tfds: - dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr); error: if (txq->entries && txq_id == trans_pcie->cmd_queue) for (i = 0; i < slots_num; i++) @@ -572,13 +565,22 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = &trans_pcie->txq[txq_id]; struct iwl_queue *q = &txq->q; + enum dma_data_direction dma_dir; if (!q->n_bd) return; + /* In the command queue, all the TBs are mapped as BIDI + * so unmap them as such. + */ + if (txq_id == trans_pcie->cmd_queue) + dma_dir = DMA_BIDIRECTIONAL; + else + dma_dir = DMA_TO_DEVICE; + spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { - iwl_pcie_txq_free_tfd(trans, txq); + iwl_pcie_txq_free_tfd(trans, txq, dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } spin_unlock_bh(&txq->lock); @@ -608,6 +610,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) if (txq_id == trans_pcie->cmd_queue) for (i = 0; i < txq->q.n_window; i++) { kfree(txq->entries[i].cmd); + kfree(txq->entries[i].copy_cmd); kfree(txq->entries[i].free_buf); } @@ -616,10 +619,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) dma_free_coherent(dev, sizeof(struct iwl_tfd) * txq->q.n_bd, txq->tfds, txq->q.dma_addr); txq->q.dma_addr = 0; - - dma_free_coherent(dev, - sizeof(*txq->scratchbufs) * txq->q.n_window, - txq->scratchbufs, txq->scratchbufs_dma); } kfree(txq->entries); @@ -963,7 +962,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); - iwl_pcie_txq_free_tfd(trans, txq); + iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); } iwl_pcie_txq_progress(trans_pcie, txq); @@ -1153,37 +1152,20 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, void *dup_buf = NULL; dma_addr_t phys_addr; int idx; - u16 copy_size, cmd_size, scratch_size; + u16 copy_size, cmd_size; bool had_nocopy = false; int i; u32 cmd_pos; - const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; - u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); /* need one for the header if the first is NOCOPY */ - BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1); - - for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { - cmddata[i] = cmd->data[i]; - cmdlen[i] = cmd->len[i]; + BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { if (!cmd->len[i]) continue; - - /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ - if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { - int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; - - if (copy > cmdlen[i]) - copy = cmdlen[i]; - cmdlen[i] -= copy; - cmddata[i] += copy; - copy_size += copy; - } - if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { had_nocopy = true; if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { @@ -1203,7 +1185,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, goto free_dup_buf; } - dup_buf = kmemdup(cmddata[i], cmdlen[i], + dup_buf = kmemdup(cmd->data[i], cmd->len[i], GFP_ATOMIC); if (!dup_buf) return -ENOMEM; @@ -1213,7 +1195,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, idx = -EINVAL; goto free_dup_buf; } - copy_size += cmdlen[i]; + copy_size += cmd->len[i]; } cmd_size += cmd->len[i]; } @@ -1260,30 +1242,30 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, /* and copy the data that needs to be copied */ cmd_pos = offsetof(struct iwl_device_cmd, payload); - copy_size = sizeof(out_cmd->hdr); - for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { - int copy = 0; - + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { if (!cmd->len[i]) continue; + if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | + IWL_HCMD_DFL_DUP)) + break; + memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); + cmd_pos += cmd->len[i]; + } - /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ - if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { - copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; - - if (copy > cmd->len[i]) - copy = cmd->len[i]; - } - - /* copy everything if not nocopy/dup */ - if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | - IWL_HCMD_DFL_DUP))) - copy = cmd->len[i]; + WARN_ON_ONCE(txq->entries[idx].copy_cmd); - if (copy) { - memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy); - cmd_pos += copy; - copy_size += copy; + /* + * since out_cmd will be the source address of the FH, it will write + * the retry count there. So when the user needs to receivce the HCMD + * that corresponds to the response in the response handler, it needs + * to set CMD_WANT_HCMD. + */ + if (cmd->flags & CMD_WANT_HCMD) { + txq->entries[idx].copy_cmd = + kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); + if (unlikely(!txq->entries[idx].copy_cmd)) { + idx = -ENOMEM; + goto out; } } @@ -1293,35 +1275,22 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); - /* start the TFD with the scratchbuf */ - scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE); - memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size); - iwl_pcie_txq_build_tfd(trans, txq, - iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr), - scratch_size, 1); - - /* map first command fragment, if any remains */ - if (copy_size > scratch_size) { - phys_addr = dma_map_single(trans->dev, - ((u8 *)&out_cmd->hdr) + scratch_size, - copy_size - scratch_size, - DMA_TO_DEVICE); - if (dma_mapping_error(trans->dev, phys_addr)) { - iwl_pcie_tfd_unmap(trans, out_meta, - &txq->tfds[q->write_ptr]); - idx = -ENOMEM; - goto out; - } - - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, - copy_size - scratch_size, 0); + phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, + DMA_BIDIRECTIONAL); + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { + idx = -ENOMEM; + goto out; } - /* map the remaining (adjusted) nocopy/dup fragments */ - for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { - const void *data = cmddata[i]; + dma_unmap_addr_set(out_meta, mapping, phys_addr); + dma_unmap_len_set(out_meta, len, copy_size); + + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); + + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + const void *data = cmd->data[i]; - if (!cmdlen[i]) + if (!cmd->len[i]) continue; if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | IWL_HCMD_DFL_DUP))) @@ -1329,15 +1298,16 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) data = dup_buf; phys_addr = dma_map_single(trans->dev, (void *)data, - cmdlen[i], DMA_TO_DEVICE); + cmd->len[i], DMA_BIDIRECTIONAL); if (dma_mapping_error(trans->dev, phys_addr)) { iwl_pcie_tfd_unmap(trans, out_meta, - &txq->tfds[q->write_ptr]); + &txq->tfds[q->write_ptr], + DMA_BIDIRECTIONAL); idx = -ENOMEM; goto out; } - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0); + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); } out_meta->flags = cmd->flags; @@ -1347,7 +1317,8 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, txq->need_update = 1; - trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); + trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, + &out_cmd->hdr, copy_size); /* start timer if queue currently empty */ if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) @@ -1406,7 +1377,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, cmd = txq->entries[cmd_index].cmd; meta = &txq->entries[cmd_index].meta; - iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]); + iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { @@ -1585,9 +1556,10 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_cmd_meta *out_meta; struct iwl_txq *txq; struct iwl_queue *q; - dma_addr_t tb0_phys, tb1_phys, scratch_phys; - void *tb1_addr; - u16 len, tb1_len, tb2_len; + dma_addr_t phys_addr = 0; + dma_addr_t txcmd_phys; + dma_addr_t scratch_phys; + u16 len, firstlen, secondlen; u8 wait_write_ptr = 0; __le16 fc = hdr->frame_control; u8 hdr_len = ieee80211_hdrlen(fc); @@ -1625,80 +1597,85 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | INDEX_TO_SEQ(q->write_ptr))); - tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr); - scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) + - offsetof(struct iwl_tx_cmd, scratch); - - tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); - tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); - /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_meta = &txq->entries[q->write_ptr].meta; /* - * The second TB (tb1) points to the remainder of the TX command - * and the 802.11 header - dword aligned size - * (This calculation modifies the TX command, so do it before the - * setup of the first TB) + * Use the first empty entry in this queue's command buffer array + * to contain the Tx command and MAC header concatenated together + * (payload data will be in another buffer). + * Size of this varies, due to varying MAC header length. + * If end is not dword aligned, we'll have 2 extra bytes at the end + * of the MAC header (device reads on dword boundaries). + * We'll tell device about this padding later. */ - len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) + - hdr_len - IWL_HCMD_SCRATCHBUF_SIZE; - tb1_len = (len + 3) & ~3; + len = sizeof(struct iwl_tx_cmd) + + sizeof(struct iwl_cmd_header) + hdr_len; + firstlen = (len + 3) & ~3; /* Tell NIC about any 2-byte padding after MAC header */ - if (tb1_len != len) + if (firstlen != len) tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; - /* The first TB points to the scratchbuf data - min_copy bytes */ - memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr, - IWL_HCMD_SCRATCHBUF_SIZE); - iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, - IWL_HCMD_SCRATCHBUF_SIZE, 1); - - /* there must be data left over for TB1 or this code must be changed */ - BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE); - - /* map the data for TB1 */ - tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE; - tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(trans->dev, tb1_phys))) + /* Physical address of this Tx command's header (not MAC header!), + * within command buffer array. */ + txcmd_phys = dma_map_single(trans->dev, + &dev_cmd->hdr, firstlen, + DMA_BIDIRECTIONAL); + if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) goto out_err; - iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0); + dma_unmap_addr_set(out_meta, mapping, txcmd_phys); + dma_unmap_len_set(out_meta, len, firstlen); - /* - * Set up TFD's third entry to point directly to remainder - * of skb, if any (802.11 null frames have no payload). - */ - tb2_len = skb->len - hdr_len; - if (tb2_len > 0) { - dma_addr_t tb2_phys = dma_map_single(trans->dev, - skb->data + hdr_len, - tb2_len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) { - iwl_pcie_tfd_unmap(trans, out_meta, - &txq->tfds[q->write_ptr]); + if (!ieee80211_has_morefrags(fc)) { + txq->need_update = 1; + } else { + wait_write_ptr = 1; + txq->need_update = 0; + } + + /* Set up TFD's 2nd entry to point directly to remainder of skb, + * if any (802.11 null frames have no payload). */ + secondlen = skb->len - hdr_len; + if (secondlen > 0) { + phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, + secondlen, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { + dma_unmap_single(trans->dev, + dma_unmap_addr(out_meta, mapping), + dma_unmap_len(out_meta, len), + DMA_BIDIRECTIONAL); goto out_err; } - iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0); } + /* Attach buffers to TFD */ + iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1); + if (secondlen > 0) + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0); + + scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + + offsetof(struct iwl_tx_cmd, scratch); + + /* take back ownership of DMA buffer to enable update */ + dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, + DMA_BIDIRECTIONAL); + tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); + tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); + /* Set up entry for this TFD in Tx byte-count array */ iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); + dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, + DMA_BIDIRECTIONAL); + trace_iwlwifi_dev_tx(trans->dev, skb, &txq->tfds[txq->q.write_ptr], sizeof(struct iwl_tfd), - &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len, - skb->data + hdr_len, tb2_len); + &dev_cmd->hdr, firstlen, + skb->data + hdr_len, secondlen); trace_iwlwifi_dev_tx_data(trans->dev, skb, - skb->data + hdr_len, tb2_len); - - if (!ieee80211_has_morefrags(fc)) { - txq->need_update = 1; - } else { - wait_write_ptr = 1; - txq->need_update = 0; - } + skb->data + hdr_len, secondlen); /* start timer if queue currently empty */ if (txq->need_update && q->read_ptr == q->write_ptr && diff --git a/trunk/drivers/net/wireless/libertas/if_cs.c b/trunk/drivers/net/wireless/libertas/if_cs.c index c94dd6802672..16beaf39dc53 100644 --- a/trunk/drivers/net/wireless/libertas/if_cs.c +++ b/trunk/drivers/net/wireless/libertas/if_cs.c @@ -999,6 +999,7 @@ static const struct pcmcia_device_id if_cs_ids[] = { }; MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); + static struct pcmcia_driver lbs_driver = { .owner = THIS_MODULE, .name = DRV_NAME, @@ -1006,4 +1007,26 @@ static struct pcmcia_driver lbs_driver = { .remove = if_cs_detach, .id_table = if_cs_ids, }; -module_pcmcia_driver(lbs_driver); + + +static int __init if_cs_init(void) +{ + int ret; + + lbs_deb_enter(LBS_DEB_CS); + ret = pcmcia_register_driver(&lbs_driver); + lbs_deb_leave(LBS_DEB_CS); + return ret; +} + + +static void __exit if_cs_exit(void) +{ + lbs_deb_enter(LBS_DEB_CS); + pcmcia_unregister_driver(&lbs_driver); + lbs_deb_leave(LBS_DEB_CS); +} + + +module_init(if_cs_init); +module_exit(if_cs_exit); diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.c b/trunk/drivers/net/wireless/libertas/if_sdio.c index 45578335e420..739309e70d8b 100644 --- a/trunk/drivers/net/wireless/libertas/if_sdio.c +++ b/trunk/drivers/net/wireless/libertas/if_sdio.c @@ -825,11 +825,6 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card) sdio_release_host(func); - /* Set fw_ready before queuing any commands so that - * lbs_thread won't block from sending them to firmware. - */ - priv->fw_ready = 1; - /* * FUNC_INIT is required for SD8688 WLAN/BT multiple functions */ @@ -844,6 +839,7 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card) netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n"); } + priv->fw_ready = 1; wake_up(&card->pwron_waitq); if (!card->started) { diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index 8aaf56ade4d9..a44023a7bd57 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -1892,8 +1892,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, } } - for (i = 0; i < min_t(u32, request->n_channels, - MWIFIEX_USER_SCAN_CHAN_MAX); i++) { + for (i = 0; i < request->n_channels; i++) { chan = request->channels[i]; priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; priv->user_scan_cfg->chan_list[i].radio_type = chan->band; diff --git a/trunk/drivers/net/wireless/mwifiex/cmdevt.c b/trunk/drivers/net/wireless/mwifiex/cmdevt.c index b5c8b962ce12..20a6c5555873 100644 --- a/trunk/drivers/net/wireless/mwifiex/cmdevt.c +++ b/trunk/drivers/net/wireless/mwifiex/cmdevt.c @@ -157,20 +157,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, return -1; } - cmd_code = le16_to_cpu(host_cmd->command); - cmd_size = le16_to_cpu(host_cmd->size); - - if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET && - cmd_code != HostCmd_CMD_FUNC_SHUTDOWN && - cmd_code != HostCmd_CMD_FUNC_INIT) { - dev_err(adapter->dev, - "DNLD_CMD: FW in reset state, ignore cmd %#x\n", - cmd_code); - mwifiex_complete_cmd(adapter, cmd_node); - mwifiex_insert_cmd_to_free_q(adapter, cmd_node); - return -1; - } - /* Set command sequence number */ adapter->seq_num++; host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO @@ -182,6 +168,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, adapter->curr_cmd = cmd_node; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + cmd_code = le16_to_cpu(host_cmd->command); + cmd_size = le16_to_cpu(host_cmd->size); + /* Adjust skb length */ if (cmd_node->cmd_skb->len > cmd_size) /* @@ -495,6 +484,8 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, data_buf); + if (!ret) + ret = mwifiex_wait_queue_complete(adapter); return ret; } @@ -597,10 +588,9 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, if (cmd_no == HostCmd_CMD_802_11_SCAN) { mwifiex_queue_scan_cmd(priv, cmd_node); } else { + adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); queue_work(adapter->workqueue, &adapter->main_work); - if (cmd_node->wait_q_enabled) - ret = mwifiex_wait_queue_complete(adapter, cmd_node); } return ret; diff --git a/trunk/drivers/net/wireless/mwifiex/init.c b/trunk/drivers/net/wireless/mwifiex/init.c index 0ff4c37ab42a..e38aa9b3663d 100644 --- a/trunk/drivers/net/wireless/mwifiex/init.c +++ b/trunk/drivers/net/wireless/mwifiex/init.c @@ -709,14 +709,6 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) return ret; } - /* cancel current command */ - if (adapter->curr_cmd) { - dev_warn(adapter->dev, "curr_cmd is still in processing\n"); - del_timer(&adapter->cmd_timer); - mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); - adapter->curr_cmd = NULL; - } - /* shut down mwifiex */ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); diff --git a/trunk/drivers/net/wireless/mwifiex/join.c b/trunk/drivers/net/wireless/mwifiex/join.c index 2fe0ceba4400..246aa62a4817 100644 --- a/trunk/drivers/net/wireless/mwifiex/join.c +++ b/trunk/drivers/net/wireless/mwifiex/join.c @@ -1117,9 +1117,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, adhoc_join->bss_descriptor.bssid, adhoc_join->bss_descriptor.ssid); - for (i = 0; i < MWIFIEX_SUPPORTED_RATES && - bss_desc->supported_rates[i]; i++) - ; + for (i = 0; bss_desc->supported_rates[i] && + i < MWIFIEX_SUPPORTED_RATES; + i++) + ; rates_size = i; /* Copy Data Rates from the Rates recorded in scan response */ diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h index 7035ade9af74..553adfb0aa81 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.h +++ b/trunk/drivers/net/wireless/mwifiex/main.h @@ -723,6 +723,7 @@ struct mwifiex_adapter { u16 cmd_wait_q_required; struct mwifiex_wait_queue cmd_wait_q; u8 scan_wait_q_woken; + struct cmd_ctrl_node *cmd_queued; spinlock_t queue_lock; /* lock for tx queues */ struct completion fw_load; u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; @@ -1017,8 +1018,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, struct mwifiex_multicast_list *mcast_list); int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, struct net_device *dev); -int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, - struct cmd_ctrl_node *cmd_queued); +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, struct cfg80211_ssid *req_ssid); int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); diff --git a/trunk/drivers/net/wireless/mwifiex/pcie.c b/trunk/drivers/net/wireless/mwifiex/pcie.c index feb204613397..35c79722c361 100644 --- a/trunk/drivers/net/wireless/mwifiex/pcie.c +++ b/trunk/drivers/net/wireless/mwifiex/pcie.c @@ -302,7 +302,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) i++; usleep_range(10, 20); /* 50ms max wait */ - if (i == 5000) + if (i == 50000) break; } @@ -1508,7 +1508,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) } memcpy(adapter->upld_buf, skb->data, min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); - skb_push(skb, INTF_HEADER_LEN); if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, PCI_DMA_FROMDEVICE)) return -1; diff --git a/trunk/drivers/net/wireless/mwifiex/scan.c b/trunk/drivers/net/wireless/mwifiex/scan.c index e7f6deaf715e..bb60c2754a97 100644 --- a/trunk/drivers/net/wireless/mwifiex/scan.c +++ b/trunk/drivers/net/wireless/mwifiex/scan.c @@ -1388,15 +1388,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); queue_work(adapter->workqueue, &adapter->main_work); - - /* Perform internal scan synchronously */ - if (!priv->scan_request) { - dev_dbg(adapter->dev, "wait internal scan\n"); - mwifiex_wait_queue_complete(adapter, cmd_node); - } } else { spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -1795,12 +1790,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, /* Need to indicate IOCTL complete */ if (adapter->curr_cmd->wait_q_enabled) { adapter->cmd_wait_q.status = 0; - if (!priv->scan_request) { - dev_dbg(adapter->dev, - "complete internal scan\n"); - mwifiex_complete_cmd(adapter, - adapter->curr_cmd); - } + mwifiex_complete_cmd(adapter, adapter->curr_cmd); } if (priv->report_scan_result) priv->report_scan_result = false; @@ -1956,6 +1946,9 @@ int mwifiex_request_scan(struct mwifiex_private *priv, /* Normal scan */ ret = mwifiex_scan_networks(priv, NULL); + if (!ret) + ret = mwifiex_wait_queue_complete(priv->adapter); + up(&priv->async_sem); return ret; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c index 13100f8de3db..9f33c92c90f5 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -54,10 +54,16 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, * This function waits on a cmd wait queue. It also cancels the pending * request after waking up, in case of errors. */ -int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, - struct cmd_ctrl_node *cmd_queued) +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) { int status; + struct cmd_ctrl_node *cmd_queued; + + if (!adapter->cmd_queued) + return 0; + + cmd_queued = adapter->cmd_queued; + adapter->cmd_queued = NULL; dev_dbg(adapter->dev, "cmd pending\n"); atomic_inc(&adapter->cmd_pending); diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_cs.c b/trunk/drivers/net/wireless/orinoco/orinoco_cs.c index d21d95939316..d7dbc00bcfbe 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_cs.c @@ -338,4 +338,18 @@ static struct pcmcia_driver orinoco_driver = { .suspend = orinoco_cs_suspend, .resume = orinoco_cs_resume, }; -module_pcmcia_driver(orinoco_driver); + +static int __init +init_orinoco_cs(void) +{ + return pcmcia_register_driver(&orinoco_driver); +} + +static void __exit +exit_orinoco_cs(void) +{ + pcmcia_unregister_driver(&orinoco_driver); +} + +module_init(init_orinoco_cs); +module_exit(exit_orinoco_cs); diff --git a/trunk/drivers/net/wireless/orinoco/spectrum_cs.c b/trunk/drivers/net/wireless/orinoco/spectrum_cs.c index e2264bc12ebf..6e28ee4e9c52 100644 --- a/trunk/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/trunk/drivers/net/wireless/orinoco/spectrum_cs.c @@ -318,4 +318,18 @@ static struct pcmcia_driver orinoco_driver = { .resume = spectrum_cs_resume, .id_table = spectrum_cs_ids, }; -module_pcmcia_driver(orinoco_driver); + +static int __init +init_spectrum_cs(void) +{ + return pcmcia_register_driver(&orinoco_driver); +} + +static void __exit +exit_spectrum_cs(void) +{ + pcmcia_unregister_driver(&orinoco_driver); +} + +module_init(init_spectrum_cs); +module_exit(exit_spectrum_cs); diff --git a/trunk/drivers/net/wireless/rt2x00/Kconfig b/trunk/drivers/net/wireless/rt2x00/Kconfig index 76cd47eb901e..44d6ead43341 100644 --- a/trunk/drivers/net/wireless/rt2x00/Kconfig +++ b/trunk/drivers/net/wireless/rt2x00/Kconfig @@ -20,7 +20,6 @@ if RT2X00 config RT2400PCI tristate "Ralink rt2400 (PCI/PCMCIA) support" depends on PCI - select RT2X00_LIB_MMIO select RT2X00_LIB_PCI select EEPROM_93CX6 ---help--- @@ -32,7 +31,6 @@ config RT2400PCI config RT2500PCI tristate "Ralink rt2500 (PCI/PCMCIA) support" depends on PCI - select RT2X00_LIB_MMIO select RT2X00_LIB_PCI select EEPROM_93CX6 ---help--- @@ -45,7 +43,6 @@ config RT61PCI tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support" depends on PCI select RT2X00_LIB_PCI - select RT2X00_LIB_MMIO select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO select CRC_ITU_T @@ -58,11 +55,10 @@ config RT61PCI config RT2800PCI tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" - depends on PCI || SOC_RT288X || SOC_RT305X + depends on PCI || RALINK_RT288X || RALINK_RT305X select RT2800_LIB - select RT2X00_LIB_MMIO select RT2X00_LIB_PCI if PCI - select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X + select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO select CRC_CCITT @@ -189,9 +185,6 @@ endif config RT2800_LIB tristate -config RT2X00_LIB_MMIO - tristate - config RT2X00_LIB_PCI tristate select RT2X00_LIB diff --git a/trunk/drivers/net/wireless/rt2x00/Makefile b/trunk/drivers/net/wireless/rt2x00/Makefile index f069d8bc5b67..349d5b8284a4 100644 --- a/trunk/drivers/net/wireless/rt2x00/Makefile +++ b/trunk/drivers/net/wireless/rt2x00/Makefile @@ -9,7 +9,6 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o -obj-$(CONFIG_RT2X00_LIB_MMIO) += rt2x00mmio.o obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o diff --git a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c index dcfb54e0c516..221beaaa83f1 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c @@ -34,7 +34,6 @@ #include #include "rt2x00.h" -#include "rt2x00mmio.h" #include "rt2x00pci.h" #include "rt2400pci.h" diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c index e1d2dc9ed28a..39edc59e8d03 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c @@ -34,7 +34,6 @@ #include #include "rt2x00.h" -#include "rt2x00mmio.h" #include "rt2x00pci.h" #include "rt2500pci.h" diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c index ba5a05625aaa..48a01aa21f1c 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c @@ -41,7 +41,6 @@ #include #include "rt2x00.h" -#include "rt2x00mmio.h" #include "rt2x00pci.h" #include "rt2x00soc.h" #include "rt2800lib.h" @@ -90,7 +89,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); } -#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); @@ -108,7 +107,7 @@ static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { return -ENOMEM; } -#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */ +#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ #ifdef CONFIG_PCI static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) @@ -1178,7 +1177,7 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table); #endif /* CONFIG_PCI */ MODULE_LICENSE("GPL"); -#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) static int rt2800soc_probe(struct platform_device *pdev) { return rt2x00soc_probe(pdev, &rt2800pci_ops); @@ -1195,7 +1194,7 @@ static struct platform_driver rt2800soc_driver = { .suspend = rt2x00soc_suspend, .resume = rt2x00soc_resume, }; -#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */ +#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ #ifdef CONFIG_PCI static int rt2800pci_probe(struct pci_dev *pci_dev, @@ -1218,7 +1217,7 @@ static int __init rt2800pci_init(void) { int ret = 0; -#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) ret = platform_driver_register(&rt2800soc_driver); if (ret) return ret; @@ -1226,7 +1225,7 @@ static int __init rt2800pci_init(void) #ifdef CONFIG_PCI ret = pci_register_driver(&rt2800pci_driver); if (ret) { -#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) platform_driver_unregister(&rt2800soc_driver); #endif return ret; @@ -1241,7 +1240,7 @@ static void __exit rt2800pci_exit(void) #ifdef CONFIG_PCI pci_unregister_driver(&rt2800pci_driver); #endif -#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) platform_driver_unregister(&rt2800soc_driver); #endif } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index 189744db65e0..1031db66474a 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1236,10 +1236,8 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev) */ if_limit = &rt2x00dev->if_limits_ap; if_limit->max = rt2x00dev->ops->max_ap_intf; - if_limit->types = BIT(NL80211_IFTYPE_AP); -#ifdef CONFIG_MAC80211_MESH - if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); -#endif + if_limit->types = BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_MESH_POINT); /* * Build up AP interface combinations structure. @@ -1311,9 +1309,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | -#ifdef CONFIG_MAC80211_MESH BIT(NL80211_IFTYPE_MESH_POINT) | -#endif BIT(NL80211_IFTYPE_WDS); rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.c deleted file mode 100644 index d84a680ba0c9..000000000000 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - Copyright (C) 2004 - 2009 Ivo van Doorn - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the - Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - Module: rt2x00mmio - Abstract: rt2x00 generic mmio device routines. - */ - -#include -#include -#include -#include - -#include "rt2x00.h" -#include "rt2x00mmio.h" - -/* - * Register access. - */ -int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const struct rt2x00_field32 field, - u32 *reg) -{ - unsigned int i; - - if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - return 0; - - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, offset, reg); - if (!rt2x00_get_field32(*reg, field)) - return 1; - udelay(REGISTER_BUSY_DELAY); - } - - printk_once(KERN_ERR "%s() Indirect register access failed: " - "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg); - *reg = ~0; - - return 0; -} -EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); - -bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue = rt2x00dev->rx; - struct queue_entry *entry; - struct queue_entry_priv_pci *entry_priv; - struct skb_frame_desc *skbdesc; - int max_rx = 16; - - while (--max_rx) { - entry = rt2x00queue_get_entry(queue, Q_INDEX); - entry_priv = entry->priv_data; - - if (rt2x00dev->ops->lib->get_entry_state(entry)) - break; - - /* - * Fill in desc fields of the skb descriptor - */ - skbdesc = get_skb_frame_desc(entry->skb); - skbdesc->desc = entry_priv->desc; - skbdesc->desc_len = entry->queue->desc_size; - - /* - * DMA is already done, notify rt2x00lib that - * it finished successfully. - */ - rt2x00lib_dmastart(entry); - rt2x00lib_dmadone(entry); - - /* - * Send the frame to rt2x00lib for further processing. - */ - rt2x00lib_rxdone(entry, GFP_ATOMIC); - } - - return !max_rx; -} -EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); - -void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) -{ - unsigned int i; - - for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) - msleep(10); -} -EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); - -/* - * Device initialization handlers. - */ -static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) -{ - struct queue_entry_priv_pci *entry_priv; - void *addr; - dma_addr_t dma; - unsigned int i; - - /* - * Allocate DMA memory for descriptor and buffer. - */ - addr = dma_alloc_coherent(rt2x00dev->dev, - queue->limit * queue->desc_size, - &dma, GFP_KERNEL); - if (!addr) - return -ENOMEM; - - memset(addr, 0, queue->limit * queue->desc_size); - - /* - * Initialize all queue entries to contain valid addresses. - */ - for (i = 0; i < queue->limit; i++) { - entry_priv = queue->entries[i].priv_data; - entry_priv->desc = addr + i * queue->desc_size; - entry_priv->desc_dma = dma + i * queue->desc_size; - } - - return 0; -} - -static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) -{ - struct queue_entry_priv_pci *entry_priv = - queue->entries[0].priv_data; - - if (entry_priv->desc) - dma_free_coherent(rt2x00dev->dev, - queue->limit * queue->desc_size, - entry_priv->desc, entry_priv->desc_dma); - entry_priv->desc = NULL; -} - -int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - int status; - - /* - * Allocate DMA - */ - queue_for_each(rt2x00dev, queue) { - status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); - if (status) - goto exit; - } - - /* - * Register interrupt handler. - */ - status = request_irq(rt2x00dev->irq, - rt2x00dev->ops->lib->irq_handler, - IRQF_SHARED, rt2x00dev->name, rt2x00dev); - if (status) { - ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", - rt2x00dev->irq, status); - goto exit; - } - - return 0; - -exit: - queue_for_each(rt2x00dev, queue) - rt2x00pci_free_queue_dma(rt2x00dev, queue); - - return status; -} -EXPORT_SYMBOL_GPL(rt2x00pci_initialize); - -void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - - /* - * Free irq line. - */ - free_irq(rt2x00dev->irq, rt2x00dev); - - /* - * Free DMA - */ - queue_for_each(rt2x00dev, queue) - rt2x00pci_free_queue_dma(rt2x00dev, queue); -} -EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); - -/* - * rt2x00mmio module information. - */ -MODULE_AUTHOR(DRV_PROJECT); -MODULE_VERSION(DRV_VERSION); -MODULE_DESCRIPTION("rt2x00 mmio library"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.h b/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.h deleted file mode 100644 index 4ecaf60175bf..000000000000 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (C) 2004 - 2009 Ivo van Doorn - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the - Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - Module: rt2x00mmio - Abstract: Data structures for the rt2x00mmio module. - */ - -#ifndef RT2X00MMIO_H -#define RT2X00MMIO_H - -#include - -/* - * Register access. - */ -static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - u32 *value) -{ - *value = readl(rt2x00dev->csr.base + offset); -} - -static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - void *value, const u32 length) -{ - memcpy_fromio(value, rt2x00dev->csr.base + offset, length); -} - -static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - u32 value) -{ - writel(value, rt2x00dev->csr.base + offset); -} - -static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const void *value, - const u32 length) -{ - __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); -} - -/** - * rt2x00pci_regbusy_read - Read from register with busy check - * @rt2x00dev: Device pointer, see &struct rt2x00_dev. - * @offset: Register offset - * @field: Field to check if register is busy - * @reg: Pointer to where register contents should be stored - * - * This function will read the given register, and checks if the - * register is busy. If it is, it will sleep for a couple of - * microseconds before reading the register again. If the register - * is not read after a certain timeout, this function will return - * FALSE. - */ -int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const struct rt2x00_field32 field, - u32 *reg); - -/** - * struct queue_entry_priv_pci: Per entry PCI specific information - * - * @desc: Pointer to device descriptor - * @desc_dma: DMA pointer to &desc. - * @data: Pointer to device's entry memory. - * @data_dma: DMA pointer to &data. - */ -struct queue_entry_priv_pci { - __le32 *desc; - dma_addr_t desc_dma; -}; - -/** - * rt2x00pci_rxdone - Handle RX done events - * @rt2x00dev: Device pointer, see &struct rt2x00_dev. - * - * Returns true if there are still rx frames pending and false if all - * pending rx frames were processed. - */ -bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); - -/** - * rt2x00pci_flush_queue - Flush data queue - * @queue: Data queue to stop - * @drop: True to drop all pending frames. - * - * This will wait for a maximum of 100ms, waiting for the queues - * to become empty. - */ -void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); - -/* - * Device initialization handlers. - */ -int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); -void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); - -#endif /* RT2X00MMIO_H */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c index e87865e33113..a0c8caef3b0a 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -32,6 +32,182 @@ #include "rt2x00.h" #include "rt2x00pci.h" +/* + * Register access. + */ +int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const struct rt2x00_field32 field, + u32 *reg) +{ + unsigned int i; + + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + return 0; + + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2x00pci_register_read(rt2x00dev, offset, reg); + if (!rt2x00_get_field32(*reg, field)) + return 1; + udelay(REGISTER_BUSY_DELAY); + } + + ERROR(rt2x00dev, "Indirect register access failed: " + "offset=0x%.08x, value=0x%.08x\n", offset, *reg); + *reg = ~0; + + return 0; +} +EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); + +bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue = rt2x00dev->rx; + struct queue_entry *entry; + struct queue_entry_priv_pci *entry_priv; + struct skb_frame_desc *skbdesc; + int max_rx = 16; + + while (--max_rx) { + entry = rt2x00queue_get_entry(queue, Q_INDEX); + entry_priv = entry->priv_data; + + if (rt2x00dev->ops->lib->get_entry_state(entry)) + break; + + /* + * Fill in desc fields of the skb descriptor + */ + skbdesc = get_skb_frame_desc(entry->skb); + skbdesc->desc = entry_priv->desc; + skbdesc->desc_len = entry->queue->desc_size; + + /* + * DMA is already done, notify rt2x00lib that + * it finished successfully. + */ + rt2x00lib_dmastart(entry); + rt2x00lib_dmadone(entry); + + /* + * Send the frame to rt2x00lib for further processing. + */ + rt2x00lib_rxdone(entry, GFP_ATOMIC); + } + + return !max_rx; +} +EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); + +void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) +{ + unsigned int i; + + for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) + msleep(10); +} +EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); + +/* + * Device initialization handlers. + */ +static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue) +{ + struct queue_entry_priv_pci *entry_priv; + void *addr; + dma_addr_t dma; + unsigned int i; + + /* + * Allocate DMA memory for descriptor and buffer. + */ + addr = dma_alloc_coherent(rt2x00dev->dev, + queue->limit * queue->desc_size, + &dma, GFP_KERNEL); + if (!addr) + return -ENOMEM; + + memset(addr, 0, queue->limit * queue->desc_size); + + /* + * Initialize all queue entries to contain valid addresses. + */ + for (i = 0; i < queue->limit; i++) { + entry_priv = queue->entries[i].priv_data; + entry_priv->desc = addr + i * queue->desc_size; + entry_priv->desc_dma = dma + i * queue->desc_size; + } + + return 0; +} + +static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue) +{ + struct queue_entry_priv_pci *entry_priv = + queue->entries[0].priv_data; + + if (entry_priv->desc) + dma_free_coherent(rt2x00dev->dev, + queue->limit * queue->desc_size, + entry_priv->desc, entry_priv->desc_dma); + entry_priv->desc = NULL; +} + +int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + int status; + + /* + * Allocate DMA + */ + queue_for_each(rt2x00dev, queue) { + status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); + if (status) + goto exit; + } + + /* + * Register interrupt handler. + */ + status = request_irq(rt2x00dev->irq, + rt2x00dev->ops->lib->irq_handler, + IRQF_SHARED, rt2x00dev->name, rt2x00dev); + if (status) { + ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", + rt2x00dev->irq, status); + goto exit; + } + + return 0; + +exit: + queue_for_each(rt2x00dev, queue) + rt2x00pci_free_queue_dma(rt2x00dev, queue); + + return status; +} +EXPORT_SYMBOL_GPL(rt2x00pci_initialize); + +void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + + /* + * Free irq line. + */ + free_irq(rt2x00dev->irq, rt2x00dev); + + /* + * Free DMA + */ + queue_for_each(rt2x00dev, queue) + rt2x00pci_free_queue_dma(rt2x00dev, queue); +} +EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); + /* * PCI driver handlers. */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h index 60d90b20f8b9..e2c99f2b9a14 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -35,6 +35,94 @@ */ #define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops) +/* + * Register access. + */ +static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u32 *value) +{ + *value = readl(rt2x00dev->csr.base + offset); +} + +static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + void *value, const u32 length) +{ + memcpy_fromio(value, rt2x00dev->csr.base + offset, length); +} + +static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u32 value) +{ + writel(value, rt2x00dev->csr.base + offset); +} + +static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const void *value, + const u32 length) +{ + __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); +} + +/** + * rt2x00pci_regbusy_read - Read from register with busy check + * @rt2x00dev: Device pointer, see &struct rt2x00_dev. + * @offset: Register offset + * @field: Field to check if register is busy + * @reg: Pointer to where register contents should be stored + * + * This function will read the given register, and checks if the + * register is busy. If it is, it will sleep for a couple of + * microseconds before reading the register again. If the register + * is not read after a certain timeout, this function will return + * FALSE. + */ +int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const struct rt2x00_field32 field, + u32 *reg); + +/** + * struct queue_entry_priv_pci: Per entry PCI specific information + * + * @desc: Pointer to device descriptor + * @desc_dma: DMA pointer to &desc. + * @data: Pointer to device's entry memory. + * @data_dma: DMA pointer to &data. + */ +struct queue_entry_priv_pci { + __le32 *desc; + dma_addr_t desc_dma; +}; + +/** + * rt2x00pci_rxdone - Handle RX done events + * @rt2x00dev: Device pointer, see &struct rt2x00_dev. + * + * Returns true if there are still rx frames pending and false if all + * pending rx frames were processed. + */ +bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); + +/** + * rt2x00pci_flush_queue - Flush data queue + * @queue: Data queue to stop + * @drop: True to drop all pending frames. + * + * This will wait for a maximum of 100ms, waiting for the queues + * to become empty. + */ +void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); + +/* + * Device initialization handlers. + */ +int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); +void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); + /* * PCI driver handlers. */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c index 9e3c8ff53e3f..f95792cfcf89 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c @@ -35,7 +35,6 @@ #include #include "rt2x00.h" -#include "rt2x00mmio.h" #include "rt2x00pci.h" #include "rt61pci.h" diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index c08d0f4c5f3d..b1ccff474c79 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1376,58 +1376,75 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw) } void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + /* dummy routine needed for callback from rtl_op_configure_filter() */ +} + +/*========================================================================== */ + +static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw, + enum nl80211_iftype type) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 filterout_non_associated_bssid = false; - if (rtlpriv->psc.rfpwr_state != ERFON) - return; - - if (check_bssid) { - u8 tmp; + switch (type) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_STATION: + filterout_non_associated_bssid = true; + break; + case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_AP: + default: + break; + } + if (filterout_non_associated_bssid) { if (IS_NORMAL_CHIP(rtlhal->version)) { - reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); - tmp = BIT(4); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *)(®_rcr)); + /* enable update TSF */ + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *)(®_rcr)); + /* disable update TSF */ + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); + break; + } } else { - reg_rcr |= RCR_CBSSID; - tmp = BIT(4) | BIT(5); + reg_rcr |= (RCR_CBSSID); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5))); } - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, - (u8 *) (®_rcr)); - _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp); - } else { - u8 tmp; + } else if (filterout_non_associated_bssid == false) { if (IS_NORMAL_CHIP(rtlhal->version)) { - reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); - tmp = BIT(4); + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); } else { - reg_rcr &= ~RCR_CBSSID; - tmp = BIT(4) | BIT(5); + reg_rcr &= (~RCR_CBSSID); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0); } - reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_RCR, (u8 *) (®_rcr)); - _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0); } } -/*========================================================================== */ - int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) { - struct rtl_priv *rtlpriv = rtl_priv(hw); - if (_rtl92cu_set_media_status(hw, type)) return -EOPNOTSUPP; - - if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { - if (type != NL80211_IFTYPE_AP) - rtl92cu_set_check_bssid(hw, true); - } else { - rtl92cu_set_check_bssid(hw, false); - } - + _rtl92cu_set_check_bssid(hw, type); return 0; } @@ -2041,6 +2058,8 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, (shortgi_rate << 4) | (shortgi_rate); } rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c index 5847d6d0881e..156b52732f3d 100644 --- a/trunk/drivers/net/wireless/rtlwifi/usb.c +++ b/trunk/drivers/net/wireless/rtlwifi/usb.c @@ -851,7 +851,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, if (unlikely(!_urb)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't allocate urb. Drop skb!\n"); - kfree_skb(skb); return; } _rtl_submit_tx_urb(hw, _urb); diff --git a/trunk/drivers/net/wireless/wl3501_cs.c b/trunk/drivers/net/wireless/wl3501_cs.c index 38d2089f338a..730186d0449b 100644 --- a/trunk/drivers/net/wireless/wl3501_cs.c +++ b/trunk/drivers/net/wireless/wl3501_cs.c @@ -2013,7 +2013,19 @@ static struct pcmcia_driver wl3501_driver = { .suspend = wl3501_suspend, .resume = wl3501_resume, }; -module_pcmcia_driver(wl3501_driver); + +static int __init wl3501_init_module(void) +{ + return pcmcia_register_driver(&wl3501_driver); +} + +static void __exit wl3501_exit_module(void) +{ + pcmcia_unregister_driver(&wl3501_driver); +} + +module_init(wl3501_init_module); +module_exit(wl3501_exit_module); MODULE_AUTHOR("Fox Chen , " "Arnaldo Carvalho de Melo ," diff --git a/trunk/drivers/nfc/microread/mei.c b/trunk/drivers/nfc/microread/mei.c index ca33ae193935..eef38cfd812e 100644 --- a/trunk/drivers/nfc/microread/mei.c +++ b/trunk/drivers/nfc/microread/mei.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -32,6 +32,9 @@ #define MICROREAD_DRIVER_NAME "microread" +#define MICROREAD_UUID UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, 0x94, \ + 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c) + struct mei_nfc_hdr { u8 cmd; u8 status; @@ -45,7 +48,7 @@ struct mei_nfc_hdr { #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) struct microread_mei_phy { - struct mei_cl_device *device; + struct mei_device *mei_device; struct nfc_hci_dev *hdev; int powered; @@ -102,14 +105,14 @@ static int microread_mei_write(void *phy_id, struct sk_buff *skb) MEI_DUMP_SKB_OUT("mei frame sent", skb); - r = mei_cl_send(phy->device, skb->data, skb->len); + r = mei_send(phy->device, skb->data, skb->len); if (r > 0) r = 0; return r; } -static void microread_event_cb(struct mei_cl_device *device, u32 events, +static void microread_event_cb(struct mei_device *device, u32 events, void *context) { struct microread_mei_phy *phy = context; @@ -117,7 +120,7 @@ static void microread_event_cb(struct mei_cl_device *device, u32 events, if (phy->hard_fault != 0) return; - if (events & BIT(MEI_CL_EVENT_RX)) { + if (events & BIT(MEI_EVENT_RX)) { struct sk_buff *skb; int reply_size; @@ -125,7 +128,7 @@ static void microread_event_cb(struct mei_cl_device *device, u32 events, if (!skb) return; - reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); + reply_size = mei_recv(device, skb->data, MEI_NFC_MAX_READ); if (reply_size < MEI_NFC_HEADER_SIZE) { kfree(skb); return; @@ -146,8 +149,8 @@ static struct nfc_phy_ops mei_phy_ops = { .disable = microread_mei_disable, }; -static int microread_mei_probe(struct mei_cl_device *device, - const struct mei_cl_device_id *id) +static int microread_mei_probe(struct mei_device *device, + const struct mei_id *id) { struct microread_mei_phy *phy; int r; @@ -161,9 +164,9 @@ static int microread_mei_probe(struct mei_cl_device *device, } phy->device = device; - mei_cl_set_drvdata(device, phy); + mei_set_clientdata(device, phy); - r = mei_cl_register_event_cb(device, microread_event_cb, phy); + r = mei_register_event_cb(device, microread_event_cb, phy); if (r) { pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); goto err_out; @@ -183,9 +186,9 @@ static int microread_mei_probe(struct mei_cl_device *device, return r; } -static int microread_mei_remove(struct mei_cl_device *device) +static int microread_mei_remove(struct mei_device *device) { - struct microread_mei_phy *phy = mei_cl_get_drvdata(device); + struct microread_mei_phy *phy = mei_get_clientdata(device); pr_info("Removing microread\n"); @@ -199,15 +202,16 @@ static int microread_mei_remove(struct mei_cl_device *device) return 0; } -static struct mei_cl_device_id microread_mei_tbl[] = { - { MICROREAD_DRIVER_NAME }, +static struct mei_id microread_mei_tbl[] = { + { MICROREAD_DRIVER_NAME, MICROREAD_UUID }, /* required last entry */ { } }; + MODULE_DEVICE_TABLE(mei, microread_mei_tbl); -static struct mei_cl_driver microread_driver = { +static struct mei_driver microread_driver = { .id_table = microread_mei_tbl, .name = MICROREAD_DRIVER_NAME, @@ -221,7 +225,7 @@ static int microread_mei_init(void) pr_debug(DRIVER_DESC ": %s\n", __func__); - r = mei_cl_driver_register(µread_driver); + r = mei_driver_register(µread_driver); if (r) { pr_err(MICROREAD_DRIVER_NAME ": driver registration failed\n"); return r; @@ -232,7 +236,7 @@ static int microread_mei_init(void) static void microread_mei_exit(void) { - mei_cl_driver_unregister(µread_driver); + mei_driver_unregister(µread_driver); } module_init(microread_mei_init); diff --git a/trunk/drivers/oprofile/oprofilefs.c b/trunk/drivers/oprofile/oprofilefs.c index 7c12d9c2b230..445ffda715ad 100644 --- a/trunk/drivers/oprofile/oprofilefs.c +++ b/trunk/drivers/oprofile/oprofilefs.c @@ -276,7 +276,6 @@ static struct file_system_type oprofilefs_type = { .mount = oprofilefs_mount, .kill_sb = kill_litter_super, }; -MODULE_ALIAS_FS("oprofilefs"); int __init oprofilefs_register(void) diff --git a/trunk/drivers/parport/parport_amiga.c b/trunk/drivers/parport/parport_amiga.c index 09503b8d12e6..ee78e0ee6e05 100644 --- a/trunk/drivers/parport/parport_amiga.c +++ b/trunk/drivers/parport/parport_amiga.c @@ -244,7 +244,20 @@ static struct platform_driver amiga_parallel_driver = { }, }; -module_platform_driver_probe(amiga_parallel_driver, amiga_parallel_probe); +static int __init amiga_parallel_init(void) +{ + return platform_driver_probe(&amiga_parallel_driver, + amiga_parallel_probe); +} + +module_init(amiga_parallel_init); + +static void __exit amiga_parallel_exit(void) +{ + platform_driver_unregister(&amiga_parallel_driver); +} + +module_exit(amiga_parallel_exit); MODULE_AUTHOR("Joerg Dorchain "); MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port"); diff --git a/trunk/drivers/parport/parport_cs.c b/trunk/drivers/parport/parport_cs.c index e9b52e4a4648..067ad517c1f5 100644 --- a/trunk/drivers/parport/parport_cs.c +++ b/trunk/drivers/parport/parport_cs.c @@ -193,4 +193,16 @@ static struct pcmcia_driver parport_cs_driver = { .remove = parport_detach, .id_table = parport_ids, }; -module_pcmcia_driver(parport_cs_driver); + +static int __init init_parport_cs(void) +{ + return pcmcia_register_driver(&parport_cs_driver); +} + +static void __exit exit_parport_cs(void) +{ + pcmcia_unregister_driver(&parport_cs_driver); +} + +module_init(init_parport_cs); +module_exit(exit_parport_cs); diff --git a/trunk/drivers/parport/parport_gsc.c b/trunk/drivers/parport/parport_gsc.c index a5251cb5fb0c..050773c36823 100644 --- a/trunk/drivers/parport/parport_gsc.c +++ b/trunk/drivers/parport/parport_gsc.c @@ -246,14 +246,14 @@ struct parport *parport_gsc_probe_port(unsigned long base, printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); return NULL; } - ops = kmemdup(&parport_gsc_ops, sizeof(struct parport_operations), - GFP_KERNEL); + ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); if (!ops) { printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n", base); kfree (priv); return NULL; } + memcpy (ops, &parport_gsc_ops, sizeof (struct parport_operations)); priv->ctr = 0xc; priv->ctr_writable = 0xff; priv->dma_buf = 0; diff --git a/trunk/drivers/parport/parport_sunbpp.c b/trunk/drivers/parport/parport_sunbpp.c index dffd6d0bd15b..5c4b6a1db6ca 100644 --- a/trunk/drivers/parport/parport_sunbpp.c +++ b/trunk/drivers/parport/parport_sunbpp.c @@ -284,11 +284,12 @@ static int bpp_probe(struct platform_device *op) size = resource_size(&op->resource[0]); dma = PARPORT_DMA_NONE; - ops = kmemdup(&parport_sunbpp_ops, sizeof(struct parport_operations), - GFP_KERNEL); + ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); if (!ops) goto out_unmap; + memcpy (ops, &parport_sunbpp_ops, sizeof(struct parport_operations)); + dprintk(("register_port\n")); if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) goto out_free_ops; diff --git a/trunk/drivers/parport/procfs.c b/trunk/drivers/parport/procfs.c index 92ed045a5f93..3f56bc086cb5 100644 --- a/trunk/drivers/parport/procfs.c +++ b/trunk/drivers/parport/procfs.c @@ -476,9 +476,10 @@ int parport_proc_register(struct parport *port) struct parport_sysctl_table *t; int i; - t = kmemdup(&parport_sysctl_template, sizeof(*t), GFP_KERNEL); + t = kmalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) return -ENOMEM; + memcpy(t, &parport_sysctl_template, sizeof(*t)); t->device_dir[0].extra1 = port; @@ -522,9 +523,10 @@ int parport_device_proc_register(struct pardevice *device) struct parport_device_sysctl_table *t; struct parport * port = device->port; - t = kmemdup(&parport_device_sysctl_template, sizeof(*t), GFP_KERNEL); + t = kmalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) return -ENOMEM; + memcpy(t, &parport_device_sysctl_template, sizeof(*t)); t->dev_dir[0].child = t->parport_dir; t->parport_dir[0].child = t->port_dir; diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index 748f8f3e9ff5..8647dc6f52d0 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -202,16 +202,20 @@ void pci_bus_add_devices(const struct pci_bus *bus) if (dev->is_added) continue; retval = pci_bus_add_device(dev); - if (retval) - dev_err(&dev->dev, "Error adding device (%d)\n", - retval); } list_for_each_entry(dev, &bus->devices, bus_list) { BUG_ON(!dev->is_added); + child = dev->subordinate; - if (child) - pci_bus_add_devices(child); + + if (!child) + continue; + pci_bus_add_devices(child); + + if (child->is_added) + continue; + child->is_added = 1; } } diff --git a/trunk/drivers/pci/hotplug/Kconfig b/trunk/drivers/pci/hotplug/Kconfig index 9fcb87f353d4..13e9e63a7266 100644 --- a/trunk/drivers/pci/hotplug/Kconfig +++ b/trunk/drivers/pci/hotplug/Kconfig @@ -52,12 +52,15 @@ config HOTPLUG_PCI_IBM When in doubt, say N. config HOTPLUG_PCI_ACPI - bool "ACPI PCI Hotplug driver" - depends on HOTPLUG_PCI=y && ((!ACPI_DOCK && ACPI) || (ACPI_DOCK)) + tristate "ACPI PCI Hotplug driver" + depends on (!ACPI_DOCK && ACPI) || (ACPI_DOCK) help Say Y here if you have a system that supports PCI Hotplug using ACPI. + To compile this driver as a module, choose M here: the + module will be called acpiphp. + When in doubt, say N. config HOTPLUG_PCI_ACPI_IBM diff --git a/trunk/drivers/pci/hotplug/acpiphp.h b/trunk/drivers/pci/hotplug/acpiphp.h index 6fdd49c6f0b9..b70ac00a117e 100644 --- a/trunk/drivers/pci/hotplug/acpiphp.h +++ b/trunk/drivers/pci/hotplug/acpiphp.h @@ -73,9 +73,8 @@ static inline const char *slot_name(struct slot *slot) */ struct acpiphp_bridge { struct list_head list; - struct list_head slots; - struct kref ref; acpi_handle handle; + struct acpiphp_slot *slots; /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ struct acpiphp_func *func; @@ -98,7 +97,7 @@ struct acpiphp_bridge { * PCI slot information for each *physical* PCI slot */ struct acpiphp_slot { - struct list_head node; + struct acpiphp_slot *next; struct acpiphp_bridge *bridge; /* parent */ struct list_head funcs; /* one slot may have different objects (i.e. for each function) */ @@ -120,6 +119,7 @@ struct acpiphp_slot { */ struct acpiphp_func { struct acpiphp_slot *slot; /* parent */ + struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ struct list_head sibling; struct notifier_block nb; @@ -146,6 +146,10 @@ struct acpiphp_attention_info #define ACPI_PCI_HOST_HID "PNP0A03" /* ACPI _STA method value (ignore bit 4; battery present) */ +#define ACPI_STA_PRESENT (0x00000001) +#define ACPI_STA_ENABLED (0x00000002) +#define ACPI_STA_SHOW_IN_UI (0x00000004) +#define ACPI_STA_FUNCTIONING (0x00000008) #define ACPI_STA_ALL (0x0000000f) /* bridge flags */ @@ -170,24 +174,25 @@ struct acpiphp_attention_info /* function prototypes */ /* acpiphp_core.c */ -int acpiphp_register_attention(struct acpiphp_attention_info*info); -int acpiphp_unregister_attention(struct acpiphp_attention_info *info); -int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); -void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); +extern int acpiphp_register_attention(struct acpiphp_attention_info*info); +extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info); +extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); +extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); /* acpiphp_glue.c */ +extern int acpiphp_glue_init (void); +extern void acpiphp_glue_exit (void); typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); -int acpiphp_enable_slot(struct acpiphp_slot *slot); -int acpiphp_disable_slot(struct acpiphp_slot *slot); -int acpiphp_eject_slot(struct acpiphp_slot *slot); -u8 acpiphp_get_power_status(struct acpiphp_slot *slot); -u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); -u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); -u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot); +extern int acpiphp_enable_slot (struct acpiphp_slot *slot); +extern int acpiphp_disable_slot (struct acpiphp_slot *slot); +extern int acpiphp_eject_slot (struct acpiphp_slot *slot); +extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot); +extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot); +extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); +extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); /* variables */ extern bool acpiphp_debug; -extern bool acpiphp_disabled; #endif /* _ACPIPHP_H */ diff --git a/trunk/drivers/pci/hotplug/acpiphp_core.c b/trunk/drivers/pci/hotplug/acpiphp_core.c index ca8127950fcd..c2fd3095701f 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_core.c +++ b/trunk/drivers/pci/hotplug/acpiphp_core.c @@ -37,7 +37,6 @@ #include #include -#include #include #include #include @@ -49,7 +48,6 @@ #define SLOT_NAME_SIZE 21 /* {_SUN} */ bool acpiphp_debug; -bool acpiphp_disabled; /* local variables */ static struct acpiphp_attention_info *attention_info; @@ -62,9 +60,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); -MODULE_PARM_DESC(disable, "disable acpiphp driver"); module_param_named(debug, acpiphp_debug, bool, 0644); -module_param_named(disable, acpiphp_disabled, bool, 0444); /* export the attention callback registration methods */ EXPORT_SYMBOL_GPL(acpiphp_register_attention); @@ -355,9 +351,27 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) } -void __init acpiphp_init(void) +static int __init acpiphp_init(void) { - info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", - acpiphp_disabled ? ", disabled by user; please report a bug" - : ""); + info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + + if (acpi_pci_disabled) + return 0; + + /* read all the ACPI info from the system */ + /* initialize internal data structure etc. */ + return acpiphp_glue_init(); +} + + +static void __exit acpiphp_exit(void) +{ + if (acpi_pci_disabled) + return; + + /* deallocate internal data structures etc. */ + acpiphp_glue_exit(); } + +module_init(acpiphp_init); +module_exit(acpiphp_exit); diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 96fed19c6d90..270fdbadc19c 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -54,7 +54,6 @@ #include "acpiphp.h" static LIST_HEAD(bridge_list); -static DEFINE_MUTEX(bridge_mutex); #define MY_NAME "acpiphp_glue" @@ -62,7 +61,6 @@ static void handle_hotplug_event_bridge (acpi_handle, u32, void *); static void acpiphp_sanitize_bus(struct pci_bus *bus); static void acpiphp_set_hpp_values(struct pci_bus *bus); static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); -static void free_bridge(struct kref *kref); /* callback routine to check for the existence of a pci dock device */ static acpi_status @@ -78,39 +76,6 @@ is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) } } -static inline void get_bridge(struct acpiphp_bridge *bridge) -{ - kref_get(&bridge->ref); -} - -static inline void put_bridge(struct acpiphp_bridge *bridge) -{ - kref_put(&bridge->ref, free_bridge); -} - -static void free_bridge(struct kref *kref) -{ - struct acpiphp_bridge *bridge; - struct acpiphp_slot *slot, *next; - struct acpiphp_func *func, *tmp; - - bridge = container_of(kref, struct acpiphp_bridge, ref); - - list_for_each_entry_safe(slot, next, &bridge->slots, node) { - list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { - kfree(func); - } - kfree(slot); - } - - /* Release reference acquired by acpiphp_bridge_handle_to_function() */ - if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) - put_bridge(bridge->func->slot->bridge); - put_device(&bridge->pci_bus->dev); - pci_dev_put(bridge->pci_dev); - kfree(bridge); -} - /* * the _DCK method can do funny things... and sometimes not * hah-hah funny. @@ -189,10 +154,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) acpi_handle tmp; acpi_status status = AE_OK; unsigned long long adr, sun; - int device, function, retval, found = 0; + int device, function, retval; struct pci_bus *pbus = bridge->pci_bus; struct pci_dev *pdev; - u32 val; if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) return AE_OK; @@ -206,7 +170,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) device = (adr >> 16) & 0xffff; function = adr & 0xffff; - pdev = bridge->pci_dev; + pdev = pbus->self; if (pdev && device_is_managed_by_native_pciehp(pdev)) return AE_OK; @@ -214,6 +178,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) if (!newfunc) return AE_NO_MEMORY; + INIT_LIST_HEAD(&newfunc->sibling); newfunc->handle = handle; newfunc->function = function; @@ -242,15 +207,14 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) } /* search for objects that share the same slot */ - list_for_each_entry(slot, &bridge->slots, node) + for (slot = bridge->slots; slot; slot = slot->next) if (slot->device == device) { if (slot->sun != sun) warn("sibling found, but _SUN doesn't match!\n"); - found = 1; break; } - if (!found) { + if (!slot) { slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); if (!slot) { kfree(newfunc); @@ -263,9 +227,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) INIT_LIST_HEAD(&slot->funcs); mutex_init(&slot->crit_sect); - mutex_lock(&bridge_mutex); - list_add_tail(&slot->node, &bridge->slots); - mutex_unlock(&bridge_mutex); + slot->next = bridge->slots; + bridge->slots = slot; + bridge->nr_slots++; dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", @@ -283,13 +247,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) } newfunc->slot = slot; - mutex_lock(&bridge_mutex); list_add_tail(&newfunc->sibling, &slot->funcs); - mutex_unlock(&bridge_mutex); - if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function), - &val, 60*1000)) + pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); + if (pdev) { slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); + pci_dev_put(pdev); + } if (is_dock_device(handle)) { /* we don't want to call this device's _EJ0 @@ -326,9 +290,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) err_exit: bridge->nr_slots--; - mutex_lock(&bridge_mutex); - list_del(&slot->node); - mutex_unlock(&bridge_mutex); + bridge->slots = slot->next; kfree(slot); kfree(newfunc); @@ -353,17 +315,13 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) acpi_status status; /* must be added to the list prior to calling register_slot */ - mutex_lock(&bridge_mutex); list_add(&bridge->list, &bridge_list); - mutex_unlock(&bridge_mutex); /* register all slot objects under this bridge */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, register_slot, NULL, bridge, NULL); if (ACPI_FAILURE(status)) { - mutex_lock(&bridge_mutex); list_del(&bridge->list); - mutex_unlock(&bridge_mutex); return; } @@ -393,46 +351,178 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle { struct acpiphp_bridge *bridge; struct acpiphp_slot *slot; - struct acpiphp_func *func = NULL; + struct acpiphp_func *func; - mutex_lock(&bridge_mutex); list_for_each_entry(bridge, &bridge_list, list) { - list_for_each_entry(slot, &bridge->slots, node) { + for (slot = bridge->slots; slot; slot = slot->next) { list_for_each_entry(func, &slot->funcs, sibling) { - if (func->handle == handle) { - get_bridge(func->slot->bridge); - mutex_unlock(&bridge_mutex); + if (func->handle == handle) return func; - } } } } - mutex_unlock(&bridge_mutex); return NULL; } +static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) +{ + acpi_handle dummy_handle; + struct acpiphp_func *func; + + if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, + "_EJ0", &dummy_handle))) { + bridge->flags |= BRIDGE_HAS_EJ0; + + dbg("found ejectable p2p bridge\n"); + + /* make link between PCI bridge and PCI function */ + func = acpiphp_bridge_handle_to_function(bridge->handle); + if (!func) + return; + bridge->func = func; + func->bridge = bridge; + } +} + + +/* allocate and initialize host bridge data structure */ +static void add_host_bridge(struct acpi_pci_root *root) +{ + struct acpiphp_bridge *bridge; + acpi_handle handle = root->device->handle; + + bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); + if (bridge == NULL) + return; + + bridge->handle = handle; + + bridge->pci_bus = root->bus; + + init_bridge_misc(bridge); +} + + +/* allocate and initialize PCI-to-PCI bridge data structure */ +static void add_p2p_bridge(acpi_handle *handle) +{ + struct acpiphp_bridge *bridge; + + bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); + if (bridge == NULL) { + err("out of memory\n"); + return; + } + + bridge->handle = handle; + config_p2p_bridge_flags(bridge); + + bridge->pci_dev = acpi_get_pci_dev(handle); + bridge->pci_bus = bridge->pci_dev->subordinate; + if (!bridge->pci_bus) { + err("This is not a PCI-to-PCI bridge!\n"); + goto err; + } + + /* + * Grab a ref to the subordinate PCI bus in case the bus is + * removed via PCI core logical hotplug. The ref pins the bus + * (which we access during module unload). + */ + get_device(&bridge->pci_bus->dev); + + init_bridge_misc(bridge); + return; + err: + pci_dev_put(bridge->pci_dev); + kfree(bridge); + return; +} + + +/* callback routine to find P2P bridges */ +static acpi_status +find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + acpi_status status; + struct pci_dev *dev; + + dev = acpi_get_pci_dev(handle); + if (!dev || !dev->subordinate) + goto out; + + /* check if this bridge has ejectable slots */ + if ((detect_ejectable_slots(handle) > 0)) { + dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); + add_p2p_bridge(handle); + } + + /* search P2P bridges under this p2p bridge */ + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + find_p2p_bridge, NULL, NULL, NULL); + if (ACPI_FAILURE(status)) + warn("find_p2p_bridge failed (error code = 0x%x)\n", status); + + out: + pci_dev_put(dev); + return AE_OK; +} + + +/* find hot-pluggable slots, and then find P2P bridge */ +static int add_bridge(struct acpi_pci_root *root) +{ + acpi_status status; + unsigned long long tmp; + acpi_handle dummy_handle; + acpi_handle handle = root->device->handle; + + /* if the bridge doesn't have _STA, we assume it is always there */ + status = acpi_get_handle(handle, "_STA", &dummy_handle); + if (ACPI_SUCCESS(status)) { + status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp); + if (ACPI_FAILURE(status)) { + dbg("%s: _STA evaluation failure\n", __func__); + return 0; + } + if ((tmp & ACPI_STA_FUNCTIONING) == 0) + /* don't register this object */ + return 0; + } + + /* check if this bridge has ejectable slots */ + if (detect_ejectable_slots(handle) > 0) { + dbg("found PCI host-bus bridge with hot-pluggable slots\n"); + add_host_bridge(root); + } + + /* search P2P bridges under this host bridge */ + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + find_p2p_bridge, NULL, NULL, NULL); + + if (ACPI_FAILURE(status)) + warn("find_p2p_bridge failed (error code = 0x%x)\n", status); + + return 0; +} + static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) { struct acpiphp_bridge *bridge; - mutex_lock(&bridge_mutex); list_for_each_entry(bridge, &bridge_list, list) - if (bridge->handle == handle) { - get_bridge(bridge); - mutex_unlock(&bridge_mutex); + if (bridge->handle == handle) return bridge; - } - mutex_unlock(&bridge_mutex); return NULL; } static void cleanup_bridge(struct acpiphp_bridge *bridge) { - struct acpiphp_slot *slot; - struct acpiphp_func *func; + struct acpiphp_slot *slot, *next; + struct acpiphp_func *func, *tmp; acpi_status status; acpi_handle handle = bridge->handle; @@ -453,8 +543,10 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) err("failed to install interrupt notify handler\n"); } - list_for_each_entry(slot, &bridge->slots, node) { - list_for_each_entry(func, &slot->funcs, sibling) { + slot = bridge->slots; + while (slot) { + next = slot->next; + list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { if (is_dock_device(func->handle)) { unregister_hotplug_dock_device(func->handle); unregister_dock_notifier(&func->nb); @@ -466,13 +558,63 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) if (ACPI_FAILURE(status)) err("failed to remove notify handler\n"); } + list_del(&func->sibling); + kfree(func); } acpiphp_unregister_hotplug_slot(slot); + list_del(&slot->funcs); + kfree(slot); + slot = next; } - mutex_lock(&bridge_mutex); + /* + * Only P2P bridges have a pci_dev + */ + if (bridge->pci_dev) + put_device(&bridge->pci_bus->dev); + + pci_dev_put(bridge->pci_dev); list_del(&bridge->list); - mutex_unlock(&bridge_mutex); + kfree(bridge); +} + +static acpi_status +cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + struct acpiphp_bridge *bridge; + + /* cleanup p2p bridges under this P2P bridge + in a depth-first manner */ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + cleanup_p2p_bridge, NULL, NULL, NULL); + + bridge = acpiphp_handle_to_bridge(handle); + if (bridge) + cleanup_bridge(bridge); + + return AE_OK; +} + +static void remove_bridge(struct acpi_pci_root *root) +{ + struct acpiphp_bridge *bridge; + acpi_handle handle = root->device->handle; + + /* cleanup p2p bridges under this host bridge + in a depth-first manner */ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + (u32)1, cleanup_p2p_bridge, NULL, NULL, NULL); + + /* + * On root bridges with hotplug slots directly underneath (ie, + * no p2p bridge between), we call cleanup_bridge(). + * + * The else clause cleans up root bridges that either had no + * hotplug slots at all, or had a p2p bridge underneath. + */ + bridge = acpiphp_handle_to_bridge(handle); + if (bridge) + cleanup_bridge(bridge); } static int power_on_slot(struct acpiphp_slot *slot) @@ -656,7 +798,6 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) } } } - /** * enable_device - enable, configure a slot * @slot: slot to be enabled @@ -669,7 +810,9 @@ static int __ref enable_device(struct acpiphp_slot *slot) struct pci_dev *dev; struct pci_bus *bus = slot->bridge->pci_bus; struct acpiphp_func *func; + int retval = 0; int num, max, pass; + acpi_status status; if (slot->flags & SLOT_ENABLED) goto err_exit; @@ -724,11 +867,23 @@ static int __ref enable_device(struct acpiphp_slot *slot) slot->flags &= (~SLOT_ENABLED); continue; } + + if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && + dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { + pci_dev_put(dev); + continue; + } + + status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); + if (ACPI_FAILURE(status)) + warn("find_p2p_bridge failed (error code = 0x%x)\n", + status); + pci_dev_put(dev); } err_exit: - return 0; + return retval; } /* return first device in slot, acquiring a reference on it */ @@ -757,6 +912,23 @@ static int disable_device(struct acpiphp_slot *slot) { struct acpiphp_func *func; struct pci_dev *pdev; + struct pci_bus *bus = slot->bridge->pci_bus; + + /* The slot will be enabled when func 0 is added, so check + func 0 before disable the slot. */ + pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); + if (!pdev) + goto err_exit; + pci_dev_put(pdev); + + list_for_each_entry(func, &slot->funcs, sibling) { + if (func->bridge) { + /* cleanup p2p bridges under this P2P bridge */ + cleanup_p2p_bridge(func->bridge->handle, + (u32)1, NULL, NULL); + func->bridge = NULL; + } + } /* * enable_device() enumerates all functions in this device via @@ -775,6 +947,7 @@ static int disable_device(struct acpiphp_slot *slot) slot->flags &= (~SLOT_ENABLED); +err_exit: return 0; } @@ -864,7 +1037,7 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) enabled = disabled = 0; - list_for_each_entry(slot, &bridge->slots, node) { + for (slot = bridge->slots; slot; slot = slot->next) { unsigned int status = get_slot_status(slot); if (slot->flags & SLOT_ENABLED) { if (status == ACPI_STA_ALL) @@ -909,11 +1082,11 @@ static void acpiphp_set_hpp_values(struct pci_bus *bus) */ static void acpiphp_sanitize_bus(struct pci_bus *bus) { - struct pci_dev *dev, *tmp; + struct pci_dev *dev; int i; unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; - list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { + list_for_each_entry(dev, &bus->devices, bus_list) { for (i=0; iresource[i]; if ((res->flags & type_mask) && !res->start && @@ -945,7 +1118,6 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) dbg("%s: re-enumerating slots under %s\n", __func__, objname); acpiphp_check_bridge(bridge); - put_bridge(bridge); } return AE_OK ; } @@ -1023,7 +1195,6 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ - put_bridge(bridge); } /** @@ -1037,8 +1208,6 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *context) { - struct acpiphp_bridge *bridge = context; - /* * Currently the code adds all hotplug events to the kacpid_wq * queue when it should add hotplug events to the kacpi_hotplug_wq. @@ -1047,7 +1216,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, * For now just re-add this work to the kacpi_hotplug_wq so we * don't deadlock on hotplug actions. */ - get_bridge(bridge); alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); } @@ -1102,7 +1270,6 @@ static void _handle_hotplug_event_func(struct work_struct *work) acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_func */ - put_bridge(func->slot->bridge); } /** @@ -1116,8 +1283,6 @@ static void _handle_hotplug_event_func(struct work_struct *work) static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context) { - struct acpiphp_func *func = context; - /* * Currently the code adds all hotplug events to the kacpid_wq * queue when it should add hotplug events to the kacpi_hotplug_wq. @@ -1126,69 +1291,33 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, * For now just re-add this work to the kacpi_hotplug_wq so we * don't deadlock on hotplug actions. */ - get_bridge(func->slot->bridge); alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); } -/* - * Create hotplug slots for the PCI bus. - * It should always return 0 to avoid skipping following notifiers. +static struct acpi_pci_driver acpi_pci_hp_driver = { + .add = add_bridge, + .remove = remove_bridge, +}; + +/** + * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures */ -void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) +int __init acpiphp_glue_init(void) { - acpi_handle dummy_handle; - struct acpiphp_bridge *bridge; - - if (acpiphp_disabled) - return; - - if (detect_ejectable_slots(handle) <= 0) - return; - - bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); - if (bridge == NULL) { - err("out of memory\n"); - return; - } - - INIT_LIST_HEAD(&bridge->slots); - kref_init(&bridge->ref); - bridge->handle = handle; - bridge->pci_dev = pci_dev_get(bus->self); - bridge->pci_bus = bus; + acpi_pci_register_driver(&acpi_pci_hp_driver); - /* - * Grab a ref to the subordinate PCI bus in case the bus is - * removed via PCI core logical hotplug. The ref pins the bus - * (which we access during module unload). - */ - get_device(&bus->dev); - - if (!pci_is_root_bus(bridge->pci_bus) && - ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_EJ0", &dummy_handle))) { - dbg("found ejectable p2p bridge\n"); - bridge->flags |= BRIDGE_HAS_EJ0; - bridge->func = acpiphp_bridge_handle_to_function(handle); - } - - init_bridge_misc(bridge); + return 0; } -/* Destroy hotplug slots associated with the PCI bus */ -void acpiphp_remove_slots(struct pci_bus *bus) -{ - struct acpiphp_bridge *bridge, *tmp; - - if (acpiphp_disabled) - return; - list_for_each_entry_safe(bridge, tmp, &bridge_list, list) - if (bridge->pci_bus == bus) { - cleanup_bridge(bridge); - put_bridge(bridge); - break; - } +/** + * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures + * + * This function frees all data allocated in acpiphp_glue_init(). + */ +void acpiphp_glue_exit(void) +{ + acpi_pci_unregister_driver(&acpi_pci_hp_driver); } /** @@ -1267,7 +1396,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) sta = get_slot_status(slot); - return (sta & ACPI_STA_DEVICE_UI) ? 0 : 1; + return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; } diff --git a/trunk/drivers/pci/hotplug/cpci_hotplug.h b/trunk/drivers/pci/hotplug/cpci_hotplug.h index 1356211431d0..9fff878cf026 100644 --- a/trunk/drivers/pci/hotplug/cpci_hotplug.h +++ b/trunk/drivers/pci/hotplug/cpci_hotplug.h @@ -75,36 +75,28 @@ static inline const char *slot_name(struct slot *slot) return hotplug_slot_name(slot->hotplug_slot); } -int cpci_hp_register_controller(struct cpci_hp_controller *controller); -int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); -int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); -int cpci_hp_unregister_bus(struct pci_bus *bus); -int cpci_hp_start(void); -int cpci_hp_stop(void); +extern int cpci_hp_register_controller(struct cpci_hp_controller *controller); +extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); +extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); +extern int cpci_hp_unregister_bus(struct pci_bus *bus); +extern int cpci_hp_start(void); +extern int cpci_hp_stop(void); /* * Internal function prototypes, these functions should not be used by * board/chassis drivers. */ -u8 cpci_get_attention_status(struct slot *slot); -u8 cpci_get_latch_status(struct slot *slot); -u8 cpci_get_adapter_status(struct slot *slot); -u16 cpci_get_hs_csr(struct slot * slot); -int cpci_set_attention_status(struct slot *slot, int status); -int cpci_check_and_clear_ins(struct slot * slot); -int cpci_check_ext(struct slot * slot); -int cpci_clear_ext(struct slot * slot); -int cpci_led_on(struct slot * slot); -int cpci_led_off(struct slot * slot); -int cpci_configure_slot(struct slot *slot); -int cpci_unconfigure_slot(struct slot *slot); - -#ifdef CONFIG_HOTPLUG_PCI_CPCI -int cpci_hotplug_init(int debug); -void cpci_hotplug_exit(void); -#else -static inline int cpci_hotplug_init(int debug) { return 0; } -static inline void cpci_hotplug_exit(void) { } -#endif +extern u8 cpci_get_attention_status(struct slot *slot); +extern u8 cpci_get_latch_status(struct slot *slot); +extern u8 cpci_get_adapter_status(struct slot *slot); +extern u16 cpci_get_hs_csr(struct slot * slot); +extern int cpci_set_attention_status(struct slot *slot, int status); +extern int cpci_check_and_clear_ins(struct slot * slot); +extern int cpci_check_ext(struct slot * slot); +extern int cpci_clear_ext(struct slot * slot); +extern int cpci_led_on(struct slot * slot); +extern int cpci_led_off(struct slot * slot); +extern int cpci_configure_slot(struct slot *slot); +extern int cpci_unconfigure_slot(struct slot *slot); #endif /* _CPCI_HOTPLUG_H */ diff --git a/trunk/drivers/pci/hotplug/cpqphp.h b/trunk/drivers/pci/hotplug/cpqphp.h index 516b87738b6e..d8ffc7366801 100644 --- a/trunk/drivers/pci/hotplug/cpqphp.h +++ b/trunk/drivers/pci/hotplug/cpqphp.h @@ -404,44 +404,50 @@ struct resource_lists { /* debugfs functions for the hotplug controller info */ -void cpqhp_initialize_debugfs(void); -void cpqhp_shutdown_debugfs(void); -void cpqhp_create_debugfs_files(struct controller *ctrl); -void cpqhp_remove_debugfs_files(struct controller *ctrl); +extern void cpqhp_initialize_debugfs(void); +extern void cpqhp_shutdown_debugfs(void); +extern void cpqhp_create_debugfs_files(struct controller *ctrl); +extern void cpqhp_remove_debugfs_files(struct controller *ctrl); /* controller functions */ -void cpqhp_pushbutton_thread(unsigned long event_pointer); -irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); -int cpqhp_find_available_resources(struct controller *ctrl, - void __iomem *rom_start); -int cpqhp_event_start_thread(void); -void cpqhp_event_stop_thread(void); -struct pci_func *cpqhp_slot_create(unsigned char busnumber); -struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, - unsigned char index); -int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); -int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); -int cpqhp_hardware_test(struct controller *ctrl, int test_num); +extern void cpqhp_pushbutton_thread(unsigned long event_pointer); +extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); +extern int cpqhp_find_available_resources(struct controller *ctrl, + void __iomem *rom_start); +extern int cpqhp_event_start_thread(void); +extern void cpqhp_event_stop_thread(void); +extern struct pci_func *cpqhp_slot_create(unsigned char busnumber); +extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, + unsigned char index); +extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); +extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); +extern int cpqhp_hardware_test(struct controller *ctrl, int test_num); /* resource functions */ -int cpqhp_resource_sort_and_combine (struct pci_resource **head); +extern int cpqhp_resource_sort_and_combine (struct pci_resource **head); /* pci functions */ -int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); -int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, - u8 slot); -int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug); -int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func); -int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func); -int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func); -int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot); -int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); -void cpqhp_destroy_board_resources(struct pci_func *func); -int cpqhp_return_board_resources(struct pci_func *func, - struct resource_lists *resources); -void cpqhp_destroy_resource_list(struct resource_lists *resources); -int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func); -int cpqhp_unconfigure_device(struct pci_func *func); +extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); +extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, + u8 slot); +extern int cpqhp_save_config(struct controller *ctrl, int busnumber, + int is_hot_plug); +extern int cpqhp_save_base_addr_length(struct controller *ctrl, + struct pci_func *func); +extern int cpqhp_save_used_resources(struct controller *ctrl, + struct pci_func *func); +extern int cpqhp_configure_board(struct controller *ctrl, + struct pci_func *func); +extern int cpqhp_save_slot_config(struct controller *ctrl, + struct pci_func *new_slot); +extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); +extern void cpqhp_destroy_board_resources(struct pci_func *func); +extern int cpqhp_return_board_resources (struct pci_func *func, + struct resource_lists *resources); +extern void cpqhp_destroy_resource_list(struct resource_lists *resources); +extern int cpqhp_configure_device(struct controller *ctrl, + struct pci_func *func); +extern int cpqhp_unconfigure_device(struct pci_func *func); /* Global variables */ extern int cpqhp_debug; diff --git a/trunk/drivers/pci/hotplug/cpqphp_nvram.h b/trunk/drivers/pci/hotplug/cpqphp_nvram.h index 34e4e54fcf15..e89c0702119d 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_nvram.h +++ b/trunk/drivers/pci/hotplug/cpqphp_nvram.h @@ -30,26 +30,26 @@ #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM -static inline void compaq_nvram_init(void __iomem *rom_start) +static inline void compaq_nvram_init (void __iomem *rom_start) { return; } -static inline int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) +static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) { return 0; } -static inline int compaq_nvram_store(void __iomem *rom_start) +static inline int compaq_nvram_store (void __iomem *rom_start) { return 0; } #else -void compaq_nvram_init(void __iomem *rom_start); -int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl); -int compaq_nvram_store(void __iomem *rom_start); +extern void compaq_nvram_init (void __iomem *rom_start); +extern int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl); +extern int compaq_nvram_store (void __iomem *rom_start); #endif diff --git a/trunk/drivers/pci/hotplug/ibmphp.h b/trunk/drivers/pci/hotplug/ibmphp.h index 8c5b25871d02..a8d391a4957d 100644 --- a/trunk/drivers/pci/hotplug/ibmphp.h +++ b/trunk/drivers/pci/hotplug/ibmphp.h @@ -275,17 +275,17 @@ extern struct list_head ibmphp_slot_head; * FUNCTION PROTOTYPES * ***********************************************************/ -void ibmphp_free_ebda_hpc_queue(void); -int ibmphp_access_ebda(void); -struct slot *ibmphp_get_slot_from_physical_num(u8); -int ibmphp_get_total_hp_slots(void); -void ibmphp_free_ibm_slot(struct slot *); -void ibmphp_free_bus_info_queue(void); -void ibmphp_free_ebda_pci_rsrc_queue(void); -struct bus_info *ibmphp_find_same_bus_num(u32); -int ibmphp_get_bus_index(u8); -u16 ibmphp_get_total_controllers(void); -int ibmphp_register_pci(void); +extern void ibmphp_free_ebda_hpc_queue (void); +extern int ibmphp_access_ebda (void); +extern struct slot *ibmphp_get_slot_from_physical_num (u8); +extern int ibmphp_get_total_hp_slots (void); +extern void ibmphp_free_ibm_slot (struct slot *); +extern void ibmphp_free_bus_info_queue (void); +extern void ibmphp_free_ebda_pci_rsrc_queue (void); +extern struct bus_info *ibmphp_find_same_bus_num (u32); +extern int ibmphp_get_bus_index (u8); +extern u16 ibmphp_get_total_controllers (void); +extern int ibmphp_register_pci (void); /* passed parameters */ #define MEM 0 @@ -381,24 +381,24 @@ struct res_needed { /* functions */ -int ibmphp_rsrc_init(void); -int ibmphp_add_resource(struct resource_node *); -int ibmphp_remove_resource(struct resource_node *); -int ibmphp_find_resource(struct bus_node *, u32, struct resource_node **, int); -int ibmphp_check_resource(struct resource_node *, u8); -int ibmphp_remove_bus(struct bus_node *, u8); -void ibmphp_free_resources(void); -int ibmphp_add_pfmem_from_mem(struct resource_node *); -struct bus_node *ibmphp_find_res_bus(u8); -void ibmphp_print_test(void); /* for debugging purposes */ +extern int ibmphp_rsrc_init (void); +extern int ibmphp_add_resource (struct resource_node *); +extern int ibmphp_remove_resource (struct resource_node *); +extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int); +extern int ibmphp_check_resource (struct resource_node *, u8); +extern int ibmphp_remove_bus (struct bus_node *, u8); +extern void ibmphp_free_resources (void); +extern int ibmphp_add_pfmem_from_mem (struct resource_node *); +extern struct bus_node *ibmphp_find_res_bus (u8); +extern void ibmphp_print_test (void); /* for debugging purposes */ -void ibmphp_hpc_initvars(void); -int ibmphp_hpc_readslot(struct slot *, u8, u8 *); -int ibmphp_hpc_writeslot(struct slot *, u8); -void ibmphp_lock_operations(void); -void ibmphp_unlock_operations(void); -int ibmphp_hpc_start_poll_thread(void); -void ibmphp_hpc_stop_poll_thread(void); +extern void ibmphp_hpc_initvars (void); +extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *); +extern int ibmphp_hpc_writeslot (struct slot *, u8); +extern void ibmphp_lock_operations (void); +extern void ibmphp_unlock_operations (void); +extern int ibmphp_hpc_start_poll_thread (void); +extern void ibmphp_hpc_stop_poll_thread (void); //---------------------------------------------------------------------------- @@ -749,11 +749,11 @@ struct controller { /* Functions */ -int ibmphp_init_devno(struct slot **); /* This function is called from EBDA, so we need it not be static */ -int ibmphp_do_disable_slot(struct slot *slot_cur); -int ibmphp_update_slot_info(struct slot *); /* This function is called from HPC, so we need it to not be be static */ -int ibmphp_configure_card(struct pci_func *, u8); -int ibmphp_unconfigure_card(struct slot **, int); +extern int ibmphp_init_devno (struct slot **); /* This function is called from EBDA, so we need it not be static */ +extern int ibmphp_do_disable_slot (struct slot *slot_cur); +extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */ +extern int ibmphp_configure_card (struct pci_func *, u8); +extern int ibmphp_unconfigure_card (struct slot **, int); extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; #endif //__IBMPHP_H diff --git a/trunk/drivers/pci/hotplug/pci_hotplug_core.c b/trunk/drivers/pci/hotplug/pci_hotplug_core.c index ec20f74c8981..202f4a969eb5 100644 --- a/trunk/drivers/pci/hotplug/pci_hotplug_core.c +++ b/trunk/drivers/pci/hotplug/pci_hotplug_core.c @@ -41,7 +41,6 @@ #include #include #include "../pci.h" -#include "cpci_hotplug.h" #define MY_NAME "pci_hotplug" @@ -64,6 +63,14 @@ static bool debug; static LIST_HEAD(pci_hotplug_slot_list); static DEFINE_MUTEX(pci_hp_mutex); +#ifdef CONFIG_HOTPLUG_PCI_CPCI +extern int cpci_hotplug_init(int debug); +extern void cpci_hotplug_exit(void); +#else +static inline int cpci_hotplug_init(int debug) { return 0; } +static inline void cpci_hotplug_exit(void) { } +#endif + /* Weee, fun with macros... */ #define GET_STATUS(name,type) \ static int get_##name (struct hotplug_slot *slot, type *value) \ @@ -517,11 +524,13 @@ int pci_hp_deregister(struct hotplug_slot *hotplug) * * Returns 0 if successful, anything else for an error. */ -int pci_hp_change_slot_info(struct hotplug_slot *hotplug, - struct hotplug_slot_info *info) +int __must_check pci_hp_change_slot_info(struct hotplug_slot *hotplug, + struct hotplug_slot_info *info) { + struct pci_slot *slot; if (!hotplug || !info) return -ENODEV; + slot = hotplug->pci_slot; memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 7fb326983ed6..2c113de94323 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -127,15 +127,15 @@ struct controller { #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) #define PSN(ctrl) ((ctrl)->slot_cap >> 19) -int pciehp_sysfs_enable_slot(struct slot *slot); -int pciehp_sysfs_disable_slot(struct slot *slot); -u8 pciehp_handle_attention_button(struct slot *p_slot); -u8 pciehp_handle_switch_change(struct slot *p_slot); -u8 pciehp_handle_presence_change(struct slot *p_slot); -u8 pciehp_handle_power_fault(struct slot *p_slot); -int pciehp_configure_device(struct slot *p_slot); -int pciehp_unconfigure_device(struct slot *p_slot); -void pciehp_queue_pushbutton_work(struct work_struct *work); +extern int pciehp_sysfs_enable_slot(struct slot *slot); +extern int pciehp_sysfs_disable_slot(struct slot *slot); +extern u8 pciehp_handle_attention_button(struct slot *p_slot); +extern u8 pciehp_handle_switch_change(struct slot *p_slot); +extern u8 pciehp_handle_presence_change(struct slot *p_slot); +extern u8 pciehp_handle_power_fault(struct slot *p_slot); +extern int pciehp_configure_device(struct slot *p_slot); +extern int pciehp_unconfigure_device(struct slot *p_slot); +extern void pciehp_queue_pushbutton_work(struct work_struct *work); struct controller *pcie_init(struct pcie_device *dev); int pcie_init_notification(struct controller *ctrl); int pciehp_enable_slot(struct slot *p_slot); @@ -166,8 +166,8 @@ static inline const char *slot_name(struct slot *slot) #include #include -void __init pciehp_acpi_slot_detection_init(void); -int pciehp_acpi_slot_detection_check(struct pci_dev *dev); +extern void __init pciehp_acpi_slot_detection_init(void); +extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); static inline void pciehp_firmware_init(void) { diff --git a/trunk/drivers/pci/hotplug/pciehp_acpi.c b/trunk/drivers/pci/hotplug/pciehp_acpi.c index ead7c534095e..24d709b7388c 100644 --- a/trunk/drivers/pci/hotplug/pciehp_acpi.c +++ b/trunk/drivers/pci/hotplug/pciehp_acpi.c @@ -90,7 +90,7 @@ static int __init dummy_probe(struct pcie_device *dev) slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) return -ENOMEM; - slot->number = (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19; + slot->number = slot_cap >> 19; list_for_each_entry(tmp, &dummy_slots, list) { if (tmp->number == slot->number) dup_slot_id++; diff --git a/trunk/drivers/pci/hotplug/rpadlpar.h b/trunk/drivers/pci/hotplug/rpadlpar.h index 81df93931ad0..4a0a59b82eae 100644 --- a/trunk/drivers/pci/hotplug/rpadlpar.h +++ b/trunk/drivers/pci/hotplug/rpadlpar.h @@ -15,10 +15,10 @@ #ifndef _RPADLPAR_IO_H_ #define _RPADLPAR_IO_H_ -int dlpar_sysfs_init(void); -void dlpar_sysfs_exit(void); +extern int dlpar_sysfs_init(void); +extern void dlpar_sysfs_exit(void); -int dlpar_add_slot(char *drc_name); -int dlpar_remove_slot(char *drc_name); +extern int dlpar_add_slot(char *drc_name); +extern int dlpar_remove_slot(char *drc_name); #endif diff --git a/trunk/drivers/pci/hotplug/rpaphp.h b/trunk/drivers/pci/hotplug/rpaphp.h index 3135856e5e1c..df5677440a08 100644 --- a/trunk/drivers/pci/hotplug/rpaphp.h +++ b/trunk/drivers/pci/hotplug/rpaphp.h @@ -86,18 +86,18 @@ extern struct list_head rpaphp_slot_head; /* function prototypes */ /* rpaphp_pci.c */ -int rpaphp_enable_slot(struct slot *slot); -int rpaphp_get_sensor_state(struct slot *slot, int *state); +extern int rpaphp_enable_slot(struct slot *slot); +extern int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ -int rpaphp_add_slot(struct device_node *dn); -int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, +extern int rpaphp_add_slot(struct device_node *dn); +extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, char **drc_name, char **drc_type, int *drc_power_domain); /* rpaphp_slot.c */ -void dealloc_slot_struct(struct slot *slot); -struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); -int rpaphp_register_slot(struct slot *slot); -int rpaphp_deregister_slot(struct slot *slot); +extern void dealloc_slot_struct(struct slot *slot); +extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); +extern int rpaphp_register_slot(struct slot *slot); +extern int rpaphp_deregister_slot(struct slot *slot); #endif /* _PPC64PHP_H */ diff --git a/trunk/drivers/pci/hotplug/s390_pci_hpc.c b/trunk/drivers/pci/hotplug/s390_pci_hpc.c index 46a7b738f61f..7db249a25016 100644 --- a/trunk/drivers/pci/hotplug/s390_pci_hpc.c +++ b/trunk/drivers/pci/hotplug/s390_pci_hpc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #define SLOT_NAME_SIZE 10 @@ -50,7 +49,6 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) return -EIO; rc = sclp_pci_configure(slot->zdev->fid); - zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, rc); if (!rc) { slot->zdev->state = ZPCI_FN_STATE_CONFIGURED; /* automatically scan the device after is was configured */ @@ -68,16 +66,16 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) if (!zpci_fn_configured(slot->zdev->state)) return -EIO; - rc = zpci_disable_device(slot->zdev); - if (rc) - return rc; /* TODO: we rely on the user to unbind/remove the device, is that plausible * or do we need to trigger that here? */ rc = sclp_pci_deconfigure(slot->zdev->fid); - zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, rc); - if (!rc) + if (!rc) { + /* Fixme: better call List-PCI to find the disabled FH + for the FID since the FH should be opaque... */ + slot->zdev->fh &= 0x7fffffff; slot->zdev->state = ZPCI_FN_STATE_STANDBY; + } return rc; } diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index e260f207a90e..b849f995075a 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -168,19 +168,19 @@ struct controller { #define WRONG_BUS_FREQUENCY 0x0000000D #define POWER_FAILURE 0x0000000E -int __must_check shpchp_create_ctrl_files(struct controller *ctrl); -void shpchp_remove_ctrl_files(struct controller *ctrl); -int shpchp_sysfs_enable_slot(struct slot *slot); -int shpchp_sysfs_disable_slot(struct slot *slot); -u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); -u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); -u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); -u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); -int shpchp_configure_device(struct slot *p_slot); -int shpchp_unconfigure_device(struct slot *p_slot); -void cleanup_slots(struct controller *ctrl); -void shpchp_queue_pushbutton_work(struct work_struct *work); -int shpc_init( struct controller *ctrl, struct pci_dev *pdev); +extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); +extern void shpchp_remove_ctrl_files(struct controller *ctrl); +extern int shpchp_sysfs_enable_slot(struct slot *slot); +extern int shpchp_sysfs_disable_slot(struct slot *slot); +extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); +extern int shpchp_configure_device(struct slot *p_slot); +extern int shpchp_unconfigure_device(struct slot *p_slot); +extern void cleanup_slots(struct controller *ctrl); +extern void shpchp_queue_pushbutton_work(struct work_struct *work); +extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); static inline const char *slot_name(struct slot *slot) { diff --git a/trunk/drivers/pci/hotplug/shpchp_sysfs.c b/trunk/drivers/pci/hotplug/shpchp_sysfs.c index e8c31fe20566..eeb23ceae4a8 100644 --- a/trunk/drivers/pci/hotplug/shpchp_sysfs.c +++ b/trunk/drivers/pci/hotplug/shpchp_sysfs.c @@ -85,7 +85,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); -int shpchp_create_ctrl_files (struct controller *ctrl) +int __must_check shpchp_create_ctrl_files (struct controller *ctrl) { return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); } diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index d40bed726769..00cc78c7aa04 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -22,12 +22,10 @@ #include #include "pci.h" +#include "msi.h" static int pci_msi_enable = 1; -#define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) - - /* Arch hooks */ #ifndef arch_msi_check_device @@ -113,26 +111,32 @@ void default_restore_msi_irqs(struct pci_dev *dev, int irq) } #endif -static void msi_set_enable(struct pci_dev *dev, int enable) +static void msi_set_enable(struct pci_dev *dev, int pos, int enable) { u16 control; - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); + BUG_ON(!pos); + + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); control &= ~PCI_MSI_FLAGS_ENABLE; if (enable) control |= PCI_MSI_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); } static void msix_set_enable(struct pci_dev *dev, int enable) { + int pos; u16 control; - pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); - control &= ~PCI_MSIX_FLAGS_ENABLE; - if (enable) - control |= PCI_MSIX_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); + control &= ~PCI_MSIX_FLAGS_ENABLE; + if (enable) + control |= PCI_MSIX_FLAGS_ENABLE; + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); + } } static inline __attribute_const__ u32 msi_mask(unsigned x) @@ -243,18 +247,18 @@ void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) msg->data = readl(base + PCI_MSIX_ENTRY_DATA); } else { struct pci_dev *dev = entry->dev; - int pos = dev->msi_cap; + int pos = entry->msi_attrib.pos; u16 data; - pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, - &msg->address_lo); + pci_read_config_dword(dev, msi_lower_address_reg(pos), + &msg->address_lo); if (entry->msi_attrib.is_64) { - pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, - &msg->address_hi); - pci_read_config_word(dev, pos + PCI_MSI_DATA_64, &data); + pci_read_config_dword(dev, msi_upper_address_reg(pos), + &msg->address_hi); + pci_read_config_word(dev, msi_data_reg(pos, 1), &data); } else { msg->address_hi = 0; - pci_read_config_word(dev, pos + PCI_MSI_DATA_32, &data); + pci_read_config_word(dev, msi_data_reg(pos, 0), &data); } msg->data = data; } @@ -298,24 +302,24 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) writel(msg->data, base + PCI_MSIX_ENTRY_DATA); } else { struct pci_dev *dev = entry->dev; - int pos = dev->msi_cap; + int pos = entry->msi_attrib.pos; u16 msgctl; - pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); + pci_read_config_word(dev, msi_control_reg(pos), &msgctl); msgctl &= ~PCI_MSI_FLAGS_QSIZE; msgctl |= entry->msi_attrib.multiple << 4; - pci_write_config_word(dev, pos + PCI_MSI_FLAGS, msgctl); + pci_write_config_word(dev, msi_control_reg(pos), msgctl); - pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, - msg->address_lo); + pci_write_config_dword(dev, msi_lower_address_reg(pos), + msg->address_lo); if (entry->msi_attrib.is_64) { - pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, - msg->address_hi); - pci_write_config_word(dev, pos + PCI_MSI_DATA_64, - msg->data); + pci_write_config_dword(dev, msi_upper_address_reg(pos), + msg->address_hi); + pci_write_config_word(dev, msi_data_reg(pos, 1), + msg->data); } else { - pci_write_config_word(dev, pos + PCI_MSI_DATA_32, - msg->data); + pci_write_config_word(dev, msi_data_reg(pos, 0), + msg->data); } } entry->msg = *msg; @@ -387,6 +391,7 @@ static void pci_intx_for_msi(struct pci_dev *dev, int enable) static void __pci_restore_msi_state(struct pci_dev *dev) { + int pos; u16 control; struct msi_desc *entry; @@ -394,20 +399,22 @@ static void __pci_restore_msi_state(struct pci_dev *dev) return; entry = irq_get_msi_desc(dev->irq); + pos = entry->msi_attrib.pos; pci_intx_for_msi(dev, 0); - msi_set_enable(dev, 0); + msi_set_enable(dev, pos, 0); arch_restore_msi_irqs(dev, dev->irq); - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); msi_mask_irq(entry, msi_capable_mask(control), entry->masked); control &= ~PCI_MSI_FLAGS_QSIZE; control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); } static void __pci_restore_msix_state(struct pci_dev *dev) { + int pos; struct msi_desc *entry; u16 control; @@ -415,12 +422,13 @@ static void __pci_restore_msix_state(struct pci_dev *dev) return; BUG_ON(list_empty(&dev->msi_list)); entry = list_first_entry(&dev->msi_list, struct msi_desc, list); - pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); + pos = entry->msi_attrib.pos; + pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); /* route the table */ pci_intx_for_msi(dev, 0); control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); list_for_each_entry(entry, &dev->msi_list, list) { arch_restore_msi_irqs(dev, entry->irq); @@ -428,7 +436,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) } control &= ~PCI_MSIX_FLAGS_MASKALL; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); } void pci_restore_msi_state(struct pci_dev *dev) @@ -476,12 +484,12 @@ static struct msi_attribute mode_attribute = __ATTR(mode, S_IRUGO, show_msi_mode, NULL); -static struct attribute *msi_irq_default_attrs[] = { +struct attribute *msi_irq_default_attrs[] = { &mode_attribute.attr, NULL }; -static void msi_kobj_release(struct kobject *kobj) +void msi_kobj_release(struct kobject *kobj) { struct msi_desc *entry = to_msi_desc(kobj); @@ -544,27 +552,27 @@ static int populate_msi_sysfs(struct pci_dev *pdev) static int msi_capability_init(struct pci_dev *dev, int nvec) { struct msi_desc *entry; - int ret; + int pos, ret; u16 control; unsigned mask; - msi_set_enable(dev, 0); /* Disable MSI during set up */ + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + msi_set_enable(dev, pos, 0); /* Disable MSI during set up */ - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); + pci_read_config_word(dev, msi_control_reg(pos), &control); /* MSI Entry Initialization */ entry = alloc_msi_entry(dev); if (!entry) return -ENOMEM; entry->msi_attrib.is_msix = 0; - entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); + entry->msi_attrib.is_64 = is_64bit_address(control); entry->msi_attrib.entry_nr = 0; - entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); + entry->msi_attrib.maskbit = is_mask_bit_support(control); entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ - entry->msi_attrib.pos = dev->msi_cap; + entry->msi_attrib.pos = pos; - entry->mask_pos = dev->msi_cap + (control & PCI_MSI_FLAGS_64BIT) ? - PCI_MSI_MASK_64 : PCI_MSI_MASK_32; + entry->mask_pos = msi_mask_reg(pos, entry->msi_attrib.is_64); /* All MSIs are unmasked by default, Mask them all */ if (entry->msi_attrib.maskbit) pci_read_config_dword(dev, entry->mask_pos, &entry->masked); @@ -590,30 +598,31 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) /* Set MSI enabled bits */ pci_intx_for_msi(dev, 0); - msi_set_enable(dev, 1); + msi_set_enable(dev, pos, 1); dev->msi_enabled = 1; dev->irq = entry->irq; return 0; } -static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries) +static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos, + unsigned nr_entries) { resource_size_t phys_addr; u32 table_offset; u8 bir; - pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, - &table_offset); - bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); - table_offset &= PCI_MSIX_TABLE_OFFSET; + pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); + table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; phys_addr = pci_resource_start(dev, bir) + table_offset; return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); } -static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, - struct msix_entry *entries, int nvec) +static int msix_setup_entries(struct pci_dev *dev, unsigned pos, + void __iomem *base, struct msix_entry *entries, + int nvec) { struct msi_desc *entry; int i; @@ -633,7 +642,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, entry->msi_attrib.is_64 = 1; entry->msi_attrib.entry_nr = entries[i].entry; entry->msi_attrib.default_irq = dev->irq; - entry->msi_attrib.pos = dev->msix_cap; + entry->msi_attrib.pos = pos; entry->mask_base = base; list_add_tail(&entry->list, &dev->msi_list); @@ -643,7 +652,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, } static void msix_program_entries(struct pci_dev *dev, - struct msix_entry *entries) + struct msix_entry *entries) { struct msi_desc *entry; int i = 0; @@ -673,22 +682,23 @@ static void msix_program_entries(struct pci_dev *dev, static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { - int ret; + int pos, ret; u16 control; void __iomem *base; - pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); /* Ensure MSI-X is disabled while it is set up */ control &= ~PCI_MSIX_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); /* Request & Map MSI-X table region */ - base = msix_map_region(dev, msix_table_size(control)); + base = msix_map_region(dev, pos, multi_msix_capable(control)); if (!base) return -ENOMEM; - ret = msix_setup_entries(dev, base, entries, nvec); + ret = msix_setup_entries(dev, pos, base, entries, nvec); if (ret) return ret; @@ -702,7 +712,7 @@ static int msix_capability_init(struct pci_dev *dev, * interrupts coming in before they're fully set up. */ control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); msix_program_entries(dev, entries); @@ -717,7 +727,7 @@ static int msix_capability_init(struct pci_dev *dev, dev->msix_enabled = 1; control &= ~PCI_MSIX_FLAGS_MASKALL; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); return 0; @@ -785,6 +795,9 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) if (ret) return ret; + if (!pci_find_capability(dev, type)) + return -EINVAL; + return 0; } @@ -803,13 +816,13 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) */ int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) { - int status, maxvec; + int status, pos, maxvec; u16 msgctl; - if (!dev->msi_cap) + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (!pos) return -EINVAL; - - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); if (nvec > maxvec) return maxvec; @@ -834,13 +847,14 @@ EXPORT_SYMBOL(pci_enable_msi_block); int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) { - int ret, nvec; + int ret, pos, nvec; u16 msgctl; - if (!dev->msi_cap) + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (!pos) return -EINVAL; - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); if (maxvec) @@ -862,19 +876,21 @@ void pci_msi_shutdown(struct pci_dev *dev) struct msi_desc *desc; u32 mask; u16 ctrl; + unsigned pos; if (!pci_msi_enable || !dev || !dev->msi_enabled) return; BUG_ON(list_empty(&dev->msi_list)); desc = list_first_entry(&dev->msi_list, struct msi_desc, list); + pos = desc->msi_attrib.pos; - msi_set_enable(dev, 0); + msi_set_enable(dev, pos, 0); pci_intx_for_msi(dev, 1); dev->msi_enabled = 0; /* Return the device with MSI unmasked as initial states */ - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &ctrl); + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl); mask = msi_capable_mask(ctrl); /* Keep cached state to be restored */ __msi_mask_irq(desc, mask, ~mask); @@ -901,13 +917,15 @@ EXPORT_SYMBOL(pci_disable_msi); */ int pci_msix_table_size(struct pci_dev *dev) { + int pos; u16 control; - if (!dev->msix_cap) + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + if (!pos) return 0; - pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); - return msix_table_size(control); + pci_read_config_word(dev, msi_control_reg(pos), &control); + return multi_msix_capable(control); } /** @@ -930,7 +948,7 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) int status, nr_entries; int i, j; - if (!entries || !dev->msix_cap) + if (!entries) return -EINVAL; status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); @@ -1030,17 +1048,15 @@ EXPORT_SYMBOL(pci_msi_enabled); void pci_msi_init_pci_dev(struct pci_dev *dev) { + int pos; INIT_LIST_HEAD(&dev->msi_list); /* Disable the msi hardware to avoid screaming interrupts * during boot. This is the power on reset default so * usually this should be a noop. */ - dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (dev->msi_cap) - msi_set_enable(dev, 0); - - dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (dev->msix_cap) - msix_set_enable(dev, 0); + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (pos) + msi_set_enable(dev, pos, 0); + msix_set_enable(dev, 0); } diff --git a/trunk/drivers/pci/msi.h b/trunk/drivers/pci/msi.h new file mode 100644 index 000000000000..65c42f80f23e --- /dev/null +++ b/trunk/drivers/pci/msi.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2003-2004 Intel + * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) + */ + +#ifndef MSI_H +#define MSI_H + +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) +#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) +#define msi_data_reg(base, is64bit) \ + (base + ((is64bit == 1) ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32)) +#define msi_mask_reg(base, is64bit) \ + (base + ((is64bit == 1) ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32)) +#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) +#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) + +#define msix_table_offset_reg(base) (base + PCI_MSIX_TABLE) +#define msix_pba_offset_reg(base) (base + PCI_MSIX_PBA) +#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) +#define multi_msix_capable(control) msix_table_size((control)) + +#endif /* MSI_H */ diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index e4b1fb2c0f5d..39c937f9b426 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -53,15 +53,14 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) return; } - /* Clear PME Status if set. */ - if (pci_dev->pme_support) - pci_check_pme_status(pci_dev); + if (!pci_dev->pm_cap || !pci_dev->pme_support + || pci_check_pme_status(pci_dev)) { + if (pci_dev->pme_poll) + pci_dev->pme_poll = false; - if (pci_dev->pme_poll) - pci_dev->pme_poll = false; - - pci_wakeup_event(pci_dev); - pm_runtime_resume(&pci_dev->dev); + pci_wakeup_event(pci_dev); + pm_runtime_resume(&pci_dev->dev); + } if (pci_dev->subordinate) pci_pme_wakeup_bus(pci_dev->subordinate); @@ -288,32 +287,6 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { .run_wake = acpi_pci_run_wake, }; -void acpi_pci_add_bus(struct pci_bus *bus) -{ - acpi_handle handle = NULL; - - if (bus->bridge) - handle = ACPI_HANDLE(bus->bridge); - if (acpi_pci_disabled || handle == NULL) - return; - - acpi_pci_slot_enumerate(bus, handle); - acpiphp_enumerate_slots(bus, handle); -} - -void acpi_pci_remove_bus(struct pci_bus *bus) -{ - /* - * bus->bridge->acpi_node.handle has already been reset to NULL - * when acpi_pci_remove_bus() is called, so don't check ACPI handle. - */ - if (acpi_pci_disabled) - return; - - acpiphp_remove_slots(bus); - acpi_pci_slot_remove(bus); -} - /* ACPI bus type */ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) { @@ -358,14 +331,8 @@ static void pci_acpi_cleanup(struct device *dev) } } -static bool pci_acpi_bus_match(struct device *dev) -{ - return dev->bus == &pci_bus_type; -} - static struct acpi_bus_type acpi_pci_bus = { - .name = "PCI", - .match = pci_acpi_bus_match, + .bus = &pci_bus_type, .find_device = acpi_pci_find_device, .setup = pci_acpi_setup, .cleanup = pci_acpi_cleanup, @@ -388,11 +355,7 @@ static int __init acpi_pci_init(void) ret = register_acpi_bus_type(&acpi_pci_bus); if (ret) return 0; - pci_set_platform_pm(&acpi_pci_platform_pm); - acpi_pci_slot_init(); - acpiphp_init(); - return 0; } arch_initcall(acpi_pci_init); diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 79277fb36c6b..1fa1e482a999 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -390,10 +390,9 @@ static void pci_device_shutdown(struct device *dev) /* * Turn off Bus Master bit on the device to tell it to not - * continue to do DMA. Don't touch devices in D3cold or unknown states. + * continue to do DMA */ - if (pci_dev->current_state <= PCI_D3hot) - pci_clear_master(pci_dev); + pci_clear_master(pci_dev); } #ifdef CONFIG_PM diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index 5b4a9d9cd200..9c6e9bb674ec 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -897,7 +897,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, if (pci_resource_len(pdev, resno) == 0) return 0; - nr = vma_pages(vma); + nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; start = vma->vm_pgoff; size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; pci_start = (mmap_api == PCI_MMAP_PROCFS) ? diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index a899d8bb190d..b099e0025d2b 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -646,11 +646,15 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) error = platform_pci_set_power_state(dev, state); if (!error) pci_update_current_state(dev, state); - } else + /* Fall back to PCI_D0 if native PM is not supported */ + if (!dev->pm_cap) + dev->current_state = PCI_D0; + } else { error = -ENODEV; - - if (error && !dev->pm_cap) /* Fall back to PCI_D0 */ - dev->current_state = PCI_D0; + /* Fall back to PCI_D0 if native PM is not supported */ + if (!dev->pm_cap) + dev->current_state = PCI_D0; + } return error; } @@ -1571,7 +1575,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable) { u16 pmcsr; - if (!dev->pme_support) + if (!dev->pm_cap) return; pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); @@ -1920,7 +1924,6 @@ void pci_pm_init(struct pci_dev *dev) dev->wakeup_prepared = false; dev->pm_cap = 0; - dev->pme_support = 0; /* find PCI PM capability in list */ pm = pci_find_capability(dev, PCI_CAP_ID_PM); @@ -1972,6 +1975,8 @@ void pci_pm_init(struct pci_dev *dev) device_set_wakeup_capable(&dev->dev, true); /* Disable the PME# generation functionality */ pci_pme_active(dev, false); + } else { + dev->pme_support = 0; } } @@ -2614,7 +2619,7 @@ void pci_release_selected_regions(struct pci_dev *pdev, int bars) pci_release_region(pdev, i); } -static int __pci_request_selected_regions(struct pci_dev *pdev, int bars, +int __pci_request_selected_regions(struct pci_dev *pdev, int bars, const char *res_name, int excl) { int i; @@ -3694,7 +3699,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock); * RETURNS: Resource alignment if it is specified. * Zero if it is not specified. */ -static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) +resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) { int seg, bus, slot, func, align_order, count; resource_size_t align = 0; @@ -3807,7 +3812,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) } } -static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) +ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) { if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; @@ -3818,7 +3823,7 @@ static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) return count; } -static ssize_t pci_get_resource_alignment_param(char *buf, size_t size) +ssize_t pci_get_resource_alignment_param(char *buf, size_t size) { size_t count; spin_lock(&resource_alignment_lock); diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 68678ed76b0d..7346ee68f47d 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -8,25 +8,26 @@ /* Functions internal to the PCI core code */ -int pci_create_sysfs_dev_files(struct pci_dev *pdev); -void pci_remove_sysfs_dev_files(struct pci_dev *pdev); +extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); +extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); #if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI) static inline void pci_create_firmware_label_files(struct pci_dev *pdev) { return; } static inline void pci_remove_firmware_label_files(struct pci_dev *pdev) { return; } #else -void pci_create_firmware_label_files(struct pci_dev *pdev); -void pci_remove_firmware_label_files(struct pci_dev *pdev); +extern void pci_create_firmware_label_files(struct pci_dev *pdev); +extern void pci_remove_firmware_label_files(struct pci_dev *pdev); #endif -void pci_cleanup_rom(struct pci_dev *dev); +extern void pci_cleanup_rom(struct pci_dev *dev); #ifdef HAVE_PCI_MMAP enum pci_mmap_api { PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices//resource */ PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/ */ }; -int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai, - enum pci_mmap_api mmap_api); +extern int pci_mmap_fits(struct pci_dev *pdev, int resno, + struct vm_area_struct *vmai, + enum pci_mmap_api mmap_api); #endif int pci_probe_reset_function(struct pci_dev *dev); @@ -59,17 +60,17 @@ struct pci_platform_pm_ops { int (*run_wake)(struct pci_dev *dev, bool enable); }; -int pci_set_platform_pm(struct pci_platform_pm_ops *ops); -void pci_update_current_state(struct pci_dev *dev, pci_power_t state); -void pci_power_up(struct pci_dev *dev); -void pci_disable_enabled_device(struct pci_dev *dev); -int pci_finish_runtime_suspend(struct pci_dev *dev); -int __pci_pme_wakeup(struct pci_dev *dev, void *ign); -void pci_wakeup_bus(struct pci_bus *bus); -void pci_config_pm_runtime_get(struct pci_dev *dev); -void pci_config_pm_runtime_put(struct pci_dev *dev); -void pci_pm_init(struct pci_dev *dev); -void pci_allocate_cap_save_buffers(struct pci_dev *dev); +extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); +extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); +extern void pci_power_up(struct pci_dev *dev); +extern void pci_disable_enabled_device(struct pci_dev *dev); +extern int pci_finish_runtime_suspend(struct pci_dev *dev); +extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); +extern void pci_wakeup_bus(struct pci_bus *bus); +extern void pci_config_pm_runtime_get(struct pci_dev *dev); +extern void pci_config_pm_runtime_put(struct pci_dev *dev); +extern void pci_pm_init(struct pci_dev *dev); +extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); void pci_free_cap_save_buffers(struct pci_dev *dev); static inline void pci_wakeup_event(struct pci_dev *dev) @@ -95,7 +96,7 @@ struct pci_vpd { struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ }; -int pci_vpd_pci22_init(struct pci_dev *dev); +extern int pci_vpd_pci22_init(struct pci_dev *dev); static inline void pci_vpd_release(struct pci_dev *dev) { if (dev->vpd) @@ -104,9 +105,9 @@ static inline void pci_vpd_release(struct pci_dev *dev) /* PCI /proc functions */ #ifdef CONFIG_PROC_FS -int pci_proc_attach_device(struct pci_dev *dev); -int pci_proc_detach_device(struct pci_dev *dev); -int pci_proc_detach_bus(struct pci_bus *bus); +extern int pci_proc_attach_device(struct pci_dev *dev); +extern int pci_proc_detach_device(struct pci_dev *dev); +extern int pci_proc_detach_bus(struct pci_bus *bus); #else static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } @@ -117,8 +118,8 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } int pci_hp_add_bridge(struct pci_dev *dev); #ifdef HAVE_PCI_LEGACY -void pci_create_legacy_files(struct pci_bus *bus); -void pci_remove_legacy_files(struct pci_bus *bus); +extern void pci_create_legacy_files(struct pci_bus *bus); +extern void pci_remove_legacy_files(struct pci_bus *bus); #else static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } @@ -133,7 +134,7 @@ extern unsigned int pci_pm_d3_delay; #ifdef CONFIG_PCI_MSI void pci_no_msi(void); -void pci_msi_init_pci_dev(struct pci_dev *dev); +extern void pci_msi_init_pci_dev(struct pci_dev *dev); #else static inline void pci_no_msi(void) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } @@ -197,11 +198,12 @@ enum pci_bar_type { bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, int crs_timeout); -int pci_setup_device(struct pci_dev *dev); -int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, - struct resource *res, unsigned int reg); -int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); -void pci_configure_ari(struct pci_dev *dev); +extern int pci_setup_device(struct pci_dev *dev); +extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, + struct resource *res, unsigned int reg); +extern int pci_resource_bar(struct pci_dev *dev, int resno, + enum pci_bar_type *type); +extern void pci_configure_ari(struct pci_dev *dev); /** * pci_ari_enabled - query ARI forwarding status @@ -215,7 +217,7 @@ static inline int pci_ari_enabled(struct pci_bus *bus) } void pci_reassigndev_resource_alignment(struct pci_dev *dev); -void pci_disable_bridge_window(struct pci_dev *dev); +extern void pci_disable_bridge_window(struct pci_dev *dev); /* Single Root I/O Virtualization */ struct pci_sriov { @@ -239,7 +241,7 @@ struct pci_sriov { }; #ifdef CONFIG_PCI_ATS -void pci_restore_ats_state(struct pci_dev *dev); +extern void pci_restore_ats_state(struct pci_dev *dev); #else static inline void pci_restore_ats_state(struct pci_dev *dev) { @@ -247,13 +249,14 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) #endif /* CONFIG_PCI_ATS */ #ifdef CONFIG_PCI_IOV -int pci_iov_init(struct pci_dev *dev); -void pci_iov_release(struct pci_dev *dev); -int pci_iov_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type); -resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); -void pci_restore_iov_state(struct pci_dev *dev); -int pci_iov_bus_range(struct pci_bus *bus); +extern int pci_iov_init(struct pci_dev *dev); +extern void pci_iov_release(struct pci_dev *dev); +extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, + enum pci_bar_type *type); +extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, + int resno); +extern void pci_restore_iov_state(struct pci_dev *dev); +extern int pci_iov_bus_range(struct pci_bus *bus); #else static inline int pci_iov_init(struct pci_dev *dev) @@ -279,10 +282,10 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) #endif /* CONFIG_PCI_IOV */ -unsigned long pci_cardbus_resource_alignment(struct resource *); +extern unsigned long pci_cardbus_resource_alignment(struct resource *); static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, - struct resource *res) + struct resource *res) { #ifdef CONFIG_PCI_IOV int resno = res - dev->resource; @@ -295,7 +298,7 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, return resource_alignment(res); } -void pci_enable_acs(struct pci_dev *dev); +extern void pci_enable_acs(struct pci_dev *dev); struct pci_dev_reset_methods { u16 vendor; @@ -304,7 +307,7 @@ struct pci_dev_reset_methods { }; #ifdef CONFIG_PCI_QUIRKS -int pci_dev_specific_reset(struct pci_dev *dev, int probe); +extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); #else static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) { diff --git a/trunk/drivers/pci/pcie/Kconfig b/trunk/drivers/pci/pcie/Kconfig index 569f82fc9e22..fde4a32a0295 100644 --- a/trunk/drivers/pci/pcie/Kconfig +++ b/trunk/drivers/pci/pcie/Kconfig @@ -82,4 +82,4 @@ endchoice config PCIE_PME def_bool y - depends on PCIEPORTBUS && PM_RUNTIME + depends on PCIEPORTBUS && PM_RUNTIME && ACPI diff --git a/trunk/drivers/pci/pcie/aer/aer_inject.c b/trunk/drivers/pci/pcie/aer/aer_inject.c index 587e7e853107..4e24cb8a94ae 100644 --- a/trunk/drivers/pci/pcie/aer/aer_inject.c +++ b/trunk/drivers/pci/pcie/aer/aer_inject.c @@ -212,8 +212,8 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, return ops->read(bus, devfn, where, size, val); } -static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) +int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size, + u32 val) { u32 *sim; struct aer_error *err; @@ -334,13 +334,13 @@ static int aer_inject(struct aer_error_inj *einj) return -ENODEV; rpdev = pcie_find_root_port(dev); if (!rpdev) { - ret = -ENODEV; + ret = -ENOTTY; goto out_put; } pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos_cap_err) { - ret = -EPERM; + ret = -ENOTTY; goto out_put; } pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); @@ -350,7 +350,7 @@ static int aer_inject(struct aer_error_inj *einj) rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); if (!rp_pos_cap_err) { - ret = -EPERM; + ret = -ENOTTY; goto out_put; } diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.h b/trunk/drivers/pci/pcie/aer/aerdrv.h index d12c77cd6991..22f840f4dda1 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.h +++ b/trunk/drivers/pci/pcie/aer/aerdrv.h @@ -110,15 +110,15 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig, } extern struct bus_type pcie_port_bus_type; -void aer_do_secondary_bus_reset(struct pci_dev *dev); -int aer_init(struct pcie_device *dev); -void aer_isr(struct work_struct *work); -void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); -void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); -irqreturn_t aer_irq(int irq, void *context); +extern void aer_do_secondary_bus_reset(struct pci_dev *dev); +extern int aer_init(struct pcie_device *dev); +extern void aer_isr(struct work_struct *work); +extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); +extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); +extern irqreturn_t aer_irq(int irq, void *context); #ifdef CONFIG_ACPI_APEI -int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); +extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); #else static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) { diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index 8ec8b4f48560..564d97f94b6c 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -89,6 +89,8 @@ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev) return -ENOSPC; } +#define PCI_BUS(x) (((x) >> 8) & 0xff) + /** * is_error_source - check whether the device is source of reported error * @dev: pointer to pci_dev to be checked @@ -104,7 +106,7 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) * When bus id is equal to 0, it might be a bad id * reported by root port. */ - if (!nosourceid && (PCI_BUS_NUM(e_info->id) != 0)) { + if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { /* Device ID match? */ if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) return true; diff --git a/trunk/drivers/pci/pcie/pme.c b/trunk/drivers/pci/pcie/pme.c index 795db1f9d50c..9ca0dc9ffd84 100644 --- a/trunk/drivers/pci/pcie/pme.c +++ b/trunk/drivers/pci/pcie/pme.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include "../pci.h" diff --git a/trunk/drivers/pci/pcie/portdrv.h b/trunk/drivers/pci/pcie/portdrv.h index d2eb80aab569..eea2ca2375e6 100644 --- a/trunk/drivers/pci/pcie/portdrv.h +++ b/trunk/drivers/pci/pcie/portdrv.h @@ -21,18 +21,18 @@ #define get_descriptor_id(type, service) (((type - 4) << 4) | service) extern struct bus_type pcie_port_bus_type; -int pcie_port_device_register(struct pci_dev *dev); +extern int pcie_port_device_register(struct pci_dev *dev); #ifdef CONFIG_PM -int pcie_port_device_suspend(struct device *dev); -int pcie_port_device_resume(struct device *dev); +extern int pcie_port_device_suspend(struct device *dev); +extern int pcie_port_device_resume(struct device *dev); #endif -void pcie_port_device_remove(struct pci_dev *dev); -int __must_check pcie_port_bus_register(void); -void pcie_port_bus_unregister(void); +extern void pcie_port_device_remove(struct pci_dev *dev); +extern int __must_check pcie_port_bus_register(void); +extern void pcie_port_bus_unregister(void); struct pci_dev; -void pcie_clear_root_pme_status(struct pci_dev *dev); +extern void pcie_clear_root_pme_status(struct pci_dev *dev); #ifdef CONFIG_HOTPLUG_PCI_PCIE extern bool pciehp_msi_disabled; @@ -59,7 +59,7 @@ static inline bool pcie_pme_no_msi(void) return pcie_pme_msi_disabled; } -void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); +extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); #else /* !CONFIG_PCIE_PME */ static inline void pcie_pme_disable_msi(void) {} static inline bool pcie_pme_no_msi(void) { return false; } @@ -67,7 +67,7 @@ static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {} #endif /* !CONFIG_PCIE_PME */ #ifdef CONFIG_ACPI -int pcie_port_acpi_setup(struct pci_dev *port, int *mask); +extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask); static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) { diff --git a/trunk/drivers/pci/pcie/portdrv_acpi.c b/trunk/drivers/pci/pcie/portdrv_acpi.c index b4d2894ee3fc..a86b56e5f2f2 100644 --- a/trunk/drivers/pci/pcie/portdrv_acpi.c +++ b/trunk/drivers/pci/pcie/portdrv_acpi.c @@ -17,7 +17,6 @@ #include "aer/aerdrv.h" #include "../pci.h" -#include "portdrv.h" /** * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index 696caed5fdf5..08c243ab034e 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -184,6 +184,14 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { #define PCIE_PORTDRV_PM_OPS NULL #endif /* !PM */ +/* + * PCIe port runtime suspend is broken for some chipsets, so use a + * black list to disable runtime PM for these chipsets. + */ +static const struct pci_device_id port_runtime_pm_black_list[] = { + { /* end: all zeroes */ } +}; + /* * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed @@ -217,11 +225,16 @@ static int pcie_portdrv_probe(struct pci_dev *dev, * it by default. */ dev->d3cold_allowed = false; + if (!pci_match_id(port_runtime_pm_black_list, dev)) + pm_runtime_put_noidle(&dev->dev); + return 0; } static void pcie_portdrv_remove(struct pci_dev *dev) { + if (!pci_match_id(port_runtime_pm_black_list, dev)) + pm_runtime_get_noresume(&dev->dev); pcie_port_device_remove(dev); pci_disable_device(dev); } @@ -259,9 +272,11 @@ static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, enum pci_channel_state error) { struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; + int ret; + + /* can not fail */ + ret = device_for_each_child(&dev->dev, &data, error_detected_iter); - /* get true return value from &data */ - device_for_each_child(&dev->dev, &data, error_detected_iter); return data.result; } @@ -293,9 +308,10 @@ static int mmio_enabled_iter(struct device *device, void *data) static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) { pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; + int retval; /* get true return value from &status */ - device_for_each_child(&dev->dev, &status, mmio_enabled_iter); + retval = device_for_each_child(&dev->dev, &status, mmio_enabled_iter); return status; } @@ -327,6 +343,7 @@ static int slot_reset_iter(struct device *device, void *data) static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) { pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; + int retval; /* If fatal, restore cfg space for possible link reset at upstream */ if (dev->error_state == pci_channel_io_frozen) { @@ -337,7 +354,8 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) } /* get true return value from &status */ - device_for_each_child(&dev->dev, &status, slot_reset_iter); + retval = device_for_each_child(&dev->dev, &status, slot_reset_iter); + return status; } @@ -363,7 +381,9 @@ static int resume_iter(struct device *device, void *data) static void pcie_portdrv_err_resume(struct pci_dev *dev) { - device_for_each_child(&dev->dev, NULL, resume_iter); + int retval; + /* nothing to do with error value, if it ever happens */ + retval = device_for_each_child(&dev->dev, NULL, resume_iter); } /* diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index 43ece5d41d36..b494066ef32f 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -673,8 +673,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, ret = device_register(&child->dev); WARN_ON(ret < 0); - pcibios_add_bus(child); - /* Create legacy_io and legacy_mem files for this bus */ pci_create_legacy_files(child); @@ -1629,7 +1627,8 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) if (!bus->is_added) { dev_dbg(&bus->dev, "fixups for bus\n"); pcibios_fixup_bus(bus); - bus->is_added = 1; + if (pci_is_root_bus(bus)) + bus->is_added = 1; } for (pass=0; pass < 2; pass++) @@ -1662,14 +1661,6 @@ int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) return 0; } -void __weak pcibios_add_bus(struct pci_bus *bus) -{ -} - -void __weak pcibios_remove_bus(struct pci_bus *bus) -{ -} - struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources) { @@ -1724,8 +1715,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, if (error) goto class_dev_reg_err; - pcibios_add_bus(b); - /* Create legacy_io and legacy_mem files for this bus */ pci_create_legacy_files(b); diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 7d68aeebf56b..0369fb6fc1da 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -324,30 +324,29 @@ static void quirk_cs5536_vsa(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); -static void quirk_io_region(struct pci_dev *dev, int port, - unsigned size, int nr, const char *name) +static void quirk_io_region(struct pci_dev *dev, unsigned region, + unsigned size, int nr, const char *name) { - u16 region; - struct pci_bus_region bus_region; - struct resource *res = dev->resource + nr; - - pci_read_config_word(dev, port, ®ion); - region &= ~(size - 1); - - if (!region) - return; + region &= ~(size-1); + if (region) { + struct pci_bus_region bus_region; + struct resource *res = dev->resource + nr; - res->name = pci_name(dev); - res->flags = IORESOURCE_IO; + res->name = pci_name(dev); + res->start = region; + res->end = region + size - 1; + res->flags = IORESOURCE_IO; - /* Convert from PCI bus to resource space */ - bus_region.start = region; - bus_region.end = region + size - 1; - pcibios_bus_to_resource(dev, res, &bus_region); + /* Convert from PCI bus to resource space. */ + bus_region.start = res->start; + bus_region.end = res->end; + pcibios_bus_to_resource(dev, res, &bus_region); - if (!pci_claim_resource(dev, nr)) - dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); -} + if (pci_claim_resource(dev, nr) == 0) + dev_info(&dev->dev, "quirk: %pR claimed by %s\n", + res, name); + } +} /* * ATI Northbridge setups MCE the processor if you even @@ -375,8 +374,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_ */ static void quirk_ali7101_acpi(struct pci_dev *dev) { - quirk_io_region(dev, 0xE0, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); - quirk_io_region(dev, 0xE2, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); + u16 region; + + pci_read_config_word(dev, 0xE0, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); + pci_read_config_word(dev, 0xE2, ®ion); + quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi); @@ -439,10 +442,12 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int */ static void quirk_piix4_acpi(struct pci_dev *dev) { - u32 res_a; + u32 region, res_a; - quirk_io_region(dev, 0x40, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); - quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); + pci_read_config_dword(dev, 0x40, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); + pci_read_config_dword(dev, 0x90, ®ion); + quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); /* Device resource A has enables for some of the other ones */ pci_read_config_dword(dev, 0x5c, &res_a); @@ -486,6 +491,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, qui */ static void quirk_ich4_lpc_acpi(struct pci_dev *dev) { + u32 region; u8 enable; /* @@ -497,14 +503,22 @@ static void quirk_ich4_lpc_acpi(struct pci_dev *dev) */ pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); - if (enable & ICH4_ACPI_EN) - quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, - "ICH4 ACPI/GPIO/TCO"); + if (enable & ICH4_ACPI_EN) { + pci_read_config_dword(dev, ICH_PMBASE, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + if (region >= PCIBIOS_MIN_IO) + quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, + "ICH4 ACPI/GPIO/TCO"); + } pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); - if (enable & ICH4_GPIO_EN) - quirk_io_region(dev, ICH4_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, - "ICH4 GPIO"); + if (enable & ICH4_GPIO_EN) { + pci_read_config_dword(dev, ICH4_GPIOBASE, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + if (region >= PCIBIOS_MIN_IO) + quirk_io_region(dev, region, 64, + PCI_BRIDGE_RESOURCES + 1, "ICH4 GPIO"); + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi); @@ -519,17 +533,26 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, qui static void ich6_lpc_acpi_gpio(struct pci_dev *dev) { + u32 region; u8 enable; pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); - if (enable & ICH6_ACPI_EN) - quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, - "ICH6 ACPI/GPIO/TCO"); + if (enable & ICH6_ACPI_EN) { + pci_read_config_dword(dev, ICH_PMBASE, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + if (region >= PCIBIOS_MIN_IO) + quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, + "ICH6 ACPI/GPIO/TCO"); + } pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); - if (enable & ICH6_GPIO_EN) - quirk_io_region(dev, ICH6_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, - "ICH6 GPIO"); + if (enable & ICH6_GPIO_EN) { + pci_read_config_dword(dev, ICH6_GPIOBASE, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + if (region >= PCIBIOS_MIN_IO) + quirk_io_region(dev, region, 64, + PCI_BRIDGE_RESOURCES + 1, "ICH6 GPIO"); + } } static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) @@ -627,9 +650,13 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_1, qui */ static void quirk_vt82c586_acpi(struct pci_dev *dev) { - if (dev->revision & 0x10) - quirk_io_region(dev, 0x48, 256, PCI_BRIDGE_RESOURCES, - "vt82c586 ACPI"); + u32 region; + + if (dev->revision & 0x10) { + pci_read_config_dword(dev, 0x48, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI"); + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi); @@ -641,12 +668,18 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt */ static void quirk_vt82c686_acpi(struct pci_dev *dev) { + u16 hm; + u32 smb; + quirk_vt82c586_acpi(dev); - quirk_io_region(dev, 0x70, 128, PCI_BRIDGE_RESOURCES+1, - "vt82c686 HW-mon"); + pci_read_config_word(dev, 0x70, &hm); + hm &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon"); - quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+2, "vt82c686 SMB"); + pci_read_config_dword(dev, 0x90, &smb); + smb &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB"); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi); @@ -657,8 +690,15 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt */ static void quirk_vt8235_acpi(struct pci_dev *dev) { - quirk_io_region(dev, 0x88, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); - quirk_io_region(dev, 0xd0, 16, PCI_BRIDGE_RESOURCES+1, "vt8235 SMB"); + u16 pm, smb; + + pci_read_config_word(dev, 0x88, &pm); + pm &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); + + pci_read_config_word(dev, 0xd0, &smb); + smb &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1, "vt8235 SMB"); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi); @@ -2554,14 +2594,6 @@ static void quirk_msi_intx_disable_ati_bug(struct pci_dev *dev) dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; pci_dev_put(p); } -static void quirk_msi_intx_disable_qca_bug(struct pci_dev *dev) -{ - /* AR816X/AR817X/E210X MSI is fixed at HW level from revision 0x18 */ - if (dev->revision < 0x18) { - dev_info(&dev->dev, "set MSI_INTX_DISABLE_BUG flag\n"); - dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; - } -} DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780, quirk_msi_intx_disable_bug); @@ -2611,16 +2643,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1073, quirk_msi_intx_disable_bug); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083, quirk_msi_intx_disable_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1090, - quirk_msi_intx_disable_qca_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1091, - quirk_msi_intx_disable_qca_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a0, - quirk_msi_intx_disable_qca_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a1, - quirk_msi_intx_disable_qca_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0xe091, - quirk_msi_intx_disable_qca_bug); #endif /* CONFIG_PCI_MSI */ /* Allow manual resource allocation for PCI hotplug bridges diff --git a/trunk/drivers/pci/remove.c b/trunk/drivers/pci/remove.c index 8fc54b7327bc..cc875e6ed159 100644 --- a/trunk/drivers/pci/remove.c +++ b/trunk/drivers/pci/remove.c @@ -50,8 +50,10 @@ void pci_remove_bus(struct pci_bus *bus) list_del(&bus->node); pci_bus_release_busn_res(bus); up_write(&pci_bus_sem); + if (!bus->is_added) + return; + pci_remove_legacy_files(bus); - pcibios_remove_bus(bus); device_unregister(&bus->dev); } EXPORT_SYMBOL(pci_remove_bus); diff --git a/trunk/drivers/pci/rom.c b/trunk/drivers/pci/rom.c index c5d0a08a8747..ab886b7ee327 100644 --- a/trunk/drivers/pci/rom.c +++ b/trunk/drivers/pci/rom.c @@ -117,12 +117,18 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) loff_t start; void __iomem *rom; + /* + * Some devices may provide ROMs via a source other than the BAR + */ + if (pdev->rom && pdev->romlen) { + *size = pdev->romlen; + return phys_to_virt(pdev->rom); /* * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy * memory map if the VGA enable bit of the Bridge Control register is * set for embedded VGA. */ - if (res->flags & IORESOURCE_ROM_SHADOW) { + } else if (res->flags & IORESOURCE_ROM_SHADOW) { /* primary video rom always starts here */ start = (loff_t)0xC0000; *size = 0x20000; /* cover C000:0 through E000:0 */ @@ -181,7 +187,8 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) return; - iounmap(rom); + if (!pdev->rom || !pdev->romlen) + iounmap(rom); /* Disable again before continuing, leave enabled if pci=rom */ if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW))) @@ -205,24 +212,7 @@ void pci_cleanup_rom(struct pci_dev *pdev) } } -/** - * pci_platform_rom - provides a pointer to any ROM image provided by the - * platform - * @pdev: pointer to pci device struct - * @size: pointer to receive size of pci window over ROM - */ -void __iomem *pci_platform_rom(struct pci_dev *pdev, size_t *size) -{ - if (pdev->rom && pdev->romlen) { - *size = pdev->romlen; - return phys_to_virt((phys_addr_t)pdev->rom); - } - - return NULL; -} - EXPORT_SYMBOL(pci_map_rom); EXPORT_SYMBOL(pci_unmap_rom); EXPORT_SYMBOL_GPL(pci_enable_rom); EXPORT_SYMBOL_GPL(pci_disable_rom); -EXPORT_SYMBOL(pci_platform_rom); diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index 16abaaa1f83c..7e8739e25b9e 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -1044,7 +1044,7 @@ static void pci_bus_size_cardbus(struct pci_bus *bus, ; } -static void __ref __pci_bus_size_bridges(struct pci_bus *bus, +void __ref __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) { struct pci_dev *dev; @@ -1545,8 +1545,6 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) enable_all: retval = pci_reenable_device(bridge); - if (retval) - dev_err(&bridge->dev, "Error reenabling bridge (%d)\n", retval); pci_set_master(bridge); pci_enable_bridges(parent); } diff --git a/trunk/drivers/pci/setup-res.c b/trunk/drivers/pci/setup-res.c index 07f2eddc09ce..81b88bda7930 100644 --- a/trunk/drivers/pci/setup-res.c +++ b/trunk/drivers/pci/setup-res.c @@ -261,6 +261,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) { struct resource *res = dev->resource + resno; resource_size_t align, size; + struct pci_bus *bus; int ret; align = pci_resource_alignment(dev, res); @@ -270,6 +271,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) return -EINVAL; } + bus = dev->bus; size = resource_size(res); ret = _pci_assign_resource(dev, resno, size, align); diff --git a/trunk/drivers/pci/slot.c b/trunk/drivers/pci/slot.c index c1e9284a677b..ac6412fb8d6f 100644 --- a/trunk/drivers/pci/slot.c +++ b/trunk/drivers/pci/slot.c @@ -377,17 +377,14 @@ void pci_hp_create_module_link(struct pci_slot *pci_slot) { struct hotplug_slot *slot = pci_slot->hotplug; struct kobject *kobj = NULL; - int ret; + int no_warn; if (!slot || !slot->ops) return; kobj = kset_find_obj(module_kset, slot->ops->mod_name); if (!kobj) return; - ret = sysfs_create_link(&pci_slot->kobj, kobj, "module"); - if (ret) - dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n", - ret); + no_warn = sysfs_create_link(&pci_slot->kobj, kobj, "module"); kobject_put(kobj); } EXPORT_SYMBOL_GPL(pci_hp_create_module_link); diff --git a/trunk/drivers/pinctrl/Kconfig b/trunk/drivers/pinctrl/Kconfig index f910962baaa7..34f51d2d90d2 100644 --- a/trunk/drivers/pinctrl/Kconfig +++ b/trunk/drivers/pinctrl/Kconfig @@ -106,11 +106,20 @@ config PINCTRL_LANTIQ select PINMUX select PINCONF +config PINCTRL_PXA3xx + bool + select PINMUX + config PINCTRL_FALCON bool depends on SOC_FALCON depends on PINCTRL_LANTIQ +config PINCTRL_MMP2 + bool "MMP2 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + config PINCTRL_MXS bool select PINMUX @@ -142,12 +151,21 @@ config PINCTRL_DB8540 bool "DB8540 pin controller driver" depends on PINCTRL_NOMADIK && ARCH_U8500 +config PINCTRL_PXA168 + bool "PXA168 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + +config PINCTRL_PXA910 + bool "PXA910 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + config PINCTRL_SINGLE tristate "One-register-per-pin type device tree based pinctrl driver" depends on OF select PINMUX select PINCONF - select GENERIC_PINCONF help This selects the device tree based generic pinctrl driver. @@ -208,11 +226,6 @@ config PINCTRL_EXYNOS5440 select PINMUX select PINCONF -config PINCTRL_S3C64XX - bool "Samsung S3C64XX SoC pinctrl driver" - depends on ARCH_S3C64XX - select PINCTRL_SAMSUNG - source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/sh-pfc/Kconfig" source "drivers/pinctrl/spear/Kconfig" diff --git a/trunk/drivers/pinctrl/Makefile b/trunk/drivers/pinctrl/Makefile index 988279ae23cd..f82cc5baf767 100644 --- a/trunk/drivers/pinctrl/Makefile +++ b/trunk/drivers/pinctrl/Makefile @@ -21,7 +21,9 @@ obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o +obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o +obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o @@ -29,6 +31,8 @@ obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o +obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o +obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o obj-$(CONFIG_PINCTRL_SUNXI) += pinctrl-sunxi.o @@ -41,7 +45,6 @@ obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o -obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index c3d222ed39a2..b0de6e7f1fdb 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -27,11 +27,6 @@ #include #include #include - -#ifdef CONFIG_GPIOLIB -#include -#endif - #include "core.h" #include "devicetree.h" #include "pinmux.h" @@ -40,17 +35,11 @@ static bool pinctrl_dummy_state; -/* Mutex taken to protect pinctrl_list */ -DEFINE_MUTEX(pinctrl_list_mutex); - -/* Mutex taken to protect pinctrl_maps */ -DEFINE_MUTEX(pinctrl_maps_mutex); - -/* Mutex taken to protect pinctrldev_list */ -DEFINE_MUTEX(pinctrldev_list_mutex); +/* Mutex taken by all entry points */ +DEFINE_MUTEX(pinctrl_mutex); /* Global list of pin control devices (struct pinctrl_dev) */ -static LIST_HEAD(pinctrldev_list); +LIST_HEAD(pinctrldev_list); /* List of pin controller handles (struct pinctrl) */ static LIST_HEAD(pinctrl_list); @@ -117,23 +106,6 @@ struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) return found ? pctldev : NULL; } -struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np) -{ - struct pinctrl_dev *pctldev; - - mutex_lock(&pinctrldev_list_mutex); - - list_for_each_entry(pctldev, &pinctrldev_list, node) - if (pctldev->dev->of_node == np) { - mutex_unlock(&pinctrldev_list_mutex); - return pctldev; - } - - mutex_lock(&pinctrldev_list_mutex); - - return NULL; -} - /** * pin_get_from_name() - look up a pin number from a name * @pctldev: the pin control device to lookup the pin on @@ -193,9 +165,9 @@ bool pin_is_valid(struct pinctrl_dev *pctldev, int pin) if (pin < 0) return false; - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); pindesc = pin_desc_get(pctldev, pin); - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return pindesc != NULL; } @@ -292,56 +264,17 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) { struct pinctrl_gpio_range *range = NULL; - mutex_lock(&pctldev->mutex); /* Loop over the ranges */ list_for_each_entry(range, &pctldev->gpio_ranges, node) { /* Check if we're in the valid range */ if (gpio >= range->base && gpio < range->base + range->npins) { - mutex_unlock(&pctldev->mutex); return range; } } - mutex_unlock(&pctldev->mutex); - return NULL; -} -/** - * pinctrl_ready_for_gpio_range() - check if other GPIO pins of - * the same GPIO chip are in range - * @gpio: gpio pin to check taken from the global GPIO pin space - * - * This function is complement of pinctrl_match_gpio_range(). If the return - * value of pinctrl_match_gpio_range() is NULL, this function could be used - * to check whether pinctrl device is ready or not. Maybe some GPIO pins - * of the same GPIO chip don't have back-end pinctrl interface. - * If the return value is true, it means that pinctrl device is ready & the - * certain GPIO pin doesn't have back-end pinctrl device. If the return value - * is false, it means that pinctrl device may not be ready. - */ -#ifdef CONFIG_GPIOLIB -static bool pinctrl_ready_for_gpio_range(unsigned gpio) -{ - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range *range = NULL; - struct gpio_chip *chip = gpio_to_chip(gpio); - - /* Loop over the pin controllers */ - list_for_each_entry(pctldev, &pinctrldev_list, node) { - /* Loop over the ranges */ - list_for_each_entry(range, &pctldev->gpio_ranges, node) { - /* Check if any gpio range overlapped with gpio chip */ - if (range->base + range->npins - 1 < chip->base || - range->base > chip->base + chip->ngpio - 1) - continue; - return true; - } - } - return false; + return NULL; } -#else -static bool pinctrl_ready_for_gpio_range(unsigned gpio) { return true; } -#endif /** * pinctrl_get_device_gpio_range() - find device for GPIO range @@ -386,9 +319,9 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range) { - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); list_add_tail(&range->node, &pctldev->gpio_ranges); - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); @@ -406,25 +339,17 @@ EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, struct pinctrl_gpio_range *range) { - struct pinctrl_dev *pctldev; - - mutex_lock(&pinctrldev_list_mutex); - - pctldev = get_pinctrl_dev_from_devname(devname); + struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname); /* * If we can't find this device, let's assume that is because * it has not probed yet, so the driver trying to register this * range need to defer probing. */ - if (!pctldev) { - mutex_unlock(&pinctrldev_list_mutex); + if (!pctldev) return ERR_PTR(-EPROBE_DEFER); - } - pinctrl_add_gpio_range(pctldev, range); - - mutex_unlock(&pinctrldev_list_mutex); + pinctrl_add_gpio_range(pctldev, range); return pctldev; } EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); @@ -440,17 +365,14 @@ pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, { struct pinctrl_gpio_range *range = NULL; - mutex_lock(&pctldev->mutex); /* Loop over the ranges */ list_for_each_entry(range, &pctldev->gpio_ranges, node) { /* Check if we're in the valid range */ if (pin >= range->pin_base && pin < range->pin_base + range->npins) { - mutex_unlock(&pctldev->mutex); return range; } } - mutex_unlock(&pctldev->mutex); return NULL; } @@ -464,9 +386,9 @@ EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin); void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range) { - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); list_del(&range->node); - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); @@ -517,13 +439,11 @@ int pinctrl_request_gpio(unsigned gpio) int ret; int pin; - mutex_lock(&pinctrldev_list_mutex); + mutex_lock(&pinctrl_mutex); ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); if (ret) { - if (pinctrl_ready_for_gpio_range(gpio)) - ret = 0; - mutex_unlock(&pinctrldev_list_mutex); + mutex_unlock(&pinctrl_mutex); return ret; } @@ -532,7 +452,7 @@ int pinctrl_request_gpio(unsigned gpio) ret = pinmux_request_gpio(pctldev, range, pin, gpio); - mutex_unlock(&pinctrldev_list_mutex); + mutex_unlock(&pinctrl_mutex); return ret; } EXPORT_SYMBOL_GPL(pinctrl_request_gpio); @@ -552,22 +472,20 @@ void pinctrl_free_gpio(unsigned gpio) int ret; int pin; - mutex_lock(&pinctrldev_list_mutex); + mutex_lock(&pinctrl_mutex); ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); if (ret) { - mutex_unlock(&pinctrldev_list_mutex); + mutex_unlock(&pinctrl_mutex); return; } - mutex_lock(&pctldev->mutex); /* Convert to the pin controllers number space */ pin = gpio - range->base + range->pin_base; pinmux_free_gpio(pctldev, pin, range); - mutex_unlock(&pctldev->mutex); - mutex_unlock(&pinctrldev_list_mutex); + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_free_gpio); @@ -578,24 +496,14 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) int ret; int pin; - mutex_lock(&pinctrldev_list_mutex); - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) { - mutex_unlock(&pinctrldev_list_mutex); + if (ret) return ret; - } - - mutex_lock(&pctldev->mutex); /* Convert to the pin controllers number space */ pin = gpio - range->base + range->pin_base; - ret = pinmux_gpio_direction(pctldev, range, pin, input); - - mutex_unlock(&pctldev->mutex); - mutex_unlock(&pinctrldev_list_mutex); - return ret; + return pinmux_gpio_direction(pctldev, range, pin, input); } /** @@ -608,7 +516,11 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) */ int pinctrl_gpio_direction_input(unsigned gpio) { - return pinctrl_gpio_direction(gpio, true); + int ret; + mutex_lock(&pinctrl_mutex); + ret = pinctrl_gpio_direction(gpio, true); + mutex_unlock(&pinctrl_mutex); + return ret; } EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); @@ -622,7 +534,11 @@ EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); */ int pinctrl_gpio_direction_output(unsigned gpio) { - return pinctrl_gpio_direction(gpio, false); + int ret; + mutex_lock(&pinctrl_mutex); + ret = pinctrl_gpio_direction(gpio, false); + mutex_unlock(&pinctrl_mutex); + return ret; } EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); @@ -725,18 +641,14 @@ static struct pinctrl *find_pinctrl(struct device *dev) { struct pinctrl *p; - mutex_lock(&pinctrl_list_mutex); list_for_each_entry(p, &pinctrl_list, node) - if (p->dev == dev) { - mutex_unlock(&pinctrl_list_mutex); + if (p->dev == dev) return p; - } - mutex_unlock(&pinctrl_list_mutex); return NULL; } -static void pinctrl_free(struct pinctrl *p, bool inlist); +static void pinctrl_put_locked(struct pinctrl *p, bool inlist); static struct pinctrl *create_pinctrl(struct device *dev) { @@ -769,7 +681,6 @@ static struct pinctrl *create_pinctrl(struct device *dev) devname = dev_name(dev); - mutex_lock(&pinctrl_maps_mutex); /* Iterate over the pin control maps to locate the right ones */ for_each_maps(maps_node, i, map) { /* Map must be for this device */ @@ -791,16 +702,13 @@ static struct pinctrl *create_pinctrl(struct device *dev) * an -EPROBE_DEFER later, as that is the worst case. */ if (ret == -EPROBE_DEFER) { - pinctrl_free(p, false); - mutex_unlock(&pinctrl_maps_mutex); + pinctrl_put_locked(p, false); return ERR_PTR(ret); } } - mutex_unlock(&pinctrl_maps_mutex); - if (ret < 0) { /* If some other error than deferral occured, return here */ - pinctrl_free(p, false); + pinctrl_put_locked(p, false); return ERR_PTR(ret); } @@ -812,11 +720,7 @@ static struct pinctrl *create_pinctrl(struct device *dev) return p; } -/** - * pinctrl_get() - retrieves the pinctrl handle for a device - * @dev: the device to obtain the handle for - */ -struct pinctrl *pinctrl_get(struct device *dev) +static struct pinctrl *pinctrl_get_locked(struct device *dev) { struct pinctrl *p; @@ -837,35 +741,43 @@ struct pinctrl *pinctrl_get(struct device *dev) return create_pinctrl(dev); } -EXPORT_SYMBOL_GPL(pinctrl_get); -static void pinctrl_free_setting(bool disable_setting, - struct pinctrl_setting *setting) +/** + * pinctrl_get() - retrieves the pinctrl handle for a device + * @dev: the device to obtain the handle for + */ +struct pinctrl *pinctrl_get(struct device *dev) { - switch (setting->type) { - case PIN_MAP_TYPE_MUX_GROUP: - if (disable_setting) - pinmux_disable_setting(setting); - pinmux_free_setting(setting); - break; - case PIN_MAP_TYPE_CONFIGS_PIN: - case PIN_MAP_TYPE_CONFIGS_GROUP: - pinconf_free_setting(setting); - break; - default: - break; - } + struct pinctrl *p; + + mutex_lock(&pinctrl_mutex); + p = pinctrl_get_locked(dev); + mutex_unlock(&pinctrl_mutex); + + return p; } +EXPORT_SYMBOL_GPL(pinctrl_get); -static void pinctrl_free(struct pinctrl *p, bool inlist) +static void pinctrl_put_locked(struct pinctrl *p, bool inlist) { struct pinctrl_state *state, *n1; struct pinctrl_setting *setting, *n2; - mutex_lock(&pinctrl_list_mutex); list_for_each_entry_safe(state, n1, &p->states, node) { list_for_each_entry_safe(setting, n2, &state->settings, node) { - pinctrl_free_setting(state == p->state, setting); + switch (setting->type) { + case PIN_MAP_TYPE_MUX_GROUP: + if (state == p->state) + pinmux_disable_setting(setting); + pinmux_free_setting(setting); + break; + case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: + pinconf_free_setting(setting); + break; + default: + break; + } list_del(&setting->node); kfree(setting); } @@ -878,7 +790,6 @@ static void pinctrl_free(struct pinctrl *p, bool inlist) if (inlist) list_del(&p->node); kfree(p); - mutex_unlock(&pinctrl_list_mutex); } /** @@ -889,7 +800,7 @@ static void pinctrl_release(struct kref *kref) { struct pinctrl *p = container_of(kref, struct pinctrl, users); - pinctrl_free(p, true); + pinctrl_put_locked(p, true); } /** @@ -898,17 +809,14 @@ static void pinctrl_release(struct kref *kref) */ void pinctrl_put(struct pinctrl *p) { + mutex_lock(&pinctrl_mutex); kref_put(&p->users, pinctrl_release); + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_put); -/** - * pinctrl_lookup_state() - retrieves a state handle from a pinctrl handle - * @p: the pinctrl handle to retrieve the state from - * @name: the state name to retrieve - */ -struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, - const char *name) +static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p, + const char *name) { struct pinctrl_state *state; @@ -925,17 +833,28 @@ struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, return state; } -EXPORT_SYMBOL_GPL(pinctrl_lookup_state); /** - * pinctrl_select_state() - select/activate/program a pinctrl state to HW - * @p: the pinctrl handle for the device that requests configuration - * @state: the state handle to select/activate/program + * pinctrl_lookup_state() - retrieves a state handle from a pinctrl handle + * @p: the pinctrl handle to retrieve the state from + * @name: the state name to retrieve */ -int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) +struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, const char *name) +{ + struct pinctrl_state *s; + + mutex_lock(&pinctrl_mutex); + s = pinctrl_lookup_state_locked(p, name); + mutex_unlock(&pinctrl_mutex); + + return s; +} +EXPORT_SYMBOL_GPL(pinctrl_lookup_state); + +static int pinctrl_select_state_locked(struct pinctrl *p, + struct pinctrl_state *state) { struct pinctrl_setting *setting, *setting2; - struct pinctrl_state *old_state = p->state; int ret; if (p->state == state) @@ -969,7 +888,7 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) } } - p->state = NULL; + p->state = state; /* Apply all the settings for the new state */ list_for_each_entry(setting, &state->settings, node) { @@ -985,36 +904,27 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) ret = -EINVAL; break; } - if (ret < 0) { - goto unapply_new_state; + /* FIXME: Difficult to return to prev state */ + return ret; } } - p->state = state; - return 0; +} -unapply_new_state: - dev_err(p->dev, "Error applying setting, reverse things back\n"); - - list_for_each_entry(setting2, &state->settings, node) { - if (&setting2->node == &setting->node) - break; - /* - * All we can do here is pinmux_disable_setting. - * That means that some pins are muxed differently now - * than they were before applying the setting (We can't - * "unmux a pin"!), but it's not a big deal since the pins - * are free to be muxed by another apply_setting. - */ - if (setting2->type == PIN_MAP_TYPE_MUX_GROUP) - pinmux_disable_setting(setting2); - } +/** + * pinctrl_select() - select/activate/program a pinctrl state to HW + * @p: the pinctrl handle for the device that requests configuratio + * @state: the state handle to select/activate/program + */ +int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) +{ + int ret; - /* There's no infinite recursive loop here because p->state is NULL */ - if (old_state) - pinctrl_select_state(p, old_state); + mutex_lock(&pinctrl_mutex); + ret = pinctrl_select_state_locked(p, state); + mutex_unlock(&pinctrl_mutex); return ret; } @@ -1069,8 +979,9 @@ static int devm_pinctrl_match(struct device *dev, void *res, void *data) */ void devm_pinctrl_put(struct pinctrl *p) { - WARN_ON(devres_release(p->dev, devm_pinctrl_release, + WARN_ON(devres_destroy(p->dev, devm_pinctrl_release, devm_pinctrl_match, p)); + pinctrl_put(p); } EXPORT_SYMBOL_GPL(devm_pinctrl_put); @@ -1144,10 +1055,10 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, } if (!locked) - mutex_lock(&pinctrl_maps_mutex); + mutex_lock(&pinctrl_mutex); list_add_tail(&maps_node->node, &pinctrl_maps); if (!locked) - mutex_unlock(&pinctrl_maps_mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -1169,15 +1080,12 @@ void pinctrl_unregister_map(struct pinctrl_map const *map) { struct pinctrl_maps *maps_node; - mutex_lock(&pinctrl_maps_mutex); list_for_each_entry(maps_node, &pinctrl_maps, node) { if (maps_node->maps == map) { list_del(&maps_node->node); - mutex_unlock(&pinctrl_maps_mutex); return; } } - mutex_unlock(&pinctrl_maps_mutex); } /** @@ -1214,7 +1122,7 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { @@ -1236,7 +1144,7 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) seq_puts(s, "\n"); } - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -1247,9 +1155,8 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) const struct pinctrl_ops *ops = pctldev->desc->pctlops; unsigned ngroups, selector = 0; - mutex_lock(&pctldev->mutex); - ngroups = ops->get_groups_count(pctldev); + mutex_lock(&pinctrl_mutex); seq_puts(s, "registered pin groups:\n"); while (selector < ngroups) { @@ -1270,7 +1177,7 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) for (i = 0; i < num_pins; i++) { pname = pin_get_name(pctldev, pins[i]); if (WARN_ON(!pname)) { - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return -EINVAL; } seq_printf(s, "pin %d (%s)\n", pins[i], pname); @@ -1280,7 +1187,7 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) selector++; } - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -1292,7 +1199,7 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) seq_puts(s, "GPIO ranges handled:\n"); - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); /* Loop over the ranges */ list_for_each_entry(range, &pctldev->gpio_ranges, node) { @@ -1303,7 +1210,7 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) (range->pin_base + range->npins - 1)); } - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -1314,7 +1221,7 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) seq_puts(s, "name [pinmux] [pinconf]\n"); - mutex_lock(&pinctrldev_list_mutex); + mutex_lock(&pinctrl_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) { seq_printf(s, "%s ", pctldev->desc->name); @@ -1329,7 +1236,7 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) seq_puts(s, "\n"); } - mutex_unlock(&pinctrldev_list_mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -1358,7 +1265,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) seq_puts(s, "Pinctrl maps:\n"); - mutex_lock(&pinctrl_maps_mutex); + mutex_lock(&pinctrl_mutex); + for_each_maps(maps_node, i, map) { seq_printf(s, "device %s\nstate %s\ntype %s (%d)\n", map->dev_name, map->name, map_type(map->type), @@ -1382,7 +1290,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) seq_printf(s, "\n"); } - mutex_unlock(&pinctrl_maps_mutex); + + mutex_unlock(&pinctrl_mutex); return 0; } @@ -1395,7 +1304,7 @@ static int pinctrl_show(struct seq_file *s, void *what) seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); - mutex_lock(&pinctrl_list_mutex); + mutex_lock(&pinctrl_mutex); list_for_each_entry(p, &pinctrl_list, node) { seq_printf(s, "device: %s current state: %s\n", @@ -1427,7 +1336,7 @@ static int pinctrl_show(struct seq_file *s, void *what) } } - mutex_unlock(&pinctrl_list_mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -1613,7 +1522,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); INIT_LIST_HEAD(&pctldev->gpio_ranges); pctldev->dev = dev; - mutex_init(&pctldev->mutex); /* check core ops for sanity */ if (pinctrl_check_ops(pctldev)) { @@ -1643,37 +1551,38 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, goto out_err; } - mutex_lock(&pinctrldev_list_mutex); - list_add_tail(&pctldev->node, &pinctrldev_list); - mutex_unlock(&pinctrldev_list_mutex); + mutex_lock(&pinctrl_mutex); - pctldev->p = pinctrl_get(pctldev->dev); + list_add_tail(&pctldev->node, &pinctrldev_list); + pctldev->p = pinctrl_get_locked(pctldev->dev); if (!IS_ERR(pctldev->p)) { pctldev->hog_default = - pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT); + pinctrl_lookup_state_locked(pctldev->p, + PINCTRL_STATE_DEFAULT); if (IS_ERR(pctldev->hog_default)) { dev_dbg(dev, "failed to lookup the default state\n"); } else { - if (pinctrl_select_state(pctldev->p, + if (pinctrl_select_state_locked(pctldev->p, pctldev->hog_default)) dev_err(dev, "failed to select default state\n"); } pctldev->hog_sleep = - pinctrl_lookup_state(pctldev->p, + pinctrl_lookup_state_locked(pctldev->p, PINCTRL_STATE_SLEEP); if (IS_ERR(pctldev->hog_sleep)) dev_dbg(dev, "failed to lookup the sleep state\n"); } + mutex_unlock(&pinctrl_mutex); + pinctrl_init_device_debugfs(pctldev); return pctldev; out_err: - mutex_destroy(&pctldev->mutex); kfree(pctldev); return NULL; } @@ -1691,13 +1600,12 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) if (pctldev == NULL) return; - mutex_lock(&pinctrldev_list_mutex); - mutex_lock(&pctldev->mutex); - pinctrl_remove_device_debugfs(pctldev); + mutex_lock(&pinctrl_mutex); + if (!IS_ERR(pctldev->p)) - pinctrl_put(pctldev->p); + pinctrl_put_locked(pctldev->p, true); /* TODO: check that no pinmuxes are still active? */ list_del(&pctldev->node); @@ -1708,10 +1616,9 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) list_for_each_entry_safe(range, n, &pctldev->gpio_ranges, node) list_del(&range->node); - mutex_unlock(&pctldev->mutex); - mutex_destroy(&pctldev->mutex); kfree(pctldev); - mutex_unlock(&pinctrldev_list_mutex); + + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_unregister); diff --git a/trunk/drivers/pinctrl/core.h b/trunk/drivers/pinctrl/core.h index 75476b3d87da..ee72f1f6d862 100644 --- a/trunk/drivers/pinctrl/core.h +++ b/trunk/drivers/pinctrl/core.h @@ -33,7 +33,6 @@ struct pinctrl_gpio_range; * @p: result of pinctrl_get() for this device * @hog_default: default state for pins hogged by this device * @hog_sleep: sleep state for pins hogged by this device - * @mutex: mutex taken on each pin controller specific action * @device_root: debugfs root for this device */ struct pinctrl_dev { @@ -47,7 +46,6 @@ struct pinctrl_dev { struct pinctrl *p; struct pinctrl_state *hog_default; struct pinctrl_state *hog_sleep; - struct mutex mutex; #ifdef CONFIG_DEBUG_FS struct dentry *device_root; #endif @@ -74,7 +72,7 @@ struct pinctrl { /** * struct pinctrl_state - a pinctrl state for a device - * @node: list node for struct pinctrl's @states field + * @node: list not for struct pinctrl's @states field * @name: the name of this state * @settings: a list of settings for this state */ @@ -170,7 +168,6 @@ struct pinctrl_maps { }; struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); -struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np); int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin); int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, @@ -189,7 +186,8 @@ void pinctrl_unregister_map(struct pinctrl_map const *map); extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev); extern int pinctrl_force_default(struct pinctrl_dev *pctldev); -extern struct mutex pinctrl_maps_mutex; +extern struct mutex pinctrl_mutex; +extern struct list_head pinctrldev_list; extern struct list_head pinctrl_maps; #define for_each_maps(_maps_node_, _i_, _map_) \ diff --git a/trunk/drivers/pinctrl/devicetree.c b/trunk/drivers/pinctrl/devicetree.c index 340fb4e6c600..fd40a11ad645 100644 --- a/trunk/drivers/pinctrl/devicetree.c +++ b/trunk/drivers/pinctrl/devicetree.c @@ -41,7 +41,7 @@ static void dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps) { if (pctldev) { - const struct pinctrl_ops *ops = pctldev->desc->pctlops; + struct pinctrl_ops *ops = pctldev->desc->pctlops; ops->dt_free_map(pctldev, map, num_maps); } else { /* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */ @@ -95,11 +95,22 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename, return pinctrl_register_map(map, num_maps, false, true); } +static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) +{ + struct pinctrl_dev *pctldev; + + list_for_each_entry(pctldev, &pinctrldev_list, node) + if (pctldev->dev->of_node == np) + return pctldev; + + return NULL; +} + struct pinctrl_dev *of_pinctrl_get(struct device_node *np) { struct pinctrl_dev *pctldev; - pctldev = get_pinctrl_dev_from_of_node(np); + pctldev = find_pinctrl_by_of_node(np); if (!pctldev) return NULL; @@ -111,7 +122,7 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename, { struct device_node *np_pctldev; struct pinctrl_dev *pctldev; - const struct pinctrl_ops *ops; + struct pinctrl_ops *ops; int ret; struct pinctrl_map *map; unsigned num_maps; @@ -127,7 +138,7 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename, /* OK let's just assume this will appear later then */ return -EPROBE_DEFER; } - pctldev = get_pinctrl_dev_from_of_node(np_pctldev); + pctldev = find_pinctrl_by_of_node(np_pctldev); if (pctldev) break; /* Do not defer probing of hogs (circular loop) */ diff --git a/trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.c index bb7ddb1bc89f..c689c04a4f52 100644 --- a/trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.c +++ b/trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.c @@ -263,7 +263,7 @@ static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, return; } -static const struct pinconf_ops mvebu_pinconf_ops = { +static struct pinconf_ops mvebu_pinconf_ops = { .pin_config_group_get = mvebu_pinconf_group_get, .pin_config_group_set = mvebu_pinconf_group_set, .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show, @@ -369,7 +369,7 @@ static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, return -ENOTSUPP; } -static const struct pinmux_ops mvebu_pinmux_ops = { +static struct pinmux_ops mvebu_pinmux_ops = { .get_functions_count = mvebu_pinmux_get_funcs_count, .get_function_name = mvebu_pinmux_get_func_name, .get_function_groups = mvebu_pinmux_get_groups, @@ -470,7 +470,7 @@ static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static const struct pinctrl_ops mvebu_pinctrl_ops = { +static struct pinctrl_ops mvebu_pinctrl_ops = { .get_groups_count = mvebu_pinctrl_get_groups_count, .get_group_name = mvebu_pinctrl_get_group_name, .get_group_pins = mvebu_pinctrl_get_group_pins, @@ -478,12 +478,8 @@ static const struct pinctrl_ops mvebu_pinctrl_ops = { .dt_free_map = mvebu_pinctrl_dt_free_map, }; -static int _add_function(struct mvebu_pinctrl_function *funcs, int *funcsize, - const char *name) +static int _add_function(struct mvebu_pinctrl_function *funcs, const char *name) { - if (*funcsize <= 0) - return -EOVERFLOW; - while (funcs->num_groups) { /* function already there */ if (strcmp(funcs->name, name) == 0) { @@ -492,12 +488,8 @@ static int _add_function(struct mvebu_pinctrl_function *funcs, int *funcsize, } funcs++; } - - /* append new unique function */ funcs->name = name; funcs->num_groups = 1; - (*funcsize)--; - return 0; } @@ -505,12 +497,12 @@ static int mvebu_pinctrl_build_functions(struct platform_device *pdev, struct mvebu_pinctrl *pctl) { struct mvebu_pinctrl_function *funcs; - int num = 0, funcsize = pctl->desc.npins; + int num = 0; int n, s; /* we allocate functions for number of pins and hope - * there are fewer unique functions than pins available */ - funcs = devm_kzalloc(&pdev->dev, funcsize * + * there are less unique functions than pins available */ + funcs = devm_kzalloc(&pdev->dev, pctl->desc.npins * sizeof(struct mvebu_pinctrl_function), GFP_KERNEL); if (!funcs) return -ENOMEM; @@ -518,27 +510,26 @@ static int mvebu_pinctrl_build_functions(struct platform_device *pdev, for (n = 0; n < pctl->num_groups; n++) { struct mvebu_pinctrl_group *grp = &pctl->groups[n]; for (s = 0; s < grp->num_settings; s++) { - int ret; - /* skip unsupported settings on this variant */ if (pctl->variant && !(pctl->variant & grp->settings[s].variant)) continue; /* check for unique functions and count groups */ - ret = _add_function(funcs, &funcsize, - grp->settings[s].name); - if (ret == -EOVERFLOW) - dev_err(&pdev->dev, - "More functions than pins(%d)\n", - pctl->desc.npins); - if (ret < 0) + if (_add_function(funcs, grp->settings[s].name)) continue; num++; } } + /* with the number of unique functions and it's groups known, + reallocate functions and assign group names */ + funcs = krealloc(funcs, num * sizeof(struct mvebu_pinctrl_function), + GFP_KERNEL); + if (!funcs) + return -ENOMEM; + pctl->num_functions = num; pctl->functions = funcs; @@ -629,7 +620,7 @@ int mvebu_pinctrl_probe(struct platform_device *pdev) /* special soc specific control */ if (ctrl->mpp_get || ctrl->mpp_set) { - if (!ctrl->name || !ctrl->mpp_get || !ctrl->mpp_set) { + if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) { dev_err(&pdev->dev, "wrong soc control info\n"); return -EINVAL; } diff --git a/trunk/drivers/pinctrl/pinconf-generic.c b/trunk/drivers/pinctrl/pinconf-generic.c index 2ad5a8d337b5..06c304ac6f7d 100644 --- a/trunk/drivers/pinctrl/pinconf-generic.c +++ b/trunk/drivers/pinctrl/pinconf-generic.c @@ -12,7 +12,6 @@ #define pr_fmt(fmt) "generic pinconfig core: " fmt #include -#include #include #include #include @@ -34,7 +33,7 @@ struct pin_config_item { #define PCONFDUMP(a, b, c) { .param = a, .display = b, .format = c } -static struct pin_config_item conf_items[] = { +struct pin_config_item conf_items[] = { PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL), PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL), PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL), @@ -60,7 +59,7 @@ void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, if (!ops->is_generic) return; - for (i = 0; i < ARRAY_SIZE(conf_items); i++) { + for(i = 0; i < ARRAY_SIZE(conf_items); i++) { unsigned long config; int ret; @@ -95,7 +94,7 @@ void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, if (!ops->is_generic) return; - for (i = 0; i < ARRAY_SIZE(conf_items); i++) { + for(i = 0; i < ARRAY_SIZE(conf_items); i++) { unsigned long config; int ret; @@ -121,17 +120,4 @@ void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, } } -void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned long config) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(conf_items); i++) { - if (pinconf_to_config_param(config) != conf_items[i].param) - continue; - seq_printf(s, "%s: 0x%x", conf_items[i].display, - pinconf_to_config_argument(config)); - } -} -EXPORT_SYMBOL_GPL(pinconf_generic_dump_config); #endif diff --git a/trunk/drivers/pinctrl/pinconf.c b/trunk/drivers/pinctrl/pinconf.c index c67c37e23dd7..ac8d382a79bb 100644 --- a/trunk/drivers/pinctrl/pinconf.c +++ b/trunk/drivers/pinctrl/pinconf.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -89,14 +88,14 @@ int pin_config_get(const char *dev_name, const char *name, struct pinctrl_dev *pctldev; int pin; + mutex_lock(&pinctrl_mutex); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) { pin = -EINVAL; - return pin; + goto unlock; } - mutex_lock(&pctldev->mutex); - pin = pin_get_from_name(pctldev, name); if (pin < 0) goto unlock; @@ -104,7 +103,7 @@ int pin_config_get(const char *dev_name, const char *name, pin = pin_config_get_for_pin(pctldev, pin, config); unlock: - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return pin; } EXPORT_SYMBOL(pin_config_get); @@ -145,14 +144,14 @@ int pin_config_set(const char *dev_name, const char *name, struct pinctrl_dev *pctldev; int pin, ret; + mutex_lock(&pinctrl_mutex); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) { ret = -EINVAL; - return ret; + goto unlock; } - mutex_lock(&pctldev->mutex); - pin = pin_get_from_name(pctldev, name); if (pin < 0) { ret = pin; @@ -162,7 +161,7 @@ int pin_config_set(const char *dev_name, const char *name, ret = pin_config_set_for_pin(pctldev, pin, config); unlock: - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return ret; } EXPORT_SYMBOL(pin_config_set); @@ -174,14 +173,13 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, const struct pinconf_ops *ops; int selector, ret; + mutex_lock(&pinctrl_mutex); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) { ret = -EINVAL; - return ret; + goto unlock; } - - mutex_lock(&pctldev->mutex); - ops = pctldev->desc->confops; if (!ops || !ops->pin_config_group_get) { @@ -201,7 +199,7 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, ret = ops->pin_config_group_get(pctldev, selector, config); unlock: - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return ret; } EXPORT_SYMBOL(pin_config_group_get); @@ -218,14 +216,13 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, int ret; int i; + mutex_lock(&pinctrl_mutex); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) { ret = -EINVAL; - return ret; + goto unlock; } - - mutex_lock(&pctldev->mutex); - ops = pctldev->desc->confops; pctlops = pctldev->desc->pctlops; @@ -281,7 +278,7 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, ret = 0; unlock: - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return ret; } @@ -489,7 +486,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what) seq_puts(s, "Pin config settings per pin\n"); seq_puts(s, "Format: pin (name): configs\n"); - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { @@ -509,7 +506,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what) seq_printf(s, "\n"); } - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -577,58 +574,122 @@ static const struct file_operations pinconf_groups_ops = { .release = single_release, }; -#define MAX_NAME_LEN 15 +/* 32bit read/write ressources */ +#define MAX_NAME_LEN 16 +char dbg_pinname[MAX_NAME_LEN]; /* shared: name of the state of the pin*/ +char dbg_state_name[MAX_NAME_LEN]; /* shared: state of the pin*/ +static u32 dbg_config; /* shared: config to be read/set for the pin & state*/ + +static int pinconf_dbg_pinname_print(struct seq_file *s, void *d) +{ + if (strlen(dbg_pinname)) + seq_printf(s, "%s\n", dbg_pinname); + else + seq_printf(s, "No pin name set\n"); + return 0; +} + +static int pinconf_dbg_pinname_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinconf_dbg_pinname_print, inode->i_private); +} + +static int pinconf_dbg_pinname_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + int err; + + if (count > MAX_NAME_LEN) + return -EINVAL; + + err = sscanf(user_buf, "%15s", dbg_pinname); + + if (err != 1) + return -EINVAL; + + return count; +} -struct dbg_cfg { - enum pinctrl_map_type map_type; - char dev_name[MAX_NAME_LEN+1]; - char state_name[MAX_NAME_LEN+1]; - char pin_name[MAX_NAME_LEN+1]; +static const struct file_operations pinconf_dbg_pinname_fops = { + .open = pinconf_dbg_pinname_open, + .write = pinconf_dbg_pinname_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, }; -/* - * Goal is to keep this structure as global in order to simply read the - * pinconf-config file after a write to check config is as expected - */ -static struct dbg_cfg pinconf_dbg_conf; +static int pinconf_dbg_state_print(struct seq_file *s, void *d) +{ + if (strlen(dbg_state_name)) + seq_printf(s, "%s\n", dbg_pinname); + else + seq_printf(s, "No pin state set\n"); + return 0; +} + +static int pinconf_dbg_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinconf_dbg_state_print, inode->i_private); +} + +static int pinconf_dbg_state_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + int err; + + if (count > MAX_NAME_LEN) + return -EINVAL; + + err = sscanf(user_buf, "%15s", dbg_state_name); + + if (err != 1) + return -EINVAL; + + return count; +} + +static const struct file_operations pinconf_dbg_pinstate_fops = { + .open = pinconf_dbg_state_open, + .write = pinconf_dbg_state_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; /** * pinconf_dbg_config_print() - display the pinctrl config from the pinctrl - * map, of the dev/pin/state that was last written to pinconf-config file. - * @s: string filled in with config description + * map, of a pin/state pair based on pinname and state that have been + * selected with the debugfs entries pinconf-name and pinconf-state + * @s: contains the 32bits config to be written * @d: not used */ static int pinconf_dbg_config_print(struct seq_file *s, void *d) { struct pinctrl_maps *maps_node; - const struct pinctrl_map *map; + struct pinctrl_map const *map; struct pinctrl_dev *pctldev = NULL; - const struct pinconf_ops *confops = NULL; - const struct pinctrl_map_configs *configs; - struct dbg_cfg *dbg = &pinconf_dbg_conf; + struct pinconf_ops *confops = NULL; int i, j; bool found = false; - unsigned long config; - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); /* Parse the pinctrl map and look for the elected pin/state */ for_each_maps(maps_node, i, map) { - if (map->type != dbg->map_type) - continue; - if (strcmp(map->dev_name, dbg->dev_name)) + if (map->type != PIN_MAP_TYPE_CONFIGS_PIN) continue; - if (strcmp(map->name, dbg->state_name)) + + if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0) continue; for (j = 0; j < map->data.configs.num_configs; j++) { - if (!strcmp(map->data.configs.group_or_pin, - dbg->pin_name)) { - /* - * We found the right pin / state, read the - * config and he pctldev for later use - */ - configs = &map->data.configs; + if (0 == strncmp(map->data.configs.group_or_pin, + dbg_pinname, MAX_NAME_LEN)) { + /* We found the right pin / state, read the + * config and store the pctldev */ + dbg_config = map->data.configs.configs[j]; pctldev = get_pinctrl_dev_from_devname (map->ctrl_dev_name); found = true; @@ -637,166 +698,74 @@ static int pinconf_dbg_config_print(struct seq_file *s, void *d) } } - if (!found) { - seq_printf(s, "No config found for dev/state/pin, expected:\n"); - seq_printf(s, "Searched dev:%s\n", dbg->dev_name); - seq_printf(s, "Searched state:%s\n", dbg->state_name); - seq_printf(s, "Searched pin:%s\n", dbg->pin_name); - seq_printf(s, "Use: modify config_pin "\ - " \n"); - goto exit; - } + mutex_unlock(&pinctrl_mutex); - config = *(configs->configs); - seq_printf(s, "Dev %s has config of %s in state %s: 0x%08lX\n", - dbg->dev_name, dbg->pin_name, - dbg->state_name, config); + if (found) { + seq_printf(s, "Config of %s in state %s: 0x%08X\n", dbg_pinname, + dbg_state_name, dbg_config); - if (pctldev) - confops = pctldev->desc->confops; + if (pctldev) + confops = pctldev->desc->confops; - if (confops && confops->pin_config_config_dbg_show) - confops->pin_config_config_dbg_show(pctldev, s, config); - -exit: - mutex_unlock(&pctldev->mutex); + if (confops && confops->pin_config_config_dbg_show) + confops->pin_config_config_dbg_show(pctldev, + s, dbg_config); + } else { + seq_printf(s, "No pin found for defined name/state\n"); + } return 0; } +static int pinconf_dbg_config_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinconf_dbg_config_print, inode->i_private); +} + /** - * pinconf_dbg_config_write() - modify the pinctrl config in the pinctrl - * map, of a dev/pin/state entry based on user entries to pinconf-config - * @user_buf: contains the modification request with expected format: - * modify config_pin - * modify is literal string, alternatives like add/delete not supported yet - * config_pin is literal, alternatives like config_mux not supported yet - * are values that should match the pinctrl-maps - * reflects the new config and is driver dependant + * pinconf_dbg_config_write() - overwrite the pinctrl config in thepinctrl + * map, of a pin/state pair based on pinname and state that have been + * selected with the debugfs entries pinconf-name and pinconf-state */ static int pinconf_dbg_config_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { + int err; + unsigned long config; struct pinctrl_maps *maps_node; - const struct pinctrl_map *map; - struct pinctrl_dev *pctldev = NULL; - const struct pinconf_ops *confops = NULL; - struct dbg_cfg *dbg = &pinconf_dbg_conf; - const struct pinctrl_map_configs *configs; - char config[MAX_NAME_LEN+1]; - bool found = false; - char buf[128]; - char *b = &buf[0]; - int buf_size; - char *token; - int i; - - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - /* - * need to parse entry and extract parameters: - * modify configs_pin devicename state pinname newvalue - */ - - /* Get arg: 'modify' */ - token = strsep(&b, " "); - if (!token) - return -EINVAL; - if (strcmp(token, "modify")) - return -EINVAL; + struct pinctrl_map const *map; + int i, j; - /* Get arg type: "config_pin" type supported so far */ - token = strsep(&b, " "); - if (!token) - return -EINVAL; - if (strcmp(token, "config_pin")) - return -EINVAL; - dbg->map_type = PIN_MAP_TYPE_CONFIGS_PIN; + err = kstrtoul_from_user(user_buf, count, 0, &config); - /* get arg 'device_name' */ - token = strsep(&b, " "); - if (token == NULL) - return -EINVAL; - if (strlen(token) >= MAX_NAME_LEN) - return -EINVAL; - strncpy(dbg->dev_name, token, MAX_NAME_LEN); + if (err) + return err; - /* get arg 'state_name' */ - token = strsep(&b, " "); - if (token == NULL) - return -EINVAL; - if (strlen(token) >= MAX_NAME_LEN) - return -EINVAL; - strncpy(dbg->state_name, token, MAX_NAME_LEN); + dbg_config = config; - /* get arg 'pin_name' */ - token = strsep(&b, " "); - if (token == NULL) - return -EINVAL; - if (strlen(token) >= MAX_NAME_LEN) - return -EINVAL; - strncpy(dbg->pin_name, token, MAX_NAME_LEN); + mutex_lock(&pinctrl_mutex); - /* get new_value of config' */ - token = strsep(&b, " "); - if (token == NULL) - return -EINVAL; - if (strlen(token) >= MAX_NAME_LEN) - return -EINVAL; - strncpy(config, token, MAX_NAME_LEN); - - mutex_lock(&pinctrl_maps_mutex); - - /* Parse the pinctrl map and look for the selected dev/state/pin */ + /* Parse the pinctrl map and look for the selected pin/state */ for_each_maps(maps_node, i, map) { - if (strcmp(map->dev_name, dbg->dev_name)) - continue; - if (map->type != dbg->map_type) + if (map->type != PIN_MAP_TYPE_CONFIGS_PIN) continue; - if (strcmp(map->name, dbg->state_name)) + + if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0) continue; /* we found the right pin / state, so overwrite config */ - if (!strcmp(map->data.configs.group_or_pin, dbg->pin_name)) { - found = true; - pctldev = get_pinctrl_dev_from_devname( - map->ctrl_dev_name); - configs = &map->data.configs; - break; - } - } - - if (!found) { - count = -EINVAL; - goto exit; - } - - if (pctldev) - confops = pctldev->desc->confops; - - if (confops && confops->pin_config_dbg_parse_modify) { - for (i = 0; i < configs->num_configs; i++) { - confops->pin_config_dbg_parse_modify(pctldev, - config, - &configs->configs[i]); + for (j = 0; j < map->data.configs.num_configs; j++) { + if (strncmp(map->data.configs.group_or_pin, dbg_pinname, + MAX_NAME_LEN) == 0) + map->data.configs.configs[j] = dbg_config; } } -exit: - mutex_unlock(&pinctrl_maps_mutex); + mutex_unlock(&pinctrl_mutex); return count; } -static int pinconf_dbg_config_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinconf_dbg_config_print, inode->i_private); -} - static const struct file_operations pinconf_dbg_pinconfig_fops = { .open = pinconf_dbg_config_open, .write = pinconf_dbg_config_write, @@ -813,6 +782,10 @@ void pinconf_init_device_debugfs(struct dentry *devroot, devroot, pctldev, &pinconf_pins_ops); debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO, devroot, pctldev, &pinconf_groups_ops); + debugfs_create_file("pinconf-name", (S_IRUGO | S_IWUSR | S_IWGRP), + devroot, pctldev, &pinconf_dbg_pinname_fops); + debugfs_create_file("pinconf-state", (S_IRUGO | S_IWUSR | S_IWGRP), + devroot, pctldev, &pinconf_dbg_pinstate_fops); debugfs_create_file("pinconf-config", (S_IRUGO | S_IWUSR | S_IWGRP), devroot, pctldev, &pinconf_dbg_pinconfig_fops); } diff --git a/trunk/drivers/pinctrl/pinconf.h b/trunk/drivers/pinctrl/pinconf.h index 92c7267244d2..e3ed8cb072a5 100644 --- a/trunk/drivers/pinctrl/pinconf.h +++ b/trunk/drivers/pinctrl/pinconf.h @@ -90,7 +90,7 @@ static inline void pinconf_init_device_debugfs(struct dentry *devroot, * pin config. */ -#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_DEBUG_FS) +#ifdef CONFIG_GENERIC_PINCONF void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned pin); @@ -98,8 +98,6 @@ void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, struct seq_file *s, const char *gname); -void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned long config); #else static inline void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, @@ -116,10 +114,4 @@ static inline void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, return; } -static inline void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, - struct seq_file *s, - unsigned long config) -{ - return; -} #endif diff --git a/trunk/drivers/pinctrl/pinctrl-ab8500.c b/trunk/drivers/pinctrl/pinctrl-ab8500.c index 2ac2d0ad3025..3b471d87c211 100644 --- a/trunk/drivers/pinctrl/pinctrl-ab8500.c +++ b/trunk/drivers/pinctrl/pinctrl-ab8500.c @@ -389,8 +389,7 @@ static const struct abx500_function ab8500_functions[] = { * alt_A | 1 | 0 | 0 */ -static struct -alternate_functions ab8500_alternate_functions[AB8500_GPIO_MAX_NUMBER + 1] = { +struct alternate_functions ab8500_alternate_functions[AB8500_GPIO_MAX_NUMBER + 1] = { ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */ ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */ ALTERNATE_FUNCTIONS(2, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */ @@ -456,7 +455,7 @@ alternate_functions ab8500_alternate_functions[AB8500_GPIO_MAX_NUMBER + 1] = { * GPIO24 and GPIO25 * GPIO36 to GPIO41 */ -static struct abx500_gpio_irq_cluster ab8500_gpio_irq_cluster[] = { +struct abx500_gpio_irq_cluster ab8500_gpio_irq_cluster[] = { GPIO_IRQ_CLUSTER(6, 13, AB8500_INT_GPIO6R), GPIO_IRQ_CLUSTER(24, 25, AB8500_INT_GPIO24R), GPIO_IRQ_CLUSTER(36, 41, AB8500_INT_GPIO36R), diff --git a/trunk/drivers/pinctrl/pinctrl-ab8505.c b/trunk/drivers/pinctrl/pinctrl-ab8505.c index bf0ef4ac376f..3a4238e879e3 100644 --- a/trunk/drivers/pinctrl/pinctrl-ab8505.c +++ b/trunk/drivers/pinctrl/pinctrl-ab8505.c @@ -271,8 +271,7 @@ static const struct abx500_function ab8505_functions[] = { * alt_A | 1 | 0 | 0 */ -static struct -alternate_functions ab8505_alternate_functions[AB8505_GPIO_MAX_NUMBER + 1] = { +struct alternate_functions ab8505_alternate_functions[AB8505_GPIO_MAX_NUMBER + 1] = { ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */ ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */ ALTERNATE_FUNCTIONS(2, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */ @@ -285,7 +284,7 @@ alternate_functions ab8505_alternate_functions[AB8505_GPIO_MAX_NUMBER + 1] = { ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9, bit 0 reserved */ ALTERNATE_FUNCTIONS(10, 1, 0, UNUSED, 1, 0, 0), /* GPIO10, altA and altB controlled by bit 0 */ - ALTERNATE_FUNCTIONS(11, 2, 1, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 2 */ + ALTERNATE_FUNCTIONS(11, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 2 */ ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12, bit3 reseved */ ALTERNATE_FUNCTIONS(13, 4, 3, 4, 1, 0, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */ ALTERNATE_FUNCTIONS(14, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */ @@ -349,7 +348,7 @@ alternate_functions ab8505_alternate_functions[AB8505_GPIO_MAX_NUMBER + 1] = { * GPIO50 * GPIO52 to GPIO53 */ -static struct abx500_gpio_irq_cluster ab8505_gpio_irq_cluster[] = { +struct abx500_gpio_irq_cluster ab8505_gpio_irq_cluster[] = { GPIO_IRQ_CLUSTER(10, 11, AB8500_INT_GPIO10R), GPIO_IRQ_CLUSTER(13, 13, AB8500_INT_GPIO13R), GPIO_IRQ_CLUSTER(40, 41, AB8500_INT_GPIO40R), diff --git a/trunk/drivers/pinctrl/pinctrl-ab8540.c b/trunk/drivers/pinctrl/pinctrl-ab8540.c index 9867535d49c1..8ee1e8d95f65 100644 --- a/trunk/drivers/pinctrl/pinctrl-ab8540.c +++ b/trunk/drivers/pinctrl/pinctrl-ab8540.c @@ -299,8 +299,7 @@ static const struct abx500_function ab8540_functions[] = { * */ -static struct -alternate_functions ab8540_alternate_functions[AB8540_GPIO_MAX_NUMBER + 1] = { +struct alternate_functions ab8540_alternate_functions[AB8540_GPIO_MAX_NUMBER + 1] = { /* GPIOSEL1 - bit 4-7 reserved */ ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */ ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */ @@ -377,7 +376,7 @@ static struct pullud ab8540_pullud = { * GPIO43 to GPIO44 * GPIO51 to GPIO54 */ -static struct abx500_gpio_irq_cluster ab8540_gpio_irq_cluster[] = { +struct abx500_gpio_irq_cluster ab8540_gpio_irq_cluster[] = { GPIO_IRQ_CLUSTER(43, 43, AB8540_INT_GPIO43F), GPIO_IRQ_CLUSTER(44, 44, AB8540_INT_GPIO44F), GPIO_IRQ_CLUSTER(51, 54, AB9540_INT_GPIO51R), diff --git a/trunk/drivers/pinctrl/pinctrl-ab9540.c b/trunk/drivers/pinctrl/pinctrl-ab9540.c index 1a281ca95dac..7610bd012b98 100644 --- a/trunk/drivers/pinctrl/pinctrl-ab9540.c +++ b/trunk/drivers/pinctrl/pinctrl-ab9540.c @@ -379,8 +379,7 @@ static const struct abx500_function ab9540_functions[] = { * alt_A | 1 | 0 | 0 */ -static struct -alternate_functions ab9540alternate_functions[AB9540_GPIO_MAX_NUMBER + 1] = { +struct alternate_functions ab9540alternate_functions[AB9540_GPIO_MAX_NUMBER + 1] = { /* GPIOSEL1 - bits 4-7 are reserved */ ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */ ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */ @@ -394,7 +393,7 @@ alternate_functions ab9540alternate_functions[AB9540_GPIO_MAX_NUMBER + 1] = { /* GPIOSEL2 - bits 0 and 3 are reserved */ ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9 */ ALTERNATE_FUNCTIONS(10, 1, 0, UNUSED, 1, 0, 0), /* GPIO10, altA and altB controlled by bit 0 */ - ALTERNATE_FUNCTIONS(11, 2, 1, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 1 */ + ALTERNATE_FUNCTIONS(11, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 1 */ ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12 */ ALTERNATE_FUNCTIONS(13, 4, 3, 4, 1, 0, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */ ALTERNATE_FUNCTIONS(14, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */ @@ -455,7 +454,7 @@ alternate_functions ab9540alternate_functions[AB9540_GPIO_MAX_NUMBER + 1] = { ALTERNATE_FUNCTIONS(54, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO54 = GPIO60, altA controlled by bit 5 */ }; -static struct abx500_gpio_irq_cluster ab9540_gpio_irq_cluster[] = { +struct abx500_gpio_irq_cluster ab9540_gpio_irq_cluster[] = { GPIO_IRQ_CLUSTER(10, 13, AB8500_INT_GPIO10R), GPIO_IRQ_CLUSTER(24, 25, AB8500_INT_GPIO24R), GPIO_IRQ_CLUSTER(40, 41, AB8500_INT_GPIO40R), diff --git a/trunk/drivers/pinctrl/pinctrl-abx500.c b/trunk/drivers/pinctrl/pinctrl-abx500.c index aa17f7580f61..caecdd373061 100644 --- a/trunk/drivers/pinctrl/pinctrl-abx500.c +++ b/trunk/drivers/pinctrl/pinctrl-abx500.c @@ -422,7 +422,7 @@ static u8 abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip, } /* check if pin use AlternateFunction register */ - if ((af.alt_bit1 == UNUSED) && (af.alt_bit2 == UNUSED)) + if ((af.alt_bit1 == UNUSED) && (af.alt_bit1 == UNUSED)) return mode; /* * if pin GPIOSEL bit is set and pin supports alternate function, @@ -517,14 +517,14 @@ static inline void abx500_gpio_dbg_show_one(struct seq_file *s, #define abx500_gpio_dbg_show NULL #endif -static int abx500_gpio_request(struct gpio_chip *chip, unsigned offset) +int abx500_gpio_request(struct gpio_chip *chip, unsigned offset) { int gpio = chip->base + offset; return pinctrl_request_gpio(gpio); } -static void abx500_gpio_free(struct gpio_chip *chip, unsigned offset) +void abx500_gpio_free(struct gpio_chip *chip, unsigned offset) { int gpio = chip->base + offset; @@ -611,7 +611,7 @@ static void abx500_pmx_disable(struct pinctrl_dev *pctldev, dev_dbg(pct->dev, "disable group %s, %u pins\n", g->name, g->npins); } -static int abx500_gpio_request_enable(struct pinctrl_dev *pctldev, +int abx500_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) { @@ -656,7 +656,7 @@ static void abx500_gpio_disable_free(struct pinctrl_dev *pctldev, { } -static const struct pinmux_ops abx500_pinmux_ops = { +static struct pinmux_ops abx500_pinmux_ops = { .get_functions_count = abx500_pmx_get_funcs_cnt, .get_function_name = abx500_pmx_get_func_name, .get_function_groups = abx500_pmx_get_func_groups, @@ -704,21 +704,21 @@ static void abx500_pin_dbg_show(struct pinctrl_dev *pctldev, chip->base + offset - 1); } -static const struct pinctrl_ops abx500_pinctrl_ops = { +static struct pinctrl_ops abx500_pinctrl_ops = { .get_groups_count = abx500_get_groups_cnt, .get_group_name = abx500_get_group_name, .get_group_pins = abx500_get_group_pins, .pin_dbg_show = abx500_pin_dbg_show, }; -static int abx500_pin_config_get(struct pinctrl_dev *pctldev, +int abx500_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { return -ENOSYS; } -static int abx500_pin_config_set(struct pinctrl_dev *pctldev, +int abx500_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, unsigned long config) { @@ -778,7 +778,7 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev, return ret; } -static const struct pinconf_ops abx500_pinconf_ops = { +static struct pinconf_ops abx500_pinconf_ops = { .pin_config_get = abx500_pin_config_get, .pin_config_set = abx500_pin_config_set, }; @@ -834,7 +834,6 @@ static const struct of_device_id abx500_gpio_match[] = { { .compatible = "stericsson,ab8505-gpio", .data = (void *)PINCTRL_AB8505, }, { .compatible = "stericsson,ab8540-gpio", .data = (void *)PINCTRL_AB8540, }, { .compatible = "stericsson,ab9540-gpio", .data = (void *)PINCTRL_AB9540, }, - { } }; static int abx500_gpio_probe(struct platform_device *pdev) @@ -880,6 +879,7 @@ static int abx500_gpio_probe(struct platform_device *pdev) pct->parent = dev_get_drvdata(pdev->dev.parent); pct->chip = abx500gpio_chip; pct->chip.dev = &pdev->dev; + pct->chip.base = pdata->gpio_base; pct->chip.base = (np) ? -1 : pdata->gpio_base; /* initialize the lock */ diff --git a/trunk/drivers/pinctrl/pinctrl-at91.c b/trunk/drivers/pinctrl/pinctrl-at91.c index 4d7f531e945d..75933a6aa828 100644 --- a/trunk/drivers/pinctrl/pinctrl-at91.c +++ b/trunk/drivers/pinctrl/pinctrl-at91.c @@ -294,7 +294,7 @@ static void at91_dt_free_map(struct pinctrl_dev *pctldev, { } -static const struct pinctrl_ops at91_pctrl_ops = { +static struct pinctrl_ops at91_pctrl_ops = { .get_groups_count = at91_get_groups_count, .get_group_name = at91_get_group_name, .get_group_pins = at91_get_group_pins, @@ -303,7 +303,7 @@ static const struct pinctrl_ops at91_pctrl_ops = { .dt_free_map = at91_dt_free_map, }; -static void __iomem *pin_to_controller(struct at91_pinctrl *info, +static void __iomem * pin_to_controller(struct at91_pinctrl *info, unsigned int bank) { return gpio_chips[bank]->regbase; @@ -501,7 +501,7 @@ static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pi } } -static int pin_check_config(struct at91_pinctrl *info, const char *name, +static int pin_check_config(struct at91_pinctrl *info, const char* name, int index, const struct at91_pmx_pin *pin) { int mux; @@ -579,7 +579,7 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, pio = pin_to_controller(info, pin->bank); mask = pin_to_mask(pin->pin); at91_mux_disable_interrupt(pio, mask); - switch (pin->mux) { + switch(pin->mux) { case AT91_MUX_GPIO: at91_mux_gpio_enable(pio, mask, 1); break; @@ -696,7 +696,7 @@ static void at91_gpio_disable_free(struct pinctrl_dev *pctldev, /* Set the pin to some default state, GPIO is usually default */ } -static const struct pinmux_ops at91_pmx_ops = { +static struct pinmux_ops at91_pmx_ops = { .get_functions_count = at91_pmx_get_funcs_count, .get_function_name = at91_pmx_get_func_name, .get_function_groups = at91_pmx_get_groups, @@ -776,7 +776,7 @@ static void at91_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, { } -static const struct pinconf_ops at91_pinconf_ops = { +static struct pinconf_ops at91_pinconf_ops = { .pin_config_get = at91_pinconf_get, .pin_config_set = at91_pinconf_set, .pin_config_dbg_show = at91_pinconf_dbg_show, @@ -812,7 +812,7 @@ static int at91_pinctrl_mux_mask(struct at91_pinctrl *info, { int ret = 0; int size; - const __be32 *list; + const const __be32 *list; list = of_get_property(np, "atmel,mux-mask", &size); if (!list) { @@ -846,7 +846,7 @@ static int at91_pinctrl_parse_groups(struct device_node *np, { struct at91_pmx_pin *pin; int size; - const __be32 *list; + const const __be32 *list; int i, j; dev_dbg(info->dev, "group(%d): %s\n", index, np->name); @@ -944,7 +944,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, return -ENODEV; info->dev = &pdev->dev; - info->ops = (struct at91_pinctrl_mux_ops *) + info->ops = (struct at91_pinctrl_mux_ops*) of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; at91_pinctrl_child_count(info, np); @@ -1002,7 +1002,7 @@ static int at91_pinctrl_probe(struct platform_device *pdev) { struct at91_pinctrl *info; struct pinctrl_pin_desc *pdesc; - int ret, i, j, k; + int ret, i, j ,k; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) @@ -1277,80 +1277,21 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type) } #ifdef CONFIG_PM - -static u32 wakeups[MAX_GPIO_BANKS]; -static u32 backups[MAX_GPIO_BANKS]; - static int gpio_irq_set_wake(struct irq_data *d, unsigned state) { struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); unsigned bank = at91_gpio->pioc_idx; - unsigned mask = 1 << d->hwirq; if (unlikely(bank >= MAX_GPIO_BANKS)) return -EINVAL; - if (state) - wakeups[bank] |= mask; - else - wakeups[bank] &= ~mask; - irq_set_irq_wake(at91_gpio->pioc_virq, state); return 0; } - -void at91_pinctrl_gpio_suspend(void) -{ - int i; - - for (i = 0; i < gpio_banks; i++) { - void __iomem *pio; - - if (!gpio_chips[i]) - continue; - - pio = gpio_chips[i]->regbase; - - backups[i] = __raw_readl(pio + PIO_IMR); - __raw_writel(backups[i], pio + PIO_IDR); - __raw_writel(wakeups[i], pio + PIO_IER); - - if (!wakeups[i]) { - clk_unprepare(gpio_chips[i]->clock); - clk_disable(gpio_chips[i]->clock); - } else { - printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", - 'A'+i, wakeups[i]); - } - } -} - -void at91_pinctrl_gpio_resume(void) -{ - int i; - - for (i = 0; i < gpio_banks; i++) { - void __iomem *pio; - - if (!gpio_chips[i]) - continue; - - pio = gpio_chips[i]->regbase; - - if (!wakeups[i]) { - if (clk_prepare(gpio_chips[i]->clock) == 0) - clk_enable(gpio_chips[i]->clock); - } - - __raw_writel(wakeups[i], pio + PIO_IDR); - __raw_writel(backups[i], pio + PIO_IER); - } -} - #else #define gpio_irq_set_wake NULL -#endif /* CONFIG_PM */ +#endif static struct irq_chip gpio_irqchip = { .name = "GPIO", @@ -1568,7 +1509,7 @@ static int at91_gpio_probe(struct platform_device *pdev) goto err; } - at91_chip->ops = (struct at91_pinctrl_mux_ops *) + at91_chip->ops = (struct at91_pinctrl_mux_ops*) of_match_device(at91_gpio_of_match, &pdev->dev)->data; at91_chip->pioc_virq = irq; at91_chip->pioc_idx = alias_idx; @@ -1605,8 +1546,7 @@ static int at91_gpio_probe(struct platform_device *pdev) chip->ngpio = ngpio; } - names = devm_kzalloc(&pdev->dev, sizeof(char *) * chip->ngpio, - GFP_KERNEL); + names = devm_kzalloc(&pdev->dev, sizeof(char*) * chip->ngpio, GFP_KERNEL); if (!names) { ret = -ENOMEM; @@ -1616,7 +1556,7 @@ static int at91_gpio_probe(struct platform_device *pdev) for (i = 0; i < chip->ngpio; i++) names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); - chip->names = (const char *const *)names; + chip->names = (const char*const*)names; range = &at91_chip->range; range->name = chip->label; diff --git a/trunk/drivers/pinctrl/pinctrl-bcm2835.c b/trunk/drivers/pinctrl/pinctrl-bcm2835.c index f28d4b08771a..4eb6d2c4e4df 100644 --- a/trunk/drivers/pinctrl/pinctrl-bcm2835.c +++ b/trunk/drivers/pinctrl/pinctrl-bcm2835.c @@ -795,7 +795,7 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, return err; } -static const struct pinctrl_ops bcm2835_pctl_ops = { +static struct pinctrl_ops bcm2835_pctl_ops = { .get_groups_count = bcm2835_pctl_get_groups_count, .get_group_name = bcm2835_pctl_get_group_name, .get_group_pins = bcm2835_pctl_get_group_pins, @@ -872,7 +872,7 @@ static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, return 0; } -static const struct pinmux_ops bcm2835_pmx_ops = { +static struct pinmux_ops bcm2835_pmx_ops = { .get_functions_count = bcm2835_pmx_get_functions_count, .get_function_name = bcm2835_pmx_get_function_name, .get_function_groups = bcm2835_pmx_get_function_groups, @@ -916,7 +916,7 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, return 0; } -static const struct pinconf_ops bcm2835_pinconf_ops = { +static struct pinconf_ops bcm2835_pinconf_ops = { .pin_config_get = bcm2835_pinconf_get, .pin_config_set = bcm2835_pinconf_set, }; diff --git a/trunk/drivers/pinctrl/pinctrl-coh901.c b/trunk/drivers/pinctrl/pinctrl-coh901.c index edde3acc4186..8b7e7bc2226b 100644 --- a/trunk/drivers/pinctrl/pinctrl-coh901.c +++ b/trunk/drivers/pinctrl/pinctrl-coh901.c @@ -318,16 +318,13 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) struct u300_gpio_port *port = NULL; struct list_head *p; int retirq; - bool found = false; list_for_each(p, &gpio->port_list) { port = list_entry(p, struct u300_gpio_port, node); - if (port->number == portno) { - found = true; + if (port->number == portno) break; - } } - if (!found) { + if (port == NULL) { dev_err(gpio->dev, "could not locate port for GPIO %d IRQ\n", offset); return -EINVAL; @@ -362,7 +359,7 @@ int u300_gpio_config_get(struct gpio_chip *chip, drmode &= (U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); drmode >>= ((offset & 0x07) << 1); - switch (param) { + switch(param) { case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: *config = 0; if (biasmode) diff --git a/trunk/drivers/pinctrl/pinctrl-exynos.c b/trunk/drivers/pinctrl/pinctrl-exynos.c index 8b10b1ac9071..538b9ddaadf7 100644 --- a/trunk/drivers/pinctrl/pinctrl-exynos.c +++ b/trunk/drivers/pinctrl/pinctrl-exynos.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -34,17 +33,6 @@ #include "pinctrl-samsung.h" #include "pinctrl-exynos.h" - -static struct samsung_pin_bank_type bank_type_off = { - .fld_width = { 4, 1, 2, 2, 2, 2, }, - .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, }, -}; - -static struct samsung_pin_bank_type bank_type_alive = { - .fld_width = { 4, 1, 2, 2, }, - .reg_offset = { 0x00, 0x04, 0x08, 0x0c, }, -}; - /* list of external wakeup controllers supported */ static const struct of_device_id exynos_wkup_irq_ids[] = { { .compatible = "samsung,exynos4210-wakeup-eint", }, @@ -87,14 +75,12 @@ static void exynos_gpio_irq_ack(struct irq_data *irqd) static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank_type *bank_type = bank->type; struct samsung_pinctrl_drv_data *d = bank->drvdata; struct samsung_pin_ctrl *ctrl = d->ctrl; unsigned int pin = irqd->hwirq; unsigned int shift = EXYNOS_EINT_CON_LEN * pin; unsigned int con, trig_type; unsigned long reg_con = ctrl->geint_con + bank->eint_offset; - unsigned long flags; unsigned int mask; switch (type) { @@ -128,19 +114,15 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) con |= trig_type << shift; writel(con, d->virt_base + reg_con); - reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; - shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; - mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; - - spin_lock_irqsave(&bank->slock, flags); + reg_con = bank->pctl_offset; + shift = pin * bank->func_width; + mask = (1 << bank->func_width) - 1; con = readl(d->virt_base + reg_con); con &= ~(mask << shift); con |= EXYNOS_EINT_FUNC << shift; writel(con, d->virt_base + reg_con); - spin_unlock_irqrestore(&bank->slock, flags); - return 0; } @@ -271,13 +253,11 @@ static void exynos_wkup_irq_ack(struct irq_data *irqd) static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank_type *bank_type = bank->type; struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned int pin = irqd->hwirq; unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset; unsigned long shift = EXYNOS_EINT_CON_LEN * pin; unsigned long con, trig_type; - unsigned long flags; unsigned int mask; switch (type) { @@ -311,19 +291,15 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) con |= trig_type << shift; writel(con, d->virt_base + reg_con); - reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; - shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; - mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; - - spin_lock_irqsave(&bank->slock, flags); + reg_con = bank->pctl_offset; + shift = pin * bank->func_width; + mask = (1 << bank->func_width) - 1; con = readl(d->virt_base + reg_con); con &= ~(mask << shift); con |= EXYNOS_EINT_FUNC << shift; writel(con, d->virt_base + reg_con); - spin_unlock_irqrestore(&bank->slock, flags); - return 0; } diff --git a/trunk/drivers/pinctrl/pinctrl-exynos.h b/trunk/drivers/pinctrl/pinctrl-exynos.h index 9b1f77a5bf0f..0a708890d8b4 100644 --- a/trunk/drivers/pinctrl/pinctrl-exynos.h +++ b/trunk/drivers/pinctrl/pinctrl-exynos.h @@ -48,18 +48,26 @@ #define EXYNOS_PIN_BANK_EINTN(pins, reg, id) \ { \ - .type = &bank_type_off, \ .pctl_offset = reg, \ .nr_pins = pins, \ + .func_width = 4, \ + .pud_width = 2, \ + .drv_width = 2, \ + .conpdn_width = 2, \ + .pudpdn_width = 2, \ .eint_type = EINT_TYPE_NONE, \ .name = id \ } #define EXYNOS_PIN_BANK_EINTG(pins, reg, id, offs) \ { \ - .type = &bank_type_off, \ .pctl_offset = reg, \ .nr_pins = pins, \ + .func_width = 4, \ + .pud_width = 2, \ + .drv_width = 2, \ + .conpdn_width = 2, \ + .pudpdn_width = 2, \ .eint_type = EINT_TYPE_GPIO, \ .eint_offset = offs, \ .name = id \ @@ -67,9 +75,11 @@ #define EXYNOS_PIN_BANK_EINTW(pins, reg, id, offs) \ { \ - .type = &bank_type_alive, \ .pctl_offset = reg, \ .nr_pins = pins, \ + .func_width = 4, \ + .pud_width = 2, \ + .drv_width = 2, \ .eint_type = EINT_TYPE_WKUP, \ .eint_offset = offs, \ .name = id \ diff --git a/trunk/drivers/pinctrl/pinctrl-exynos5440.c b/trunk/drivers/pinctrl/pinctrl-exynos5440.c index 6038503ed929..1376eb7305db 100644 --- a/trunk/drivers/pinctrl/pinctrl-exynos5440.c +++ b/trunk/drivers/pinctrl/pinctrl-exynos5440.c @@ -20,9 +20,6 @@ #include #include #include -#include -#include -#include #include "core.h" /* EXYNOS5440 GPIO and Pinctrl register offsets */ @@ -40,7 +37,6 @@ #define GPIO_DS1 0x2C #define EXYNOS5440_MAX_PINS 23 -#define EXYNOS5440_MAX_GPIO_INT 8 #define PIN_NAME_LENGTH 10 #define GROUP_SUFFIX "-grp" @@ -113,7 +109,6 @@ struct exynos5440_pmx_func { struct exynos5440_pinctrl_priv_data { void __iomem *reg_base; struct gpio_chip *gc; - struct irq_domain *irq_domain; const struct exynos5440_pin_group *pin_groups; unsigned int nr_groups; @@ -121,16 +116,6 @@ struct exynos5440_pinctrl_priv_data { unsigned int nr_functions; }; -/** - * struct exynos5440_gpio_intr_data: private data for gpio interrupts. - * @priv: driver's private runtime data. - * @gpio_int: gpio interrupt number. - */ -struct exynos5440_gpio_intr_data { - struct exynos5440_pinctrl_priv_data *priv; - unsigned int gpio_int; -}; - /* list of all possible config options supported */ static struct pin_config { char *prop_cfg; @@ -301,7 +286,7 @@ static void exynos5440_dt_free_map(struct pinctrl_dev *pctldev, } /* list of pinctrl callbacks for the pinctrl core */ -static const struct pinctrl_ops exynos5440_pctrl_ops = { +static struct pinctrl_ops exynos5440_pctrl_ops = { .get_groups_count = exynos5440_get_group_count, .get_group_name = exynos5440_get_group_name, .get_group_pins = exynos5440_get_group_pins, @@ -389,7 +374,7 @@ static int exynos5440_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, } /* list of pinmux callbacks for the pinmux vertical in pinctrl core */ -static const struct pinmux_ops exynos5440_pinmux_ops = { +static struct pinmux_ops exynos5440_pinmux_ops = { .get_functions_count = exynos5440_get_functions_count, .get_function_name = exynos5440_pinmux_get_fname, .get_function_groups = exynos5440_pinmux_get_groups, @@ -538,7 +523,7 @@ static int exynos5440_pinconf_group_get(struct pinctrl_dev *pctldev, } /* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */ -static const struct pinconf_ops exynos5440_pinconf_ops = { +static struct pinconf_ops exynos5440_pinconf_ops = { .pin_config_get = exynos5440_pinconf_get, .pin_config_set = exynos5440_pinconf_set, .pin_config_group_get = exynos5440_pinconf_group_get, @@ -613,22 +598,6 @@ static int exynos5440_gpio_direction_output(struct gpio_chip *gc, unsigned offse return 0; } -/* gpiolib gpio_to_irq callback function */ -static int exynos5440_gpio_to_irq(struct gpio_chip *gc, unsigned offset) -{ - struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev); - unsigned int virq; - - if (offset < 16 || offset > 23) - return -ENXIO; - - if (!priv->irq_domain) - return -ENXIO; - - virq = irq_create_mapping(priv->irq_domain, offset - 16); - return virq ? : -ENXIO; -} - /* parse the pin numbers listed in the 'samsung,exynos5440-pins' property */ static int exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev, struct device_node *cfg_np, unsigned int **pin_list, @@ -701,10 +670,8 @@ static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev, ret = exynos5440_pinctrl_parse_dt_pins(pdev, cfg_np, &pin_list, &npins); - if (ret) { - gname = NULL; - goto skip_to_pin_function; - } + if (ret) + return ret; /* derive pin group name from the node name */ gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN, @@ -720,7 +687,6 @@ static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev, grp->num_pins = npins; grp++; -skip_to_pin_function: ret = of_property_read_u32(cfg_np, "samsung,exynos5440-pin-function", &function); if (ret) @@ -743,7 +709,7 @@ static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev, return -ENOMEM; } func->groups[0] = gname; - func->num_groups = gname ? 1 : 0; + func->num_groups = 1; func->function = function; func++; func_idx++; @@ -852,7 +818,6 @@ static int exynos5440_gpiolib_register(struct platform_device *pdev, gc->get = exynos5440_gpio_get; gc->direction_input = exynos5440_gpio_direction_input; gc->direction_output = exynos5440_gpio_direction_output; - gc->to_irq = exynos5440_gpio_to_irq; gc->label = "gpiolib-exynos5440"; gc->owner = THIS_MODULE; ret = gpiochip_add(gc); @@ -877,110 +842,6 @@ static int exynos5440_gpiolib_unregister(struct platform_device *pdev, return 0; } -static void exynos5440_gpio_irq_unmask(struct irq_data *irqd) -{ - struct exynos5440_pinctrl_priv_data *d; - unsigned long gpio_int; - - d = irq_data_get_irq_chip_data(irqd); - gpio_int = readl(d->reg_base + GPIO_INT); - gpio_int |= 1 << irqd->hwirq; - writel(gpio_int, d->reg_base + GPIO_INT); -} - -static void exynos5440_gpio_irq_mask(struct irq_data *irqd) -{ - struct exynos5440_pinctrl_priv_data *d; - unsigned long gpio_int; - - d = irq_data_get_irq_chip_data(irqd); - gpio_int = readl(d->reg_base + GPIO_INT); - gpio_int &= ~(1 << irqd->hwirq); - writel(gpio_int, d->reg_base + GPIO_INT); -} - -/* irq_chip for gpio interrupts */ -static struct irq_chip exynos5440_gpio_irq_chip = { - .name = "exynos5440_gpio_irq_chip", - .irq_unmask = exynos5440_gpio_irq_unmask, - .irq_mask = exynos5440_gpio_irq_mask, -}; - -/* interrupt handler for GPIO interrupts 0..7 */ -static irqreturn_t exynos5440_gpio_irq(int irq, void *data) -{ - struct exynos5440_gpio_intr_data *intd = data; - struct exynos5440_pinctrl_priv_data *d = intd->priv; - int virq; - - virq = irq_linear_revmap(d->irq_domain, intd->gpio_int); - if (!virq) - return IRQ_NONE; - generic_handle_irq(virq); - return IRQ_HANDLED; -} - -static int exynos5440_gpio_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct exynos5440_pinctrl_priv_data *d = h->host_data; - - irq_set_chip_data(virq, d); - irq_set_chip_and_handler(virq, &exynos5440_gpio_irq_chip, - handle_level_irq); - set_irq_flags(virq, IRQF_VALID); - return 0; -} - -/* irq domain callbacks for gpio interrupt controller */ -static const struct irq_domain_ops exynos5440_gpio_irqd_ops = { - .map = exynos5440_gpio_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - -/* setup handling of gpio interrupts */ -static int exynos5440_gpio_irq_init(struct platform_device *pdev, - struct exynos5440_pinctrl_priv_data *priv) -{ - struct device *dev = &pdev->dev; - struct exynos5440_gpio_intr_data *intd; - int i, irq, ret; - - intd = devm_kzalloc(dev, sizeof(*intd) * EXYNOS5440_MAX_GPIO_INT, - GFP_KERNEL); - if (!intd) { - dev_err(dev, "failed to allocate memory for gpio intr data\n"); - return -ENOMEM; - } - - for (i = 0; i < EXYNOS5440_MAX_GPIO_INT; i++) { - irq = irq_of_parse_and_map(dev->of_node, i); - if (irq <= 0) { - dev_err(dev, "irq parsing failed\n"); - return -EINVAL; - } - - intd->gpio_int = i; - intd->priv = priv; - ret = devm_request_irq(dev, irq, exynos5440_gpio_irq, - 0, dev_name(dev), intd++); - if (ret) { - dev_err(dev, "irq request failed\n"); - return -ENXIO; - } - } - - priv->irq_domain = irq_domain_add_linear(dev->of_node, - EXYNOS5440_MAX_GPIO_INT, - &exynos5440_gpio_irqd_ops, priv); - if (!priv->irq_domain) { - dev_err(dev, "failed to create irq domain\n"); - return -ENXIO; - } - - return 0; -} - static int exynos5440_pinctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -993,7 +854,7 @@ static int exynos5440_pinctrl_probe(struct platform_device *pdev) return -ENODEV; } - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(dev, sizeof(priv), GFP_KERNEL); if (!priv) { dev_err(dev, "could not allocate memory for private data\n"); return -ENOMEM; @@ -1019,12 +880,6 @@ static int exynos5440_pinctrl_probe(struct platform_device *pdev) return ret; } - ret = exynos5440_gpio_irq_init(pdev, priv); - if (ret) { - dev_err(dev, "failed to setup gpio interrupts\n"); - return ret; - } - platform_set_drvdata(pdev, priv); dev_info(dev, "EXYNOS5440 pinctrl driver registered\n"); return 0; diff --git a/trunk/drivers/pinctrl/pinctrl-falcon.c b/trunk/drivers/pinctrl/pinctrl-falcon.c index f9b2a1d4854f..af97a1f90007 100644 --- a/trunk/drivers/pinctrl/pinctrl-falcon.c +++ b/trunk/drivers/pinctrl/pinctrl-falcon.c @@ -353,7 +353,7 @@ static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev, { } -static const struct pinconf_ops falcon_pinconf_ops = { +static struct pinconf_ops falcon_pinconf_ops = { .pin_config_get = falcon_pinconf_get, .pin_config_set = falcon_pinconf_set, .pin_config_group_get = falcon_pinconf_group_get, diff --git a/trunk/drivers/pinctrl/pinctrl-imx.c b/trunk/drivers/pinctrl/pinctrl-imx.c index 0ef190449eab..4cebb9c6c5c5 100644 --- a/trunk/drivers/pinctrl/pinctrl-imx.c +++ b/trunk/drivers/pinctrl/pinctrl-imx.c @@ -207,7 +207,7 @@ static void imx_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static const struct pinctrl_ops imx_pctrl_ops = { +static struct pinctrl_ops imx_pctrl_ops = { .get_groups_count = imx_get_groups_count, .get_group_name = imx_get_group_name, .get_group_pins = imx_get_group_pins, @@ -299,7 +299,7 @@ static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static const struct pinmux_ops imx_pmx_ops = { +static struct pinmux_ops imx_pmx_ops = { .get_functions_count = imx_pmx_get_funcs_count, .get_function_name = imx_pmx_get_func_name, .get_function_groups = imx_pmx_get_groups, @@ -397,7 +397,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, } } -static const struct pinconf_ops imx_pinconf_ops = { +static struct pinconf_ops imx_pinconf_ops = { .pin_config_get = imx_pinconf_get, .pin_config_set = imx_pinconf_set, .pin_config_dbg_show = imx_pinconf_dbg_show, diff --git a/trunk/drivers/pinctrl/pinctrl-lantiq.c b/trunk/drivers/pinctrl/pinctrl-lantiq.c index 615c5002b757..a70384611351 100644 --- a/trunk/drivers/pinctrl/pinctrl-lantiq.c +++ b/trunk/drivers/pinctrl/pinctrl-lantiq.c @@ -169,7 +169,7 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } -static const struct pinctrl_ops ltq_pctrl_ops = { +static struct pinctrl_ops ltq_pctrl_ops = { .get_groups_count = ltq_get_group_count, .get_group_name = ltq_get_group_name, .get_group_pins = ltq_get_group_pins, @@ -311,7 +311,7 @@ static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev, return info->apply_mux(pctrldev, mfp, pin_func); } -static const struct pinmux_ops ltq_pmx_ops = { +static struct pinmux_ops ltq_pmx_ops = { .get_functions_count = ltq_pmx_func_count, .get_function_name = ltq_pmx_func_name, .get_function_groups = ltq_pmx_get_groups, diff --git a/trunk/drivers/pinctrl/pinctrl-mmp2.c b/trunk/drivers/pinctrl/pinctrl-mmp2.c new file mode 100644 index 000000000000..4afa56a3a51d --- /dev/null +++ b/trunk/drivers/pinctrl/pinctrl-mmp2.c @@ -0,0 +1,722 @@ +/* + * linux/drivers/pinctrl/pinmux-mmp2.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define MMP2_DS_MASK 0x1800 +#define MMP2_DS_SHIFT 11 +#define MMP2_SLEEP_MASK 0x38 +#define MMP2_SLEEP_SELECT (1 << 9) +#define MMP2_SLEEP_DATA (1 << 8) +#define MMP2_SLEEP_DIR (1 << 7) + +#define MFPR_MMP2(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + MMP2_MUX_##f0, \ + MMP2_MUX_##f1, \ + MMP2_MUX_##f2, \ + MMP2_MUX_##f3, \ + MMP2_MUX_##f4, \ + MMP2_MUX_##f5, \ + MMP2_MUX_##f6, \ + MMP2_MUX_##f7, \ + }, \ + } + +#define GRP_MMP2(a, m, p) \ + { .name = a, .mux = MMP2_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 174 pins */ +enum mmp2_pin_list { + /* 0~168: GPIO0~GPIO168 */ + TWSI4_SCL = 169, + TWSI4_SDA, /* 170 */ + G_CLKREQ, + VCXO_REQ, + VCXO_OUT, +}; + +enum mmp2_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + MMP2_MUX_GPIO = 0, + MMP2_MUX_G_CLKREQ, + MMP2_MUX_VCXO_REQ, + MMP2_MUX_VCXO_OUT, + MMP2_MUX_KP_MK, + MMP2_MUX_KP_DK, + MMP2_MUX_CCIC1, + MMP2_MUX_CCIC2, + MMP2_MUX_SPI, + MMP2_MUX_SSPA2, + MMP2_MUX_ROT, + MMP2_MUX_I2S, + MMP2_MUX_TB, + MMP2_MUX_CAM2, + MMP2_MUX_HDMI, + MMP2_MUX_TWSI2, + MMP2_MUX_TWSI3, + MMP2_MUX_TWSI4, + MMP2_MUX_TWSI5, + MMP2_MUX_TWSI6, + MMP2_MUX_UART1, + MMP2_MUX_UART2, + MMP2_MUX_UART3, + MMP2_MUX_UART4, + MMP2_MUX_SSP1_RX, + MMP2_MUX_SSP1_FRM, + MMP2_MUX_SSP1_TXRX, + MMP2_MUX_SSP2_RX, + MMP2_MUX_SSP2_FRM, + MMP2_MUX_SSP1, + MMP2_MUX_SSP2, + MMP2_MUX_SSP3, + MMP2_MUX_SSP4, + MMP2_MUX_MMC1, + MMP2_MUX_MMC2, + MMP2_MUX_MMC3, + MMP2_MUX_MMC4, + MMP2_MUX_ULPI, + MMP2_MUX_AC, + MMP2_MUX_CA, + MMP2_MUX_PWM, + MMP2_MUX_USIM, + MMP2_MUX_TIPU, + MMP2_MUX_PLL, + MMP2_MUX_NAND, + MMP2_MUX_FSIC, + MMP2_MUX_SLEEP_IND, + MMP2_MUX_EXT_DMA, + MMP2_MUX_ONE_WIRE, + MMP2_MUX_LCD, + MMP2_MUX_SMC, + MMP2_MUX_SMC_INT, + MMP2_MUX_MSP, + MMP2_MUX_G_CLKOUT, + MMP2_MUX_32K_CLKOUT, + MMP2_MUX_PRI_JTAG, + MMP2_MUX_AAS_JTAG, + MMP2_MUX_AAS_GPIO, + MMP2_MUX_AAS_SPI, + MMP2_MUX_AAS_TWSI, + MMP2_MUX_AAS_DEU_EX, + MMP2_MUX_NONE = 0xffff, +}; + +static struct pinctrl_pin_desc mmp2_pads[] = { + /* + * The name indicates function 0 of this pin. + * After reset, function 0 is the default function of pin. + */ + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(GPIO123, "GPIO123"), + PINCTRL_PIN(GPIO124, "GPIO124"), + PINCTRL_PIN(GPIO125, "GPIO125"), + PINCTRL_PIN(GPIO126, "GPIO126"), + PINCTRL_PIN(GPIO127, "GPIO127"), + PINCTRL_PIN(GPIO128, "GPIO128"), + PINCTRL_PIN(GPIO129, "GPIO129"), + PINCTRL_PIN(GPIO130, "GPIO130"), + PINCTRL_PIN(GPIO131, "GPIO131"), + PINCTRL_PIN(GPIO132, "GPIO132"), + PINCTRL_PIN(GPIO133, "GPIO133"), + PINCTRL_PIN(GPIO134, "GPIO134"), + PINCTRL_PIN(GPIO135, "GPIO135"), + PINCTRL_PIN(GPIO136, "GPIO136"), + PINCTRL_PIN(GPIO137, "GPIO137"), + PINCTRL_PIN(GPIO138, "GPIO138"), + PINCTRL_PIN(GPIO139, "GPIO139"), + PINCTRL_PIN(GPIO140, "GPIO140"), + PINCTRL_PIN(GPIO141, "GPIO141"), + PINCTRL_PIN(GPIO142, "GPIO142"), + PINCTRL_PIN(GPIO143, "GPIO143"), + PINCTRL_PIN(GPIO144, "GPIO144"), + PINCTRL_PIN(GPIO145, "GPIO145"), + PINCTRL_PIN(GPIO146, "GPIO146"), + PINCTRL_PIN(GPIO147, "GPIO147"), + PINCTRL_PIN(GPIO148, "GPIO148"), + PINCTRL_PIN(GPIO149, "GPIO149"), + PINCTRL_PIN(GPIO150, "GPIO150"), + PINCTRL_PIN(GPIO151, "GPIO151"), + PINCTRL_PIN(GPIO152, "GPIO152"), + PINCTRL_PIN(GPIO153, "GPIO153"), + PINCTRL_PIN(GPIO154, "GPIO154"), + PINCTRL_PIN(GPIO155, "GPIO155"), + PINCTRL_PIN(GPIO156, "GPIO156"), + PINCTRL_PIN(GPIO157, "GPIO157"), + PINCTRL_PIN(GPIO158, "GPIO158"), + PINCTRL_PIN(GPIO159, "GPIO159"), + PINCTRL_PIN(GPIO160, "GPIO160"), + PINCTRL_PIN(GPIO161, "GPIO161"), + PINCTRL_PIN(GPIO162, "GPIO162"), + PINCTRL_PIN(GPIO163, "GPIO163"), + PINCTRL_PIN(GPIO164, "GPIO164"), + PINCTRL_PIN(GPIO165, "GPIO165"), + PINCTRL_PIN(GPIO166, "GPIO166"), + PINCTRL_PIN(GPIO167, "GPIO167"), + PINCTRL_PIN(GPIO168, "GPIO168"), + PINCTRL_PIN(TWSI4_SCL, "TWSI4_SCL"), + PINCTRL_PIN(TWSI4_SDA, "TWSI4_SDA"), + PINCTRL_PIN(G_CLKREQ, "G_CLKREQ"), + PINCTRL_PIN(VCXO_REQ, "VCXO_REQ"), + PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"), +}; + +struct pxa3xx_mfp_pin mmp2_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_MMP2(GPIO0, 0x054, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO1, 0x058, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO2, 0x05C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO3, 0x060, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO4, 0x064, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO5, 0x068, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO6, 0x06C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO7, 0x070, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO8, 0x074, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO9, 0x078, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO10, 0x07C, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO11, 0x080, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO12, 0x084, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO13, 0x088, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO14, 0x08C, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO15, 0x090, GPIO, KP_MK, KP_DK, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO16, 0x094, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO17, 0x098, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO18, 0x09C, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO19, 0x0A0, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO20, 0x0A4, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO21, 0x0A8, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO22, 0x0AC, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO23, 0x0B0, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO24, 0x0B4, GPIO, I2S, VCXO_OUT, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO25, 0x0B8, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO26, 0x0BC, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO27, 0x0C0, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO28, 0x0C4, GPIO, I2S, NONE, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO29, 0x0C8, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO30, 0x0CC, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO31, 0x0D0, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO32, 0x0D4, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO33, 0x0D8, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO34, 0x0DC, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO35, 0x0E0, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO36, 0x0E4, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO37, 0x0E8, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO38, 0x0EC, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO39, 0x0F0, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO40, 0x0F4, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO41, 0x0F8, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO42, 0x0FC, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO43, 0x100, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI), + MFPR_MMP2(GPIO44, 0x104, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI), + MFPR_MMP2(GPIO45, 0x108, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE), + MFPR_MMP2(GPIO46, 0x10C, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE), + MFPR_MMP2(GPIO47, 0x110, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE), + MFPR_MMP2(GPIO48, 0x114, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE), + MFPR_MMP2(GPIO49, 0x118, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE), + MFPR_MMP2(GPIO50, 0x11C, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE), + MFPR_MMP2(GPIO51, 0x120, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE), + MFPR_MMP2(GPIO52, 0x124, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE), + MFPR_MMP2(GPIO53, 0x128, GPIO, UART3, TWSI2, VCXO_REQ, NONE, PWM, NONE, AAS_TWSI), + MFPR_MMP2(GPIO54, 0x12C, GPIO, UART3, TWSI2, VCXO_OUT, HDMI, PWM, NONE, AAS_TWSI), + MFPR_MMP2(GPIO55, 0x130, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, SSP3, AAS_TWSI), + MFPR_MMP2(GPIO56, 0x134, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, KP_DK, AAS_TWSI), + MFPR_MMP2(GPIO57, 0x138, GPIO, SSP2_RX, SSP1_TXRX, SSP2_FRM, SSP1_RX, VCXO_REQ, KP_DK, NONE), + MFPR_MMP2(GPIO58, 0x13C, GPIO, SSP2, SSP1_RX, SSP1_FRM, SSP1_TXRX, VCXO_REQ, KP_DK, NONE), + MFPR_MMP2(GPIO59, 0x280, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE), + MFPR_MMP2(GPIO60, 0x284, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE), + MFPR_MMP2(GPIO61, 0x288, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, HDMI, NONE), + MFPR_MMP2(GPIO62, 0x28C, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, NONE, NONE), + MFPR_MMP2(GPIO63, 0x290, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO64, 0x294, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO65, 0x298, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO66, 0x29C, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO67, 0x2A0, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, NONE, NONE), + MFPR_MMP2(GPIO68, 0x2A4, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE), + MFPR_MMP2(GPIO69, 0x2A8, GPIO, CCIC1, ULPI, MMC3, CCIC2, NONE, LCD, NONE), + MFPR_MMP2(GPIO70, 0x2AC, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE), + MFPR_MMP2(GPIO71, 0x2B0, GPIO, TWSI3, NONE, PWM, NONE, NONE, LCD, AAS_TWSI), + MFPR_MMP2(GPIO72, 0x2B4, GPIO, TWSI3, HDMI, PWM, NONE, NONE, LCD, AAS_TWSI), + MFPR_MMP2(GPIO73, 0x2B8, GPIO, VCXO_REQ, 32K_CLKOUT, PWM, VCXO_OUT, NONE, LCD, NONE), + MFPR_MMP2(GPIO74, 0x170, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO75, 0x174, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO76, 0x178, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO77, 0x17C, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO78, 0x180, GPIO, LCD, HDMI, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO79, 0x184, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO80, 0x188, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO81, 0x18C, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO82, 0x190, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO83, 0x194, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO84, 0x198, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU), + MFPR_MMP2(GPIO85, 0x19C, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU), + MFPR_MMP2(GPIO86, 0x1A0, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU), + MFPR_MMP2(GPIO87, 0x1A4, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU), + MFPR_MMP2(GPIO88, 0x1A8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO89, 0x1AC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO90, 0x1B0, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO91, 0x1B4, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO92, 0x1B8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO93, 0x1BC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO94, 0x1C0, GPIO, LCD, AAS_GPIO, SPI, NONE, AAS_SPI, CCIC2, TIPU), + MFPR_MMP2(GPIO95, 0x1C4, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, CCIC2, TIPU), + MFPR_MMP2(GPIO96, 0x1C8, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU), + MFPR_MMP2(GPIO97, 0x1CC, GPIO, LCD, TWSI6, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU), + MFPR_MMP2(GPIO98, 0x1D0, GPIO, LCD, TWSI6, SPI, ONE_WIRE, NONE, NONE, TIPU), + MFPR_MMP2(GPIO99, 0x1D4, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU), + MFPR_MMP2(GPIO100, 0x1D8, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU), + MFPR_MMP2(GPIO101, 0x1DC, GPIO, LCD, SMC, SPI, NONE, NONE, NONE, TIPU), + MFPR_MMP2(GPIO102, 0x000, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE), + MFPR_MMP2(GPIO103, 0x004, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE), + MFPR_MMP2(GPIO104, 0x1FC, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO105, 0x1F8, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO106, 0x1F4, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO107, 0x1F0, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO108, 0x21C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO109, 0x218, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO110, 0x214, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO111, 0x200, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO112, 0x244, NAND, GPIO, MMC3, SMC, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO113, 0x25C, SMC, GPIO, EXT_DMA, MMC3, SMC, HDMI, NONE, NONE), + MFPR_MMP2(GPIO114, 0x164, G_CLKOUT, 32K_CLKOUT, HDMI, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO115, 0x260, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO116, 0x264, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO117, 0x268, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO118, 0x26C, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO119, 0x270, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO120, 0x274, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO121, 0x278, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO122, 0x27C, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO123, 0x148, GPIO, SLEEP_IND, ONE_WIRE, 32K_CLKOUT, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO124, 0x00C, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO125, 0x010, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO126, 0x014, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO127, 0x018, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO128, 0x01C, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO129, 0x020, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO130, 0x024, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO131, 0x028, GPIO, MMC1, NONE, MSP, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO132, 0x02C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO133, 0x030, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO134, 0x034, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO135, 0x038, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO136, 0x03C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO137, 0x040, GPIO, HDMI, LCD, MSP, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO138, 0x044, GPIO, NONE, LCD, MMC3, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO139, 0x048, GPIO, MMC1, PRI_JTAG, MSP, NONE, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO140, 0x04C, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE), + MFPR_MMP2(GPIO141, 0x050, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE), + MFPR_MMP2(GPIO142, 0x008, USIM, GPIO, FSIC, KP_DK, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO143, 0x220, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO144, 0x224, NAND, GPIO, SMC_INT, SMC, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO145, 0x228, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO146, 0x22C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO147, 0x230, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO148, 0x234, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO149, 0x238, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO150, 0x23C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO151, 0x240, SMC, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO152, 0x248, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO153, 0x24C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO154, 0x254, SMC_INT, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO155, 0x258, EXT_DMA, GPIO, SMC, NONE, EXT_DMA, NONE, NONE, NONE), + MFPR_MMP2(GPIO156, 0x14C, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO157, 0x150, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO158, 0x154, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO159, 0x158, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO160, 0x250, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO161, 0x210, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO162, 0x20C, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO163, 0x208, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO164, 0x204, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO165, 0x1EC, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO166, 0x1E8, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO167, 0x1E4, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO168, 0x1E0, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(TWSI4_SCL, 0x2BC, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(TWSI4_SDA, 0x2C0, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(G_CLKREQ, 0x160, G_CLKREQ, ONE_WIRE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(VCXO_REQ, 0x168, VCXO_REQ, ONE_WIRE, PLL, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(VCXO_OUT, 0x16C, VCXO_OUT, 32K_CLKOUT, NONE, NONE, NONE, NONE, NONE, NONE), +}; + +static const unsigned mmp2_uart1_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned mmp2_uart1_pin2[] = {GPIO45, GPIO46}; +static const unsigned mmp2_uart1_pin3[] = {GPIO140, GPIO141}; +static const unsigned mmp2_uart2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_uart2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned mmp2_uart2_pin4[] = {GPIO74, GPIO75, GPIO76, GPIO77}; +static const unsigned mmp2_uart2_pin5[] = {GPIO55, GPIO56}; +static const unsigned mmp2_uart2_pin6[] = {GPIO140, GPIO141}; +static const unsigned mmp2_uart3_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_uart3_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart3_pin3[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned mmp2_uart3_pin4[] = {GPIO59, GPIO60, GPIO61, GPIO62}; +static const unsigned mmp2_uart3_pin5[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_uart3_pin6[] = {GPIO51, GPIO52}; +static const unsigned mmp2_uart4_pin1[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart4_pin2[] = {GPIO63, GPIO64, GPIO65, GPIO66}; +static const unsigned mmp2_uart4_pin3[] = {GPIO74, GPIO75, GPIO76, GPIO77}; +static const unsigned mmp2_uart4_pin4[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_uart4_pin5[] = {GPIO59, GPIO60}; +static const unsigned mmp2_kpdk_pin1[] = {GPIO16, GPIO17, GPIO18, GPIO19}; +static const unsigned mmp2_kpdk_pin2[] = {GPIO16, GPIO17}; +static const unsigned mmp2_twsi2_pin1[] = {GPIO37, GPIO38}; +static const unsigned mmp2_twsi2_pin2[] = {GPIO39, GPIO40}; +static const unsigned mmp2_twsi2_pin3[] = {GPIO43, GPIO44}; +static const unsigned mmp2_twsi2_pin4[] = {GPIO53, GPIO54}; +static const unsigned mmp2_twsi2_pin5[] = {GPIO55, GPIO56}; +static const unsigned mmp2_twsi3_pin1[] = {GPIO71, GPIO72}; +static const unsigned mmp2_twsi3_pin2[] = {GPIO95, GPIO96}; +static const unsigned mmp2_twsi4_pin1[] = {TWSI4_SCL, TWSI4_SDA}; +static const unsigned mmp2_twsi5_pin1[] = {GPIO41, GPIO42}; +static const unsigned mmp2_twsi5_pin2[] = {GPIO84, GPIO85}; +static const unsigned mmp2_twsi5_pin3[] = {GPIO99, GPIO100}; +static const unsigned mmp2_twsi6_pin1[] = {GPIO47, GPIO48}; +static const unsigned mmp2_twsi6_pin2[] = {GPIO86, GPIO87}; +static const unsigned mmp2_twsi6_pin3[] = {GPIO97, GPIO98}; +static const unsigned mmp2_ccic1_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23}; +static const unsigned mmp2_ccic1_pin2[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ccic2_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ccic2_pin2[] = {GPIO82, GPIO83, GPIO86, GPIO87, + GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95}; +static const unsigned mmp2_ulpi_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ro_pin1[] = {GPIO16, GPIO17}; +static const unsigned mmp2_ro_pin2[] = {GPIO18, GPIO19}; +static const unsigned mmp2_ro_pin3[] = {GPIO51, GPIO52}; +static const unsigned mmp2_ro_pin4[] = {GPIO55, GPIO56}; +static const unsigned mmp2_i2s_pin1[] = {GPIO24, GPIO25, GPIO26, GPIO27, + GPIO28}; +static const unsigned mmp2_i2s_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned mmp2_ssp1_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_ssp1_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_ssp1_pin3[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_ssp2_pin1[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned mmp2_ssp3_pin1[] = {GPIO119, GPIO120, GPIO121, GPIO122}; +static const unsigned mmp2_ssp3_pin2[] = {GPIO132, GPIO133, GPIO133, GPIO136}; +static const unsigned mmp2_sspa2_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28}; +static const unsigned mmp2_sspa2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned mmp2_mmc1_pin1[] = {GPIO131, GPIO132, GPIO133, GPIO134, + GPIO136, GPIO139, GPIO140, GPIO141}; +static const unsigned mmp2_mmc2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42}; +static const unsigned mmp2_mmc3_pin1[] = {GPIO111, GPIO112, GPIO151, GPIO162, + GPIO163, GPIO164, GPIO165, GPIO166, GPIO167, GPIO168}; + +static struct pxa3xx_pin_group mmp2_grps[] = { + GRP_MMP2("uart1 4p1", UART1, mmp2_uart1_pin1), + GRP_MMP2("uart1 2p2", UART1, mmp2_uart1_pin2), + GRP_MMP2("uart1 2p3", UART1, mmp2_uart1_pin3), + GRP_MMP2("uart2 4p1", UART2, mmp2_uart2_pin1), + GRP_MMP2("uart2 4p2", UART2, mmp2_uart2_pin2), + GRP_MMP2("uart2 4p3", UART2, mmp2_uart2_pin3), + GRP_MMP2("uart2 4p4", UART2, mmp2_uart2_pin4), + GRP_MMP2("uart2 2p5", UART2, mmp2_uart2_pin5), + GRP_MMP2("uart2 2p6", UART2, mmp2_uart2_pin6), + GRP_MMP2("uart3 4p1", UART3, mmp2_uart3_pin1), + GRP_MMP2("uart3 4p2", UART3, mmp2_uart3_pin2), + GRP_MMP2("uart3 4p3", UART3, mmp2_uart3_pin3), + GRP_MMP2("uart3 4p4", UART3, mmp2_uart3_pin4), + GRP_MMP2("uart3 4p5", UART3, mmp2_uart3_pin5), + GRP_MMP2("uart3 2p6", UART3, mmp2_uart3_pin6), + GRP_MMP2("uart4 4p1", UART4, mmp2_uart4_pin1), + GRP_MMP2("uart4 4p2", UART4, mmp2_uart4_pin2), + GRP_MMP2("uart4 4p3", UART4, mmp2_uart4_pin3), + GRP_MMP2("uart4 4p4", UART4, mmp2_uart4_pin4), + GRP_MMP2("uart4 2p5", UART4, mmp2_uart4_pin5), + GRP_MMP2("kpdk 4p1", KP_DK, mmp2_kpdk_pin1), + GRP_MMP2("kpdk 4p2", KP_DK, mmp2_kpdk_pin2), + GRP_MMP2("twsi2-1", TWSI2, mmp2_twsi2_pin1), + GRP_MMP2("twsi2-2", TWSI2, mmp2_twsi2_pin2), + GRP_MMP2("twsi2-3", TWSI2, mmp2_twsi2_pin3), + GRP_MMP2("twsi2-4", TWSI2, mmp2_twsi2_pin4), + GRP_MMP2("twsi2-5", TWSI2, mmp2_twsi2_pin5), + GRP_MMP2("twsi3-1", TWSI3, mmp2_twsi3_pin1), + GRP_MMP2("twsi3-2", TWSI3, mmp2_twsi3_pin2), + GRP_MMP2("twsi4", TWSI4, mmp2_twsi4_pin1), + GRP_MMP2("twsi5-1", TWSI5, mmp2_twsi5_pin1), + GRP_MMP2("twsi5-2", TWSI5, mmp2_twsi5_pin2), + GRP_MMP2("twsi5-3", TWSI5, mmp2_twsi5_pin3), + GRP_MMP2("twsi6-1", TWSI6, mmp2_twsi6_pin1), + GRP_MMP2("twsi6-2", TWSI6, mmp2_twsi6_pin2), + GRP_MMP2("twsi6-3", TWSI6, mmp2_twsi6_pin3), + GRP_MMP2("ccic1-1", CCIC1, mmp2_ccic1_pin1), + GRP_MMP2("ccic1-2", CCIC1, mmp2_ccic1_pin2), + GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin1), + GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin2), + GRP_MMP2("ulpi", ULPI, mmp2_ulpi_pin1), + GRP_MMP2("ro-1", ROT, mmp2_ro_pin1), + GRP_MMP2("ro-2", ROT, mmp2_ro_pin2), + GRP_MMP2("ro-3", ROT, mmp2_ro_pin3), + GRP_MMP2("ro-4", ROT, mmp2_ro_pin4), + GRP_MMP2("i2s 5p1", I2S, mmp2_i2s_pin1), + GRP_MMP2("i2s 4p2", I2S, mmp2_i2s_pin2), + GRP_MMP2("ssp1 4p1", SSP1, mmp2_ssp1_pin1), + GRP_MMP2("ssp1 4p2", SSP1, mmp2_ssp1_pin2), + GRP_MMP2("ssp1 4p3", SSP1, mmp2_ssp1_pin3), + GRP_MMP2("ssp2 4p1", SSP2, mmp2_ssp2_pin1), + GRP_MMP2("ssp3 4p1", SSP3, mmp2_ssp3_pin1), + GRP_MMP2("ssp3 4p2", SSP3, mmp2_ssp3_pin2), + GRP_MMP2("sspa2 4p1", SSPA2, mmp2_sspa2_pin1), + GRP_MMP2("sspa2 4p2", SSPA2, mmp2_sspa2_pin2), + GRP_MMP2("mmc1 8p1", MMC1, mmp2_mmc1_pin1), + GRP_MMP2("mmc2 6p1", MMC2, mmp2_mmc2_pin1), + GRP_MMP2("mmc3 10p1", MMC3, mmp2_mmc3_pin1), +}; + +static const char * const mmp2_uart1_grps[] = {"uart1 4p1", "uart1 2p2", + "uart1 2p3"}; +static const char * const mmp2_uart2_grps[] = {"uart2 4p1", "uart2 4p2", + "uart2 4p3", "uart2 4p4", "uart2 4p5", "uart2 4p6"}; +static const char * const mmp2_uart3_grps[] = {"uart3 4p1", "uart3 4p2", + "uart3 4p3", "uart3 4p4", "uart3 4p5", "uart3 2p6"}; +static const char * const mmp2_uart4_grps[] = {"uart4 4p1", "uart4 4p2", + "uart4 4p3", "uart4 4p4", "uart4 2p5"}; +static const char * const mmp2_kpdk_grps[] = {"kpdk 4p1", "kpdk 4p2"}; +static const char * const mmp2_twsi2_grps[] = {"twsi2-1", "twsi2-2", + "twsi2-3", "twsi2-4", "twsi2-5"}; +static const char * const mmp2_twsi3_grps[] = {"twsi3-1", "twsi3-2"}; +static const char * const mmp2_twsi4_grps[] = {"twsi4"}; +static const char * const mmp2_twsi5_grps[] = {"twsi5-1", "twsi5-2", + "twsi5-3"}; +static const char * const mmp2_twsi6_grps[] = {"twsi6-1", "twsi6-2", + "twsi6-3"}; +static const char * const mmp2_ccic1_grps[] = {"ccic1-1", "ccic1-2"}; +static const char * const mmp2_ccic2_grps[] = {"ccic2-1", "ccic2-2"}; +static const char * const mmp2_ulpi_grps[] = {"ulpi"}; +static const char * const mmp2_ro_grps[] = {"ro-1", "ro-2", "ro-3", "ro-4"}; +static const char * const mmp2_i2s_grps[] = {"i2s 5p1", "i2s 4p2"}; +static const char * const mmp2_ssp1_grps[] = {"ssp1 4p1", "ssp1 4p2", + "ssp1 4p3"}; +static const char * const mmp2_ssp2_grps[] = {"ssp2 4p1"}; +static const char * const mmp2_ssp3_grps[] = {"ssp3 4p1", "ssp3 4p2"}; +static const char * const mmp2_sspa2_grps[] = {"sspa2 4p1", "sspa2 4p2"}; +static const char * const mmp2_mmc1_grps[] = {"mmc1 8p1"}; +static const char * const mmp2_mmc2_grps[] = {"mmc2 6p1"}; +static const char * const mmp2_mmc3_grps[] = {"mmc3 10p1"}; + +static struct pxa3xx_pmx_func mmp2_funcs[] = { + {"uart1", ARRAY_AND_SIZE(mmp2_uart1_grps)}, + {"uart2", ARRAY_AND_SIZE(mmp2_uart2_grps)}, + {"uart3", ARRAY_AND_SIZE(mmp2_uart3_grps)}, + {"uart4", ARRAY_AND_SIZE(mmp2_uart4_grps)}, + {"kpdk", ARRAY_AND_SIZE(mmp2_kpdk_grps)}, + {"twsi2", ARRAY_AND_SIZE(mmp2_twsi2_grps)}, + {"twsi3", ARRAY_AND_SIZE(mmp2_twsi3_grps)}, + {"twsi4", ARRAY_AND_SIZE(mmp2_twsi4_grps)}, + {"twsi5", ARRAY_AND_SIZE(mmp2_twsi5_grps)}, + {"twsi6", ARRAY_AND_SIZE(mmp2_twsi6_grps)}, + {"ccic1", ARRAY_AND_SIZE(mmp2_ccic1_grps)}, + {"ccic2", ARRAY_AND_SIZE(mmp2_ccic2_grps)}, + {"ulpi", ARRAY_AND_SIZE(mmp2_ulpi_grps)}, + {"ro", ARRAY_AND_SIZE(mmp2_ro_grps)}, + {"i2s", ARRAY_AND_SIZE(mmp2_i2s_grps)}, + {"ssp1", ARRAY_AND_SIZE(mmp2_ssp1_grps)}, + {"ssp2", ARRAY_AND_SIZE(mmp2_ssp2_grps)}, + {"ssp3", ARRAY_AND_SIZE(mmp2_ssp3_grps)}, + {"sspa2", ARRAY_AND_SIZE(mmp2_sspa2_grps)}, + {"mmc1", ARRAY_AND_SIZE(mmp2_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(mmp2_mmc2_grps)}, + {"mmc3", ARRAY_AND_SIZE(mmp2_mmc3_grps)}, +}; + +static struct pinctrl_desc mmp2_pctrl_desc = { + .name = "mmp2-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info mmp2_info = { + .mfp = mmp2_mfp, + .num_mfp = ARRAY_SIZE(mmp2_mfp), + .grps = mmp2_grps, + .num_grps = ARRAY_SIZE(mmp2_grps), + .funcs = mmp2_funcs, + .num_funcs = ARRAY_SIZE(mmp2_funcs), + .num_gpio = 169, + .desc = &mmp2_pctrl_desc, + .pads = mmp2_pads, + .num_pads = ARRAY_SIZE(mmp2_pads), + + .cputype = PINCTRL_MMP2, + .ds_mask = MMP2_DS_MASK, + .ds_shift = MMP2_DS_SHIFT, +}; + +static int mmp2_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &mmp2_info); +} + +static int mmp2_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver mmp2_pinmux_driver = { + .driver = { + .name = "mmp2-pinmux", + .owner = THIS_MODULE, + }, + .probe = mmp2_pinmux_probe, + .remove = mmp2_pinmux_remove, +}; + +static int __init mmp2_pinmux_init(void) +{ + return platform_driver_register(&mmp2_pinmux_driver); +} +core_initcall_sync(mmp2_pinmux_init); + +static void __exit mmp2_pinmux_exit(void) +{ + platform_driver_unregister(&mmp2_pinmux_driver); +} +module_exit(mmp2_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-mxs.c b/trunk/drivers/pinctrl/pinctrl-mxs.c index b45c4eb35798..23af9f1f9c35 100644 --- a/trunk/drivers/pinctrl/pinctrl-mxs.c +++ b/trunk/drivers/pinctrl/pinctrl-mxs.c @@ -158,7 +158,7 @@ static void mxs_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static const struct pinctrl_ops mxs_pinctrl_ops = { +static struct pinctrl_ops mxs_pinctrl_ops = { .get_groups_count = mxs_get_groups_count, .get_group_name = mxs_get_group_name, .get_group_pins = mxs_get_group_pins, @@ -219,7 +219,7 @@ static int mxs_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static const struct pinmux_ops mxs_pinmux_ops = { +static struct pinmux_ops mxs_pinmux_ops = { .get_functions_count = mxs_pinctrl_get_funcs_count, .get_function_name = mxs_pinctrl_get_func_name, .get_function_groups = mxs_pinctrl_get_func_groups, @@ -319,7 +319,7 @@ static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, "0x%lx", config); } -static const struct pinconf_ops mxs_pinconf_ops = { +static struct pinconf_ops mxs_pinconf_ops = { .pin_config_get = mxs_pinconf_get, .pin_config_set = mxs_pinconf_set, .pin_config_group_get = mxs_pinconf_group_get, diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c b/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c index c74840729648..30b4da91ef7e 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c @@ -466,7 +466,7 @@ static const unsigned mc1_a_1_pins[] = { DB8500_PIN_AH16, DB8500_PIN_AG15, DB8500_PIN_AJ15, DB8500_PIN_AG14, DB8500_PIN_AF13, DB8500_PIN_AG13, DB8500_PIN_AH15 }; static const unsigned mc1_a_2_pins[] = { DB8500_PIN_AH16, DB8500_PIN_AJ15, - DB8500_PIN_AG14, DB8500_PIN_AF13, DB8500_PIN_AG13, DB8500_PIN_AH15 }; + DB8500_PIN_AG14, DB8500_PIN_AF13, DB8500_PIN_AG13,DB8500_PIN_AH15 }; static const unsigned mc1dir_a_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12, DB8500_PIN_AH12, DB8500_PIN_AH11 }; static const unsigned hsir_a_1_pins[] = { DB8500_PIN_AG10, DB8500_PIN_AH10, @@ -663,7 +663,7 @@ static const unsigned hwobs_oc4_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; -#define DB8500_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \ +#define DB8500_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \ .npins = ARRAY_SIZE(a##_pins), .altsetting = b } static const struct nmk_pingroup nmk_db8500_groups[] = { diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik-stn8815.c b/trunk/drivers/pinctrl/pinctrl-nomadik-stn8815.c index ed39dcafd4f8..924a3393fa82 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik-stn8815.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik-stn8815.c @@ -299,7 +299,7 @@ static const unsigned i2c0_a_1_pins[] = { STN8815_PIN_D3, STN8815_PIN_D2 }; static const unsigned u1_b_1_pins[] = { STN8815_PIN_B16, STN8815_PIN_A16 }; static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 }; -#define STN8815_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \ +#define STN8815_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \ .npins = ARRAY_SIZE(a##_pins), .altsetting = b } static const struct nmk_pingroup nmk_stn8815_groups[] = { diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik.c b/trunk/drivers/pinctrl/pinctrl-nomadik.c index 435bf3078d2c..36d20293de5c 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik.c @@ -1565,8 +1565,8 @@ static int nmk_dt_add_map_configs(struct pinctrl_map **map, return 0; } -#define NMK_CONFIG_PIN(x, y) { .property = x, .config = y, } -#define NMK_CONFIG_PIN_ARRAY(x, y) { .property = x, .choice = y, \ +#define NMK_CONFIG_PIN(x,y) { .property = x, .config = y, } +#define NMK_CONFIG_PIN_ARRAY(x,y) { .property = x, .choice = y, \ .size = ARRAY_SIZE(y), } static const unsigned long nmk_pin_input_modes[] = { @@ -1764,7 +1764,7 @@ int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } -static const struct pinctrl_ops nmk_pinctrl_ops = { +static struct pinctrl_ops nmk_pinctrl_ops = { .get_groups_count = nmk_get_groups_cnt, .get_group_name = nmk_get_group_name, .get_group_pins = nmk_get_group_pins, @@ -1975,7 +1975,7 @@ static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, /* Set the pin to some default state, GPIO is usually default */ } -static const struct pinmux_ops nmk_pinmux_ops = { +static struct pinmux_ops nmk_pinmux_ops = { .get_functions_count = nmk_pmx_get_funcs_cnt, .get_function_name = nmk_pmx_get_func_name, .get_function_groups = nmk_pmx_get_func_groups, @@ -2068,7 +2068,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, pin, cfg, pullnames[pull], slpmnames[slpm], output ? "output " : "input", output ? (val ? "high" : "low") : "", - lowemi ? "on" : "off"); + lowemi ? "on" : "off" ); clk_enable(nmk_chip->clk); bit = pin % NMK_GPIO_PER_CHIP; @@ -2089,7 +2089,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, return 0; } -static const struct pinconf_ops nmk_pinconf_ops = { +static struct pinconf_ops nmk_pinconf_ops = { .pin_config_get = nmk_pin_config_get, .pin_config_set = nmk_pin_config_set, }; @@ -2111,10 +2111,6 @@ static const struct of_device_id nmk_pinctrl_match[] = { .compatible = "stericsson,nmk-pinctrl", .data = (void *)PINCTRL_NMK_DB8500, }, - { - .compatible = "stericsson,nmk-pinctrl-db8540", - .data = (void *)PINCTRL_NMK_DB8540, - }, {}, }; diff --git a/trunk/drivers/pinctrl/pinctrl-pxa168.c b/trunk/drivers/pinctrl/pinctrl-pxa168.c new file mode 100644 index 000000000000..d9cd2b457484 --- /dev/null +++ b/trunk/drivers/pinctrl/pinctrl-pxa168.c @@ -0,0 +1,651 @@ +/* + * linux/drivers/pinctrl/pinmux-pxa168.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define PXA168_DS_MASK 0x1800 +#define PXA168_DS_SHIFT 11 +#define PXA168_SLEEP_MASK 0x38 +#define PXA168_SLEEP_SELECT (1 << 9) +#define PXA168_SLEEP_DATA (1 << 8) +#define PXA168_SLEEP_DIR (1 << 7) + +#define MFPR_168(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + PXA168_MUX_##f0, \ + PXA168_MUX_##f1, \ + PXA168_MUX_##f2, \ + PXA168_MUX_##f3, \ + PXA168_MUX_##f4, \ + PXA168_MUX_##f5, \ + PXA168_MUX_##f6, \ + PXA168_MUX_##f7, \ + }, \ + } + +#define GRP_168(a, m, p) \ + { .name = a, .mux = PXA168_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 131 pins */ +enum pxa168_pin_list { + /* 0~122: GPIO0~GPIO122 */ + PWR_SCL = 123, + PWR_SDA, + TDI, + TMS, + TCK, + TDO, + TRST, + WAKEUP = 130, +}; + +enum pxa168_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + PXA168_MUX_GPIO = 0, + PXA168_MUX_DFIO, + PXA168_MUX_NAND, + PXA168_MUX_SMC, + PXA168_MUX_SMC_CS0, + PXA168_MUX_SMC_CS1, + PXA168_MUX_SMC_INT, + PXA168_MUX_SMC_RDY, + PXA168_MUX_MMC1, + PXA168_MUX_MMC2, + PXA168_MUX_MMC2_CMD, + PXA168_MUX_MMC2_CLK, + PXA168_MUX_MMC3, + PXA168_MUX_MMC3_CMD, + PXA168_MUX_MMC3_CLK, + PXA168_MUX_MMC4, + PXA168_MUX_MSP, + PXA168_MUX_MSP_DAT3, + PXA168_MUX_MSP_INS, + PXA168_MUX_I2C, + PXA168_MUX_PWRI2C, + PXA168_MUX_AC97, + PXA168_MUX_AC97_SYSCLK, + PXA168_MUX_PWM, + PXA168_MUX_PWM1, + PXA168_MUX_XD, + PXA168_MUX_XP, + PXA168_MUX_LCD, + PXA168_MUX_CCIC, + PXA168_MUX_CF, + PXA168_MUX_CF_RDY, + PXA168_MUX_CF_nINPACK, + PXA168_MUX_CF_nWAIT, + PXA168_MUX_KP_MKOUT, + PXA168_MUX_KP_MKIN, + PXA168_MUX_KP_DK, + PXA168_MUX_ETH, + PXA168_MUX_ETH_TX, + PXA168_MUX_ETH_RX, + PXA168_MUX_ONE_WIRE, + PXA168_MUX_UART1, + PXA168_MUX_UART1_TX, + PXA168_MUX_UART1_CTS, + PXA168_MUX_UART1_nRI, + PXA168_MUX_UART1_DTR, + PXA168_MUX_UART2, + PXA168_MUX_UART2_TX, + PXA168_MUX_UART3, + PXA168_MUX_UART3_TX, + PXA168_MUX_UART3_CTS, + PXA168_MUX_SSP1, + PXA168_MUX_SSP1_TX, + PXA168_MUX_SSP2, + PXA168_MUX_SSP2_TX, + PXA168_MUX_SSP3, + PXA168_MUX_SSP3_TX, + PXA168_MUX_SSP4, + PXA168_MUX_SSP4_TX, + PXA168_MUX_SSP5, + PXA168_MUX_SSP5_TX, + PXA168_MUX_USB, + PXA168_MUX_JTAG, + PXA168_MUX_RESET, + PXA168_MUX_WAKEUP, + PXA168_MUX_EXT_32K_IN, + PXA168_MUX_NONE = 0xffff, +}; + +static struct pinctrl_pin_desc pxa168_pads[] = { + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(PWR_SCL, "PWR_SCL"), + PINCTRL_PIN(PWR_SDA, "PWR_SDA"), + PINCTRL_PIN(TDI, "TDI"), + PINCTRL_PIN(TMS, "TMS"), + PINCTRL_PIN(TCK, "TCK"), + PINCTRL_PIN(TDO, "TDO"), + PINCTRL_PIN(TRST, "TRST"), + PINCTRL_PIN(WAKEUP, "WAKEUP"), +}; + +struct pxa3xx_mfp_pin pxa168_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_168(GPIO0, 0x04C, DFIO, NONE, NONE, MSP, MMC3_CMD, GPIO, MMC3, NONE), + MFPR_168(GPIO1, 0x050, DFIO, NONE, NONE, MSP, MMC3_CLK, GPIO, MMC3, NONE), + MFPR_168(GPIO2, 0x054, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO3, 0x058, DFIO, NONE, NONE, NONE, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO4, 0x05C, DFIO, NONE, NONE, MSP_DAT3, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO5, 0x060, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO6, 0x064, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO7, 0x068, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO8, 0x06C, DFIO, MMC2, UART3_TX, NONE, MMC2_CMD, GPIO, MMC3_CLK, NONE), + MFPR_168(GPIO9, 0x070, DFIO, MMC2, UART3, NONE, MMC2_CLK, GPIO, MMC3_CMD, NONE), + MFPR_168(GPIO10, 0x074, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP_DAT3, NONE), + MFPR_168(GPIO11, 0x078, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO12, 0x07C, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO13, 0x080, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO14, 0x084, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO15, 0x088, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO16, 0x08C, GPIO, NAND, SMC_CS0, SMC_CS1, NONE, NONE, MMC3, NONE), + MFPR_168(GPIO17, 0x090, NAND, NONE, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO18, 0x094, GPIO, NAND, SMC_CS1, SMC_CS0, NONE, NONE, NONE, NONE), + MFPR_168(GPIO19, 0x098, SMC_CS0, NONE, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO20, 0x09C, GPIO, NONE, SMC_CS1, CF, CF_RDY, NONE, NONE, NONE), + MFPR_168(GPIO21, 0x0A0, NAND, MMC2_CLK, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO22, 0x0A4, NAND, MMC2_CMD, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO23, 0x0A8, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO24, 0x0AC, NAND, NONE, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO25, 0x0B0, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO26, 0x0B4, GPIO, NAND, NONE, NONE, CF, NONE, NONE, NONE), + MFPR_168(GPIO27, 0x0B8, SMC_INT, NAND, SMC, NONE, SMC_RDY, GPIO, NONE, NONE), + MFPR_168(GPIO28, 0x0BC, SMC_RDY, MMC4, SMC, CF_RDY, NONE, GPIO, MMC2_CMD, NONE), + MFPR_168(GPIO29, 0x0C0, SMC, MMC4, NONE, CF, NONE, GPIO, MMC2_CLK, KP_DK), + MFPR_168(GPIO30, 0x0C4, SMC, MMC4, UART3_TX, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO31, 0x0C8, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO32, 0x0CC, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO33, 0x0D0, SMC, MMC4, UART3, CF, CF_nINPACK, GPIO, MMC2, KP_DK), + MFPR_168(GPIO34, 0x0D4, GPIO, NONE, SMC_CS1, CF, CF_nWAIT, NONE, MMC3, KP_DK), + MFPR_168(GPIO35, 0x0D8, GPIO, NONE, SMC, CF_nINPACK, NONE, NONE, MMC3_CMD, KP_DK), + MFPR_168(GPIO36, 0x0DC, GPIO, NONE, SMC, CF_nWAIT, NONE, NONE, MMC3_CLK, KP_DK), + MFPR_168(GPIO37, 0x000, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO38, 0x004, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO39, 0x008, GPIO, NONE, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO40, 0x00C, GPIO, MMC1, MSP, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO41, 0x010, GPIO, MMC1, MSP, NONE, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO42, 0x014, GPIO, I2C, NONE, MSP, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO43, 0x018, GPIO, MMC1, MSP, MSP_INS, NONE, NONE, KP_MKIN, KP_DK), + MFPR_168(GPIO44, 0x01C, GPIO, MMC1, MSP_DAT3, MSP, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO45, 0x020, GPIO, NONE, NONE, MSP, CCIC, XP, NONE, KP_DK), + MFPR_168(GPIO46, 0x024, GPIO, MMC1, MSP_INS, MSP, CCIC, NONE, KP_MKOUT, KP_DK), + MFPR_168(GPIO47, 0x028, GPIO, NONE, NONE, MSP_INS, NONE, XP, NONE, KP_DK), + MFPR_168(GPIO48, 0x02C, GPIO, MMC1, NONE, MSP_DAT3, CCIC, NONE, NONE, KP_DK), + MFPR_168(GPIO49, 0x030, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO50, 0x034, GPIO, I2C, NONE, MSP, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO51, 0x038, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO52, 0x03C, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO53, 0x040, GPIO, MMC1, NONE, NONE, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO54, 0x044, GPIO, MMC1, NONE, NONE, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO55, 0x048, GPIO, NONE, NONE, MSP, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO56, 0x0E0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO57, 0x0E4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO58, 0x0E8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO59, 0x0EC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO60, 0x0F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO61, 0x0F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO62, 0x0F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO63, 0x0FC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO64, 0x100, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO65, 0x104, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO66, 0x108, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO67, 0x10C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO68, 0x110, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO69, 0x114, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO70, 0x118, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO71, 0x11C, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO72, 0x120, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO73, 0x124, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO74, 0x128, GPIO, LCD, PWM, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO75, 0x12C, GPIO, LCD, PWM, XD, ONE_WIRE, NONE, NONE, NONE), + MFPR_168(GPIO76, 0x130, GPIO, LCD, PWM, I2C, NONE, NONE, MSP_INS, NONE), + MFPR_168(GPIO77, 0x134, GPIO, LCD, PWM1, I2C, ONE_WIRE, NONE, XD, NONE), + MFPR_168(GPIO78, 0x138, GPIO, LCD, NONE, NONE, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO79, 0x13C, GPIO, LCD, NONE, NONE, ONE_WIRE, MMC4, NONE, NONE), + MFPR_168(GPIO80, 0x140, GPIO, LCD, NONE, I2C, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO81, 0x144, GPIO, LCD, NONE, I2C, ONE_WIRE, MMC4, NONE, NONE), + MFPR_168(GPIO82, 0x148, GPIO, LCD, PWM, NONE, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO83, 0x14C, GPIO, LCD, PWM, NONE, RESET, MMC4, NONE, NONE), + MFPR_168(GPIO84, 0x150, GPIO, NONE, PWM, ONE_WIRE, PWM1, NONE, NONE, EXT_32K_IN), + MFPR_168(GPIO85, 0x154, GPIO, NONE, PWM1, NONE, NONE, NONE, NONE, USB), + MFPR_168(GPIO86, 0x158, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5_TX, SSP5), + MFPR_168(GPIO87, 0x15C, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5, SSP5_TX), + MFPR_168(GPIO88, 0x160, GPIO, MMC2, UART2, UART2_TX, JTAG, ETH_TX, ETH_RX, SSP5), + MFPR_168(GPIO89, 0x164, GPIO, MMC2, UART2_TX, UART2, JTAG, ETH_TX, ETH_RX, SSP5), + MFPR_168(GPIO90, 0x168, GPIO, MMC2, NONE, SSP3, JTAG, ETH_TX, ETH_RX, NONE), + MFPR_168(GPIO91, 0x16C, GPIO, MMC2, NONE, SSP3, SSP4, ETH_TX, ETH_RX, NONE), + MFPR_168(GPIO92, 0x170, GPIO, MMC2, NONE, SSP3, SSP3_TX, ETH, NONE, NONE), + MFPR_168(GPIO93, 0x174, GPIO, MMC2, NONE, SSP3_TX, SSP3, ETH, NONE, NONE), + MFPR_168(GPIO94, 0x178, GPIO, MMC2_CMD, SSP3, AC97_SYSCLK, AC97, ETH, NONE, NONE), + MFPR_168(GPIO95, 0x17C, GPIO, MMC2_CLK, NONE, NONE, AC97, ETH, NONE, NONE), + MFPR_168(GPIO96, 0x180, GPIO, PWM, NONE, MMC2, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO97, 0x184, GPIO, PWM, ONE_WIRE, NONE, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO98, 0x188, GPIO, PWM1, UART3_TX, UART3, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO99, 0x18C, GPIO, ONE_WIRE, UART3, UART3_TX, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO100, 0x190, GPIO, NONE, UART3_CTS, UART3, NONE, ETH, NONE, NONE), + MFPR_168(GPIO101, 0x194, GPIO, NONE, UART3, UART3_CTS, NONE, ETH, NONE, NONE), + MFPR_168(GPIO102, 0x198, GPIO, I2C, UART3, SSP4, NONE, NONE, NONE, NONE), + MFPR_168(GPIO103, 0x19C, GPIO, I2C, UART3, SSP4, SSP2, ETH, NONE, NONE), + MFPR_168(GPIO104, 0x1A0, GPIO, PWM, UART1, SSP4, SSP4_TX, AC97, KP_MKOUT, NONE), + MFPR_168(GPIO105, 0x1A4, GPIO, I2C, UART1, SSP4_TX, SSP4, AC97, KP_MKOUT, NONE), + MFPR_168(GPIO106, 0x1A8, GPIO, I2C, PWM1, AC97_SYSCLK, MMC2, NONE, KP_MKOUT, NONE), + MFPR_168(GPIO107, 0x1AC, GPIO, UART1_TX, UART1, NONE, SSP2, MSP_DAT3, NONE, KP_MKIN), + MFPR_168(GPIO108, 0x1B0, GPIO, UART1, UART1_TX, NONE, SSP2_TX, MSP, NONE, KP_MKIN), + MFPR_168(GPIO109, 0x1B4, GPIO, UART1_CTS, UART1, NONE, AC97_SYSCLK, MSP, NONE, KP_MKIN), + MFPR_168(GPIO110, 0x1B8, GPIO, UART1, UART1_CTS, NONE, SMC_RDY, MSP, NONE, KP_MKIN), + MFPR_168(GPIO111, 0x1BC, GPIO, UART1_nRI, UART1, SSP3, SSP2, MSP, XD, KP_MKOUT), + MFPR_168(GPIO112, 0x1C0, GPIO, UART1_DTR, UART1, ONE_WIRE, SSP2, MSP, XD, KP_MKOUT), + MFPR_168(GPIO113, 0x1C4, GPIO, NONE, NONE, NONE, NONE, NONE, AC97_SYSCLK, NONE), + MFPR_168(GPIO114, 0x1C8, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO115, 0x1CC, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO116, 0x1D0, GPIO, SSP1_TX, SSP1, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO117, 0x1D4, GPIO, SSP1, SSP1_TX, NONE, MMC2_CMD, NONE, AC97, NONE), + MFPR_168(GPIO118, 0x1D8, GPIO, SSP2, NONE, NONE, MMC2_CLK, NONE, AC97, KP_MKIN), + MFPR_168(GPIO119, 0x1DC, GPIO, SSP2, NONE, NONE, MMC2, NONE, AC97, KP_MKIN), + MFPR_168(GPIO120, 0x1E0, GPIO, SSP2, SSP2_TX, NONE, MMC2, NONE, NONE, KP_MKIN), + MFPR_168(GPIO121, 0x1E4, GPIO, SSP2_TX, SSP2, NONE, MMC2, NONE, NONE, KP_MKIN), + MFPR_168(GPIO122, 0x1E8, GPIO, AC97_SYSCLK, SSP2, PWM, MMC2, NONE, NONE, NONE), + MFPR_168(PWR_SCL, 0x1EC, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, MMC4), + MFPR_168(PWR_SDA, 0x1F0, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, NONE), + MFPR_168(TDI, 0x1F4, JTAG, PWM1, UART2, MMC4, SSP5, NONE, XD, MMC4), + MFPR_168(TMS, 0x1F8, JTAG, PWM, UART2, NONE, SSP5, NONE, XD, MMC4), + MFPR_168(TCK, 0x1FC, JTAG, PWM, UART2, UART2_TX, SSP5, NONE, XD, MMC4), + MFPR_168(TDO, 0x200, JTAG, PWM, UART2_TX, UART2, SSP5_TX, NONE, XD, MMC4), + MFPR_168(TRST, 0x204, JTAG, ONE_WIRE, SSP2, SSP3, AC97_SYSCLK, NONE, XD, MMC4), + MFPR_168(WAKEUP, 0x208, WAKEUP, ONE_WIRE, PWM1, PWM, SSP2, NONE, GPIO, MMC4), +}; + +static const unsigned p168_jtag_pin1[] = {TDI, TMS, TCK, TDO, TRST}; +static const unsigned p168_wakeup_pin1[] = {WAKEUP}; +static const unsigned p168_ssp1rx_pin1[] = {GPIO114, GPIO115, GPIO116}; +static const unsigned p168_ssp1tx_pin1[] = {GPIO117}; +static const unsigned p168_ssp4rx_pin1[] = {GPIO102, GPIO103, GPIO104}; +static const unsigned p168_ssp4tx_pin1[] = {GPIO105}; +static const unsigned p168_ssp5rx_pin1[] = {GPIO86, GPIO88, GPIO89}; +static const unsigned p168_ssp5tx_pin1[] = {GPIO87}; +static const unsigned p168_i2c_pin1[] = {GPIO105, GPIO106}; +static const unsigned p168_pwri2c_pin1[] = {PWR_SCL, PWR_SDA}; +static const unsigned p168_mmc1_pin1[] = {GPIO40, GPIO41, GPIO43, GPIO46, + GPIO49, GPIO51, GPIO52, GPIO53}; +static const unsigned p168_mmc2_data_pin1[] = {GPIO90, GPIO91, GPIO92, GPIO93}; +static const unsigned p168_mmc2_cmd_pin1[] = {GPIO94}; +static const unsigned p168_mmc2_clk_pin1[] = {GPIO95}; +static const unsigned p168_mmc3_data_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, + GPIO4, GPIO5, GPIO6, GPIO7}; +static const unsigned p168_mmc3_cmd_pin1[] = {GPIO9}; +static const unsigned p168_mmc3_clk_pin1[] = {GPIO8}; +static const unsigned p168_eth_pin1[] = {GPIO92, GPIO93, GPIO100, GPIO101, + GPIO103}; +static const unsigned p168_ethtx_pin1[] = {GPIO86, GPIO87, GPIO88, GPIO89, + GPIO90, GPIO91}; +static const unsigned p168_ethrx_pin1[] = {GPIO94, GPIO95, GPIO96, GPIO97, + GPIO98, GPIO99}; +static const unsigned p168_uart1rx_pin1[] = {GPIO107}; +static const unsigned p168_uart1tx_pin1[] = {GPIO108}; +static const unsigned p168_uart3rx_pin1[] = {GPIO98, GPIO100, GPIO101}; +static const unsigned p168_uart3tx_pin1[] = {GPIO99}; +static const unsigned p168_msp_pin1[] = {GPIO40, GPIO41, GPIO42, GPIO43, + GPIO44, GPIO50}; +static const unsigned p168_ccic_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42, GPIO44, GPIO45, GPIO46, GPIO48, GPIO54, GPIO55}; +static const unsigned p168_xd_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42, GPIO44, GPIO45, GPIO47, GPIO48, GPIO49, GPIO50, + GPIO51, GPIO52}; +static const unsigned p168_lcd_pin1[] = {GPIO56, GPIO57, GPIO58, GPIO59, + GPIO60, GPIO61, GPIO62, GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, + GPIO68, GPIO69, GPIO70, GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, + GPIO76, GPIO77, GPIO78, GPIO79, GPIO80, GPIO81, GPIO82, GPIO83}; +static const unsigned p168_dfio_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, + GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, + GPIO13, GPIO14, GPIO15}; +static const unsigned p168_nand_pin1[] = {GPIO16, GPIO17, GPIO21, GPIO22, + GPIO24, GPIO26}; +static const unsigned p168_smc_pin1[] = {GPIO23, GPIO25, GPIO29, GPIO35, + GPIO36}; +static const unsigned p168_smccs0_pin1[] = {GPIO18}; +static const unsigned p168_smccs1_pin1[] = {GPIO34}; +static const unsigned p168_smcrdy_pin1[] = {GPIO28}; +static const unsigned p168_ac97sysclk_pin1[] = {GPIO113}; +static const unsigned p168_ac97_pin1[] = {GPIO114, GPIO115, GPIO117, GPIO118, + GPIO119}; +static const unsigned p168_cf_pin1[] = {GPIO19, GPIO20, GPIO23, GPIO25, + GPIO28, GPIO29, GPIO30, GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, + GPIO36}; +static const unsigned p168_kpmkin_pin1[] = {GPIO109, GPIO110, GPIO121}; +static const unsigned p168_kpmkout_pin1[] = {GPIO111, GPIO112}; +static const unsigned p168_gpio86_pin1[] = {WAKEUP}; +static const unsigned p168_gpio86_pin2[] = {GPIO86}; +static const unsigned p168_gpio87_pin1[] = {GPIO87}; +static const unsigned p168_gpio87_pin2[] = {PWR_SDA}; +static const unsigned p168_gpio88_pin1[] = {GPIO88}; +static const unsigned p168_gpio88_pin2[] = {PWR_SCL}; + +static struct pxa3xx_pin_group pxa168_grps[] = { + GRP_168("uart1rx-1", UART1, p168_uart1rx_pin1), + GRP_168("uart1tx-1", UART1_TX, p168_uart1tx_pin1), + GRP_168("uart3rx-1", UART3, p168_uart3rx_pin1), + GRP_168("uart3tx-1", UART3_TX, p168_uart3tx_pin1), + GRP_168("ssp1rx-1", SSP1, p168_ssp1rx_pin1), + GRP_168("ssp1tx-1", SSP1_TX, p168_ssp1tx_pin1), + GRP_168("ssp4rx-1", SSP4, p168_ssp4rx_pin1), + GRP_168("ssp4tx-1", SSP4_TX, p168_ssp4tx_pin1), + GRP_168("ssp5rx-1", SSP5, p168_ssp5rx_pin1), + GRP_168("ssp5tx-1", SSP5_TX, p168_ssp5tx_pin1), + GRP_168("jtag", JTAG, p168_jtag_pin1), + GRP_168("wakeup", WAKEUP, p168_wakeup_pin1), + GRP_168("i2c", I2C, p168_i2c_pin1), + GRP_168("pwri2c", PWRI2C, p168_pwri2c_pin1), + GRP_168("mmc1 8p1", MMC1, p168_mmc1_pin1), + GRP_168("mmc2 4p1", MMC2, p168_mmc2_data_pin1), + GRP_168("mmc2 cmd1", MMC2_CMD, p168_mmc2_cmd_pin1), + GRP_168("mmc2 clk1", MMC2_CLK, p168_mmc2_clk_pin1), + GRP_168("mmc3 8p1", MMC3, p168_mmc3_data_pin1), + GRP_168("mmc3 cmd1", MMC3_CMD, p168_mmc3_cmd_pin1), + GRP_168("mmc3 clk1", MMC3_CLK, p168_mmc3_clk_pin1), + GRP_168("eth", ETH, p168_eth_pin1), + GRP_168("eth rx", ETH_RX, p168_ethrx_pin1), + GRP_168("eth tx", ETH_TX, p168_ethtx_pin1), + GRP_168("msp", MSP, p168_msp_pin1), + GRP_168("ccic", CCIC, p168_ccic_pin1), + GRP_168("xd", XD, p168_xd_pin1), + GRP_168("lcd", LCD, p168_lcd_pin1), + GRP_168("dfio", DFIO, p168_dfio_pin1), + GRP_168("nand", NAND, p168_nand_pin1), + GRP_168("smc", SMC, p168_smc_pin1), + GRP_168("smc cs0", SMC_CS0, p168_smccs0_pin1), + GRP_168("smc cs1", SMC_CS1, p168_smccs1_pin1), + GRP_168("smc rdy", SMC_RDY, p168_smcrdy_pin1), + GRP_168("ac97 sysclk", AC97_SYSCLK, p168_ac97sysclk_pin1), + GRP_168("ac97", AC97, p168_ac97_pin1), + GRP_168("cf", CF, p168_cf_pin1), + GRP_168("kp mkin 3p1", KP_MKIN, p168_kpmkin_pin1), + GRP_168("kp mkout 2p1", KP_MKOUT, p168_kpmkout_pin1), + GRP_168("gpio86-1", GPIO, p168_gpio86_pin1), + GRP_168("gpio86-2", GPIO, p168_gpio86_pin2), + GRP_168("gpio87-1", GPIO, p168_gpio87_pin1), + GRP_168("gpio87-2", GPIO, p168_gpio87_pin2), + GRP_168("gpio88-1", GPIO, p168_gpio88_pin1), + GRP_168("gpio88-2", GPIO, p168_gpio88_pin2), +}; + +static const char * const p168_uart1rx_grps[] = {"uart1rx-1"}; +static const char * const p168_uart1tx_grps[] = {"uart1tx-1"}; +static const char * const p168_uart3rx_grps[] = {"uart3rx-1"}; +static const char * const p168_uart3tx_grps[] = {"uart3tx-1"}; +static const char * const p168_ssp1rx_grps[] = {"ssp1rx-1"}; +static const char * const p168_ssp1tx_grps[] = {"ssp1tx-1"}; +static const char * const p168_ssp4rx_grps[] = {"ssp4rx-1"}; +static const char * const p168_ssp4tx_grps[] = {"ssp4tx-1"}; +static const char * const p168_ssp5rx_grps[] = {"ssp5rx-1"}; +static const char * const p168_ssp5tx_grps[] = {"ssp5tx-1"}; +static const char * const p168_i2c_grps[] = {"i2c"}; +static const char * const p168_pwri2c_grps[] = {"pwri2c"}; +static const char * const p168_mmc1_grps[] = {"mmc1 8p1"}; +static const char * const p168_mmc2_data_grps[] = {"mmc2 4p1"}; +static const char * const p168_mmc2_cmd_grps[] = {"mmc2 cmd1"}; +static const char * const p168_mmc2_clk_grps[] = {"mmc2 clk1"}; +static const char * const p168_mmc3_data_grps[] = {"mmc3 8p1"}; +static const char * const p168_mmc3_cmd_grps[] = {"mmc3 cmd1"}; +static const char * const p168_mmc3_clk_grps[] = {"mmc3 clk1"}; +static const char * const p168_eth_grps[] = {"eth"}; +static const char * const p168_ethrx_grps[] = {"eth rx"}; +static const char * const p168_ethtx_grps[] = {"eth tx"}; +static const char * const p168_msp_grps[] = {"msp"}; +static const char * const p168_ccic_grps[] = {"ccic"}; +static const char * const p168_xd_grps[] = {"xd"}; +static const char * const p168_lcd_grps[] = {"lcd"}; +static const char * const p168_dfio_grps[] = {"dfio"}; +static const char * const p168_nand_grps[] = {"nand"}; +static const char * const p168_smc_grps[] = {"smc"}; +static const char * const p168_smccs0_grps[] = {"smc cs0"}; +static const char * const p168_smccs1_grps[] = {"smc cs1"}; +static const char * const p168_smcrdy_grps[] = {"smc rdy"}; +static const char * const p168_ac97sysclk_grps[] = {"ac97 sysclk"}; +static const char * const p168_ac97_grps[] = {"ac97"}; +static const char * const p168_cf_grps[] = {"cf"}; +static const char * const p168_kpmkin_grps[] = {"kp mkin 3p1"}; +static const char * const p168_kpmkout_grps[] = {"kp mkout 2p1"}; +static const char * const p168_gpio86_grps[] = {"gpio86-1", "gpio86-2"}; +static const char * const p168_gpio87_grps[] = {"gpio87-1", "gpio87-2"}; +static const char * const p168_gpio88_grps[] = {"gpio88-1", "gpio88-2"}; + +static struct pxa3xx_pmx_func pxa168_funcs[] = { + {"uart1 rx", ARRAY_AND_SIZE(p168_uart1rx_grps)}, + {"uart1 tx", ARRAY_AND_SIZE(p168_uart1tx_grps)}, + {"uart3 rx", ARRAY_AND_SIZE(p168_uart3rx_grps)}, + {"uart3 tx", ARRAY_AND_SIZE(p168_uart3tx_grps)}, + {"ssp1 rx", ARRAY_AND_SIZE(p168_ssp1rx_grps)}, + {"ssp1 tx", ARRAY_AND_SIZE(p168_ssp1tx_grps)}, + {"ssp4 rx", ARRAY_AND_SIZE(p168_ssp4rx_grps)}, + {"ssp4 tx", ARRAY_AND_SIZE(p168_ssp4tx_grps)}, + {"ssp5 rx", ARRAY_AND_SIZE(p168_ssp5rx_grps)}, + {"ssp5 tx", ARRAY_AND_SIZE(p168_ssp5tx_grps)}, + {"i2c", ARRAY_AND_SIZE(p168_i2c_grps)}, + {"pwri2c", ARRAY_AND_SIZE(p168_pwri2c_grps)}, + {"mmc1", ARRAY_AND_SIZE(p168_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(p168_mmc2_data_grps)}, + {"mmc2 cmd", ARRAY_AND_SIZE(p168_mmc2_cmd_grps)}, + {"mmc2 clk", ARRAY_AND_SIZE(p168_mmc2_clk_grps)}, + {"mmc3", ARRAY_AND_SIZE(p168_mmc3_data_grps)}, + {"mmc3 cmd", ARRAY_AND_SIZE(p168_mmc3_cmd_grps)}, + {"mmc3 clk", ARRAY_AND_SIZE(p168_mmc3_clk_grps)}, + {"eth", ARRAY_AND_SIZE(p168_eth_grps)}, + {"eth rx", ARRAY_AND_SIZE(p168_ethrx_grps)}, + {"eth tx", ARRAY_AND_SIZE(p168_ethtx_grps)}, + {"msp", ARRAY_AND_SIZE(p168_msp_grps)}, + {"ccic", ARRAY_AND_SIZE(p168_ccic_grps)}, + {"xd", ARRAY_AND_SIZE(p168_xd_grps)}, + {"lcd", ARRAY_AND_SIZE(p168_lcd_grps)}, + {"dfio", ARRAY_AND_SIZE(p168_dfio_grps)}, + {"nand", ARRAY_AND_SIZE(p168_nand_grps)}, + {"smc", ARRAY_AND_SIZE(p168_smc_grps)}, + {"smc cs0", ARRAY_AND_SIZE(p168_smccs0_grps)}, + {"smc cs1", ARRAY_AND_SIZE(p168_smccs1_grps)}, + {"smc rdy", ARRAY_AND_SIZE(p168_smcrdy_grps)}, + {"ac97", ARRAY_AND_SIZE(p168_ac97_grps)}, + {"ac97 sysclk", ARRAY_AND_SIZE(p168_ac97sysclk_grps)}, + {"cf", ARRAY_AND_SIZE(p168_cf_grps)}, + {"kpmkin", ARRAY_AND_SIZE(p168_kpmkin_grps)}, + {"kpmkout", ARRAY_AND_SIZE(p168_kpmkout_grps)}, + {"gpio86", ARRAY_AND_SIZE(p168_gpio86_grps)}, + {"gpio87", ARRAY_AND_SIZE(p168_gpio87_grps)}, + {"gpio88", ARRAY_AND_SIZE(p168_gpio88_grps)}, +}; + +static struct pinctrl_desc pxa168_pctrl_desc = { + .name = "pxa168-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info pxa168_info = { + .mfp = pxa168_mfp, + .num_mfp = ARRAY_SIZE(pxa168_mfp), + .grps = pxa168_grps, + .num_grps = ARRAY_SIZE(pxa168_grps), + .funcs = pxa168_funcs, + .num_funcs = ARRAY_SIZE(pxa168_funcs), + .num_gpio = 128, + .desc = &pxa168_pctrl_desc, + .pads = pxa168_pads, + .num_pads = ARRAY_SIZE(pxa168_pads), + + .cputype = PINCTRL_PXA168, + .ds_mask = PXA168_DS_MASK, + .ds_shift = PXA168_DS_SHIFT, +}; + +static int pxa168_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &pxa168_info); +} + +static int pxa168_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver pxa168_pinmux_driver = { + .driver = { + .name = "pxa168-pinmux", + .owner = THIS_MODULE, + }, + .probe = pxa168_pinmux_probe, + .remove = pxa168_pinmux_remove, +}; + +static int __init pxa168_pinmux_init(void) +{ + return platform_driver_register(&pxa168_pinmux_driver); +} +core_initcall_sync(pxa168_pinmux_init); + +static void __exit pxa168_pinmux_exit(void) +{ + platform_driver_unregister(&pxa168_pinmux_driver); +} +module_exit(pxa168_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-pxa3xx.c b/trunk/drivers/pinctrl/pinctrl-pxa3xx.c new file mode 100644 index 000000000000..1f49bb02a6af --- /dev/null +++ b/trunk/drivers/pinctrl/pinctrl-pxa3xx.c @@ -0,0 +1,227 @@ +/* + * linux/drivers/pinctrl/pinctrl-pxa3xx.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = { + .name = "PXA3xx GPIO", + .id = 0, + .base = 0, + .pin_base = 0, +}; + +static int pxa3xx_get_groups_count(struct pinctrl_dev *pctrldev) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + + return info->num_grps; +} + +static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev, + unsigned selector) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + + return info->grps[selector].name; +} + +static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev, + unsigned selector, + const unsigned **pins, + unsigned *num_pins) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + + *pins = info->grps[selector].pins; + *num_pins = info->grps[selector].npins; + return 0; +} + +static struct pinctrl_ops pxa3xx_pctrl_ops = { + .get_groups_count = pxa3xx_get_groups_count, + .get_group_name = pxa3xx_get_group_name, + .get_group_pins = pxa3xx_get_group_pins, +}; + +static int pxa3xx_pmx_get_funcs_count(struct pinctrl_dev *pctrldev) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + + return info->num_funcs; +} + +static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev, + unsigned func) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + return info->funcs[func].name; +} + +static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func, + const char * const **groups, + unsigned * const num_groups) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + *groups = info->funcs[func].groups; + *num_groups = info->funcs[func].num_groups; + return 0; +} + +/* Return function number. If failure, return negative value. */ +static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux) +{ + int i; + for (i = 0; i < PXA3xx_MAX_MUX; i++) { + if (mfp->func[i] == mux) + break; + } + if (i >= PXA3xx_MAX_MUX) + return -EINVAL; + return i; +} + +/* check whether current pin configuration is valid. Negative for failure */ +static int match_group_mux(struct pxa3xx_pin_group *grp, + struct pxa3xx_pinmux_info *info, + unsigned mux) +{ + int i, pin, ret = 0; + for (i = 0; i < grp->npins; i++) { + pin = grp->pins[i]; + ret = match_mux(&info->mfp[pin], mux); + if (ret < 0) { + dev_err(info->dev, "Can't find mux %d on pin%d\n", + mux, pin); + break; + } + } + return ret; +} + +static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func, + unsigned group) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + struct pxa3xx_pin_group *pin_grp = &info->grps[group]; + unsigned int data; + int i, mfpr, pin, pin_func; + + if (!pin_grp->npins || + (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) { + dev_err(info->dev, "Failed to set the pin group: %d\n", group); + return -EINVAL; + } + for (i = 0; i < pin_grp->npins; i++) { + pin = pin_grp->pins[i]; + pin_func = match_mux(&info->mfp[pin], pin_grp->mux); + mfpr = info->mfp[pin].mfpr; + data = readl_relaxed(info->virt_base + mfpr); + data &= ~MFPR_FUNC_MASK; + data |= pin_func; + writel_relaxed(data, info->virt_base + mfpr); + } + return 0; +} + +static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev, + struct pinctrl_gpio_range *range, + unsigned pin) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + unsigned int data; + int pin_func, mfpr; + + pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO); + if (pin_func < 0) { + dev_err(info->dev, "No GPIO function on pin%d (%s)\n", + pin, info->pads[pin].name); + return -EINVAL; + } + mfpr = info->mfp[pin].mfpr; + /* write gpio function into mfpr register */ + data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK; + data |= pin_func; + writel_relaxed(data, info->virt_base + mfpr); + return 0; +} + +static struct pinmux_ops pxa3xx_pmx_ops = { + .get_functions_count = pxa3xx_pmx_get_funcs_count, + .get_function_name = pxa3xx_pmx_get_func_name, + .get_function_groups = pxa3xx_pmx_get_groups, + .enable = pxa3xx_pmx_enable, + .gpio_request_enable = pxa3xx_pmx_request_gpio, +}; + +int pxa3xx_pinctrl_register(struct platform_device *pdev, + struct pxa3xx_pinmux_info *info) +{ + struct pinctrl_desc *desc; + struct resource *res; + + if (!info || !info->cputype) + return -EINVAL; + desc = info->desc; + desc->pins = info->pads; + desc->npins = info->num_pads; + desc->pctlops = &pxa3xx_pctrl_ops; + desc->pmxops = &pxa3xx_pmx_ops; + info->dev = &pdev->dev; + pxa3xx_pinctrl_gpio_range.npins = info->num_gpio; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOENT; + info->virt_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(info->virt_base)) + return PTR_ERR(info->virt_base); + info->pctrl = pinctrl_register(desc, &pdev->dev, info); + if (!info->pctrl) { + dev_err(&pdev->dev, "failed to register PXA pinmux driver\n"); + return -EINVAL; + } + pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range); + platform_set_drvdata(pdev, info); + return 0; +} + +int pxa3xx_pinctrl_unregister(struct platform_device *pdev) +{ + struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev); + + pinctrl_unregister(info->pctrl); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int __init pxa3xx_pinctrl_init(void) +{ + pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n"); + return 0; +} +core_initcall_sync(pxa3xx_pinctrl_init); + +static void __exit pxa3xx_pinctrl_exit(void) +{ +} +module_exit(pxa3xx_pinctrl_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-pxa3xx.h b/trunk/drivers/pinctrl/pinctrl-pxa3xx.h new file mode 100644 index 000000000000..92fad0880834 --- /dev/null +++ b/trunk/drivers/pinctrl/pinctrl-pxa3xx.h @@ -0,0 +1,262 @@ +/* + * linux/drivers/pinctrl/pinctrl-pxa3xx.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#ifndef __PINCTRL_PXA3XX_H + +#include +#include + +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +#define PXA3xx_MUX_GPIO 0 + +#define PXA3xx_MAX_MUX 8 +#define MFPR_FUNC_MASK 0x7 + +enum pxa_cpu_type { + PINCTRL_INVALID = 0, + PINCTRL_PXA300, + PINCTRL_PXA310, + PINCTRL_PXA320, + PINCTRL_PXA168, + PINCTRL_PXA910, + PINCTRL_PXA930, + PINCTRL_PXA955, + PINCTRL_MMP2, + PINCTRL_MAX, +}; + +struct pxa3xx_mfp_pin { + const char *name; + const unsigned int pin; + const unsigned int mfpr; /* register offset */ + const unsigned short func[8]; +}; + +struct pxa3xx_pin_group { + const char *name; + const unsigned mux; + const unsigned *pins; + const unsigned npins; +}; + +struct pxa3xx_pmx_func { + const char *name; + const char * const * groups; + const unsigned num_groups; +}; + +struct pxa3xx_pinmux_info { + struct device *dev; + struct pinctrl_dev *pctrl; + enum pxa_cpu_type cputype; + void __iomem *virt_base; + + struct pxa3xx_mfp_pin *mfp; + unsigned int num_mfp; + struct pxa3xx_pin_group *grps; + unsigned int num_grps; + struct pxa3xx_pmx_func *funcs; + unsigned int num_funcs; + unsigned int num_gpio; + struct pinctrl_desc *desc; + struct pinctrl_pin_desc *pads; + unsigned int num_pads; + + unsigned ds_mask; /* drive strength mask */ + unsigned ds_shift; /* drive strength shift */ + unsigned slp_mask; /* sleep mask */ + unsigned slp_input_low; + unsigned slp_input_high; + unsigned slp_output_low; + unsigned slp_output_high; + unsigned slp_float; +}; + +enum pxa3xx_pin_list { + GPIO0 = 0, + GPIO1, + GPIO2, + GPIO3, + GPIO4, + GPIO5, + GPIO6, + GPIO7, + GPIO8, + GPIO9, + GPIO10, /* 10 */ + GPIO11, + GPIO12, + GPIO13, + GPIO14, + GPIO15, + GPIO16, + GPIO17, + GPIO18, + GPIO19, + GPIO20, /* 20 */ + GPIO21, + GPIO22, + GPIO23, + GPIO24, + GPIO25, + GPIO26, + GPIO27, + GPIO28, + GPIO29, + GPIO30, /* 30 */ + GPIO31, + GPIO32, + GPIO33, + GPIO34, + GPIO35, + GPIO36, + GPIO37, + GPIO38, + GPIO39, + GPIO40, /* 40 */ + GPIO41, + GPIO42, + GPIO43, + GPIO44, + GPIO45, + GPIO46, + GPIO47, + GPIO48, + GPIO49, + GPIO50, /* 50 */ + GPIO51, + GPIO52, + GPIO53, + GPIO54, + GPIO55, + GPIO56, + GPIO57, + GPIO58, + GPIO59, + GPIO60, /* 60 */ + GPIO61, + GPIO62, + GPIO63, + GPIO64, + GPIO65, + GPIO66, + GPIO67, + GPIO68, + GPIO69, + GPIO70, /* 70 */ + GPIO71, + GPIO72, + GPIO73, + GPIO74, + GPIO75, + GPIO76, + GPIO77, + GPIO78, + GPIO79, + GPIO80, /* 80 */ + GPIO81, + GPIO82, + GPIO83, + GPIO84, + GPIO85, + GPIO86, + GPIO87, + GPIO88, + GPIO89, + GPIO90, /* 90 */ + GPIO91, + GPIO92, + GPIO93, + GPIO94, + GPIO95, + GPIO96, + GPIO97, + GPIO98, + GPIO99, + GPIO100, /* 100 */ + GPIO101, + GPIO102, + GPIO103, + GPIO104, + GPIO105, + GPIO106, + GPIO107, + GPIO108, + GPIO109, + GPIO110, /* 110 */ + GPIO111, + GPIO112, + GPIO113, + GPIO114, + GPIO115, + GPIO116, + GPIO117, + GPIO118, + GPIO119, + GPIO120, /* 120 */ + GPIO121, + GPIO122, + GPIO123, + GPIO124, + GPIO125, + GPIO126, + GPIO127, + GPIO128, + GPIO129, + GPIO130, /* 130 */ + GPIO131, + GPIO132, + GPIO133, + GPIO134, + GPIO135, + GPIO136, + GPIO137, + GPIO138, + GPIO139, + GPIO140, /* 140 */ + GPIO141, + GPIO142, + GPIO143, + GPIO144, + GPIO145, + GPIO146, + GPIO147, + GPIO148, + GPIO149, + GPIO150, /* 150 */ + GPIO151, + GPIO152, + GPIO153, + GPIO154, + GPIO155, + GPIO156, + GPIO157, + GPIO158, + GPIO159, + GPIO160, /* 160 */ + GPIO161, + GPIO162, + GPIO163, + GPIO164, + GPIO165, + GPIO166, + GPIO167, + GPIO168, + GPIO169, +}; + +extern int pxa3xx_pinctrl_register(struct platform_device *pdev, + struct pxa3xx_pinmux_info *info); +extern int pxa3xx_pinctrl_unregister(struct platform_device *pdev); +#endif /* __PINCTRL_PXA3XX_H */ diff --git a/trunk/drivers/pinctrl/pinctrl-pxa910.c b/trunk/drivers/pinctrl/pinctrl-pxa910.c new file mode 100644 index 000000000000..a2f917b847fb --- /dev/null +++ b/trunk/drivers/pinctrl/pinctrl-pxa910.c @@ -0,0 +1,1007 @@ +/* + * linux/drivers/pinctrl/pinmux-pxa910.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define PXA910_DS_MASK 0x1800 +#define PXA910_DS_SHIFT 11 +#define PXA910_SLEEP_MASK 0x38 +#define PXA910_SLEEP_SELECT (1 << 9) +#define PXA910_SLEEP_DATA (1 << 8) +#define PXA910_SLEEP_DIR (1 << 7) + +#define MFPR_910(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + PXA910_MUX_##f0, \ + PXA910_MUX_##f1, \ + PXA910_MUX_##f2, \ + PXA910_MUX_##f3, \ + PXA910_MUX_##f4, \ + PXA910_MUX_##f5, \ + PXA910_MUX_##f6, \ + PXA910_MUX_##f7, \ + }, \ + } + +#define GRP_910(a, m, p) \ + { .name = a, .mux = PXA910_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 170 pins */ +enum pxa910_pin_list { + /* 0~127: GPIO0~GPIO127 */ + ND_IO15 = 128, + ND_IO14, + ND_IO13, /* 130 */ + ND_IO12, + ND_IO11, + ND_IO10, + ND_IO9, + ND_IO8, + ND_IO7, + ND_IO6, + ND_IO5, + ND_IO4, + ND_IO3, /* 140 */ + ND_IO2, + ND_IO1, + ND_IO0, + ND_NCS0, + ND_NCS1, + SM_NCS0, + SM_NCS1, + ND_NWE, + ND_NRE, + ND_CLE, /* 150 */ + ND_ALE, + SM_SCLK, + ND_RDY0, + SM_ADV, + ND_RDY1, + SM_ADVMUX, + SM_RDY, + MMC1_DAT7, + MMC1_DAT6, + MMC1_DAT5, /* 160 */ + MMC1_DAT4, + MMC1_DAT3, + MMC1_DAT2, + MMC1_DAT1, + MMC1_DAT0, + MMC1_CMD, + MMC1_CLK, + MMC1_CD, + VCXO_OUT, +}; + +enum pxa910_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + PXA910_MUX_GPIO = 0, + PXA910_MUX_NAND, + PXA910_MUX_USIM2, + PXA910_MUX_EXT_DMA, + PXA910_MUX_EXT_INT, + PXA910_MUX_MMC1, + PXA910_MUX_MMC2, + PXA910_MUX_MMC3, + PXA910_MUX_SM_INT, + PXA910_MUX_PRI_JTAG, + PXA910_MUX_SEC1_JTAG, + PXA910_MUX_SEC2_JTAG, + PXA910_MUX_RESET, /* SLAVE RESET OUT */ + PXA910_MUX_CLK_REQ, + PXA910_MUX_VCXO_REQ, + PXA910_MUX_VCXO_OUT, + PXA910_MUX_VCXO_REQ2, + PXA910_MUX_VCXO_OUT2, + PXA910_MUX_SPI, + PXA910_MUX_SPI2, + PXA910_MUX_GSSP, + PXA910_MUX_SSP0, + PXA910_MUX_SSP1, + PXA910_MUX_SSP2, + PXA910_MUX_DSSP2, + PXA910_MUX_DSSP3, + PXA910_MUX_UART0, + PXA910_MUX_UART1, + PXA910_MUX_UART2, + PXA910_MUX_TWSI, + PXA910_MUX_CCIC, + PXA910_MUX_PWM0, + PXA910_MUX_PWM1, + PXA910_MUX_PWM2, + PXA910_MUX_PWM3, + PXA910_MUX_HSL, + PXA910_MUX_ONE_WIRE, + PXA910_MUX_LCD, + PXA910_MUX_DAC_ST23, + PXA910_MUX_ULPI, + PXA910_MUX_TB, + PXA910_MUX_KP_MK, + PXA910_MUX_KP_DK, + PXA910_MUX_TCU_GPOA, + PXA910_MUX_TCU_GPOB, + PXA910_MUX_ROT, + PXA910_MUX_TDS, + PXA910_MUX_32K_CLK, /* 32KHz CLK OUT */ + PXA910_MUX_MN_CLK, /* MN CLK OUT */ + PXA910_MUX_SMC, + PXA910_MUX_SM_ADDR18, + PXA910_MUX_SM_ADDR19, + PXA910_MUX_SM_ADDR20, + PXA910_MUX_NONE = 0xffff, +}; + + +static struct pinctrl_pin_desc pxa910_pads[] = { + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(GPIO123, "GPIO123"), + PINCTRL_PIN(GPIO124, "GPIO124"), + PINCTRL_PIN(GPIO125, "GPIO125"), + PINCTRL_PIN(GPIO126, "GPIO126"), + PINCTRL_PIN(GPIO127, "GPIO127"), + PINCTRL_PIN(ND_IO15, "ND_IO15"), + PINCTRL_PIN(ND_IO14, "ND_IO14"), + PINCTRL_PIN(ND_IO13, "ND_IO13"), + PINCTRL_PIN(ND_IO12, "ND_IO12"), + PINCTRL_PIN(ND_IO11, "ND_IO11"), + PINCTRL_PIN(ND_IO10, "ND_IO10"), + PINCTRL_PIN(ND_IO9, "ND_IO9"), + PINCTRL_PIN(ND_IO8, "ND_IO8"), + PINCTRL_PIN(ND_IO7, "ND_IO7"), + PINCTRL_PIN(ND_IO6, "ND_IO6"), + PINCTRL_PIN(ND_IO5, "ND_IO5"), + PINCTRL_PIN(ND_IO4, "ND_IO4"), + PINCTRL_PIN(ND_IO3, "ND_IO3"), + PINCTRL_PIN(ND_IO2, "ND_IO2"), + PINCTRL_PIN(ND_IO1, "ND_IO1"), + PINCTRL_PIN(ND_IO0, "ND_IO0"), + PINCTRL_PIN(ND_NCS0, "ND_NCS0_SM_NCS2"), + PINCTRL_PIN(ND_NCS1, "ND_NCS1_SM_NCS3"), + PINCTRL_PIN(SM_NCS0, "SM_NCS0"), + PINCTRL_PIN(SM_NCS1, "SM_NCS1"), + PINCTRL_PIN(ND_NWE, "ND_NWE"), + PINCTRL_PIN(ND_NRE, "ND_NRE"), + PINCTRL_PIN(ND_CLE, "ND_CLE_SM_NOE"), + PINCTRL_PIN(ND_ALE, "ND_ALE_SM_NWE"), + PINCTRL_PIN(SM_SCLK, "SM_SCLK"), + PINCTRL_PIN(ND_RDY0, "ND_RDY0"), + PINCTRL_PIN(SM_ADV, "SM_ADV"), + PINCTRL_PIN(ND_RDY1, "ND_RDY1"), + PINCTRL_PIN(SM_RDY, "SM_RDY"), + PINCTRL_PIN(MMC1_DAT7, "MMC1_DAT7"), + PINCTRL_PIN(MMC1_DAT6, "MMC1_DAT6"), + PINCTRL_PIN(MMC1_DAT5, "MMC1_DAT5"), + PINCTRL_PIN(MMC1_DAT4, "MMC1_DAT4"), + PINCTRL_PIN(MMC1_DAT3, "MMC1_DAT3"), + PINCTRL_PIN(MMC1_DAT2, "MMC1_DAT2"), + PINCTRL_PIN(MMC1_DAT1, "MMC1_DAT1"), + PINCTRL_PIN(MMC1_DAT0, "MMC1_DAT0"), + PINCTRL_PIN(MMC1_CMD, "MMC1 CMD"), + PINCTRL_PIN(MMC1_CLK, "MMC1 CLK"), + PINCTRL_PIN(MMC1_CD, "MMC1 CD"), + PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"), +}; + +struct pxa3xx_mfp_pin pxa910_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_910(GPIO0, 0x0DC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO1, 0x0E0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO2, 0x0E4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO3, 0x0E8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO4, 0x0EC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO5, 0x0F0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO6, 0x0F4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO7, 0x0F8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO8, 0x0FC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO9, 0x100, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO10, 0x104, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO11, 0x108, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO12, 0x10C, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE), + MFPR_910(GPIO13, 0x110, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE), + MFPR_910(GPIO14, 0x114, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE), + MFPR_910(GPIO15, 0x118, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE), + MFPR_910(GPIO16, 0x11C, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE), + MFPR_910(GPIO17, 0x120, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE), + MFPR_910(GPIO18, 0x124, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE), + MFPR_910(GPIO19, 0x128, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE), + MFPR_910(GPIO20, 0x12C, GPIO, SSP1, NONE, NONE, VCXO_OUT, NONE, NONE, NONE), + MFPR_910(GPIO21, 0x130, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO22, 0x134, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO23, 0x138, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO24, 0x13C, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO25, 0x140, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO26, 0x144, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO27, 0x148, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO28, 0x14C, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO29, 0x150, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO30, 0x154, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO31, 0x158, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO32, 0x15C, GPIO, UART0, DAC_ST23, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO33, 0x160, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO34, 0x164, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO35, 0x168, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO36, 0x16C, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO37, 0x170, GPIO, MMC2, NONE, NONE, NONE, SPI, HSL, NONE), + MFPR_910(GPIO38, 0x174, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO39, 0x178, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO40, 0x17C, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO41, 0x180, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO42, 0x184, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO43, 0x188, GPIO, UART1, NONE, DAC_ST23, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO44, 0x18C, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO45, 0x190, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO46, 0x194, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO47, 0x198, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE), + MFPR_910(GPIO48, 0x19C, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE), + MFPR_910(GPIO49, 0x1A0, GPIO, SSP0, UART0, VCXO_REQ, NONE, SSP2, NONE, MMC3), + MFPR_910(GPIO50, 0x1A4, GPIO, SSP0, UART0, VCXO_OUT, NONE, SSP2, NONE, MMC3), + MFPR_910(GPIO51, 0x1A8, GPIO, UART2, PWM1, TWSI, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO52, 0x1AC, GPIO, UART2, DAC_ST23, TWSI, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO53, 0x1B0, GPIO, UART2, TWSI, NONE, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO54, 0x1B4, GPIO, UART2, TWSI, SSP0, NONE, NONE, DSSP3, NONE), + MFPR_910(GPIO55, 0x2F0, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO56, 0x2F4, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO57, 0x2F8, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO58, 0x2FC, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO59, 0x300, TDS, GPIO, TCU_GPOA, TCU_GPOB, ONE_WIRE, NONE, NONE, NONE), + MFPR_910(GPIO60, 0x304, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO61, 0x308, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO62, 0x30C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO63, 0x310, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO64, 0x314, GPIO, SPI2, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO65, 0x318, GPIO, SPI2, NONE, NONE, NONE, NONE, ONE_WIRE, HSL), + MFPR_910(GPIO66, 0x31C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO67, 0x1B8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO68, 0x1BC, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO69, 0x1C0, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO70, 0x1C4, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO71, 0x1C8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO72, 0x1CC, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO73, 0x1D0, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO74, 0x1D4, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO75, 0x1D8, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO76, 0x1DC, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO77, 0x1E0, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO78, 0x1E4, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO79, 0x1E8, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO80, 0x1EC, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO81, 0x1F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO82, 0x1F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO83, 0x1F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO84, 0x1FC, GPIO, LCD, VCXO_REQ2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO85, 0x200, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO86, 0x204, GPIO, LCD, VCXO_OUT2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO87, 0x208, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO88, 0x20C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO89, 0x210, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO90, 0x214, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO91, 0x218, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO92, 0x21C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO93, 0x220, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO94, 0x224, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO95, 0x228, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO96, 0x22C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO97, 0x230, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO98, 0x234, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO99, 0x0B0, MMC1, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO100, 0x238, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO101, 0x23C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO102, 0x240, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2), + MFPR_910(GPIO103, 0x244, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2), + MFPR_910(GPIO104, 0x248, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO105, 0x24C, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO106, 0x250, GPIO, LCD, DSSP3, ONE_WIRE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO107, 0x254, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO108, 0x258, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO109, 0x25C, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO110, 0x298, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO111, 0x29C, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO112, 0x2A0, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO113, 0x2A4, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO114, 0x2A8, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO115, 0x2AC, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO116, 0x2B0, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO117, 0x0B4, PRI_JTAG, GPIO, PWM0, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO118, 0x0B8, PRI_JTAG, GPIO, PWM1, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO119, 0x0BC, PRI_JTAG, GPIO, PWM2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO120, 0x0C0, PRI_JTAG, GPIO, PWM3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO121, 0x32C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO122, 0x0C8, RESET, GPIO, 32K_CLK, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO123, 0x0CC, CLK_REQ, GPIO, ONE_WIRE, EXT_DMA, NONE, NONE, NONE, NONE), + MFPR_910(GPIO124, 0x0D0, GPIO, MN_CLK, DAC_ST23, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO125, 0x0D4, VCXO_REQ, GPIO, NONE, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(GPIO126, 0x06C, GPIO, SMC, NONE, SM_ADDR18, NONE, EXT_DMA, NONE, NONE), + MFPR_910(GPIO127, 0x070, GPIO, SMC, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO15, 0x004, NAND, GPIO, USIM2, EXT_DMA, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO14, 0x008, NAND, GPIO, USIM2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO13, 0x00C, NAND, GPIO, USIM2, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO12, 0x010, NAND, GPIO, SSP2, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO11, 0x014, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO10, 0x018, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO9, 0x01C, NAND, GPIO, SSP2, NONE, VCXO_OUT2, NONE, NONE, NONE), + MFPR_910(ND_IO8, 0x020, NAND, GPIO, NONE, NONE, PWM3, NONE, NONE, NONE), + MFPR_910(ND_IO7, 0x024, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO6, 0x028, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO5, 0x02C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO4, 0x030, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO3, 0x034, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO2, 0x038, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO1, 0x03C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO0, 0x040, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NCS0, 0x044, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NCS1, 0x048, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_NCS0, 0x04C, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_NCS1, 0x050, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NWE, 0x054, GPIO, NAND, NONE, SM_ADDR20, NONE, SMC, NONE, NONE), + MFPR_910(ND_NRE, 0x058, GPIO, NAND, NONE, SMC, NONE, EXT_DMA, NONE, NONE), + MFPR_910(ND_CLE, 0x05C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_ALE, 0x060, GPIO, NAND, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_SCLK, 0x064, MMC3, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_RDY0, 0x068, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE), + MFPR_910(SM_ADV, 0x074, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_RDY1, 0x078, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE), + MFPR_910(SM_ADVMUX, 0x07C, SMC, GPIO, NONE, SM_ADDR19, NONE, NONE, NONE, NONE), + MFPR_910(SM_RDY, 0x080, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT7, 0x084, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT6, 0x088, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT5, 0x08C, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT4, 0x090, MMC1, GPIO, NONE, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT3, 0x094, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT2, 0x098, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE), + MFPR_910(MMC1_DAT1, 0x09C, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE), + MFPR_910(MMC1_DAT0, 0x0A0, MMC1, HSL, SEC2_JTAG, SSP2, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CMD, 0x0A4, MMC1, HSL, SEC1_JTAG, SSP2, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CLK, 0x0A8, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CD, 0x0AC, MMC1, GPIO, SEC1_JTAG, NONE, NONE, NONE, NONE, NONE), + MFPR_910(VCXO_OUT, 0x0D8, VCXO_OUT, PWM3, NONE, NONE, NONE, NONE, NONE, NONE), +}; + + +static const unsigned p910_usim2_pin1[] = {GPIO67, GPIO68, GPIO69}; +static const unsigned p910_usim2_pin2[] = {ND_IO15, ND_IO14, ND_IO13}; +static const unsigned p910_mmc1_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_DAT4, MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, MMC1_CMD, + MMC1_CLK, MMC1_CD, GPIO99}; +static const unsigned p910_mmc2_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO37, GPIO38, GPIO39, GPIO40, GPIO41, GPIO42}; +static const unsigned p910_mmc3_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO49, GPIO50}; +static const unsigned p910_mmc3_pin2[] = {ND_IO7, ND_IO6, ND_IO5, ND_IO4, + ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_CLE, SM_SCLK}; +static const unsigned p910_uart0_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned p910_uart1_pin1[] = {GPIO47, GPIO48}; +static const unsigned p910_uart1_pin2[] = {GPIO31, GPIO32}; +static const unsigned p910_uart1_pin3[] = {GPIO45, GPIO46}; +static const unsigned p910_uart1_pin4[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned p910_uart1_pin5[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_uart2_pin1[] = {GPIO43, GPIO44}; +static const unsigned p910_uart2_pin2[] = {GPIO51, GPIO52}; +static const unsigned p910_uart2_pin3[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_uart2_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_twsi_pin1[] = {GPIO51, GPIO52}; +static const unsigned p910_twsi_pin2[] = {GPIO53, GPIO54}; +static const unsigned p910_twsi_pin3[] = {GPIO79, GPIO80}; +static const unsigned p910_ccic_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78}; +static const unsigned p910_lcd_pin1[] = {GPIO81, GPIO82, GPIO83, GPIO84, + GPIO85, GPIO86, GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, + GPIO93, GPIO94, GPIO95, GPIO96, GPIO97, GPIO98, GPIO100, GPIO101, + GPIO102, GPIO103}; +static const unsigned p910_spi_pin1[] = {GPIO104, GPIO105, GPIO107, GPIO108}; +static const unsigned p910_spi_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_spi_pin3[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO37}; +static const unsigned p910_spi_pin4[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71}; +static const unsigned p910_spi2_pin1[] = {GPIO64, GPIO65}; +static const unsigned p910_spi2_pin2[] = {GPIO102, GPIO103}; +static const unsigned p910_dssp2_pin1[] = {GPIO102, GPIO103, GPIO104, GPIO105}; +static const unsigned p910_dssp2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_dssp2_pin3[] = {GPIO111, GPIO112, GPIO113}; +static const unsigned p910_dssp3_pin1[] = {GPIO106, GPIO107, GPIO108, GPIO109}; +static const unsigned p910_dssp3_pin2[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_dssp3_pin3[] = {GPIO114, GPIO115, GPIO116}; +static const unsigned p910_ssp0_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_CLK}; +static const unsigned p910_ssp0_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned p910_ssp0_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned p910_ssp0_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_ssp1_pin1[] = {GPIO21, GPIO22, GPIO23, GPIO24}; +static const unsigned p910_ssp1_pin2[] = {GPIO20, GPIO21, GPIO22, GPIO23, + GPIO24}; +static const unsigned p910_ssp2_pin1[] = {MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, + MMC1_CMD}; +static const unsigned p910_ssp2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned p910_ssp2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned p910_ssp2_pin4[] = {ND_IO12, ND_IO11, ND_IO10, ND_IO9}; +static const unsigned p910_gssp_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28}; +static const unsigned p910_pwm0_pin1[] = {GPIO117}; +static const unsigned p910_pwm1_pin1[] = {GPIO118}; +static const unsigned p910_pwm1_pin2[] = {GPIO51}; +static const unsigned p910_pwm2_pin1[] = {GPIO119}; +static const unsigned p910_pwm3_pin1[] = {GPIO120}; +static const unsigned p910_pwm3_pin2[] = {ND_IO8}; +static const unsigned p910_pwm3_pin3[] = {VCXO_OUT}; +static const unsigned p910_pri_jtag_pin1[] = {GPIO117, GPIO118, GPIO119, + GPIO120}; +static const unsigned p910_sec1_jtag_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_CMD, MMC1_CD}; +static const unsigned p910_sec2_jtag_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_DAT0, MMC1_CLK}; +static const unsigned p910_hsl_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42}; +static const unsigned p910_hsl_pin2[] = {GPIO61, GPIO62, GPIO63, GPIO64, + GPIO65, GPIO66}; +static const unsigned p910_hsl_pin3[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_DAT0, MMC1_CMD, MMC1_CLK}; +static const unsigned p910_w1_pin1[] = {GPIO59}; +static const unsigned p910_w1_pin2[] = {GPIO65}; +static const unsigned p910_w1_pin3[] = {GPIO106}; +static const unsigned p910_w1_pin4[] = {GPIO123}; +static const unsigned p910_kpmk_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, + GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, + GPIO14, GPIO15}; +static const unsigned p910_kpmk_pin2[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, + GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO12}; +static const unsigned p910_kpdk_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19}; +static const unsigned p910_tds_pin1[] = {GPIO55, GPIO56, GPIO57, GPIO58, + GPIO59}; +static const unsigned p910_tds_pin2[] = {GPIO55, GPIO57, GPIO58, GPIO59}; +static const unsigned p910_tb_pin1[] = {GPIO14, GPIO15, GPIO16, GPIO17}; +static const unsigned p910_tb_pin2[] = {GPIO55, GPIO56, GPIO57, GPIO58}; +static const unsigned p910_tb_pin3[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_DAT4}; +static const unsigned p910_ext_dma0_pin1[] = {GPIO72}; +static const unsigned p910_ext_dma0_pin2[] = {ND_IO15}; +static const unsigned p910_ext_dma0_pin3[] = {ND_NRE}; +static const unsigned p910_ext_dma1_pin1[] = {GPIO73}; +static const unsigned p910_ext_dma1_pin2[] = {GPIO123}; +static const unsigned p910_ext_dma1_pin3[] = {GPIO126}; +static const unsigned p910_ext_dma2_pin1[] = {GPIO74}; +static const unsigned p910_ext0_int_pin1[] = {GPIO44}; +static const unsigned p910_ext0_int_pin2[] = {ND_IO13}; +static const unsigned p910_ext1_int_pin1[] = {GPIO45}; +static const unsigned p910_ext1_int_pin2[] = {ND_IO12}; +static const unsigned p910_ext2_int_pin1[] = {GPIO46}; +static const unsigned p910_ext2_int_pin2[] = {GPIO125}; +static const unsigned p910_dac_st23_pin1[] = {GPIO32}; +static const unsigned p910_dac_st23_pin2[] = {GPIO43}; +static const unsigned p910_dac_st23_pin3[] = {GPIO52}; +static const unsigned p910_dac_st23_pin4[] = {GPIO124}; +static const unsigned p910_vcxo_out_pin1[] = {GPIO50}; +static const unsigned p910_vcxo_out_pin2[] = {VCXO_OUT}; +static const unsigned p910_vcxo_out_pin3[] = {GPIO20}; +static const unsigned p910_vcxo_req_pin1[] = {GPIO49}; +static const unsigned p910_vcxo_req_pin2[] = {GPIO125}; +static const unsigned p910_vcxo_out2_pin1[] = {GPIO86}; +static const unsigned p910_vcxo_out2_pin2[] = {ND_IO9}; +static const unsigned p910_vcxo_req2_pin1[] = {GPIO84}; +static const unsigned p910_ulpi_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78}; +static const unsigned p910_nand_pin1[] = {ND_IO15, ND_IO14, ND_IO13, ND_IO12, + ND_IO11, ND_IO10, ND_IO9, ND_IO8, ND_IO7, ND_IO6, ND_IO5, ND_IO4, + ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_NCS0, ND_NWE, ND_NRE, ND_CLE, + ND_ALE, ND_RDY0}; +static const unsigned p910_gpio0_pin1[] = {GPIO0}; +static const unsigned p910_gpio0_pin2[] = {SM_ADV}; +static const unsigned p910_gpio1_pin1[] = {GPIO1}; +static const unsigned p910_gpio1_pin2[] = {ND_RDY1}; +static const unsigned p910_gpio2_pin1[] = {GPIO2}; +static const unsigned p910_gpio2_pin2[] = {SM_ADVMUX}; +static const unsigned p910_gpio3_pin1[] = {GPIO3}; +static const unsigned p910_gpio3_pin2[] = {SM_RDY}; +static const unsigned p910_gpio20_pin1[] = {GPIO20}; +static const unsigned p910_gpio20_pin2[] = {ND_IO15}; +static const unsigned p910_gpio20_pin3[] = {MMC1_DAT6}; +static const unsigned p910_gpio21_pin1[] = {GPIO21}; +static const unsigned p910_gpio21_pin2[] = {ND_IO14}; +static const unsigned p910_gpio21_pin3[] = {MMC1_DAT5}; +static const unsigned p910_gpio22_pin1[] = {GPIO22}; +static const unsigned p910_gpio22_pin2[] = {ND_IO13}; +static const unsigned p910_gpio22_pin3[] = {MMC1_DAT4}; +static const unsigned p910_gpio23_pin1[] = {GPIO23}; +static const unsigned p910_gpio23_pin2[] = {ND_IO12}; +static const unsigned p910_gpio23_pin3[] = {MMC1_CD}; +static const unsigned p910_gpio24_pin1[] = {GPIO24}; +static const unsigned p910_gpio24_pin2[] = {ND_IO11}; +static const unsigned p910_gpio24_pin3[] = {MMC1_DAT7}; +static const unsigned p910_gpio25_pin1[] = {GPIO25}; +static const unsigned p910_gpio25_pin2[] = {ND_IO10}; +static const unsigned p910_gpio26_pin1[] = {GPIO26}; +static const unsigned p910_gpio26_pin2[] = {ND_IO9}; +static const unsigned p910_gpio27_pin1[] = {GPIO27}; +static const unsigned p910_gpio27_pin2[] = {ND_IO8}; +static const unsigned p910_gpio85_pin1[] = {GPIO85}; +static const unsigned p910_gpio85_pin2[] = {ND_NCS0}; +static const unsigned p910_gpio86_pin1[] = {GPIO86}; +static const unsigned p910_gpio86_pin2[] = {ND_NCS1}; +static const unsigned p910_gpio87_pin1[] = {GPIO87}; +static const unsigned p910_gpio87_pin2[] = {SM_NCS0}; +static const unsigned p910_gpio88_pin1[] = {GPIO88}; +static const unsigned p910_gpio88_pin2[] = {SM_NCS1}; +static const unsigned p910_gpio89_pin1[] = {GPIO89}; +static const unsigned p910_gpio89_pin2[] = {ND_NWE}; +static const unsigned p910_gpio90_pin1[] = {GPIO90}; +static const unsigned p910_gpio90_pin2[] = {ND_NRE}; +static const unsigned p910_gpio91_pin1[] = {GPIO91}; +static const unsigned p910_gpio91_pin2[] = {ND_ALE}; +static const unsigned p910_gpio92_pin1[] = {GPIO92}; +static const unsigned p910_gpio92_pin2[] = {ND_RDY0}; + +static struct pxa3xx_pin_group pxa910_grps[] = { + GRP_910("usim2 3p1", USIM2, p910_usim2_pin1), + GRP_910("usim2 3p2", USIM2, p910_usim2_pin2), + GRP_910("mmc1 12p", MMC1, p910_mmc1_pin1), + GRP_910("mmc2 10p", MMC2, p910_mmc2_pin1), + GRP_910("mmc3 6p", MMC3, p910_mmc3_pin1), + GRP_910("mmc3 10p", MMC3, p910_mmc3_pin2), + GRP_910("uart0 4p", UART0, p910_uart0_pin1), + GRP_910("uart1 2p1", UART1, p910_uart1_pin1), + GRP_910("uart1 2p2", UART1, p910_uart1_pin2), + GRP_910("uart1 2p3", UART1, p910_uart1_pin3), + GRP_910("uart1 4p4", UART1, p910_uart1_pin4), + GRP_910("uart1 4p5", UART1, p910_uart1_pin5), + GRP_910("uart2 2p1", UART2, p910_uart2_pin1), + GRP_910("uart2 2p2", UART2, p910_uart2_pin2), + GRP_910("uart2 4p3", UART2, p910_uart2_pin3), + GRP_910("uart2 4p4", UART2, p910_uart2_pin4), + GRP_910("twsi 2p1", TWSI, p910_twsi_pin1), + GRP_910("twsi 2p2", TWSI, p910_twsi_pin2), + GRP_910("twsi 2p3", TWSI, p910_twsi_pin3), + GRP_910("ccic", CCIC, p910_ccic_pin1), + GRP_910("lcd", LCD, p910_lcd_pin1), + GRP_910("spi 4p1", SPI, p910_spi_pin1), + GRP_910("spi 4p2", SPI, p910_spi_pin2), + GRP_910("spi 5p3", SPI, p910_spi_pin3), + GRP_910("spi 5p4", SPI, p910_spi_pin4), + GRP_910("dssp2 4p1", DSSP2, p910_dssp2_pin1), + GRP_910("dssp2 4p2", DSSP2, p910_dssp2_pin2), + GRP_910("dssp2 3p3", DSSP2, p910_dssp2_pin3), + GRP_910("dssp3 4p1", DSSP3, p910_dssp3_pin1), + GRP_910("dssp3 4p2", DSSP3, p910_dssp3_pin2), + GRP_910("dssp3 3p3", DSSP3, p910_dssp3_pin3), + GRP_910("ssp0 4p1", SSP0, p910_ssp0_pin1), + GRP_910("ssp0 4p2", SSP0, p910_ssp0_pin2), + GRP_910("ssp0 4p3", SSP0, p910_ssp0_pin3), + GRP_910("ssp0 4p4", SSP0, p910_ssp0_pin4), + GRP_910("ssp1 4p1", SSP1, p910_ssp1_pin1), + GRP_910("ssp1 5p2", SSP1, p910_ssp1_pin2), + GRP_910("ssp2 4p1", SSP2, p910_ssp2_pin1), + GRP_910("ssp2 4p2", SSP2, p910_ssp2_pin2), + GRP_910("ssp2 4p3", SSP2, p910_ssp2_pin3), + GRP_910("ssp2 4p4", SSP2, p910_ssp2_pin4), + GRP_910("gssp", GSSP, p910_gssp_pin1), + GRP_910("pwm0", PWM0, p910_pwm0_pin1), + GRP_910("pwm1-1", PWM1, p910_pwm1_pin1), + GRP_910("pwm1-2", PWM1, p910_pwm1_pin2), + GRP_910("pwm2", PWM2, p910_pwm2_pin1), + GRP_910("pwm3-1", PWM3, p910_pwm3_pin1), + GRP_910("pwm3-2", PWM3, p910_pwm3_pin2), + GRP_910("pwm3-3", PWM3, p910_pwm3_pin3), + GRP_910("pri jtag", PRI_JTAG, p910_pri_jtag_pin1), + GRP_910("sec1 jtag", SEC1_JTAG, p910_sec1_jtag_pin1), + GRP_910("sec2 jtag", SEC2_JTAG, p910_sec2_jtag_pin1), + GRP_910("hsl 6p1", HSL, p910_hsl_pin1), + GRP_910("hsl 6p2", HSL, p910_hsl_pin2), + GRP_910("hsl 6p3", HSL, p910_hsl_pin3), + GRP_910("w1-1", ONE_WIRE, p910_w1_pin1), + GRP_910("w1-2", ONE_WIRE, p910_w1_pin2), + GRP_910("w1-3", ONE_WIRE, p910_w1_pin3), + GRP_910("w1-4", ONE_WIRE, p910_w1_pin4), + GRP_910("kpmk 16p1", KP_MK, p910_kpmk_pin1), + GRP_910("kpmk 11p2", KP_MK, p910_kpmk_pin2), + GRP_910("kpdk 8p1", KP_DK, p910_kpdk_pin1), + GRP_910("tds 5p1", TDS, p910_tds_pin1), + GRP_910("tds 4p2", TDS, p910_tds_pin2), + GRP_910("tb 4p1", TB, p910_tb_pin1), + GRP_910("tb 4p2", TB, p910_tb_pin2), + GRP_910("tb 4p3", TB, p910_tb_pin3), + GRP_910("ext dma0-1", EXT_DMA, p910_ext_dma0_pin1), + GRP_910("ext dma0-2", EXT_DMA, p910_ext_dma0_pin2), + GRP_910("ext dma0-3", EXT_DMA, p910_ext_dma0_pin3), + GRP_910("ext dma1-1", EXT_DMA, p910_ext_dma1_pin1), + GRP_910("ext dma1-2", EXT_DMA, p910_ext_dma1_pin2), + GRP_910("ext dma1-3", EXT_DMA, p910_ext_dma1_pin3), + GRP_910("ext dma2", EXT_DMA, p910_ext_dma2_pin1), + GRP_910("ext0 int-1", EXT_INT, p910_ext0_int_pin1), + GRP_910("ext0 int-2", EXT_INT, p910_ext0_int_pin2), + GRP_910("ext1 int-1", EXT_INT, p910_ext1_int_pin1), + GRP_910("ext1 int-2", EXT_INT, p910_ext1_int_pin2), + GRP_910("ext2 int-1", EXT_INT, p910_ext2_int_pin1), + GRP_910("ext2 int-2", EXT_INT, p910_ext2_int_pin2), + GRP_910("dac st23-1", DAC_ST23, p910_dac_st23_pin1), + GRP_910("dac st23-2", DAC_ST23, p910_dac_st23_pin2), + GRP_910("dac st23-3", DAC_ST23, p910_dac_st23_pin3), + GRP_910("dac st23-4", DAC_ST23, p910_dac_st23_pin4), + GRP_910("vcxo out-1", VCXO_OUT, p910_vcxo_out_pin1), + GRP_910("vcxo out-2", VCXO_OUT, p910_vcxo_out_pin2), + GRP_910("vcxo out-3", VCXO_OUT, p910_vcxo_out_pin3), + GRP_910("vcxo req-1", VCXO_REQ, p910_vcxo_req_pin1), + GRP_910("vcxo req-2", VCXO_REQ, p910_vcxo_req_pin2), + GRP_910("vcxo out2-1", VCXO_OUT2, p910_vcxo_out2_pin1), + GRP_910("vcxo out2-2", VCXO_OUT2, p910_vcxo_out2_pin2), + GRP_910("vcxo req2", VCXO_REQ2, p910_vcxo_req2_pin1), + GRP_910("ulpi", ULPI, p910_ulpi_pin1), + GRP_910("nand", NAND, p910_nand_pin1), + GRP_910("gpio0-1", GPIO, p910_gpio0_pin1), + GRP_910("gpio0-2", GPIO, p910_gpio0_pin2), + GRP_910("gpio1-1", GPIO, p910_gpio1_pin1), + GRP_910("gpio1-2", GPIO, p910_gpio1_pin2), + GRP_910("gpio2-1", GPIO, p910_gpio2_pin1), + GRP_910("gpio2-2", GPIO, p910_gpio2_pin2), + GRP_910("gpio3-1", GPIO, p910_gpio3_pin1), + GRP_910("gpio3-2", GPIO, p910_gpio3_pin2), + GRP_910("gpio20-1", GPIO, p910_gpio20_pin1), + GRP_910("gpio20-2", GPIO, p910_gpio20_pin2), + GRP_910("gpio21-1", GPIO, p910_gpio21_pin1), + GRP_910("gpio21-2", GPIO, p910_gpio21_pin2), + GRP_910("gpio22-1", GPIO, p910_gpio22_pin1), + GRP_910("gpio22-2", GPIO, p910_gpio22_pin2), + GRP_910("gpio23-1", GPIO, p910_gpio23_pin1), + GRP_910("gpio23-2", GPIO, p910_gpio23_pin2), + GRP_910("gpio24-1", GPIO, p910_gpio24_pin1), + GRP_910("gpio24-2", GPIO, p910_gpio24_pin2), + GRP_910("gpio25-1", GPIO, p910_gpio25_pin1), + GRP_910("gpio25-2", GPIO, p910_gpio25_pin2), + GRP_910("gpio26-1", GPIO, p910_gpio26_pin1), + GRP_910("gpio26-2", GPIO, p910_gpio26_pin2), + GRP_910("gpio27-1", GPIO, p910_gpio27_pin1), + GRP_910("gpio27-2", GPIO, p910_gpio27_pin2), + GRP_910("gpio85-1", GPIO, p910_gpio85_pin1), + GRP_910("gpio85-2", GPIO, p910_gpio85_pin2), + GRP_910("gpio86-1", GPIO, p910_gpio86_pin1), + GRP_910("gpio86-2", GPIO, p910_gpio86_pin2), + GRP_910("gpio87-1", GPIO, p910_gpio87_pin1), + GRP_910("gpio87-2", GPIO, p910_gpio87_pin2), + GRP_910("gpio88-1", GPIO, p910_gpio88_pin1), + GRP_910("gpio88-2", GPIO, p910_gpio88_pin2), + GRP_910("gpio89-1", GPIO, p910_gpio89_pin1), + GRP_910("gpio89-2", GPIO, p910_gpio89_pin2), + GRP_910("gpio90-1", GPIO, p910_gpio90_pin1), + GRP_910("gpio90-2", GPIO, p910_gpio90_pin2), + GRP_910("gpio91-1", GPIO, p910_gpio91_pin1), + GRP_910("gpio91-2", GPIO, p910_gpio91_pin2), + GRP_910("gpio92-1", GPIO, p910_gpio92_pin1), + GRP_910("gpio92-2", GPIO, p910_gpio92_pin2), +}; + +static const char * const p910_usim2_grps[] = {"usim2 3p1", "usim2 3p2"}; +static const char * const p910_mmc1_grps[] = {"mmc1 12p"}; +static const char * const p910_mmc2_grps[] = {"mmc2 10p"}; +static const char * const p910_mmc3_grps[] = {"mmc3 6p", "mmc3 10p"}; +static const char * const p910_uart0_grps[] = {"uart0 4p"}; +static const char * const p910_uart1_grps[] = {"uart1 2p1", "uart1 2p2", + "uart1 2p3", "uart1 4p4", "uart1 4p5"}; +static const char * const p910_uart2_grps[] = {"uart2 2p1", "uart2 2p2", + "uart2 4p3", "uart2 4p4"}; +static const char * const p910_twsi_grps[] = {"twsi 2p1", "twsi 2p2", + "twsi 2p3"}; +static const char * const p910_ccic_grps[] = {"ccic"}; +static const char * const p910_lcd_grps[] = {"lcd"}; +static const char * const p910_spi_grps[] = {"spi 4p1", "spi 4p2", "spi 5p3", + "spi 5p4"}; +static const char * const p910_dssp2_grps[] = {"dssp2 4p1", "dssp2 4p2", + "dssp2 3p3"}; +static const char * const p910_dssp3_grps[] = {"dssp3 4p1", "dssp3 4p2", + "dssp3 3p3"}; +static const char * const p910_ssp0_grps[] = {"ssp0 4p1", "ssp0 4p2", + "ssp0 4p3", "ssp0 4p4"}; +static const char * const p910_ssp1_grps[] = {"ssp1 4p1", "ssp1 5p2"}; +static const char * const p910_ssp2_grps[] = {"ssp2 4p1", "ssp2 4p2", + "ssp2 4p3", "ssp2 4p4"}; +static const char * const p910_gssp_grps[] = {"gssp"}; +static const char * const p910_pwm0_grps[] = {"pwm0"}; +static const char * const p910_pwm1_grps[] = {"pwm1-1", "pwm1-2"}; +static const char * const p910_pwm2_grps[] = {"pwm2"}; +static const char * const p910_pwm3_grps[] = {"pwm3-1", "pwm3-2", "pwm3-3"}; +static const char * const p910_pri_jtag_grps[] = {"pri jtag"}; +static const char * const p910_sec1_jtag_grps[] = {"sec1 jtag"}; +static const char * const p910_sec2_jtag_grps[] = {"sec2 jtag"}; +static const char * const p910_hsl_grps[] = {"hsl 6p1", "hsl 6p2", "hsl 6p3"}; +static const char * const p910_w1_grps[] = {"w1-1", "w1-2", "w1-3", "w1-4"}; +static const char * const p910_kpmk_grps[] = {"kpmk 16p1", "kpmk 11p2"}; +static const char * const p910_kpdk_grps[] = {"kpdk 8p1"}; +static const char * const p910_tds_grps[] = {"tds 5p1", "tds 4p2"}; +static const char * const p910_tb_grps[] = {"tb 4p1", "tb 4p2", "tb 4p3"}; +static const char * const p910_dma0_grps[] = {"ext dma0-1", "ext dma0-2", + "ext dma0-3"}; +static const char * const p910_dma1_grps[] = {"ext dma1-1", "ext dma1-2", + "ext dma1-3"}; +static const char * const p910_dma2_grps[] = {"ext dma2"}; +static const char * const p910_int0_grps[] = {"ext0 int-1", "ext0 int-2"}; +static const char * const p910_int1_grps[] = {"ext1 int-1", "ext1 int-2"}; +static const char * const p910_int2_grps[] = {"ext2 int-1", "ext2 int-2"}; +static const char * const p910_dac_st23_grps[] = {"dac st23-1", "dac st23-2", + "dac st23-3", "dac st23-4"}; +static const char * const p910_vcxo_out_grps[] = {"vcxo out-1", "vcxo out-2", + "vcxo out-3"}; +static const char * const p910_vcxo_req_grps[] = {"vcxo req-1", "vcxo req-2"}; +static const char * const p910_vcxo_out2_grps[] = {"vcxo out2-1", + "vcxo out2-2"}; +static const char * const p910_vcxo_req2_grps[] = {"vcxo req2"}; +static const char * const p910_ulpi_grps[] = {"ulpi"}; +static const char * const p910_nand_grps[] = {"nand"}; +static const char * const p910_gpio0_grps[] = {"gpio0-1", "gpio0-2"}; +static const char * const p910_gpio1_grps[] = {"gpio1-1", "gpio1-2"}; +static const char * const p910_gpio2_grps[] = {"gpio2-1", "gpio2-2"}; +static const char * const p910_gpio3_grps[] = {"gpio3-1", "gpio3-2"}; +static const char * const p910_gpio20_grps[] = {"gpio20-1", "gpio20-2"}; +static const char * const p910_gpio21_grps[] = {"gpio21-1", "gpio21-2"}; +static const char * const p910_gpio22_grps[] = {"gpio22-1", "gpio22-2"}; +static const char * const p910_gpio23_grps[] = {"gpio23-1", "gpio23-2"}; +static const char * const p910_gpio24_grps[] = {"gpio24-1", "gpio24-2"}; +static const char * const p910_gpio25_grps[] = {"gpio25-1", "gpio25-2"}; +static const char * const p910_gpio26_grps[] = {"gpio26-1", "gpio26-2"}; +static const char * const p910_gpio27_grps[] = {"gpio27-1", "gpio27-2"}; +static const char * const p910_gpio85_grps[] = {"gpio85-1", "gpio85-2"}; +static const char * const p910_gpio86_grps[] = {"gpio86-1", "gpio86-2"}; +static const char * const p910_gpio87_grps[] = {"gpio87-1", "gpio87-2"}; +static const char * const p910_gpio88_grps[] = {"gpio88-1", "gpio88-2"}; +static const char * const p910_gpio89_grps[] = {"gpio89-1", "gpio89-2"}; +static const char * const p910_gpio90_grps[] = {"gpio90-1", "gpio90-2"}; +static const char * const p910_gpio91_grps[] = {"gpio91-1", "gpio91-2"}; +static const char * const p910_gpio92_grps[] = {"gpio92-1", "gpio92-2"}; + +static struct pxa3xx_pmx_func pxa910_funcs[] = { + {"usim2", ARRAY_AND_SIZE(p910_usim2_grps)}, + {"mmc1", ARRAY_AND_SIZE(p910_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(p910_mmc2_grps)}, + {"mmc3", ARRAY_AND_SIZE(p910_mmc3_grps)}, + {"uart0", ARRAY_AND_SIZE(p910_uart0_grps)}, + {"uart1", ARRAY_AND_SIZE(p910_uart1_grps)}, + {"uart2", ARRAY_AND_SIZE(p910_uart2_grps)}, + {"twsi", ARRAY_AND_SIZE(p910_twsi_grps)}, + {"ccic", ARRAY_AND_SIZE(p910_ccic_grps)}, + {"lcd", ARRAY_AND_SIZE(p910_lcd_grps)}, + {"spi", ARRAY_AND_SIZE(p910_spi_grps)}, + {"dssp2", ARRAY_AND_SIZE(p910_dssp2_grps)}, + {"dssp3", ARRAY_AND_SIZE(p910_dssp3_grps)}, + {"ssp0", ARRAY_AND_SIZE(p910_ssp0_grps)}, + {"ssp1", ARRAY_AND_SIZE(p910_ssp1_grps)}, + {"ssp2", ARRAY_AND_SIZE(p910_ssp2_grps)}, + {"gssp", ARRAY_AND_SIZE(p910_gssp_grps)}, + {"pwm0", ARRAY_AND_SIZE(p910_pwm0_grps)}, + {"pwm1", ARRAY_AND_SIZE(p910_pwm1_grps)}, + {"pwm2", ARRAY_AND_SIZE(p910_pwm2_grps)}, + {"pwm3", ARRAY_AND_SIZE(p910_pwm3_grps)}, + {"pri_jtag", ARRAY_AND_SIZE(p910_pri_jtag_grps)}, + {"sec1_jtag", ARRAY_AND_SIZE(p910_sec1_jtag_grps)}, + {"sec2_jtag", ARRAY_AND_SIZE(p910_sec2_jtag_grps)}, + {"hsl", ARRAY_AND_SIZE(p910_hsl_grps)}, + {"w1", ARRAY_AND_SIZE(p910_w1_grps)}, + {"kpmk", ARRAY_AND_SIZE(p910_kpmk_grps)}, + {"kpdk", ARRAY_AND_SIZE(p910_kpdk_grps)}, + {"tds", ARRAY_AND_SIZE(p910_tds_grps)}, + {"tb", ARRAY_AND_SIZE(p910_tb_grps)}, + {"dma0", ARRAY_AND_SIZE(p910_dma0_grps)}, + {"dma1", ARRAY_AND_SIZE(p910_dma1_grps)}, + {"dma2", ARRAY_AND_SIZE(p910_dma2_grps)}, + {"int0", ARRAY_AND_SIZE(p910_int0_grps)}, + {"int1", ARRAY_AND_SIZE(p910_int1_grps)}, + {"int2", ARRAY_AND_SIZE(p910_int2_grps)}, + {"dac_st23", ARRAY_AND_SIZE(p910_dac_st23_grps)}, + {"vcxo_out", ARRAY_AND_SIZE(p910_vcxo_out_grps)}, + {"vcxo_req", ARRAY_AND_SIZE(p910_vcxo_req_grps)}, + {"vcxo_out2", ARRAY_AND_SIZE(p910_vcxo_out2_grps)}, + {"vcxo_req2", ARRAY_AND_SIZE(p910_vcxo_req2_grps)}, + {"ulpi", ARRAY_AND_SIZE(p910_ulpi_grps)}, + {"nand", ARRAY_AND_SIZE(p910_nand_grps)}, + {"gpio0", ARRAY_AND_SIZE(p910_gpio0_grps)}, + {"gpio1", ARRAY_AND_SIZE(p910_gpio1_grps)}, + {"gpio2", ARRAY_AND_SIZE(p910_gpio2_grps)}, + {"gpio3", ARRAY_AND_SIZE(p910_gpio3_grps)}, + {"gpio20", ARRAY_AND_SIZE(p910_gpio20_grps)}, + {"gpio21", ARRAY_AND_SIZE(p910_gpio21_grps)}, + {"gpio22", ARRAY_AND_SIZE(p910_gpio22_grps)}, + {"gpio23", ARRAY_AND_SIZE(p910_gpio23_grps)}, + {"gpio24", ARRAY_AND_SIZE(p910_gpio24_grps)}, + {"gpio25", ARRAY_AND_SIZE(p910_gpio25_grps)}, + {"gpio26", ARRAY_AND_SIZE(p910_gpio26_grps)}, + {"gpio27", ARRAY_AND_SIZE(p910_gpio27_grps)}, + {"gpio85", ARRAY_AND_SIZE(p910_gpio85_grps)}, + {"gpio86", ARRAY_AND_SIZE(p910_gpio86_grps)}, + {"gpio87", ARRAY_AND_SIZE(p910_gpio87_grps)}, + {"gpio88", ARRAY_AND_SIZE(p910_gpio88_grps)}, + {"gpio89", ARRAY_AND_SIZE(p910_gpio89_grps)}, + {"gpio90", ARRAY_AND_SIZE(p910_gpio90_grps)}, + {"gpio91", ARRAY_AND_SIZE(p910_gpio91_grps)}, + {"gpio92", ARRAY_AND_SIZE(p910_gpio92_grps)}, +}; + +static struct pinctrl_desc pxa910_pctrl_desc = { + .name = "pxa910-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info pxa910_info = { + .mfp = pxa910_mfp, + .num_mfp = ARRAY_SIZE(pxa910_mfp), + .grps = pxa910_grps, + .num_grps = ARRAY_SIZE(pxa910_grps), + .funcs = pxa910_funcs, + .num_funcs = ARRAY_SIZE(pxa910_funcs), + .num_gpio = 128, + .desc = &pxa910_pctrl_desc, + .pads = pxa910_pads, + .num_pads = ARRAY_SIZE(pxa910_pads), + + .cputype = PINCTRL_PXA910, + .ds_mask = PXA910_DS_MASK, + .ds_shift = PXA910_DS_SHIFT, +}; + +static int pxa910_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &pxa910_info); +} + +static int pxa910_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver pxa910_pinmux_driver = { + .driver = { + .name = "pxa910-pinmux", + .owner = THIS_MODULE, + }, + .probe = pxa910_pinmux_probe, + .remove = pxa910_pinmux_remove, +}; + +static int __init pxa910_pinmux_init(void) +{ + return platform_driver_register(&pxa910_pinmux_driver); +} +core_initcall_sync(pxa910_pinmux_init); + +static void __exit pxa910_pinmux_exit(void) +{ + platform_driver_unregister(&pxa910_pinmux_driver); +} +module_exit(pxa910_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-s3c64xx.c b/trunk/drivers/pinctrl/pinctrl-s3c64xx.c deleted file mode 100644 index 89143c903000..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-s3c64xx.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * S3C64xx specific support for pinctrl-samsung driver. - * - * Copyright (c) 2013 Tomasz Figa - * - * Based on pinctrl-exynos.c, please see the file for original copyrights. - * - * 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 file contains the Samsung S3C64xx specific information required by the - * the Samsung pinctrl/gpiolib driver. It also includes the implementation of - * external gpio and wakeup interrupt support. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-samsung.h" - -#define NUM_EINT0 28 -#define NUM_EINT0_IRQ 4 -#define EINT_MAX_PER_REG 16 -#define EINT_MAX_PER_GROUP 16 - -/* External GPIO and wakeup interrupt related definitions */ -#define SVC_GROUP_SHIFT 4 -#define SVC_GROUP_MASK 0xf -#define SVC_NUM_MASK 0xf -#define SVC_GROUP(x) ((x >> SVC_GROUP_SHIFT) & \ - SVC_GROUP_MASK) - -#define EINT12CON_REG 0x200 -#define EINT12MASK_REG 0x240 -#define EINT12PEND_REG 0x260 - -#define EINT_OFFS(i) ((i) % (2 * EINT_MAX_PER_GROUP)) -#define EINT_GROUP(i) ((i) / EINT_MAX_PER_GROUP) -#define EINT_REG(g) (4 * ((g) / 2)) - -#define EINTCON_REG(i) (EINT12CON_REG + EINT_REG(EINT_GROUP(i))) -#define EINTMASK_REG(i) (EINT12MASK_REG + EINT_REG(EINT_GROUP(i))) -#define EINTPEND_REG(i) (EINT12PEND_REG + EINT_REG(EINT_GROUP(i))) - -#define SERVICE_REG 0x284 -#define SERVICEPEND_REG 0x288 - -#define EINT0CON0_REG 0x900 -#define EINT0MASK_REG 0x920 -#define EINT0PEND_REG 0x924 - -/* S3C64xx specific external interrupt trigger types */ -#define EINT_LEVEL_LOW 0 -#define EINT_LEVEL_HIGH 1 -#define EINT_EDGE_FALLING 2 -#define EINT_EDGE_RISING 4 -#define EINT_EDGE_BOTH 6 -#define EINT_CON_MASK 0xF -#define EINT_CON_LEN 4 - -static struct samsung_pin_bank_type bank_type_4bit_off = { - .fld_width = { 4, 1, 2, 0, 2, 2, }, - .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, }, -}; - -static struct samsung_pin_bank_type bank_type_4bit_alive = { - .fld_width = { 4, 1, 2, }, - .reg_offset = { 0x00, 0x04, 0x08, }, -}; - -static struct samsung_pin_bank_type bank_type_4bit2_off = { - .fld_width = { 4, 1, 2, 0, 2, 2, }, - .reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, }, -}; - -static struct samsung_pin_bank_type bank_type_4bit2_alive = { - .fld_width = { 4, 1, 2, }, - .reg_offset = { 0x00, 0x08, 0x0c, }, -}; - -static struct samsung_pin_bank_type bank_type_2bit_off = { - .fld_width = { 2, 1, 2, 0, 2, 2, }, - .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, }, -}; - -static struct samsung_pin_bank_type bank_type_2bit_alive = { - .fld_width = { 2, 1, 2, }, - .reg_offset = { 0x00, 0x04, 0x08, }, -}; - -#define PIN_BANK_4BIT(pins, reg, id) \ - { \ - .type = &bank_type_4bit_off, \ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_NONE, \ - .name = id \ - } - -#define PIN_BANK_4BIT_EINTG(pins, reg, id, eoffs) \ - { \ - .type = &bank_type_4bit_off, \ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_GPIO, \ - .eint_func = 7, \ - .eint_mask = (1 << (pins)) - 1, \ - .eint_offset = eoffs, \ - .name = id \ - } - -#define PIN_BANK_4BIT_EINTW(pins, reg, id, eoffs, emask) \ - { \ - .type = &bank_type_4bit_alive,\ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_WKUP, \ - .eint_func = 3, \ - .eint_mask = emask, \ - .eint_offset = eoffs, \ - .name = id \ - } - -#define PIN_BANK_4BIT2_EINTG(pins, reg, id, eoffs) \ - { \ - .type = &bank_type_4bit2_off, \ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_GPIO, \ - .eint_func = 7, \ - .eint_mask = (1 << (pins)) - 1, \ - .eint_offset = eoffs, \ - .name = id \ - } - -#define PIN_BANK_4BIT2_EINTW(pins, reg, id, eoffs, emask) \ - { \ - .type = &bank_type_4bit2_alive,\ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_WKUP, \ - .eint_func = 3, \ - .eint_mask = emask, \ - .eint_offset = eoffs, \ - .name = id \ - } - -#define PIN_BANK_4BIT2_ALIVE(pins, reg, id) \ - { \ - .type = &bank_type_4bit2_alive,\ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_NONE, \ - .name = id \ - } - -#define PIN_BANK_2BIT(pins, reg, id) \ - { \ - .type = &bank_type_2bit_off, \ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_NONE, \ - .name = id \ - } - -#define PIN_BANK_2BIT_EINTG(pins, reg, id, eoffs, emask) \ - { \ - .type = &bank_type_2bit_off, \ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_GPIO, \ - .eint_func = 3, \ - .eint_mask = emask, \ - .eint_offset = eoffs, \ - .name = id \ - } - -#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs) \ - { \ - .type = &bank_type_2bit_alive,\ - .pctl_offset = reg, \ - .nr_pins = pins, \ - .eint_type = EINT_TYPE_WKUP, \ - .eint_func = 2, \ - .eint_mask = (1 << (pins)) - 1, \ - .eint_offset = eoffs, \ - .name = id \ - } - -/** - * struct s3c64xx_eint0_data: EINT0 common data - * @drvdata: pin controller driver data - * @domains: IRQ domains of particular EINT0 interrupts - * @pins: pin offsets inside of banks of particular EINT0 interrupts - */ -struct s3c64xx_eint0_data { - struct samsung_pinctrl_drv_data *drvdata; - struct irq_domain *domains[NUM_EINT0]; - u8 pins[NUM_EINT0]; -}; - -/** - * struct s3c64xx_eint0_domain_data: EINT0 per-domain data - * @bank: pin bank related to the domain - * @eints: EINT0 interrupts related to the domain - */ -struct s3c64xx_eint0_domain_data { - struct samsung_pin_bank *bank; - u8 eints[]; -}; - -/** - * struct s3c64xx_eint_gpio_data: GPIO EINT data - * @drvdata: pin controller driver data - * @domains: array of domains related to EINT interrupt groups - */ -struct s3c64xx_eint_gpio_data { - struct samsung_pinctrl_drv_data *drvdata; - struct irq_domain *domains[]; -}; - -/* - * Common functions for S3C64xx EINT configuration - */ - -static int s3c64xx_irq_get_trigger(unsigned int type) -{ - int trigger; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - trigger = EINT_EDGE_RISING; - break; - case IRQ_TYPE_EDGE_FALLING: - trigger = EINT_EDGE_FALLING; - break; - case IRQ_TYPE_EDGE_BOTH: - trigger = EINT_EDGE_BOTH; - break; - case IRQ_TYPE_LEVEL_HIGH: - trigger = EINT_LEVEL_HIGH; - break; - case IRQ_TYPE_LEVEL_LOW: - trigger = EINT_LEVEL_LOW; - break; - default: - return -EINVAL; - } - - return trigger; -} - -static void s3c64xx_irq_set_handler(unsigned int irq, unsigned int type) -{ - /* Edge- and level-triggered interrupts need different handlers */ - if (type & IRQ_TYPE_EDGE_BOTH) - __irq_set_handler_locked(irq, handle_edge_irq); - else - __irq_set_handler_locked(irq, handle_level_irq); -} - -static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, - struct samsung_pin_bank *bank, int pin) -{ - struct samsung_pin_bank_type *bank_type = bank->type; - unsigned long flags; - void __iomem *reg; - u8 shift; - u32 mask; - u32 val; - - /* Make sure that pin is configured as interrupt */ - reg = d->virt_base + bank->pctl_offset; - shift = pin; - if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) { - /* 4-bit bank type with 2 con regs */ - reg += 4; - shift -= 8; - } - - shift = shift * bank_type->fld_width[PINCFG_TYPE_FUNC]; - mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; - - spin_lock_irqsave(&bank->slock, flags); - - val = readl(reg); - val &= ~(mask << shift); - val |= bank->eint_func << shift; - writel(val, reg); - - spin_unlock_irqrestore(&bank->slock, flags); -} - -/* - * Functions for EINT GPIO configuration (EINT groups 1-9) - */ - -static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask) -{ - struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; - unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; - void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset); - u32 val; - - val = readl(reg); - if (mask) - val |= 1 << index; - else - val &= ~(1 << index); - writel(val, reg); -} - -static void s3c64xx_gpio_irq_unmask(struct irq_data *irqd) -{ - s3c64xx_gpio_irq_set_mask(irqd, false); -} - -static void s3c64xx_gpio_irq_mask(struct irq_data *irqd) -{ - s3c64xx_gpio_irq_set_mask(irqd, true); -} - -static void s3c64xx_gpio_irq_ack(struct irq_data *irqd) -{ - struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; - unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; - void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset); - - writel(1 << index, reg); -} - -static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) -{ - struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; - void __iomem *reg; - int trigger; - u8 shift; - u32 val; - - trigger = s3c64xx_irq_get_trigger(type); - if (trigger < 0) { - pr_err("unsupported external interrupt type\n"); - return -EINVAL; - } - - s3c64xx_irq_set_handler(irqd->irq, type); - - /* Set up interrupt trigger */ - reg = d->virt_base + EINTCON_REG(bank->eint_offset); - shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq; - shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */ - - val = readl(reg); - val &= ~(EINT_CON_MASK << shift); - val |= trigger << shift; - writel(val, reg); - - s3c64xx_irq_set_function(d, bank, irqd->hwirq); - - return 0; -} - -/* - * irq_chip for gpio interrupts. - */ -static struct irq_chip s3c64xx_gpio_irq_chip = { - .name = "GPIO", - .irq_unmask = s3c64xx_gpio_irq_unmask, - .irq_mask = s3c64xx_gpio_irq_mask, - .irq_ack = s3c64xx_gpio_irq_ack, - .irq_set_type = s3c64xx_gpio_irq_set_type, -}; - -static int s3c64xx_gpio_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct samsung_pin_bank *bank = h->host_data; - - if (!(bank->eint_mask & (1 << hw))) - return -EINVAL; - - irq_set_chip_and_handler(virq, - &s3c64xx_gpio_irq_chip, handle_level_irq); - irq_set_chip_data(virq, bank); - set_irq_flags(virq, IRQF_VALID); - - return 0; -} - -/* - * irq domain callbacks for external gpio interrupt controller. - */ -static const struct irq_domain_ops s3c64xx_gpio_irqd_ops = { - .map = s3c64xx_gpio_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - -static void s3c64xx_eint_gpio_irq(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_get_chip(irq); - struct s3c64xx_eint_gpio_data *data = irq_get_handler_data(irq); - struct samsung_pinctrl_drv_data *drvdata = data->drvdata; - - chained_irq_enter(chip, desc); - - do { - unsigned int svc; - unsigned int group; - unsigned int pin; - unsigned int virq; - - svc = readl(drvdata->virt_base + SERVICE_REG); - group = SVC_GROUP(svc); - pin = svc & SVC_NUM_MASK; - - if (!group) - break; - - /* Group 1 is used for two pin banks */ - if (group == 1) { - if (pin < 8) - group = 0; - else - pin -= 8; - } - - virq = irq_linear_revmap(data->domains[group], pin); - /* - * Something must be really wrong if an unmapped EINT - * was unmasked... - */ - BUG_ON(!virq); - - generic_handle_irq(virq); - } while (1); - - chained_irq_exit(chip, desc); -} - -/** - * s3c64xx_eint_gpio_init() - setup handling of external gpio interrupts. - * @d: driver data of samsung pinctrl driver. - */ -static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d) -{ - struct s3c64xx_eint_gpio_data *data; - struct samsung_pin_bank *bank; - struct device *dev = d->dev; - unsigned int nr_domains; - unsigned int i; - - if (!d->irq) { - dev_err(dev, "irq number not available\n"); - return -EINVAL; - } - - nr_domains = 0; - bank = d->ctrl->pin_banks; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { - unsigned int nr_eints; - unsigned int mask; - - if (bank->eint_type != EINT_TYPE_GPIO) - continue; - - mask = bank->eint_mask; - nr_eints = fls(mask); - - bank->irq_domain = irq_domain_add_linear(bank->of_node, - nr_eints, &s3c64xx_gpio_irqd_ops, bank); - if (!bank->irq_domain) { - dev_err(dev, "gpio irq domain add failed\n"); - return -ENXIO; - } - - ++nr_domains; - } - - data = devm_kzalloc(dev, sizeof(*data) - + nr_domains * sizeof(*data->domains), GFP_KERNEL); - if (!data) { - dev_err(dev, "failed to allocate handler data\n"); - return -ENOMEM; - } - data->drvdata = d; - - bank = d->ctrl->pin_banks; - nr_domains = 0; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { - if (bank->eint_type != EINT_TYPE_GPIO) - continue; - - data->domains[nr_domains++] = bank->irq_domain; - } - - irq_set_chained_handler(d->irq, s3c64xx_eint_gpio_irq); - irq_set_handler_data(d->irq, data); - - return 0; -} - -/* - * Functions for configuration of EINT0 wake-up interrupts - */ - -static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask) -{ - struct s3c64xx_eint0_domain_data *ddata = - irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; - u32 val; - - val = readl(d->virt_base + EINT0MASK_REG); - if (mask) - val |= 1 << ddata->eints[irqd->hwirq]; - else - val &= ~(1 << ddata->eints[irqd->hwirq]); - writel(val, d->virt_base + EINT0MASK_REG); -} - -static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd) -{ - s3c64xx_eint0_irq_set_mask(irqd, false); -} - -static void s3c64xx_eint0_irq_mask(struct irq_data *irqd) -{ - s3c64xx_eint0_irq_set_mask(irqd, true); -} - -static void s3c64xx_eint0_irq_ack(struct irq_data *irqd) -{ - struct s3c64xx_eint0_domain_data *ddata = - irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; - - writel(1 << ddata->eints[irqd->hwirq], - d->virt_base + EINT0PEND_REG); -} - -static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) -{ - struct s3c64xx_eint0_domain_data *ddata = - irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank *bank = ddata->bank; - struct samsung_pinctrl_drv_data *d = bank->drvdata; - void __iomem *reg; - int trigger; - u8 shift; - u32 val; - - trigger = s3c64xx_irq_get_trigger(type); - if (trigger < 0) { - pr_err("unsupported external interrupt type\n"); - return -EINVAL; - } - - s3c64xx_irq_set_handler(irqd->irq, type); - - /* Set up interrupt trigger */ - reg = d->virt_base + EINT0CON0_REG; - shift = ddata->eints[irqd->hwirq]; - if (shift >= EINT_MAX_PER_REG) { - reg += 4; - shift -= EINT_MAX_PER_REG; - } - shift = EINT_CON_LEN * (shift / 2); - - val = readl(reg); - val &= ~(EINT_CON_MASK << shift); - val |= trigger << shift; - writel(val, reg); - - s3c64xx_irq_set_function(d, bank, irqd->hwirq); - - return 0; -} - -/* - * irq_chip for wakeup interrupts - */ -static struct irq_chip s3c64xx_eint0_irq_chip = { - .name = "EINT0", - .irq_unmask = s3c64xx_eint0_irq_unmask, - .irq_mask = s3c64xx_eint0_irq_mask, - .irq_ack = s3c64xx_eint0_irq_ack, - .irq_set_type = s3c64xx_eint0_irq_set_type, -}; - -static inline void s3c64xx_irq_demux_eint(unsigned int irq, - struct irq_desc *desc, u32 range) -{ - struct irq_chip *chip = irq_get_chip(irq); - struct s3c64xx_eint0_data *data = irq_get_handler_data(irq); - struct samsung_pinctrl_drv_data *drvdata = data->drvdata; - unsigned int pend, mask; - - chained_irq_enter(chip, desc); - - pend = readl(drvdata->virt_base + EINT0PEND_REG); - mask = readl(drvdata->virt_base + EINT0MASK_REG); - - pend = pend & range & ~mask; - pend &= range; - - while (pend) { - unsigned int virq; - - irq = fls(pend) - 1; - pend &= ~(1 << irq); - - virq = irq_linear_revmap(data->domains[irq], data->pins[irq]); - /* - * Something must be really wrong if an unmapped EINT - * was unmasked... - */ - BUG_ON(!virq); - - generic_handle_irq(virq); - } - - chained_irq_exit(chip, desc); -} - -static void s3c64xx_demux_eint0_3(unsigned int irq, struct irq_desc *desc) -{ - s3c64xx_irq_demux_eint(irq, desc, 0xf); -} - -static void s3c64xx_demux_eint4_11(unsigned int irq, struct irq_desc *desc) -{ - s3c64xx_irq_demux_eint(irq, desc, 0xff0); -} - -static void s3c64xx_demux_eint12_19(unsigned int irq, struct irq_desc *desc) -{ - s3c64xx_irq_demux_eint(irq, desc, 0xff000); -} - -static void s3c64xx_demux_eint20_27(unsigned int irq, struct irq_desc *desc) -{ - s3c64xx_irq_demux_eint(irq, desc, 0xff00000); -} - -static irq_flow_handler_t s3c64xx_eint0_handlers[NUM_EINT0_IRQ] = { - s3c64xx_demux_eint0_3, - s3c64xx_demux_eint4_11, - s3c64xx_demux_eint12_19, - s3c64xx_demux_eint20_27, -}; - -static int s3c64xx_eint0_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct s3c64xx_eint0_domain_data *ddata = h->host_data; - struct samsung_pin_bank *bank = ddata->bank; - - if (!(bank->eint_mask & (1 << hw))) - return -EINVAL; - - irq_set_chip_and_handler(virq, - &s3c64xx_eint0_irq_chip, handle_level_irq); - irq_set_chip_data(virq, ddata); - set_irq_flags(virq, IRQF_VALID); - - return 0; -} - -/* - * irq domain callbacks for external wakeup interrupt controller. - */ -static const struct irq_domain_ops s3c64xx_eint0_irqd_ops = { - .map = s3c64xx_eint0_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - -/* list of external wakeup controllers supported */ -static const struct of_device_id s3c64xx_eint0_irq_ids[] = { - { .compatible = "samsung,s3c64xx-wakeup-eint", }, - { } -}; - -/** - * s3c64xx_eint_eint0_init() - setup handling of external wakeup interrupts. - * @d: driver data of samsung pinctrl driver. - */ -static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d) -{ - struct device *dev = d->dev; - struct device_node *eint0_np = NULL; - struct device_node *np; - struct samsung_pin_bank *bank; - struct s3c64xx_eint0_data *data; - unsigned int i; - - for_each_child_of_node(dev->of_node, np) { - if (of_match_node(s3c64xx_eint0_irq_ids, np)) { - eint0_np = np; - break; - } - } - if (!eint0_np) - return -ENODEV; - - data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) { - dev_err(dev, "could not allocate memory for wkup eint data\n"); - return -ENOMEM; - } - data->drvdata = d; - - for (i = 0; i < NUM_EINT0_IRQ; ++i) { - unsigned int irq; - - irq = irq_of_parse_and_map(eint0_np, i); - if (!irq) { - dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i); - return -ENXIO; - } - - irq_set_chained_handler(irq, s3c64xx_eint0_handlers[i]); - irq_set_handler_data(irq, data); - } - - bank = d->ctrl->pin_banks; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { - struct s3c64xx_eint0_domain_data *ddata; - unsigned int nr_eints; - unsigned int mask; - unsigned int irq; - unsigned int pin; - - if (bank->eint_type != EINT_TYPE_WKUP) - continue; - - mask = bank->eint_mask; - nr_eints = fls(mask); - - ddata = devm_kzalloc(dev, - sizeof(*ddata) + nr_eints, GFP_KERNEL); - if (!ddata) { - dev_err(dev, "failed to allocate domain data\n"); - return -ENOMEM; - } - ddata->bank = bank; - - bank->irq_domain = irq_domain_add_linear(bank->of_node, - nr_eints, &s3c64xx_eint0_irqd_ops, ddata); - if (!bank->irq_domain) { - dev_err(dev, "wkup irq domain add failed\n"); - return -ENXIO; - } - - irq = bank->eint_offset; - mask = bank->eint_mask; - for (pin = 0; mask; ++pin, mask >>= 1) { - if (!(mask & 1)) - continue; - data->domains[irq] = bank->irq_domain; - data->pins[irq] = pin; - ddata->eints[pin] = irq; - ++irq; - } - } - - return 0; -} - -/* pin banks of s3c64xx pin-controller 0 */ -static struct samsung_pin_bank s3c64xx_pin_banks0[] = { - PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0), - PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8), - PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16), - PIN_BANK_4BIT_EINTG(5, 0x060, "gpd", 32), - PIN_BANK_4BIT(5, 0x080, "gpe"), - PIN_BANK_2BIT_EINTG(16, 0x0a0, "gpf", 48, 0x3fff), - PIN_BANK_4BIT_EINTG(7, 0x0c0, "gpg", 64), - PIN_BANK_4BIT2_EINTG(10, 0x0e0, "gph", 80), - PIN_BANK_2BIT(16, 0x100, "gpi"), - PIN_BANK_2BIT(12, 0x120, "gpj"), - PIN_BANK_4BIT2_ALIVE(16, 0x800, "gpk"), - PIN_BANK_4BIT2_EINTW(15, 0x810, "gpl", 16, 0x7f00), - PIN_BANK_4BIT_EINTW(6, 0x820, "gpm", 23, 0x1f), - PIN_BANK_2BIT_EINTW(16, 0x830, "gpn", 0), - PIN_BANK_2BIT_EINTG(16, 0x140, "gpo", 96, 0xffff), - PIN_BANK_2BIT_EINTG(15, 0x160, "gpp", 112, 0x7fff), - PIN_BANK_2BIT_EINTG(9, 0x180, "gpq", 128, 0x1ff), -}; - -/* - * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes - * one gpio/pin-mux/pinconfig controller. - */ -struct samsung_pin_ctrl s3c64xx_pin_ctrl[] = { - { - /* pin-controller instance 1 data */ - .pin_banks = s3c64xx_pin_banks0, - .nr_banks = ARRAY_SIZE(s3c64xx_pin_banks0), - .eint_gpio_init = s3c64xx_eint_gpio_init, - .eint_wkup_init = s3c64xx_eint_eint0_init, - .label = "S3C64xx-GPIO", - }, -}; diff --git a/trunk/drivers/pinctrl/pinctrl-samsung.c b/trunk/drivers/pinctrl/pinctrl-samsung.c index 4f54faf2971f..f206df175656 100644 --- a/trunk/drivers/pinctrl/pinctrl-samsung.c +++ b/trunk/drivers/pinctrl/pinctrl-samsung.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "core.h" #include "pinctrl-samsung.h" @@ -215,7 +214,7 @@ static void samsung_dt_free_map(struct pinctrl_dev *pctldev, } /* list of pinctrl callbacks for the pinctrl core */ -static const struct pinctrl_ops samsung_pctrl_ops = { +static struct pinctrl_ops samsung_pctrl_ops = { .get_groups_count = samsung_get_group_count, .get_group_name = samsung_get_group_name, .get_group_pins = samsung_get_group_pins, @@ -275,6 +274,10 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, *offset = pin - b->pin_base; if (bank) *bank = b; + + /* some banks have two config registers in a single bank */ + if (*offset * b->func_width > BITS_PER_LONG) + *reg += 4; } /* enable or disable a pinmux function */ @@ -286,7 +289,6 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, struct samsung_pin_bank *bank; void __iomem *reg; u32 mask, shift, data, pin_offset, cnt; - unsigned long flags; drvdata = pinctrl_dev_get_drvdata(pctldev); pins = drvdata->pin_groups[group].pins; @@ -296,28 +298,16 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, * pin function number in the config register. */ for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { - struct samsung_pin_bank_type *type; - pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base, ®, &pin_offset, &bank); - type = bank->type; - mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; - shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; - if (shift >= 32) { - /* Some banks have two config registers */ - shift -= 32; - reg += 4; - } - - spin_lock_irqsave(&bank->slock, flags); + mask = (1 << bank->func_width) - 1; + shift = pin_offset * bank->func_width; - data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); + data = readl(reg); data &= ~(mask << shift); if (enable) data |= drvdata->pin_groups[group].func << shift; - writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); - - spin_unlock_irqrestore(&bank->slock, flags); + writel(data, reg); } } @@ -344,44 +334,30 @@ static void samsung_pinmux_disable(struct pinctrl_dev *pctldev, static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset, bool input) { - struct samsung_pin_bank_type *type; struct samsung_pin_bank *bank; struct samsung_pinctrl_drv_data *drvdata; void __iomem *reg; u32 data, pin_offset, mask, shift; - unsigned long flags; bank = gc_to_pin_bank(range->gc); - type = bank->type; drvdata = pinctrl_dev_get_drvdata(pctldev); pin_offset = offset - bank->pin_base; - reg = drvdata->virt_base + bank->pctl_offset + - type->reg_offset[PINCFG_TYPE_FUNC]; - - mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; - shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; - if (shift >= 32) { - /* Some banks have two config registers */ - shift -= 32; - reg += 4; - } + reg = drvdata->virt_base + bank->pctl_offset; - spin_lock_irqsave(&bank->slock, flags); + mask = (1 << bank->func_width) - 1; + shift = pin_offset * bank->func_width; data = readl(reg); data &= ~(mask << shift); if (!input) data |= FUNC_OUTPUT << shift; writel(data, reg); - - spin_unlock_irqrestore(&bank->slock, flags); - return 0; } /* list of pinmux callbacks for the pinmux vertical in pinctrl core */ -static const struct pinmux_ops samsung_pinmux_ops = { +static struct pinmux_ops samsung_pinmux_ops = { .get_functions_count = samsung_get_functions_count, .get_function_name = samsung_pinmux_get_fname, .get_function_groups = samsung_pinmux_get_groups, @@ -395,26 +371,40 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config, bool set) { struct samsung_pinctrl_drv_data *drvdata; - struct samsung_pin_bank_type *type; struct samsung_pin_bank *bank; void __iomem *reg_base; enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config); u32 data, width, pin_offset, mask, shift; u32 cfg_value, cfg_reg; - unsigned long flags; drvdata = pinctrl_dev_get_drvdata(pctldev); pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, ®_base, &pin_offset, &bank); - type = bank->type; - if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type]) + switch (cfg_type) { + case PINCFG_TYPE_PUD: + width = bank->pud_width; + cfg_reg = PUD_REG; + break; + case PINCFG_TYPE_DRV: + width = bank->drv_width; + cfg_reg = DRV_REG; + break; + case PINCFG_TYPE_CON_PDN: + width = bank->conpdn_width; + cfg_reg = CONPDN_REG; + break; + case PINCFG_TYPE_PUD_PDN: + width = bank->pudpdn_width; + cfg_reg = PUDPDN_REG; + break; + default: + WARN_ON(1); return -EINVAL; + } - width = type->fld_width[cfg_type]; - cfg_reg = type->reg_offset[cfg_type]; - - spin_lock_irqsave(&bank->slock, flags); + if (!width) + return -EINVAL; mask = (1 << width) - 1; shift = pin_offset * width; @@ -430,9 +420,6 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, data &= mask; *config = PINCFG_PACK(cfg_type, data); } - - spin_unlock_irqrestore(&bank->slock, flags); - return 0; } @@ -481,7 +468,7 @@ static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev, } /* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */ -static const struct pinconf_ops samsung_pinconf_ops = { +static struct pinconf_ops samsung_pinconf_ops = { .pin_config_get = samsung_pinconf_get, .pin_config_set = samsung_pinconf_set, .pin_config_group_get = samsung_pinconf_group_get, @@ -492,22 +479,16 @@ static const struct pinconf_ops samsung_pinconf_ops = { static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) { struct samsung_pin_bank *bank = gc_to_pin_bank(gc); - struct samsung_pin_bank_type *type = bank->type; - unsigned long flags; void __iomem *reg; u32 data; reg = bank->drvdata->virt_base + bank->pctl_offset; - spin_lock_irqsave(&bank->slock, flags); - - data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); + data = readl(reg + DAT_REG); data &= ~(1 << offset); if (value) data |= 1 << offset; - writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]); - - spin_unlock_irqrestore(&bank->slock, flags); + writel(data, reg + DAT_REG); } /* gpiolib gpio_get callback function */ @@ -516,11 +497,10 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) void __iomem *reg; u32 data; struct samsung_pin_bank *bank = gc_to_pin_bank(gc); - struct samsung_pin_bank_type *type = bank->type; reg = bank->drvdata->virt_base + bank->pctl_offset; - data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); + data = readl(reg + DAT_REG); data >>= offset; data &= 1; return data; @@ -879,7 +859,6 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( bank = ctrl->pin_banks; for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - spin_lock_init(&bank->slock); bank->drvdata = d; bank->pin_base = ctrl->nr_pins; ctrl->nr_pins += bank->nr_pins; @@ -965,16 +944,10 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) } static const struct of_device_id samsung_pinctrl_dt_match[] = { -#ifdef CONFIG_PINCTRL_EXYNOS { .compatible = "samsung,exynos4210-pinctrl", .data = (void *)exynos4210_pin_ctrl }, { .compatible = "samsung,exynos4x12-pinctrl", .data = (void *)exynos4x12_pin_ctrl }, -#endif -#ifdef CONFIG_PINCTRL_S3C64XX - { .compatible = "samsung,s3c64xx-pinctrl", - .data = s3c64xx_pin_ctrl }, -#endif {}, }; MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match); diff --git a/trunk/drivers/pinctrl/pinctrl-samsung.h b/trunk/drivers/pinctrl/pinctrl-samsung.h index 45f27b41e30c..e2d4e67f7e88 100644 --- a/trunk/drivers/pinctrl/pinctrl-samsung.h +++ b/trunk/drivers/pinctrl/pinctrl-samsung.h @@ -25,27 +25,28 @@ #include +/* register offsets within a pin bank */ +#define DAT_REG 0x4 +#define PUD_REG 0x8 +#define DRV_REG 0xC +#define CONPDN_REG 0x10 +#define PUDPDN_REG 0x14 + /* pinmux function number for pin as gpio output line */ #define FUNC_OUTPUT 0x1 /** * enum pincfg_type - possible pin configuration types supported. - * @PINCFG_TYPE_FUNC: Function configuration. - * @PINCFG_TYPE_DAT: Pin value configuration. * @PINCFG_TYPE_PUD: Pull up/down configuration. * @PINCFG_TYPE_DRV: Drive strength configuration. * @PINCFG_TYPE_CON_PDN: Pin function in power down mode. * @PINCFG_TYPE_PUD_PDN: Pull up/down configuration in power down mode. */ enum pincfg_type { - PINCFG_TYPE_FUNC, - PINCFG_TYPE_DAT, PINCFG_TYPE_PUD, PINCFG_TYPE_DRV, PINCFG_TYPE_CON_PDN, PINCFG_TYPE_PUD_PDN, - - PINCFG_TYPE_NUM }; /* @@ -101,41 +102,34 @@ enum eint_type { struct samsung_pinctrl_drv_data; -/** - * struct samsung_pin_bank_type: pin bank type description - * @fld_width: widths of configuration bitfields (0 if unavailable) - * @reg_offset: offsets of configuration registers (don't care of width is 0) - */ -struct samsung_pin_bank_type { - u8 fld_width[PINCFG_TYPE_NUM]; - u8 reg_offset[PINCFG_TYPE_NUM]; -}; - /** * struct samsung_pin_bank: represent a controller pin-bank. - * @type: type of the bank (register offsets and bitfield widths) * @pctl_offset: starting offset of the pin-bank registers. * @pin_base: starting pin number of the bank. * @nr_pins: number of pins included in this bank. - * @eint_func: function to set in CON register to configure pin as EINT. + * @func_width: width of the function selector bit field. + * @pud_width: width of the pin pull up/down selector bit field. + * @drv_width: width of the pin driver strength selector bit field. + * @conpdn_width: width of the sleep mode function selector bin field. + * @pudpdn_width: width of the sleep mode pull up/down selector bit field. * @eint_type: type of the external interrupt supported by the bank. - * @eint_mask: bit mask of pins which support EINT function. * @name: name to be prefixed for each pin in this pin bank. * @of_node: OF node of the bank. * @drvdata: link to controller driver data * @irq_domain: IRQ domain of the bank. * @gpio_chip: GPIO chip of the bank. * @grange: linux gpio pin range supported by this bank. - * @slock: spinlock protecting bank registers */ struct samsung_pin_bank { - struct samsung_pin_bank_type *type; u32 pctl_offset; u32 pin_base; u8 nr_pins; - u8 eint_func; + u8 func_width; + u8 pud_width; + u8 drv_width; + u8 conpdn_width; + u8 pudpdn_width; enum eint_type eint_type; - u32 eint_mask; u32 eint_offset; char *name; struct device_node *of_node; @@ -143,7 +137,6 @@ struct samsung_pin_bank { struct irq_domain *irq_domain; struct gpio_chip gpio_chip; struct pinctrl_gpio_range grange; - spinlock_t slock; }; /** @@ -244,6 +237,5 @@ struct samsung_pmx_func { /* list of all exported SoC specific data */ extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; -extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; #endif /* __PINCTRL_SAMSUNG_H */ diff --git a/trunk/drivers/pinctrl/pinctrl-single.c b/trunk/drivers/pinctrl/pinctrl-single.c index 5f2d2bfd356e..5c32e880bcb2 100644 --- a/trunk/drivers/pinctrl/pinctrl-single.c +++ b/trunk/drivers/pinctrl/pinctrl-single.c @@ -22,10 +22,8 @@ #include #include -#include #include "core.h" -#include "pinconf.h" #define DRIVER_NAME "pinctrl-single" #define PCS_MUX_PINS_NAME "pinctrl-single,pins" @@ -60,33 +58,6 @@ struct pcs_func_vals { unsigned mask; }; -/** - * struct pcs_conf_vals - pinconf parameter, pinconf register offset - * and value, enable, disable, mask - * @param: config parameter - * @val: user input bits in the pinconf register - * @enable: enable bits in the pinconf register - * @disable: disable bits in the pinconf register - * @mask: mask bits in the register value - */ -struct pcs_conf_vals { - enum pin_config_param param; - unsigned val; - unsigned enable; - unsigned disable; - unsigned mask; -}; - -/** - * struct pcs_conf_type - pinconf property name, pinconf param pair - * @name: property name in DTS file - * @param: config parameter - */ -struct pcs_conf_type { - const char *name; - enum pin_config_param param; -}; - /** * struct pcs_function - pinctrl function * @name: pinctrl function name @@ -102,22 +73,6 @@ struct pcs_function { unsigned nvals; const char **pgnames; int npgnames; - struct pcs_conf_vals *conf; - int nconfs; - struct list_head node; -}; - -/** - * struct pcs_gpiofunc_range - pin ranges with same mux value of gpio function - * @offset: offset base of pins - * @npins: number pins with the same mux value of gpio function - * @gpiofunc: mux value of gpio function - * @node: list node - */ -struct pcs_gpiofunc_range { - unsigned offset; - unsigned npins; - unsigned gpiofunc; struct list_head node; }; @@ -162,14 +117,12 @@ struct pcs_name { * @fshift: function register shift * @foff: value to turn mux off * @fmax: max number of functions in fmask - * @is_pinconf: whether supports pinconf * @names: array of register names for pins * @pins: physical pins on the SoC * @pgtree: pingroup index radix tree * @ftree: function index radix tree * @pingroups: list of pingroups * @functions: list of functions - * @gpiofuncs: list of gpio functions * @ngroups: number of pingroups * @nfuncs: number of functions * @desc: pin controller descriptor @@ -189,14 +142,12 @@ struct pcs_device { unsigned foff; unsigned fmax; bool bits_per_mux; - bool is_pinconf; struct pcs_name *names; struct pcs_data pins; struct radix_tree_root pgtree; struct radix_tree_root ftree; struct list_head pingroups; struct list_head functions; - struct list_head gpiofuncs; unsigned ngroups; unsigned nfuncs; struct pinctrl_desc desc; @@ -204,16 +155,6 @@ struct pcs_device { void (*write)(unsigned val, void __iomem *reg); }; -static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long *config); -static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long config); - -static enum pin_config_param pcs_bias[] = { - PIN_CONFIG_BIAS_PULL_DOWN, - PIN_CONFIG_BIAS_PULL_UP, -}; - /* * REVISIT: Reads and writes could eventually use regmap or something * generic. But at least on omaps, some mux registers are performance @@ -329,7 +270,7 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config, struct pinctrl_map **map, unsigned *num_maps); -static const struct pinctrl_ops pcs_pinctrl_ops = { +static struct pinctrl_ops pcs_pinctrl_ops = { .get_groups_count = pcs_get_groups_count, .get_group_name = pcs_get_group_name, .get_group_pins = pcs_get_group_pins, @@ -385,28 +326,6 @@ static int pcs_get_function_groups(struct pinctrl_dev *pctldev, return 0; } -static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned pin, - struct pcs_function **func) -{ - struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); - struct pin_desc *pdesc = pin_desc_get(pctldev, pin); - const struct pinctrl_setting_mux *setting; - unsigned fselector; - - /* If pin is not described in DTS & enabled, mux_setting is NULL. */ - setting = pdesc->mux_setting; - if (!setting) - return -ENOTSUPP; - fselector = setting->func; - *func = radix_tree_lookup(&pcs->ftree, fselector); - if (!(*func)) { - dev_err(pcs->dev, "%s could not find function%i\n", - __func__, fselector); - return -ENOTSUPP; - } - return 0; -} - static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector, unsigned group) { @@ -415,9 +334,6 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector, int i; pcs = pinctrl_dev_get_drvdata(pctldev); - /* If function mask is null, needn't enable it. */ - if (!pcs->fmask) - return 0; func = radix_tree_lookup(&pcs->ftree, fselector); if (!func) return -EINVAL; @@ -452,10 +368,6 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, int i; pcs = pinctrl_dev_get_drvdata(pctldev); - /* If function mask is null, needn't disable it. */ - if (!pcs->fmask) - return; - func = radix_tree_lookup(&pcs->ftree, fselector); if (!func) { dev_err(pcs->dev, "%s could not find function%i\n", @@ -491,33 +403,12 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, } static int pcs_request_gpio(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned pin) + struct pinctrl_gpio_range *range, unsigned offset) { - struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); - struct pcs_gpiofunc_range *frange = NULL; - struct list_head *pos, *tmp; - int mux_bytes = 0; - unsigned data; - - /* If function mask is null, return directly. */ - if (!pcs->fmask) - return -ENOTSUPP; - - list_for_each_safe(pos, tmp, &pcs->gpiofuncs) { - frange = list_entry(pos, struct pcs_gpiofunc_range, node); - if (pin >= frange->offset + frange->npins - || pin < frange->offset) - continue; - mux_bytes = pcs->width / BITS_PER_BYTE; - data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask; - data |= frange->gpiofunc; - pcs->write(data, pcs->base + pin * mux_bytes); - break; - } - return 0; + return -ENOTSUPP; } -static const struct pinmux_ops pcs_pinmux_ops = { +static struct pinmux_ops pcs_pinmux_ops = { .get_functions_count = pcs_get_functions_count, .get_function_name = pcs_get_function_name, .get_function_groups = pcs_get_function_groups, @@ -526,190 +417,32 @@ static const struct pinmux_ops pcs_pinmux_ops = { .gpio_request_enable = pcs_request_gpio, }; -/* Clear BIAS value */ -static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin) -{ - unsigned long config; - int i; - for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) { - config = pinconf_to_config_packed(pcs_bias[i], 0); - pcs_pinconf_set(pctldev, pin, config); - } -} - -/* - * Check whether PIN_CONFIG_BIAS_DISABLE is valid. - * It's depend on that PULL_DOWN & PULL_UP configs are all invalid. - */ -static bool pcs_pinconf_bias_disable(struct pinctrl_dev *pctldev, unsigned pin) -{ - unsigned long config; - int i; - - for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) { - config = pinconf_to_config_packed(pcs_bias[i], 0); - if (!pcs_pinconf_get(pctldev, pin, &config)) - goto out; - } - return true; -out: - return false; -} - static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { - struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); - struct pcs_function *func; - enum pin_config_param param; - unsigned offset = 0, data = 0, i, j, ret; - - ret = pcs_get_function(pctldev, pin, &func); - if (ret) - return ret; - - for (i = 0; i < func->nconfs; i++) { - param = pinconf_to_config_param(*config); - if (param == PIN_CONFIG_BIAS_DISABLE) { - if (pcs_pinconf_bias_disable(pctldev, pin)) { - *config = 0; - return 0; - } else { - return -ENOTSUPP; - } - } else if (param != func->conf[i].param) { - continue; - } - - offset = pin * (pcs->width / BITS_PER_BYTE); - data = pcs->read(pcs->base + offset) & func->conf[i].mask; - switch (func->conf[i].param) { - /* 4 parameters */ - case PIN_CONFIG_BIAS_PULL_DOWN: - case PIN_CONFIG_BIAS_PULL_UP: - case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - if ((data != func->conf[i].enable) || - (data == func->conf[i].disable)) - return -ENOTSUPP; - *config = 0; - break; - /* 2 parameters */ - case PIN_CONFIG_INPUT_SCHMITT: - for (j = 0; j < func->nconfs; j++) { - switch (func->conf[j].param) { - case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - if (data != func->conf[j].enable) - return -ENOTSUPP; - break; - default: - break; - } - } - *config = data; - break; - case PIN_CONFIG_DRIVE_STRENGTH: - case PIN_CONFIG_SLEW_RATE: - default: - *config = data; - break; - } - return 0; - } return -ENOTSUPP; } static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, unsigned long config) { - struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); - struct pcs_function *func; - unsigned offset = 0, shift = 0, i, data, ret; - u16 arg; - - ret = pcs_get_function(pctldev, pin, &func); - if (ret) - return ret; - - for (i = 0; i < func->nconfs; i++) { - if (pinconf_to_config_param(config) == func->conf[i].param) { - offset = pin * (pcs->width / BITS_PER_BYTE); - data = pcs->read(pcs->base + offset); - arg = pinconf_to_config_argument(config); - switch (func->conf[i].param) { - /* 2 parameters */ - case PIN_CONFIG_INPUT_SCHMITT: - case PIN_CONFIG_DRIVE_STRENGTH: - case PIN_CONFIG_SLEW_RATE: - shift = ffs(func->conf[i].mask) - 1; - data &= ~func->conf[i].mask; - data |= (arg << shift) & func->conf[i].mask; - break; - /* 4 parameters */ - case PIN_CONFIG_BIAS_DISABLE: - pcs_pinconf_clear_bias(pctldev, pin); - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - case PIN_CONFIG_BIAS_PULL_UP: - if (arg) - pcs_pinconf_clear_bias(pctldev, pin); - /* fall through */ - case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - data &= ~func->conf[i].mask; - if (arg) - data |= func->conf[i].enable; - else - data |= func->conf[i].disable; - break; - default: - return -ENOTSUPP; - } - pcs->write(data, pcs->base + offset); - return 0; - } - } return -ENOTSUPP; } static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev, unsigned group, unsigned long *config) { - const unsigned *pins; - unsigned npins, old = 0; - int i, ret; - - ret = pcs_get_group_pins(pctldev, group, &pins, &npins); - if (ret) - return ret; - for (i = 0; i < npins; i++) { - if (pcs_pinconf_get(pctldev, pins[i], config)) - return -ENOTSUPP; - /* configs do not match between two pins */ - if (i && (old != *config)) - return -ENOTSUPP; - old = *config; - } - return 0; + return -ENOTSUPP; } static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group, unsigned long config) { - const unsigned *pins; - unsigned npins; - int i, ret; - - ret = pcs_get_group_pins(pctldev, group, &pins, &npins); - if (ret) - return ret; - for (i = 0; i < npins; i++) { - if (pcs_pinconf_set(pctldev, pins[i], config)) - return -ENOTSUPP; - } - return 0; + return -ENOTSUPP; } static void pcs_pinconf_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned pin) + struct seq_file *s, unsigned offset) { } @@ -718,22 +451,13 @@ static void pcs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, { } -static void pcs_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, - unsigned long config) -{ - pinconf_generic_dump_config(pctldev, s, config); -} - -static const struct pinconf_ops pcs_pinconf_ops = { +static struct pinconf_ops pcs_pinconf_ops = { .pin_config_get = pcs_pinconf_get, .pin_config_set = pcs_pinconf_set, .pin_config_group_get = pcs_pinconf_group_get, .pin_config_group_set = pcs_pinconf_group_set, .pin_config_dbg_show = pcs_pinconf_dbg_show, .pin_config_group_dbg_show = pcs_pinconf_group_dbg_show, - .pin_config_config_dbg_show = pcs_pinconf_config_dbg_show, - .is_generic = true, }; /** @@ -924,158 +648,11 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset) return index; } -/* - * check whether data matches enable bits or disable bits - * Return value: 1 for matching enable bits, 0 for matching disable bits, - * and negative value for matching failure. - */ -static int pcs_config_match(unsigned data, unsigned enable, unsigned disable) -{ - int ret = -EINVAL; - - if (data == enable) - ret = 1; - else if (data == disable) - ret = 0; - return ret; -} - -static void add_config(struct pcs_conf_vals **conf, enum pin_config_param param, - unsigned value, unsigned enable, unsigned disable, - unsigned mask) -{ - (*conf)->param = param; - (*conf)->val = value; - (*conf)->enable = enable; - (*conf)->disable = disable; - (*conf)->mask = mask; - (*conf)++; -} - -static void add_setting(unsigned long **setting, enum pin_config_param param, - unsigned arg) -{ - **setting = pinconf_to_config_packed(param, arg); - (*setting)++; -} - -/* add pinconf setting with 2 parameters */ -static void pcs_add_conf2(struct pcs_device *pcs, struct device_node *np, - const char *name, enum pin_config_param param, - struct pcs_conf_vals **conf, unsigned long **settings) -{ - unsigned value[2], shift; - int ret; - - ret = of_property_read_u32_array(np, name, value, 2); - if (ret) - return; - /* set value & mask */ - value[0] &= value[1]; - shift = ffs(value[1]) - 1; - /* skip enable & disable */ - add_config(conf, param, value[0], 0, 0, value[1]); - add_setting(settings, param, value[0] >> shift); -} - -/* add pinconf setting with 4 parameters */ -static void pcs_add_conf4(struct pcs_device *pcs, struct device_node *np, - const char *name, enum pin_config_param param, - struct pcs_conf_vals **conf, unsigned long **settings) -{ - unsigned value[4]; - int ret; - - /* value to set, enable, disable, mask */ - ret = of_property_read_u32_array(np, name, value, 4); - if (ret) - return; - if (!value[3]) { - dev_err(pcs->dev, "mask field of the property can't be 0\n"); - return; - } - value[0] &= value[3]; - value[1] &= value[3]; - value[2] &= value[3]; - ret = pcs_config_match(value[0], value[1], value[2]); - if (ret < 0) - dev_dbg(pcs->dev, "failed to match enable or disable bits\n"); - add_config(conf, param, value[0], value[1], value[2], value[3]); - add_setting(settings, param, ret); -} - -static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, - struct pcs_function *func, - struct pinctrl_map **map) - -{ - struct pinctrl_map *m = *map; - int i = 0, nconfs = 0; - unsigned long *settings = NULL, *s = NULL; - struct pcs_conf_vals *conf = NULL; - struct pcs_conf_type prop2[] = { - { "pinctrl-single,drive-strength", PIN_CONFIG_DRIVE_STRENGTH, }, - { "pinctrl-single,slew-rate", PIN_CONFIG_SLEW_RATE, }, - { "pinctrl-single,input-schmitt", PIN_CONFIG_INPUT_SCHMITT, }, - }; - struct pcs_conf_type prop4[] = { - { "pinctrl-single,bias-pullup", PIN_CONFIG_BIAS_PULL_UP, }, - { "pinctrl-single,bias-pulldown", PIN_CONFIG_BIAS_PULL_DOWN, }, - { "pinctrl-single,input-schmitt-enable", - PIN_CONFIG_INPUT_SCHMITT_ENABLE, }, - }; - - /* If pinconf isn't supported, don't parse properties in below. */ - if (!pcs->is_pinconf) - return 0; - - /* cacluate how much properties are supported in current node */ - for (i = 0; i < ARRAY_SIZE(prop2); i++) { - if (of_find_property(np, prop2[i].name, NULL)) - nconfs++; - } - for (i = 0; i < ARRAY_SIZE(prop4); i++) { - if (of_find_property(np, prop4[i].name, NULL)) - nconfs++; - } - if (!nconfs) - return 0; - - func->conf = devm_kzalloc(pcs->dev, - sizeof(struct pcs_conf_vals) * nconfs, - GFP_KERNEL); - if (!func->conf) - return -ENOMEM; - func->nconfs = nconfs; - conf = &(func->conf[0]); - m++; - settings = devm_kzalloc(pcs->dev, sizeof(unsigned long) * nconfs, - GFP_KERNEL); - if (!settings) - return -ENOMEM; - s = &settings[0]; - - for (i = 0; i < ARRAY_SIZE(prop2); i++) - pcs_add_conf2(pcs, np, prop2[i].name, prop2[i].param, - &conf, &s); - for (i = 0; i < ARRAY_SIZE(prop4); i++) - pcs_add_conf4(pcs, np, prop4[i].name, prop4[i].param, - &conf, &s); - m->type = PIN_MAP_TYPE_CONFIGS_GROUP; - m->data.configs.group_or_pin = np->name; - m->data.configs.configs = settings; - m->data.configs.num_configs = nconfs; - return 0; -} - -static void pcs_free_pingroups(struct pcs_device *pcs); - /** * smux_parse_one_pinctrl_entry() - parses a device tree mux entry * @pcs: pinctrl driver instance * @np: device node of the mux entry * @map: map entry - * @num_maps: number of map * @pgnames: pingroup names * * Note that this binding currently supports only sets of one register + value. @@ -1092,7 +669,6 @@ static void pcs_free_pingroups(struct pcs_device *pcs); static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, struct device_node *np, struct pinctrl_map **map, - unsigned *num_maps, const char **pgnames) { struct pcs_func_vals *vals; @@ -1165,18 +741,8 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, (*map)->data.mux.group = np->name; (*map)->data.mux.function = np->name; - if (pcs->is_pinconf) { - if (pcs_parse_pinconf(pcs, np, function, map)) - goto free_pingroups; - *num_maps = 2; - } else { - *num_maps = 1; - } return 0; -free_pingroups: - pcs_free_pingroups(pcs); - *num_maps = 1; free_function: pcs_remove_function(pcs, function); @@ -1205,8 +771,7 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, pcs = pinctrl_dev_get_drvdata(pctldev); - /* create 2 maps. One is for pinmux, and the other is for pinconf. */ - *map = devm_kzalloc(pcs->dev, sizeof(**map) * 2, GFP_KERNEL); + *map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL); if (!*map) return -ENOMEM; @@ -1218,13 +783,13 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, goto free_map; } - ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, num_maps, - pgnames); + ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, pgnames); if (ret < 0) { dev_err(pcs->dev, "no pins entries for %s\n", np_config->name); goto free_pgnames; } + *num_maps = 1; return 0; @@ -1314,37 +879,6 @@ static void pcs_free_resources(struct pcs_device *pcs) static struct of_device_id pcs_of_match[]; -static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) -{ - const char *propname = "pinctrl-single,gpio-range"; - const char *cellname = "#pinctrl-single,gpio-range-cells"; - struct of_phandle_args gpiospec; - struct pcs_gpiofunc_range *range; - int ret, i; - - for (i = 0; ; i++) { - ret = of_parse_phandle_with_args(node, propname, cellname, - i, &gpiospec); - /* Do not treat it as error. Only treat it as end condition. */ - if (ret) { - ret = 0; - break; - } - range = devm_kzalloc(pcs->dev, sizeof(*range), GFP_KERNEL); - if (!range) { - ret = -ENOMEM; - break; - } - range->offset = gpiospec.args[0]; - range->npins = gpiospec.args[1]; - range->gpiofunc = gpiospec.args[2]; - mutex_lock(&pcs->mutex); - list_add_tail(&range->node, &pcs->gpiofuncs); - mutex_unlock(&pcs->mutex); - } - return ret; -} - static int pcs_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1366,23 +900,14 @@ static int pcs_probe(struct platform_device *pdev) mutex_init(&pcs->mutex); INIT_LIST_HEAD(&pcs->pingroups); INIT_LIST_HEAD(&pcs->functions); - INIT_LIST_HEAD(&pcs->gpiofuncs); - pcs->is_pinconf = match->data; PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width, "register width not specified\n"); - ret = of_property_read_u32(np, "pinctrl-single,function-mask", - &pcs->fmask); - if (!ret) { - pcs->fshift = ffs(pcs->fmask) - 1; - pcs->fmax = pcs->fmask >> pcs->fshift; - } else { - /* If mask property doesn't exist, function mux is invalid. */ - pcs->fmask = 0; - pcs->fshift = 0; - pcs->fmax = 0; - } + PCS_GET_PROP_U32("pinctrl-single,function-mask", &pcs->fmask, + "function register mask not specified\n"); + pcs->fshift = ffs(pcs->fmask) - 1; + pcs->fmax = pcs->fmask >> pcs->fshift; ret = of_property_read_u32(np, "pinctrl-single,function-off", &pcs->foff); @@ -1436,8 +961,7 @@ static int pcs_probe(struct platform_device *pdev) pcs->desc.name = DRIVER_NAME; pcs->desc.pctlops = &pcs_pinctrl_ops; pcs->desc.pmxops = &pcs_pinmux_ops; - if (pcs->is_pinconf) - pcs->desc.confops = &pcs_pinconf_ops; + pcs->desc.confops = &pcs_pinconf_ops; pcs->desc.owner = THIS_MODULE; ret = pcs_allocate_pin_table(pcs); @@ -1451,10 +975,6 @@ static int pcs_probe(struct platform_device *pdev) goto free; } - ret = pcs_add_gpio_func(np, pcs); - if (ret < 0) - goto free; - dev_info(pcs->dev, "%i pins at pa %p size %u\n", pcs->desc.npins, pcs->base, pcs->size); @@ -1479,8 +999,7 @@ static int pcs_remove(struct platform_device *pdev) } static struct of_device_id pcs_of_match[] = { - { .compatible = "pinctrl-single", .data = (void *)false }, - { .compatible = "pinconf-single", .data = (void *)true }, + { .compatible = DRIVER_NAME, }, { }, }; MODULE_DEVICE_TABLE(of, pcs_of_match); diff --git a/trunk/drivers/pinctrl/pinctrl-sirf.c b/trunk/drivers/pinctrl/pinctrl-sirf.c index fb9062570745..d02498b30c6e 100644 --- a/trunk/drivers/pinctrl/pinctrl-sirf.c +++ b/trunk/drivers/pinctrl/pinctrl-sirf.c @@ -979,7 +979,7 @@ static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static const struct pinctrl_ops sirfsoc_pctrl_ops = { +static struct pinctrl_ops sirfsoc_pctrl_ops = { .get_groups_count = sirfsoc_get_groups_count, .get_group_name = sirfsoc_get_group_name, .get_group_pins = sirfsoc_get_group_pins, @@ -1181,7 +1181,7 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, return 0; } -static const struct pinmux_ops sirfsoc_pinmux_ops = { +static struct pinmux_ops sirfsoc_pinmux_ops = { .enable = sirfsoc_pinmux_enable, .disable = sirfsoc_pinmux_disable, .get_functions_count = sirfsoc_pinmux_get_funcs_count, @@ -1685,12 +1685,15 @@ static void sirfsoc_gpio_set_pullup(const u32 *pullups) const unsigned long *p = (const unsigned long *)pullups; for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for_each_set_bit(n, p + i, BITS_PER_LONG) { + n = find_first_bit(p + i, BITS_PER_LONG); + while (n < BITS_PER_LONG) { u32 offset = SIRFSOC_GPIO_CTRL(i, n); u32 val = readl(sgpio_bank[i].chip.regs + offset); val |= SIRFSOC_GPIO_CTL_PULL_MASK; val |= SIRFSOC_GPIO_CTL_PULL_HIGH; writel(val, sgpio_bank[i].chip.regs + offset); + + n = find_next_bit(p + i, BITS_PER_LONG, n + 1); } } } @@ -1701,12 +1704,15 @@ static void sirfsoc_gpio_set_pulldown(const u32 *pulldowns) const unsigned long *p = (const unsigned long *)pulldowns; for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for_each_set_bit(n, p + i, BITS_PER_LONG) { + n = find_first_bit(p + i, BITS_PER_LONG); + while (n < BITS_PER_LONG) { u32 offset = SIRFSOC_GPIO_CTRL(i, n); u32 val = readl(sgpio_bank[i].chip.regs + offset); val |= SIRFSOC_GPIO_CTL_PULL_MASK; val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH; writel(val, sgpio_bank[i].chip.regs + offset); + + n = find_next_bit(p + i, BITS_PER_LONG, n + 1); } } } diff --git a/trunk/drivers/pinctrl/pinctrl-sunxi.c b/trunk/drivers/pinctrl/pinctrl-sunxi.c index c52fc2c08732..80b11e3415bc 100644 --- a/trunk/drivers/pinctrl/pinctrl-sunxi.c +++ b/trunk/drivers/pinctrl/pinctrl-sunxi.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include @@ -31,856 +30,482 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN_PA0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ERXD3 */ - SUNXI_FUNCTION(0x3, "spi1"), /* CS0 */ - SUNXI_FUNCTION(0x4, "uart2")), /* RTS */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ERXD2 */ - SUNXI_FUNCTION(0x3, "spi1"), /* CLK */ - SUNXI_FUNCTION(0x4, "uart2")), /* CTS */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ERXD1 */ - SUNXI_FUNCTION(0x3, "spi1"), /* MOSI */ - SUNXI_FUNCTION(0x4, "uart2")), /* TX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ERXD0 */ - SUNXI_FUNCTION(0x3, "spi1"), /* MISO */ - SUNXI_FUNCTION(0x4, "uart2")), /* RX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ETXD3 */ - SUNXI_FUNCTION(0x3, "spi1")), /* CS1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ETXD2 */ - SUNXI_FUNCTION(0x3, "spi3")), /* CS0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ETXD1 */ - SUNXI_FUNCTION(0x3, "spi3")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ETXD0 */ - SUNXI_FUNCTION(0x3, "spi3")), /* MOSI */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ERXCK */ - SUNXI_FUNCTION(0x3, "spi3")), /* MISO */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ERXERR */ - SUNXI_FUNCTION(0x3, "spi3")), /* CS1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PA10, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ERXDV */ SUNXI_FUNCTION(0x4, "uart1")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA11, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* EMDC */ SUNXI_FUNCTION(0x4, "uart1")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA12, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* EMDIO */ - SUNXI_FUNCTION(0x3, "uart6"), /* TX */ SUNXI_FUNCTION(0x4, "uart1")), /* RTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA13, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ETXEN */ - SUNXI_FUNCTION(0x3, "uart6"), /* RX */ SUNXI_FUNCTION(0x4, "uart1")), /* CTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA14, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ETXCK */ - SUNXI_FUNCTION(0x3, "uart7"), /* TX */ SUNXI_FUNCTION(0x4, "uart1")), /* DTR */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA15, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ECRS */ - SUNXI_FUNCTION(0x3, "uart7"), /* RX */ SUNXI_FUNCTION(0x4, "uart1")), /* DSR */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA16, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ECOL */ - SUNXI_FUNCTION(0x3, "can"), /* TX */ SUNXI_FUNCTION(0x4, "uart1")), /* DCD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA17, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "emac"), /* ETXERR */ - SUNXI_FUNCTION(0x3, "can"), /* RX */ SUNXI_FUNCTION(0x4, "uart1")), /* RING */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "pwm")), /* PWM0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ir0")), /* TX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ir0")), /* RX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s"), /* MCLK */ - SUNXI_FUNCTION(0x3, "ac97")), /* MCLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s"), /* BCLK */ - SUNXI_FUNCTION(0x3, "ac97")), /* BCLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s"), /* LRCK */ - SUNXI_FUNCTION(0x3, "ac97")), /* SYNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s"), /* DO0 */ - SUNXI_FUNCTION(0x3, "ac97")), /* DO */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s")), /* DO1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s")), /* DO2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s")), /* DO3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s"), /* DI */ - SUNXI_FUNCTION(0x3, "ac97")), /* DI */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi2")), /* CS1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi2"), /* CS0 */ - SUNXI_FUNCTION(0x3, "jtag")), /* MS0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi2"), /* CLK */ - SUNXI_FUNCTION(0x3, "jtag")), /* CK0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi2"), /* MOSI */ - SUNXI_FUNCTION(0x3, "jtag")), /* DO0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi2"), /* MISO */ - SUNXI_FUNCTION(0x3, "jtag")), /* DI0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c2")), /* SCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c2")), /* SDA */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB22, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart0"), /* TX */ - SUNXI_FUNCTION(0x3, "ir1")), /* TX */ + SUNXI_FUNCTION(0x2, "uart0")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB23, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart0"), /* RX */ - SUNXI_FUNCTION(0x3, "ir1")), /* RX */ + SUNXI_FUNCTION(0x2, "uart0")), /* RX */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NWE */ - SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NALE */ - SUNXI_FUNCTION(0x3, "spi0")), /* MISO */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NCLE */ - SUNXI_FUNCTION(0x3, "spi0")), /* SCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NCE1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NCE0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NRE# */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NRB0 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NRB1 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ0 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ1 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ2 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ3 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NDQ4 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NDQ5 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NDQ6 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NDQ7 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NWP */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NCE2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NCE3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NCE4 */ - SUNXI_FUNCTION(0x3, "spi2")), /* CS0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NCE5 */ - SUNXI_FUNCTION(0x3, "spi2")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NCE6 */ - SUNXI_FUNCTION(0x3, "spi2")), /* MOSI */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC22, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NCE7 */ - SUNXI_FUNCTION(0x3, "spi2")), /* MISO */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC23, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "spi0")), /* CS0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC24, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NDQS */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D0 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D1 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */ - SUNXI_FUNCTION(0x3, "lvds0")), /* VM3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VP0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VN0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VP1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VN1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VP2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VN2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VPC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VP3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */ - SUNXI_FUNCTION(0x3, "lvds1")), /* VN3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D20 */ - SUNXI_FUNCTION(0x3, "csi1")), /* MCLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D21 */ - SUNXI_FUNCTION(0x3, "sim")), /* VPPEN */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D22 */ - SUNXI_FUNCTION(0x3, "sim")), /* VPPPP */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* D23 */ - SUNXI_FUNCTION(0x3, "sim")), /* DET */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* CLK */ - SUNXI_FUNCTION(0x3, "sim")), /* VCCEN */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* DE */ - SUNXI_FUNCTION(0x3, "sim")), /* RST */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* HSYNC */ - SUNXI_FUNCTION(0x3, "sim")), /* SCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0"), /* VSYNC */ - SUNXI_FUNCTION(0x3, "sim")), /* SDA */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* CLK */ - SUNXI_FUNCTION(0x3, "csi0")), /* PCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* ERR */ - SUNXI_FUNCTION(0x3, "csi0")), /* CK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* SYNC */ - SUNXI_FUNCTION(0x3, "csi0")), /* HSYNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* DVLD */ - SUNXI_FUNCTION(0x3, "csi0")), /* VSYNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* D0 */ - SUNXI_FUNCTION(0x3, "csi0")), /* D0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* D1 */ - SUNXI_FUNCTION(0x3, "csi0"), /* D1 */ - SUNXI_FUNCTION(0x4, "sim")), /* VPPEN */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* D2 */ - SUNXI_FUNCTION(0x3, "csi0")), /* D2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* D3 */ - SUNXI_FUNCTION(0x3, "csi0")), /* D3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* D4 */ - SUNXI_FUNCTION(0x3, "csi0")), /* D4 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* D5 */ - SUNXI_FUNCTION(0x3, "csi0")), /* D5 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* D6 */ - SUNXI_FUNCTION(0x3, "csi0")), /* D6 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts0"), /* D7 */ - SUNXI_FUNCTION(0x3, "csi0")), /* D7 */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */ - SUNXI_FUNCTION(0x4, "jtag")), /* MSI */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */ - SUNXI_FUNCTION(0x4, "jtag")), /* DI1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */ SUNXI_FUNCTION(0x4, "uart0")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */ - SUNXI_FUNCTION(0x4, "jtag")), /* DO1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */ SUNXI_FUNCTION(0x4, "uart0")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */ - SUNXI_FUNCTION(0x4, "jtag")), /* CK1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* CLK */ - SUNXI_FUNCTION(0x3, "csi1"), /* PCK */ - SUNXI_FUNCTION(0x4, "mmc1")), /* CMD */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* ERR */ - SUNXI_FUNCTION(0x3, "csi1"), /* CK */ - SUNXI_FUNCTION(0x4, "mmc1")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* SYNC */ - SUNXI_FUNCTION(0x3, "csi1"), /* HSYNC */ - SUNXI_FUNCTION(0x4, "mmc1")), /* D0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* DVLD */ - SUNXI_FUNCTION(0x3, "csi1"), /* VSYNC */ - SUNXI_FUNCTION(0x4, "mmc1")), /* D1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* D0 */ - SUNXI_FUNCTION(0x3, "csi1"), /* D0 */ - SUNXI_FUNCTION(0x4, "mmc1"), /* D2 */ - SUNXI_FUNCTION(0x5, "csi0")), /* D8 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* D1 */ - SUNXI_FUNCTION(0x3, "csi1"), /* D1 */ - SUNXI_FUNCTION(0x4, "mmc1"), /* D3 */ - SUNXI_FUNCTION(0x5, "csi0")), /* D9 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* D2 */ - SUNXI_FUNCTION(0x3, "csi1"), /* D2 */ - SUNXI_FUNCTION(0x4, "uart3"), /* TX */ - SUNXI_FUNCTION(0x5, "csi0")), /* D10 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* D3 */ - SUNXI_FUNCTION(0x3, "csi1"), /* D3 */ - SUNXI_FUNCTION(0x4, "uart3"), /* RX */ - SUNXI_FUNCTION(0x5, "csi0")), /* D11 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* D4 */ - SUNXI_FUNCTION(0x3, "csi1"), /* D4 */ - SUNXI_FUNCTION(0x4, "uart3"), /* RTS */ - SUNXI_FUNCTION(0x5, "csi0")), /* D12 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* D5 */ - SUNXI_FUNCTION(0x3, "csi1"), /* D5 */ - SUNXI_FUNCTION(0x4, "uart3"), /* CTS */ - SUNXI_FUNCTION(0x5, "csi0")), /* D13 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* D6 */ - SUNXI_FUNCTION(0x3, "csi1"), /* D6 */ - SUNXI_FUNCTION(0x4, "uart4"), /* TX */ - SUNXI_FUNCTION(0x5, "csi0")), /* D14 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ts1"), /* D7 */ - SUNXI_FUNCTION(0x3, "csi1"), /* D7 */ - SUNXI_FUNCTION(0x4, "uart4"), /* RX */ - SUNXI_FUNCTION(0x5, "csi0")), /* D15 */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D0 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAA0 */ - SUNXI_FUNCTION(0x4, "uart3"), /* TX */ - SUNXI_FUNCTION(0x7, "csi1")), /* D0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D1 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAA1 */ - SUNXI_FUNCTION(0x4, "uart3"), /* RX */ - SUNXI_FUNCTION(0x7, "csi1")), /* D1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D2 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAA2 */ - SUNXI_FUNCTION(0x4, "uart3"), /* RTS */ - SUNXI_FUNCTION(0x7, "csi1")), /* D2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D3 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAIRQ */ - SUNXI_FUNCTION(0x4, "uart3"), /* CTS */ - SUNXI_FUNCTION(0x7, "csi1")), /* D3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D4 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD0 */ - SUNXI_FUNCTION(0x4, "uart4"), /* TX */ - SUNXI_FUNCTION(0x7, "csi1")), /* D4 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D5 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD1 */ - SUNXI_FUNCTION(0x4, "uart4"), /* RX */ - SUNXI_FUNCTION(0x7, "csi1")), /* D5 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D6 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD2 */ - SUNXI_FUNCTION(0x4, "uart5"), /* TX */ - SUNXI_FUNCTION(0x5, "ms"), /* BS */ - SUNXI_FUNCTION(0x7, "csi1")), /* D6 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D7 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD3 */ - SUNXI_FUNCTION(0x4, "uart5"), /* RX */ - SUNXI_FUNCTION(0x5, "ms"), /* CLK */ - SUNXI_FUNCTION(0x7, "csi1")), /* D7 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D8 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD4 */ - SUNXI_FUNCTION(0x4, "keypad"), /* IN0 */ - SUNXI_FUNCTION(0x5, "ms"), /* D0 */ - SUNXI_FUNCTION(0x7, "csi1")), /* D8 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D9 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD5 */ - SUNXI_FUNCTION(0x4, "keypad"), /* IN1 */ - SUNXI_FUNCTION(0x5, "ms"), /* D1 */ - SUNXI_FUNCTION(0x7, "csi1")), /* D9 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D10 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD6 */ - SUNXI_FUNCTION(0x4, "keypad"), /* IN2 */ - SUNXI_FUNCTION(0x5, "ms"), /* D2 */ - SUNXI_FUNCTION(0x7, "csi1")), /* D10 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D11 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD7 */ - SUNXI_FUNCTION(0x4, "keypad"), /* IN3 */ - SUNXI_FUNCTION(0x5, "ms"), /* D3 */ - SUNXI_FUNCTION(0x7, "csi1")), /* D11 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D12 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD8 */ - SUNXI_FUNCTION(0x4, "ps2"), /* SCK1 */ - SUNXI_FUNCTION(0x7, "csi1")), /* D12 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D13 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD9 */ - SUNXI_FUNCTION(0x4, "ps2"), /* SDA1 */ - SUNXI_FUNCTION(0x5, "sim"), /* RST */ - SUNXI_FUNCTION(0x7, "csi1")), /* D13 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D14 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD10 */ - SUNXI_FUNCTION(0x4, "keypad"), /* IN4 */ - SUNXI_FUNCTION(0x5, "sim"), /* VPPEN */ - SUNXI_FUNCTION(0x7, "csi1")), /* D14 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D15 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD11 */ - SUNXI_FUNCTION(0x4, "keypad"), /* IN5 */ - SUNXI_FUNCTION(0x5, "sim"), /* VPPPP */ - SUNXI_FUNCTION(0x7, "csi1")), /* D15 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D16 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD12 */ - SUNXI_FUNCTION(0x4, "keypad"), /* IN6 */ - SUNXI_FUNCTION(0x7, "csi1")), /* D16 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D17 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD13 */ - SUNXI_FUNCTION(0x4, "keypad"), /* IN7 */ - SUNXI_FUNCTION(0x5, "sim"), /* VCCEN */ - SUNXI_FUNCTION(0x7, "csi1")), /* D17 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D18 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD14 */ - SUNXI_FUNCTION(0x4, "keypad"), /* OUT0 */ - SUNXI_FUNCTION(0x5, "sim"), /* SCK */ - SUNXI_FUNCTION(0x7, "csi1")), /* D18 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D19 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAD15 */ - SUNXI_FUNCTION(0x4, "keypad"), /* OUT1 */ - SUNXI_FUNCTION(0x5, "sim"), /* SDA */ - SUNXI_FUNCTION(0x7, "csi1")), /* D19 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D20 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAOE */ - SUNXI_FUNCTION(0x4, "can"), /* TX */ - SUNXI_FUNCTION(0x7, "csi1")), /* D20 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D21 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATADREQ */ - SUNXI_FUNCTION(0x4, "can"), /* RX */ - SUNXI_FUNCTION(0x7, "csi1")), /* D21 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH22, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D22 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATADACK */ - SUNXI_FUNCTION(0x4, "keypad"), /* OUT2 */ - SUNXI_FUNCTION(0x5, "mmc1"), /* CMD */ - SUNXI_FUNCTION(0x7, "csi1")), /* D22 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH23, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* D23 */ - SUNXI_FUNCTION(0x3, "pata"), /* ATACS0 */ - SUNXI_FUNCTION(0x4, "keypad"), /* OUT3 */ - SUNXI_FUNCTION(0x5, "mmc1"), /* CLK */ - SUNXI_FUNCTION(0x7, "csi1")), /* D23 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH24, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* CLK */ - SUNXI_FUNCTION(0x3, "pata"), /* ATACS1 */ - SUNXI_FUNCTION(0x4, "keypad"), /* OUT4 */ - SUNXI_FUNCTION(0x5, "mmc1"), /* D0 */ - SUNXI_FUNCTION(0x7, "csi1")), /* PCLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH25, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* DE */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAIORDY */ - SUNXI_FUNCTION(0x4, "keypad"), /* OUT5 */ - SUNXI_FUNCTION(0x5, "mmc1"), /* D1 */ - SUNXI_FUNCTION(0x7, "csi1")), /* FIELD */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH26, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* HSYNC */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAIOR */ - SUNXI_FUNCTION(0x4, "keypad"), /* OUT6 */ - SUNXI_FUNCTION(0x5, "mmc1"), /* D2 */ - SUNXI_FUNCTION(0x7, "csi1")), /* HSYNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PH27, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd1"), /* VSYNC */ - SUNXI_FUNCTION(0x3, "pata"), /* ATAIOW */ - SUNXI_FUNCTION(0x4, "keypad"), /* OUT7 */ - SUNXI_FUNCTION(0x5, "mmc1"), /* D3 */ - SUNXI_FUNCTION(0x7, "csi1")), /* VSYNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI0, SUNXI_FUNCTION(0x0, "gpio_in"), @@ -893,401 +518,277 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = { SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "pwm")), /* PWM1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc3")), /* CMD */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc3")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc3")), /* D0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc3")), /* D1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc3")), /* D2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc3")), /* D3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi0"), /* CS0 */ - SUNXI_FUNCTION(0x3, "uart5")), /* TX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi0"), /* CLK */ - SUNXI_FUNCTION(0x3, "uart5")), /* RX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi0"), /* MOSI */ - SUNXI_FUNCTION(0x3, "uart6")), /* TX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi0"), /* MISO */ - SUNXI_FUNCTION(0x3, "uart6")), /* RX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi0"), /* CS1 */ - SUNXI_FUNCTION(0x3, "ps2"), /* SCK1 */ - SUNXI_FUNCTION(0x4, "timer4")), /* TCLKIN0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* CS1 */ - SUNXI_FUNCTION(0x3, "ps2"), /* SDA1 */ - SUNXI_FUNCTION(0x4, "timer5")), /* TCLKIN1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */ - SUNXI_FUNCTION(0x3, "uart2")), /* RTS */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* CLK */ - SUNXI_FUNCTION(0x3, "uart2")), /* CTS */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */ - SUNXI_FUNCTION(0x3, "uart2")), /* TX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* MISO */ - SUNXI_FUNCTION(0x3, "uart2")), /* RX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ps2"), /* SCK0 */ - SUNXI_FUNCTION(0x3, "uart7"), /* TX */ - SUNXI_FUNCTION(0x4, "hdmi")), /* HSCL */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ps2"), /* SDA0 */ - SUNXI_FUNCTION(0x3, "uart7"), /* RX */ - SUNXI_FUNCTION(0x4, "hdmi")), /* HSDA */ + SUNXI_FUNCTION(0x1, "gpio_out")), }; static const struct sunxi_desc_pin sun5i_a13_pins[] = { /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "pwm")), + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ir0")), /* TX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "ir0")), /* RX */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi2")), /* CS1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c2")), /* SCK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2c2")), /* SDA */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NWE */ - SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NALE */ - SUNXI_FUNCTION(0x3, "spi0")), /* MISO */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NCLE */ - SUNXI_FUNCTION(0x3, "spi0")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NCE1 */ - SUNXI_FUNCTION(0x3, "spi0")), /* CS0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NCE0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0")), /* NRE */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NRB0 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NRB1 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ0 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ1 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ2 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ3 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ4 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ5 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ6 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQ7 */ - SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand0"), /* NDQS */ - SUNXI_FUNCTION(0x4, "uart3")), /* RTS */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D4 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D5 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D6 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D7 */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D10 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D11 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D12 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D13 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D14 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D15 */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D18 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D19 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D20 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D21 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D22 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* D23 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* DE */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* HSYNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "lcd0")), /* VSYNC */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x3, "csi0"), /* PCLK */ - SUNXI_FUNCTION(0x4, "spi2")), /* CS0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x3, "csi0"), /* MCLK */ - SUNXI_FUNCTION(0x4, "spi2")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x3, "csi0"), /* HSYNC */ - SUNXI_FUNCTION(0x4, "spi2")), /* MOSI */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* VSYNC */ - SUNXI_FUNCTION(0x4, "spi2")), /* MISO */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* D0 */ - SUNXI_FUNCTION(0x4, "mmc2")), /* D0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* D1 */ - SUNXI_FUNCTION(0x4, "mmc2")), /* D1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* D2 */ - SUNXI_FUNCTION(0x4, "mmc2")), /* D2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* D3 */ - SUNXI_FUNCTION(0x4, "mmc2")), /* D3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* D4 */ - SUNXI_FUNCTION(0x4, "mmc2")), /* CMD */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* D5 */ - SUNXI_FUNCTION(0x4, "mmc2")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* D6 */ SUNXI_FUNCTION(0x4, "uart1")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "csi0"), /* D7 */ SUNXI_FUNCTION(0x4, "uart1")), /* RX */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x4, "mmc0")), /* D1 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x4, "mmc0")), /* D0 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x4, "mmc0")), /* CLK */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x4, "mmc0")), /* CMD */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x4, "mmc0")), /* D3 */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x4, "mmc0")), /* D2 */ + SUNXI_FUNCTION(0x1, "gpio_out")), /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0, SUNXI_FUNCTION(0x0, "gpio_in"), @@ -1301,34 +802,24 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */ SUNXI_FUNCTION(0x4, "uart1")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */ SUNXI_FUNCTION(0x4, "uart1")), /* RX */ -/* Hole */ + /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */ - SUNXI_FUNCTION(0x3, "uart3")), /* TX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* CLK */ - SUNXI_FUNCTION(0x3, "uart3")), /* RX */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */ - SUNXI_FUNCTION(0x3, "uart3")), /* CTS */ + SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PG12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "spi1"), /* MISO */ - SUNXI_FUNCTION(0x3, "uart3")), /* RTS */ + SUNXI_FUNCTION(0x1, "gpio_out")), }; static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = { @@ -1538,7 +1029,7 @@ static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static const struct pinctrl_ops sunxi_pctrl_ops = { +static struct pinctrl_ops sunxi_pctrl_ops = { .dt_node_to_map = sunxi_pctrl_dt_node_to_map, .dt_free_map = sunxi_pctrl_dt_free_map, .get_groups_count = sunxi_pctrl_get_groups_count, @@ -1607,7 +1098,7 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, return 0; } -static const struct pinconf_ops sunxi_pconf_ops = { +static struct pinconf_ops sunxi_pconf_ops = { .pin_config_group_get = sunxi_pconf_group_get, .pin_config_group_set = sunxi_pconf_group_set, }; @@ -1713,7 +1204,7 @@ sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, return ret; } -static const struct pinmux_ops sunxi_pmx_ops = { +static struct pinmux_ops sunxi_pmx_ops = { .get_functions_count = sunxi_pmx_get_funcs_cnt, .get_function_name = sunxi_pmx_get_func_name, .get_function_groups = sunxi_pmx_get_func_groups, @@ -1918,7 +1409,6 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev) struct pinctrl_pin_desc *pins; struct sunxi_pinctrl *pctl; int i, ret, last_pin; - struct clk *clk; pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); if (!pctl) @@ -1989,12 +1479,6 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev) goto gpiochip_error; } - clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) - goto gpiochip_error; - - clk_prepare_enable(clk); - dev_info(&pdev->dev, "initialized sunXi PIO driver\n"); return 0; diff --git a/trunk/drivers/pinctrl/pinctrl-tegra.c b/trunk/drivers/pinctrl/pinctrl-tegra.c index 2fa9bc6cd7ab..f195d77a3572 100644 --- a/trunk/drivers/pinctrl/pinctrl-tegra.c +++ b/trunk/drivers/pinctrl/pinctrl-tegra.c @@ -316,7 +316,7 @@ static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } -static const struct pinctrl_ops tegra_pinctrl_ops = { +static struct pinctrl_ops tegra_pinctrl_ops = { .get_groups_count = tegra_pinctrl_get_groups_count, .get_group_name = tegra_pinctrl_get_group_name, .get_group_pins = tegra_pinctrl_get_group_pins, @@ -401,7 +401,7 @@ static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev, pmx_writel(pmx, val, g->mux_bank, g->mux_reg); } -static const struct pinmux_ops tegra_pinmux_ops = { +static struct pinmux_ops tegra_pinmux_ops = { .get_functions_count = tegra_pinctrl_get_funcs_count, .get_function_name = tegra_pinctrl_get_func_name, .get_function_groups = tegra_pinctrl_get_func_groups, @@ -676,7 +676,7 @@ static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, } #endif -static const struct pinconf_ops tegra_pinconf_ops = { +static struct pinconf_ops tegra_pinconf_ops = { .pin_config_get = tegra_pinconf_get, .pin_config_set = tegra_pinconf_set, .pin_config_group_get = tegra_pinconf_group_get, diff --git a/trunk/drivers/pinctrl/pinctrl-u300.c b/trunk/drivers/pinctrl/pinctrl-u300.c index 6a3a7503e6a0..2b5772550836 100644 --- a/trunk/drivers/pinctrl/pinctrl-u300.c +++ b/trunk/drivers/pinctrl/pinctrl-u300.c @@ -860,7 +860,7 @@ static void u300_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, seq_printf(s, " " DRIVER_NAME); } -static const struct pinctrl_ops u300_pctrl_ops = { +static struct pinctrl_ops u300_pctrl_ops = { .get_groups_count = u300_get_groups_count, .get_group_name = u300_get_group_name, .get_group_pins = u300_get_group_pins, @@ -1003,7 +1003,7 @@ static int u300_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static const struct pinmux_ops u300_pmx_ops = { +static struct pinmux_ops u300_pmx_ops = { .get_functions_count = u300_pmx_get_funcs_count, .get_function_name = u300_pmx_get_func_name, .get_function_groups = u300_pmx_get_groups, @@ -1046,7 +1046,7 @@ static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, return 0; } -static const struct pinconf_ops u300_pconf_ops = { +static struct pinconf_ops u300_pconf_ops = { .is_generic = true, .pin_config_get = u300_pin_config_get, .pin_config_set = u300_pin_config_set, diff --git a/trunk/drivers/pinctrl/pinctrl-xway.c b/trunk/drivers/pinctrl/pinctrl-xway.c index f2977cff8366..068224efa6fa 100644 --- a/trunk/drivers/pinctrl/pinctrl-xway.c +++ b/trunk/drivers/pinctrl/pinctrl-xway.c @@ -553,7 +553,7 @@ int xway_pinconf_group_set(struct pinctrl_dev *pctldev, return ret; } -static const struct pinconf_ops xway_pinconf_ops = { +static struct pinconf_ops xway_pinconf_ops = { .pin_config_get = xway_pinconf_get, .pin_config_set = xway_pinconf_set, .pin_config_group_set = xway_pinconf_group_set, diff --git a/trunk/drivers/pinctrl/pinmux.c b/trunk/drivers/pinctrl/pinmux.c index 88cc5095d0c9..1a00658b3ea0 100644 --- a/trunk/drivers/pinctrl/pinmux.c +++ b/trunk/drivers/pinctrl/pinmux.c @@ -194,11 +194,6 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, } if (!gpio_range) { - /* - * A pin should not be freed more times than allocated. - */ - if (WARN_ON(!desc->mux_usecount)) - return NULL; desc->mux_usecount--; if (desc->mux_usecount) return NULL; @@ -506,7 +501,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what) if (!pmxops) return 0; - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); nfuncs = pmxops->get_functions_count(pctldev); while (func_selector < nfuncs) { const char *func = pmxops->get_function_name(pctldev, @@ -530,7 +525,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what) func_selector++; } - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -548,7 +543,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what) seq_puts(s, "Pinmux settings per pin\n"); seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n"); - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_mutex); /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { @@ -583,7 +578,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what) seq_printf(s, "\n"); } - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_mutex); return 0; } diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear.c b/trunk/drivers/pinctrl/spear/pinctrl-spear.c index 116da0412c4b..6a7dae70db08 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear.c @@ -198,7 +198,7 @@ static void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static const struct pinctrl_ops spear_pinctrl_ops = { +static struct pinctrl_ops spear_pinctrl_ops = { .get_groups_count = spear_pinctrl_get_groups_cnt, .get_group_name = spear_pinctrl_get_group_name, .get_group_pins = spear_pinctrl_get_group_pins, @@ -340,7 +340,7 @@ static void gpio_disable_free(struct pinctrl_dev *pctldev, gpio_request_endisable(pctldev, range, offset, false); } -static const struct pinmux_ops spear_pinmux_ops = { +static struct pinmux_ops spear_pinmux_ops = { .get_functions_count = spear_pinctrl_get_funcs_count, .get_function_name = spear_pinctrl_get_func_name, .get_function_groups = spear_pinctrl_get_func_groups, diff --git a/trunk/drivers/platform/x86/chromeos_laptop.c b/trunk/drivers/platform/x86/chromeos_laptop.c index 3e5b4497a1d0..93d66809355a 100644 --- a/trunk/drivers/platform/x86/chromeos_laptop.c +++ b/trunk/drivers/platform/x86/chromeos_laptop.c @@ -23,9 +23,6 @@ #include #include -#include -#include -#include #include #define ATMEL_TP_I2C_ADDR 0x4b @@ -70,49 +67,15 @@ static struct i2c_board_info __initdata tsl2563_als_device = { I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), }; -static struct mxt_platform_data atmel_224s_tp_platform_data = { - .x_line = 18, - .y_line = 12, - .x_size = 102*20, - .y_size = 68*20, - .blen = 0x80, /* Gain setting is in upper 4 bits */ - .threshold = 0x32, - .voltage = 0, /* 3.3V */ - .orient = MXT_VERTICAL_FLIP, - .irqflags = IRQF_TRIGGER_FALLING, - .is_tp = true, - .key_map = { KEY_RESERVED, - KEY_RESERVED, - KEY_RESERVED, - BTN_LEFT }, - .config = NULL, - .config_length = 0, -}; - static struct i2c_board_info __initdata atmel_224s_tp_device = { I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR), - .platform_data = &atmel_224s_tp_platform_data, + .platform_data = NULL, .flags = I2C_CLIENT_WAKE, }; -static struct mxt_platform_data atmel_1664s_platform_data = { - .x_line = 32, - .y_line = 50, - .x_size = 1700, - .y_size = 2560, - .blen = 0x89, /* Gain setting is in upper 4 bits */ - .threshold = 0x28, - .voltage = 0, /* 3.3V */ - .orient = MXT_ROTATED_90_COUNTER, - .irqflags = IRQF_TRIGGER_FALLING, - .is_tp = false, - .config = NULL, - .config_length = 0, -}; - static struct i2c_board_info __initdata atmel_1664s_device = { I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR), - .platform_data = &atmel_1664s_platform_data, + .platform_data = NULL, .flags = I2C_CLIENT_WAKE, }; diff --git a/trunk/drivers/platform/x86/hp-wmi.c b/trunk/drivers/platform/x86/hp-wmi.c index 1a779bbfb87d..45cacf79f3a7 100644 --- a/trunk/drivers/platform/x86/hp-wmi.c +++ b/trunk/drivers/platform/x86/hp-wmi.c @@ -134,6 +134,7 @@ static const struct key_entry hp_wmi_keymap[] = { { KE_KEY, 0x2142, { KEY_MEDIA } }, { KE_KEY, 0x213b, { KEY_INFO } }, { KE_KEY, 0x2169, { KEY_DIRECTION } }, + { KE_KEY, 0x216a, { KEY_SETUP } }, { KE_KEY, 0x231b, { KEY_HELP } }, { KE_END, 0 } }; @@ -924,6 +925,9 @@ static int __init hp_wmi_init(void) err = hp_wmi_input_setup(); if (err) return err; + + //Enable magic for hotkeys that run on the SMBus + ec_write(0xe6,0x6e); } if (bios_capable) { diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index edec135b1685..9a907567f41e 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -1964,6 +1964,9 @@ struct tp_nvram_state { /* kthread for the hotkey poller */ static struct task_struct *tpacpi_hotkey_task; +/* Acquired while the poller kthread is running, use to sync start/stop */ +static struct mutex hotkey_thread_mutex; + /* * Acquire mutex to write poller control variables as an * atomic block. @@ -2459,6 +2462,8 @@ static int hotkey_kthread(void *data) unsigned int poll_freq; bool was_frozen; + mutex_lock(&hotkey_thread_mutex); + if (tpacpi_lifecycle == TPACPI_LIFE_EXITING) goto exit; @@ -2518,6 +2523,7 @@ static int hotkey_kthread(void *data) } exit: + mutex_unlock(&hotkey_thread_mutex); return 0; } @@ -2527,6 +2533,9 @@ static void hotkey_poll_stop_sync(void) if (tpacpi_hotkey_task) { kthread_stop(tpacpi_hotkey_task); tpacpi_hotkey_task = NULL; + mutex_lock(&hotkey_thread_mutex); + /* at this point, the thread did exit */ + mutex_unlock(&hotkey_thread_mutex); } } @@ -3225,6 +3234,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) mutex_init(&hotkey_mutex); #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL + mutex_init(&hotkey_thread_mutex); mutex_init(&hotkey_thread_data_mutex); #endif diff --git a/trunk/drivers/pnp/pnpacpi/core.c b/trunk/drivers/pnp/pnpacpi/core.c index 55cd459a3908..8813fc03aa09 100644 --- a/trunk/drivers/pnp/pnpacpi/core.c +++ b/trunk/drivers/pnp/pnpacpi/core.c @@ -353,14 +353,8 @@ static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle) /* complete initialization of a PNPACPI device includes having * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling. */ -static bool acpi_pnp_bus_match(struct device *dev) -{ - return dev->bus == &pnp_bus_type; -} - static struct acpi_bus_type __initdata acpi_pnp_bus = { - .name = "PNP", - .match = acpi_pnp_bus_match, + .bus = &pnp_bus_type, .find_device = acpi_pnp_find_device, }; diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index e3661c20cf38..da9782bd27d0 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -2830,7 +2830,7 @@ EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); * regulator_allow_bypass - allow the regulator to go into bypass mode * * @regulator: Regulator to configure - * @enable: enable or disable bypass mode + * @allow: enable or disable bypass mode * * Allow the regulator to go into bypass mode if all other consumers * for the regulator also enable bypass mode and the machine @@ -3057,13 +3057,9 @@ int regulator_bulk_enable(int num_consumers, return 0; err: - for (i = 0; i < num_consumers; i++) { - if (consumers[i].ret < 0) - pr_err("Failed to enable %s: %d\n", consumers[i].supply, - consumers[i].ret); - else - regulator_disable(consumers[i].consumer); - } + pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret); + while (--i >= 0) + regulator_disable(consumers[i].consumer); return ret; } diff --git a/trunk/drivers/regulator/db8500-prcmu.c b/trunk/drivers/regulator/db8500-prcmu.c index a53c11a529d5..219d162b651e 100644 --- a/trunk/drivers/regulator/db8500-prcmu.c +++ b/trunk/drivers/regulator/db8500-prcmu.c @@ -528,7 +528,7 @@ static int db8500_regulator_probe(struct platform_device *pdev) return 0; } -static int db8500_regulator_remove(struct platform_device *pdev) +static int __exit db8500_regulator_remove(struct platform_device *pdev) { int i; @@ -553,7 +553,7 @@ static struct platform_driver db8500_regulator_driver = { .owner = THIS_MODULE, }, .probe = db8500_regulator_probe, - .remove = db8500_regulator_remove, + .remove = __exit_p(db8500_regulator_remove), }; static int __init db8500_regulator_init(void) diff --git a/trunk/drivers/regulator/palmas-regulator.c b/trunk/drivers/regulator/palmas-regulator.c index 39cf14606784..cde13bb5a8fb 100644 --- a/trunk/drivers/regulator/palmas-regulator.c +++ b/trunk/drivers/regulator/palmas-regulator.c @@ -4,7 +4,6 @@ * Copyright 2011-2012 Texas Instruments Inc. * * Author: Graeme Gregory - * Author: Ian Lartey * * 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 @@ -157,7 +156,7 @@ static const struct regs_info palmas_regs_info[] = { * * So they are basically (maxV-minV)/stepV */ -#define PALMAS_SMPS_NUM_VOLTAGES 117 +#define PALMAS_SMPS_NUM_VOLTAGES 116 #define PALMAS_SMPS10_NUM_VOLTAGES 2 #define PALMAS_LDO_NUM_VOLTAGES 50 diff --git a/trunk/drivers/regulator/twl-regulator.c b/trunk/drivers/regulator/twl-regulator.c index f705d25b437c..74508cc62d67 100644 --- a/trunk/drivers/regulator/twl-regulator.c +++ b/trunk/drivers/regulator/twl-regulator.c @@ -471,23 +471,24 @@ twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) selector); } -static int twl4030ldo_get_voltage_sel(struct regulator_dev *rdev) +static int twl4030ldo_get_voltage(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); - int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE); + int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, + VREG_VOLTAGE); if (vsel < 0) return vsel; vsel &= info->table_len - 1; - return vsel; + return LDO_MV(info->table[vsel]) * 1000; } static struct regulator_ops twl4030ldo_ops = { .list_voltage = twl4030ldo_list_voltage, .set_voltage_sel = twl4030ldo_set_voltage_sel, - .get_voltage_sel = twl4030ldo_get_voltage_sel, + .get_voltage = twl4030ldo_get_voltage, .enable = twl4030reg_enable, .disable = twl4030reg_disable, diff --git a/trunk/drivers/remoteproc/Kconfig b/trunk/drivers/remoteproc/Kconfig index c6d77e20622c..cc1f7bf53fd0 100644 --- a/trunk/drivers/remoteproc/Kconfig +++ b/trunk/drivers/remoteproc/Kconfig @@ -4,7 +4,7 @@ menu "Remoteproc drivers" config REMOTEPROC tristate depends on HAS_DMA - select FW_LOADER + select FW_CONFIG select VIRTIO config OMAP_REMOTEPROC diff --git a/trunk/drivers/remoteproc/remoteproc_core.c b/trunk/drivers/remoteproc/remoteproc_core.c index 8edb4aed5d36..29387df4bfc9 100644 --- a/trunk/drivers/remoteproc/remoteproc_core.c +++ b/trunk/drivers/remoteproc/remoteproc_core.c @@ -217,7 +217,7 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i) * TODO: support predefined notifyids (via resource table) */ ret = idr_alloc(&rproc->notifyids, rvring, 0, 0, GFP_KERNEL); - if (ret < 0) { + if (ret) { dev_err(dev, "idr_alloc failed: %d\n", ret); dma_free_coherent(dev->parent, size, va, dma); return ret; @@ -366,12 +366,10 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, /* it is now safe to add the virtio device */ ret = rproc_add_virtio_dev(rvdev, rsc->id); if (ret) - goto remove_rvdev; + goto free_rvdev; return 0; -remove_rvdev: - list_del(&rvdev->node); free_rvdev: kfree(rvdev); return ret; diff --git a/trunk/drivers/remoteproc/ste_modem_rproc.c b/trunk/drivers/remoteproc/ste_modem_rproc.c index fb95c4220052..a7743c069339 100644 --- a/trunk/drivers/remoteproc/ste_modem_rproc.c +++ b/trunk/drivers/remoteproc/ste_modem_rproc.c @@ -240,8 +240,6 @@ static int sproc_drv_remove(struct platform_device *pdev) /* Unregister as remoteproc device */ rproc_del(sproc->rproc); - dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE, - sproc->fw_addr, sproc->fw_dma_addr); rproc_put(sproc->rproc); mdev->drv_data = NULL; @@ -299,13 +297,10 @@ static int sproc_probe(struct platform_device *pdev) /* Register as a remoteproc device */ err = rproc_add(rproc); if (err) - goto free_mem; + goto free_rproc; return 0; -free_mem: - dma_free_coherent(rproc->dev.parent, SPROC_FW_SIZE, - sproc->fw_addr, sproc->fw_dma_addr); free_rproc: /* Reset device data upon error */ mdev->drv_data = NULL; diff --git a/trunk/drivers/rtc/rtc-da9052.c b/trunk/drivers/rtc/rtc-da9052.c index 969abbad7fe3..0dde688ca09b 100644 --- a/trunk/drivers/rtc/rtc-da9052.c +++ b/trunk/drivers/rtc/rtc-da9052.c @@ -239,9 +239,11 @@ static int da9052_rtc_probe(struct platform_device *pdev) rtc->da9052 = dev_get_drvdata(pdev->dev.parent); platform_set_drvdata(pdev, rtc); - rtc->irq = DA9052_IRQ_ALARM; - ret = da9052_request_irq(rtc->da9052, rtc->irq, "ALM", - da9052_rtc_irq, rtc); + rtc->irq = platform_get_irq_byname(pdev, "ALM"); + ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, + da9052_rtc_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "ALM", rtc); if (ret != 0) { rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); return ret; diff --git a/trunk/drivers/rtc/rtc-mv.c b/trunk/drivers/rtc/rtc-mv.c index 8f87fec27ce7..57233c885998 100644 --- a/trunk/drivers/rtc/rtc-mv.c +++ b/trunk/drivers/rtc/rtc-mv.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -42,7 +41,6 @@ struct rtc_plat_data { struct rtc_device *rtc; void __iomem *ioaddr; int irq; - struct clk *clk; }; static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -223,7 +221,6 @@ static int mv_rtc_probe(struct platform_device *pdev) struct rtc_plat_data *pdata; resource_size_t size; u32 rtc_time; - int ret = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -242,17 +239,11 @@ static int mv_rtc_probe(struct platform_device *pdev) if (!pdata->ioaddr) return -ENOMEM; - pdata->clk = devm_clk_get(&pdev->dev, NULL); - /* Not all SoCs require a clock.*/ - if (!IS_ERR(pdata->clk)) - clk_prepare_enable(pdata->clk); - /* make sure the 24 hours mode is enabled */ rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS); if (rtc_time & RTC_HOURS_12H_MODE) { dev_err(&pdev->dev, "24 Hours mode not supported.\n"); - ret = -EINVAL; - goto out; + return -EINVAL; } /* make sure it is actually functional */ @@ -261,8 +252,7 @@ static int mv_rtc_probe(struct platform_device *pdev) rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS); if (rtc_time == 0x01000000) { dev_err(&pdev->dev, "internal RTC not ticking\n"); - ret = -ENODEV; - goto out; + return -ENODEV; } } @@ -278,10 +268,8 @@ static int mv_rtc_probe(struct platform_device *pdev) } else pdata->rtc = rtc_device_register(pdev->name, &pdev->dev, &mv_rtc_ops, THIS_MODULE); - if (IS_ERR(pdata->rtc)) { - ret = PTR_ERR(pdata->rtc); - goto out; - } + if (IS_ERR(pdata->rtc)) + return PTR_ERR(pdata->rtc); if (pdata->irq >= 0) { writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); @@ -294,11 +282,6 @@ static int mv_rtc_probe(struct platform_device *pdev) } return 0; -out: - if (!IS_ERR(pdata->clk)) - clk_disable_unprepare(pdata->clk); - - return ret; } static int __exit mv_rtc_remove(struct platform_device *pdev) @@ -309,9 +292,6 @@ static int __exit mv_rtc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); rtc_device_unregister(pdata->rtc); - if (!IS_ERR(pdata->clk)) - clk_disable_unprepare(pdata->clk); - return 0; } diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 82758cbb220b..f1b7fdc58a5f 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -246,7 +246,7 @@ static struct dentry *dasd_debugfs_setup(const char *name, static int dasd_state_known_to_basic(struct dasd_device *device) { struct dasd_block *block = device->block; - int rc = 0; + int rc; /* Allocate and register gendisk structure. */ if (block) { @@ -273,8 +273,7 @@ static int dasd_state_known_to_basic(struct dasd_device *device) DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created"); device->state = DASD_STATE_BASIC; - - return rc; + return 0; } /* @@ -283,7 +282,6 @@ static int dasd_state_known_to_basic(struct dasd_device *device) static int dasd_state_basic_to_known(struct dasd_device *device) { int rc; - if (device->block) { dasd_profile_exit(&device->block->profile); if (device->block->debugfs_dentry) @@ -334,10 +332,8 @@ static int dasd_state_basic_to_ready(struct dasd_device *device) if (block->base->discipline->do_analysis != NULL) rc = block->base->discipline->do_analysis(block); if (rc) { - if (rc != -EAGAIN) { + if (rc != -EAGAIN) device->state = DASD_STATE_UNFMT; - goto out; - } return rc; } dasd_setup_queue(block); @@ -345,16 +341,11 @@ static int dasd_state_basic_to_ready(struct dasd_device *device) block->blocks << block->s2b_shift); device->state = DASD_STATE_READY; rc = dasd_scan_partitions(block); - if (rc) { + if (rc) device->state = DASD_STATE_BASIC; - return rc; - } } else { device->state = DASD_STATE_READY; } -out: - if (device->discipline->basic_to_ready) - rc = device->discipline->basic_to_ready(device); return rc; } @@ -377,11 +368,6 @@ static int dasd_state_ready_to_basic(struct dasd_device *device) { int rc; - if (device->discipline->ready_to_basic) { - rc = device->discipline->ready_to_basic(device); - if (rc) - return rc; - } device->state = DASD_STATE_BASIC; if (device->block) { struct dasd_block *block = device->block; @@ -416,10 +402,16 @@ static int dasd_state_unfmt_to_basic(struct dasd_device *device) static int dasd_state_ready_to_online(struct dasd_device * device) { + int rc; struct gendisk *disk; struct disk_part_iter piter; struct hd_struct *part; + if (device->discipline->ready_to_online) { + rc = device->discipline->ready_to_online(device); + if (rc) + return rc; + } device->state = DASD_STATE_ONLINE; if (device->block) { dasd_schedule_block_bh(device->block); @@ -452,7 +444,6 @@ static int dasd_state_online_to_ready(struct dasd_device *device) if (rc) return rc; } - device->state = DASD_STATE_READY; if (device->block && !(device->features & DASD_FEATURE_USERAW)) { disk = device->block->bdev->bd_disk; @@ -2232,77 +2223,6 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) return rc; } -static inline int _wait_for_wakeup_queue(struct list_head *ccw_queue) -{ - struct dasd_ccw_req *cqr; - - list_for_each_entry(cqr, ccw_queue, blocklist) { - if (cqr->callback_data != DASD_SLEEPON_END_TAG) - return 0; - } - - return 1; -} - -static int _dasd_sleep_on_queue(struct list_head *ccw_queue, int interruptible) -{ - struct dasd_device *device; - int rc; - struct dasd_ccw_req *cqr, *n; - -retry: - list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) { - device = cqr->startdev; - if (cqr->status != DASD_CQR_FILLED) /*could be failed*/ - continue; - - if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags) && - !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) { - cqr->status = DASD_CQR_FAILED; - cqr->intrc = -EPERM; - continue; - } - /*Non-temporary stop condition will trigger fail fast*/ - if (device->stopped & ~DASD_STOPPED_PENDING && - test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && - !dasd_eer_enabled(device)) { - cqr->status = DASD_CQR_FAILED; - cqr->intrc = -EAGAIN; - continue; - } - - /*Don't try to start requests if device is stopped*/ - if (interruptible) { - rc = wait_event_interruptible( - generic_waitq, !device->stopped); - if (rc == -ERESTARTSYS) { - cqr->status = DASD_CQR_FAILED; - cqr->intrc = rc; - continue; - } - } else - wait_event(generic_waitq, !(device->stopped)); - - if (!cqr->callback) - cqr->callback = dasd_wakeup_cb; - cqr->callback_data = DASD_SLEEPON_START_TAG; - dasd_add_request_tail(cqr); - } - - wait_event(generic_waitq, _wait_for_wakeup_queue(ccw_queue)); - - rc = 0; - list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) { - if (__dasd_sleep_on_erp(cqr)) - rc = 1; - } - if (rc) - goto retry; - - - return 0; -} - /* * Queue a request to the tail of the device ccw_queue and wait for * it's completion. @@ -2312,15 +2232,6 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr) return _dasd_sleep_on(cqr, 0); } -/* - * Start requests from a ccw_queue and wait for their completion. - */ -int dasd_sleep_on_queue(struct list_head *ccw_queue) -{ - return _dasd_sleep_on_queue(ccw_queue, 0); -} -EXPORT_SYMBOL(dasd_sleep_on_queue); - /* * Queue a request to the tail of the device ccw_queue and wait * interruptible for it's completion. @@ -2751,26 +2662,6 @@ static void _dasd_wake_block_flush_cb(struct dasd_ccw_req *cqr, void *data) wake_up(&dasd_flush_wq); } -/* - * Requeue a request back to the block request queue - * only works for block requests - */ -static int _dasd_requeue_request(struct dasd_ccw_req *cqr) -{ - struct dasd_block *block = cqr->block; - struct request *req; - unsigned long flags; - - if (!block) - return -EINVAL; - spin_lock_irqsave(&block->queue_lock, flags); - req = (struct request *) cqr->callback_data; - blk_requeue_request(block->request_queue, req); - spin_unlock_irqrestore(&block->queue_lock, flags); - - return 0; -} - /* * Go through all request on the dasd_block request queue, cancel them * on the respective dasd_device, and return them to the generic @@ -3489,11 +3380,10 @@ EXPORT_SYMBOL_GPL(dasd_generic_verify_path); int dasd_generic_pm_freeze(struct ccw_device *cdev) { - struct dasd_device *device = dasd_device_from_cdev(cdev); - struct list_head freeze_queue; struct dasd_ccw_req *cqr, *n; - struct dasd_ccw_req *refers; int rc; + struct list_head freeze_queue; + struct dasd_device *device = dasd_device_from_cdev(cdev); if (IS_ERR(device)) return PTR_ERR(device); @@ -3506,8 +3396,7 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev) /* disallow new I/O */ dasd_device_set_stop_bits(device, DASD_STOPPED_PM); - - /* clear active requests and requeue them to block layer if possible */ + /* clear active requests */ INIT_LIST_HEAD(&freeze_queue); spin_lock_irq(get_ccwdev_lock(cdev)); rc = 0; @@ -3527,6 +3416,7 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev) } list_move_tail(&cqr->devlist, &freeze_queue); } + spin_unlock_irq(get_ccwdev_lock(cdev)); list_for_each_entry_safe(cqr, n, &freeze_queue, devlist) { @@ -3534,38 +3424,12 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev) (cqr->status != DASD_CQR_CLEAR_PENDING)); if (cqr->status == DASD_CQR_CLEARED) cqr->status = DASD_CQR_QUEUED; - - /* requeue requests to blocklayer will only work for - block device requests */ - if (_dasd_requeue_request(cqr)) - continue; - - /* remove requests from device and block queue */ - list_del_init(&cqr->devlist); - while (cqr->refers != NULL) { - refers = cqr->refers; - /* remove the request from the block queue */ - list_del(&cqr->blocklist); - /* free the finished erp request */ - dasd_free_erp_request(cqr, cqr->memdev); - cqr = refers; - } - if (cqr->block) - list_del_init(&cqr->blocklist); - cqr->block->base->discipline->free_cp( - cqr, (struct request *) cqr->callback_data); } + /* move freeze_queue to start of the ccw_queue */ + spin_lock_irq(get_ccwdev_lock(cdev)); + list_splice_tail(&freeze_queue, &device->ccw_queue); + spin_unlock_irq(get_ccwdev_lock(cdev)); - /* - * if requests remain then they are internal request - * and go back to the device queue - */ - if (!list_empty(&freeze_queue)) { - /* move freeze_queue to start of the ccw_queue */ - spin_lock_irq(get_ccwdev_lock(cdev)); - list_splice_tail(&freeze_queue, &device->ccw_queue); - spin_unlock_irq(get_ccwdev_lock(cdev)); - } dasd_put_device(device); return rc; } diff --git a/trunk/drivers/s390/block/dasd_devmap.c b/trunk/drivers/s390/block/dasd_devmap.c index a71bb8aaca1d..c196827c228f 100644 --- a/trunk/drivers/s390/block/dasd_devmap.c +++ b/trunk/drivers/s390/block/dasd_devmap.c @@ -410,7 +410,8 @@ dasd_add_busid(const char *bus_id, int features) struct dasd_devmap *devmap, *new, *tmp; int hash; - new = kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); + new = (struct dasd_devmap *) + kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); if (!new) return ERR_PTR(-ENOMEM); spin_lock(&dasd_devmap_lock); diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index 6a44b27623ed..6999fd919e94 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -2022,7 +2022,7 @@ static int dasd_eckd_do_analysis(struct dasd_block *block) return dasd_eckd_end_analysis(block); } -static int dasd_eckd_basic_to_ready(struct dasd_device *device) +static int dasd_eckd_ready_to_online(struct dasd_device *device) { return dasd_alias_add_device(device); }; @@ -2031,11 +2031,6 @@ static int dasd_eckd_online_to_ready(struct dasd_device *device) { cancel_work_sync(&device->reload_device); cancel_work_sync(&device->kick_validate); - return 0; -}; - -static int dasd_eckd_ready_to_basic(struct dasd_device *device) -{ return dasd_alias_remove_device(device); }; @@ -2055,34 +2050,45 @@ dasd_eckd_fill_geometry(struct dasd_block *block, struct hd_geometry *geo) } static struct dasd_ccw_req * -dasd_eckd_build_format(struct dasd_device *base, - struct format_data_t *fdata) +dasd_eckd_format_device(struct dasd_device * device, + struct format_data_t * fdata) { - struct dasd_eckd_private *base_priv; - struct dasd_eckd_private *start_priv; - struct dasd_device *startdev; + struct dasd_eckd_private *private; struct dasd_ccw_req *fcp; struct eckd_count *ect; - struct ch_t address; struct ccw1 *ccw; void *data; int rpt; + struct ch_t address; int cplength, datasize; - int i, j; + int i; int intensity = 0; int r0_perm; - int nr_tracks; - - startdev = dasd_alias_get_start_dev(base); - if (!startdev) - startdev = base; - - start_priv = (struct dasd_eckd_private *) startdev->private; - base_priv = (struct dasd_eckd_private *) base->private; - rpt = recs_per_track(&base_priv->rdc_data, 0, fdata->blksize); + private = (struct dasd_eckd_private *) device->private; + rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize); + set_ch_t(&address, + fdata->start_unit / private->rdc_data.trk_per_cyl, + fdata->start_unit % private->rdc_data.trk_per_cyl); - nr_tracks = fdata->stop_unit - fdata->start_unit + 1; + /* Sanity checks. */ + if (fdata->start_unit >= + (private->real_cyl * private->rdc_data.trk_per_cyl)) { + dev_warn(&device->cdev->dev, "Start track number %d used in " + "formatting is too big\n", fdata->start_unit); + return ERR_PTR(-EINVAL); + } + if (fdata->start_unit > fdata->stop_unit) { + dev_warn(&device->cdev->dev, "Start track %d used in " + "formatting exceeds end track\n", fdata->start_unit); + return ERR_PTR(-EINVAL); + } + if (dasd_check_blocksize(fdata->blksize) != 0) { + dev_warn(&device->cdev->dev, + "The DASD cannot be formatted with block size %d\n", + fdata->blksize); + return ERR_PTR(-EINVAL); + } /* * fdata->intensity is a bit string that tells us what to do: @@ -2100,282 +2106,149 @@ dasd_eckd_build_format(struct dasd_device *base, r0_perm = 1; intensity = fdata->intensity; } - switch (intensity) { case 0x00: /* Normal format */ case 0x08: /* Normal format, use cdl. */ - cplength = 2 + (rpt*nr_tracks); - datasize = sizeof(struct PFX_eckd_data) + + cplength = 2 + rpt; + datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) + - rpt * nr_tracks * sizeof(struct eckd_count); + rpt * sizeof(struct eckd_count); break; case 0x01: /* Write record zero and format track. */ case 0x09: /* Write record zero and format track, use cdl. */ - cplength = 2 + rpt * nr_tracks; - datasize = sizeof(struct PFX_eckd_data) + + cplength = 3 + rpt; + datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) + sizeof(struct eckd_count) + - rpt * nr_tracks * sizeof(struct eckd_count); + rpt * sizeof(struct eckd_count); break; case 0x04: /* Invalidate track. */ case 0x0c: /* Invalidate track, use cdl. */ cplength = 3; - datasize = sizeof(struct PFX_eckd_data) + + datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) + sizeof(struct eckd_count); break; default: - dev_warn(&startdev->cdev->dev, - "An I/O control call used incorrect flags 0x%x\n", - fdata->intensity); + dev_warn(&device->cdev->dev, "An I/O control call used " + "incorrect flags 0x%x\n", fdata->intensity); return ERR_PTR(-EINVAL); } /* Allocate the format ccw request. */ - fcp = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, - datasize, startdev); + fcp = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize, device); if (IS_ERR(fcp)) return fcp; - start_priv->count++; data = fcp->data; ccw = fcp->cpaddr; switch (intensity & ~0x08) { case 0x00: /* Normal format. */ - prefix(ccw++, (struct PFX_eckd_data *) data, - fdata->start_unit, fdata->stop_unit, - DASD_ECKD_CCW_WRITE_CKD, base, startdev); + define_extent(ccw++, (struct DE_eckd_data *) data, + fdata->start_unit, fdata->start_unit, + DASD_ECKD_CCW_WRITE_CKD, device); /* grant subsystem permission to format R0 */ if (r0_perm) - ((struct PFX_eckd_data *)data) - ->define_extent.ga_extended |= 0x04; - data += sizeof(struct PFX_eckd_data); + ((struct DE_eckd_data *)data)->ga_extended |= 0x04; + data += sizeof(struct DE_eckd_data); ccw[-1].flags |= CCW_FLAG_CC; locate_record(ccw++, (struct LO_eckd_data *) data, - fdata->start_unit, 0, rpt*nr_tracks, - DASD_ECKD_CCW_WRITE_CKD, base, + fdata->start_unit, 0, rpt, + DASD_ECKD_CCW_WRITE_CKD, device, fdata->blksize); data += sizeof(struct LO_eckd_data); break; case 0x01: /* Write record zero + format track. */ - prefix(ccw++, (struct PFX_eckd_data *) data, - fdata->start_unit, fdata->stop_unit, - DASD_ECKD_CCW_WRITE_RECORD_ZERO, - base, startdev); - data += sizeof(struct PFX_eckd_data); + define_extent(ccw++, (struct DE_eckd_data *) data, + fdata->start_unit, fdata->start_unit, + DASD_ECKD_CCW_WRITE_RECORD_ZERO, + device); + data += sizeof(struct DE_eckd_data); ccw[-1].flags |= CCW_FLAG_CC; locate_record(ccw++, (struct LO_eckd_data *) data, - fdata->start_unit, 0, rpt * nr_tracks + 1, - DASD_ECKD_CCW_WRITE_RECORD_ZERO, base, - base->block->bp_block); + fdata->start_unit, 0, rpt + 1, + DASD_ECKD_CCW_WRITE_RECORD_ZERO, device, + device->block->bp_block); data += sizeof(struct LO_eckd_data); break; case 0x04: /* Invalidate track. */ - prefix(ccw++, (struct PFX_eckd_data *) data, - fdata->start_unit, fdata->stop_unit, - DASD_ECKD_CCW_WRITE_CKD, base, startdev); - data += sizeof(struct PFX_eckd_data); + define_extent(ccw++, (struct DE_eckd_data *) data, + fdata->start_unit, fdata->start_unit, + DASD_ECKD_CCW_WRITE_CKD, device); + data += sizeof(struct DE_eckd_data); ccw[-1].flags |= CCW_FLAG_CC; locate_record(ccw++, (struct LO_eckd_data *) data, fdata->start_unit, 0, 1, - DASD_ECKD_CCW_WRITE_CKD, base, 8); + DASD_ECKD_CCW_WRITE_CKD, device, 8); data += sizeof(struct LO_eckd_data); break; } - - for (j = 0; j < nr_tracks; j++) { - /* calculate cylinder and head for the current track */ - set_ch_t(&address, - (fdata->start_unit + j) / - base_priv->rdc_data.trk_per_cyl, - (fdata->start_unit + j) % - base_priv->rdc_data.trk_per_cyl); - if (intensity & 0x01) { /* write record zero */ - ect = (struct eckd_count *) data; - data += sizeof(struct eckd_count); - ect->cyl = address.cyl; - ect->head = address.head; - ect->record = 0; - ect->kl = 0; - ect->dl = 8; - ccw[-1].flags |= CCW_FLAG_CC; - ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO; - ccw->flags = CCW_FLAG_SLI; - ccw->count = 8; - ccw->cda = (__u32)(addr_t) ect; - ccw++; - } - if ((intensity & ~0x08) & 0x04) { /* erase track */ + if (intensity & 0x01) { /* write record zero */ + ect = (struct eckd_count *) data; + data += sizeof(struct eckd_count); + ect->cyl = address.cyl; + ect->head = address.head; + ect->record = 0; + ect->kl = 0; + ect->dl = 8; + ccw[-1].flags |= CCW_FLAG_CC; + ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO; + ccw->flags = CCW_FLAG_SLI; + ccw->count = 8; + ccw->cda = (__u32)(addr_t) ect; + ccw++; + } + if ((intensity & ~0x08) & 0x04) { /* erase track */ + ect = (struct eckd_count *) data; + data += sizeof(struct eckd_count); + ect->cyl = address.cyl; + ect->head = address.head; + ect->record = 1; + ect->kl = 0; + ect->dl = 0; + ccw[-1].flags |= CCW_FLAG_CC; + ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD; + ccw->flags = CCW_FLAG_SLI; + ccw->count = 8; + ccw->cda = (__u32)(addr_t) ect; + } else { /* write remaining records */ + for (i = 0; i < rpt; i++) { ect = (struct eckd_count *) data; data += sizeof(struct eckd_count); ect->cyl = address.cyl; ect->head = address.head; - ect->record = 1; + ect->record = i + 1; ect->kl = 0; - ect->dl = 0; + ect->dl = fdata->blksize; + /* Check for special tracks 0-1 when formatting CDL */ + if ((intensity & 0x08) && + fdata->start_unit == 0) { + if (i < 3) { + ect->kl = 4; + ect->dl = sizes_trk0[i] - 4; + } + } + if ((intensity & 0x08) && + fdata->start_unit == 1) { + ect->kl = 44; + ect->dl = LABEL_SIZE - 44; + } ccw[-1].flags |= CCW_FLAG_CC; ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD; ccw->flags = CCW_FLAG_SLI; ccw->count = 8; ccw->cda = (__u32)(addr_t) ect; - } else { /* write remaining records */ - for (i = 0; i < rpt; i++) { - ect = (struct eckd_count *) data; - data += sizeof(struct eckd_count); - ect->cyl = address.cyl; - ect->head = address.head; - ect->record = i + 1; - ect->kl = 0; - ect->dl = fdata->blksize; - /* - * Check for special tracks 0-1 - * when formatting CDL - */ - if ((intensity & 0x08) && - fdata->start_unit == 0) { - if (i < 3) { - ect->kl = 4; - ect->dl = sizes_trk0[i] - 4; - } - } - if ((intensity & 0x08) && - fdata->start_unit == 1) { - ect->kl = 44; - ect->dl = LABEL_SIZE - 44; - } - ccw[-1].flags |= CCW_FLAG_CC; - if (i != 0 || j == 0) - ccw->cmd_code = - DASD_ECKD_CCW_WRITE_CKD; - else - ccw->cmd_code = - DASD_ECKD_CCW_WRITE_CKD_MT; - ccw->flags = CCW_FLAG_SLI; - ccw->count = 8; - ccw->cda = (__u32)(addr_t) ect; - ccw++; - } + ccw++; } } - - fcp->startdev = startdev; - fcp->memdev = startdev; + fcp->startdev = device; + fcp->memdev = device; fcp->retries = 256; - fcp->expires = startdev->default_expires * HZ; fcp->buildclk = get_tod_clock(); fcp->status = DASD_CQR_FILLED; - return fcp; } -static int -dasd_eckd_format_device(struct dasd_device *base, - struct format_data_t *fdata) -{ - struct dasd_ccw_req *cqr, *n; - struct dasd_block *block; - struct dasd_eckd_private *private; - struct list_head format_queue; - struct dasd_device *device; - int old_stop, format_step; - int step, rc = 0; - - block = base->block; - private = (struct dasd_eckd_private *) base->private; - - /* Sanity checks. */ - if (fdata->start_unit >= - (private->real_cyl * private->rdc_data.trk_per_cyl)) { - dev_warn(&base->cdev->dev, - "Start track number %u used in formatting is too big\n", - fdata->start_unit); - return -EINVAL; - } - if (fdata->stop_unit >= - (private->real_cyl * private->rdc_data.trk_per_cyl)) { - dev_warn(&base->cdev->dev, - "Stop track number %u used in formatting is too big\n", - fdata->stop_unit); - return -EINVAL; - } - if (fdata->start_unit > fdata->stop_unit) { - dev_warn(&base->cdev->dev, - "Start track %u used in formatting exceeds end track\n", - fdata->start_unit); - return -EINVAL; - } - if (dasd_check_blocksize(fdata->blksize) != 0) { - dev_warn(&base->cdev->dev, - "The DASD cannot be formatted with block size %u\n", - fdata->blksize); - return -EINVAL; - } - - INIT_LIST_HEAD(&format_queue); - old_stop = fdata->stop_unit; - - while (fdata->start_unit <= 1) { - fdata->stop_unit = fdata->start_unit; - cqr = dasd_eckd_build_format(base, fdata); - list_add(&cqr->blocklist, &format_queue); - - fdata->stop_unit = old_stop; - fdata->start_unit++; - - if (fdata->start_unit > fdata->stop_unit) - goto sleep; - } - -retry: - format_step = 255 / recs_per_track(&private->rdc_data, 0, - fdata->blksize); - while (fdata->start_unit <= old_stop) { - step = fdata->stop_unit - fdata->start_unit + 1; - if (step > format_step) - fdata->stop_unit = fdata->start_unit + format_step - 1; - - cqr = dasd_eckd_build_format(base, fdata); - if (IS_ERR(cqr)) { - if (PTR_ERR(cqr) == -ENOMEM) { - /* - * not enough memory available - * go to out and start requests - * retry after first requests were finished - */ - fdata->stop_unit = old_stop; - goto sleep; - } else - return PTR_ERR(cqr); - } - list_add(&cqr->blocklist, &format_queue); - - fdata->start_unit = fdata->stop_unit + 1; - fdata->stop_unit = old_stop; - } - -sleep: - dasd_sleep_on_queue(&format_queue); - - list_for_each_entry_safe(cqr, n, &format_queue, blocklist) { - device = cqr->startdev; - private = (struct dasd_eckd_private *) device->private; - if (cqr->status == DASD_CQR_FAILED) - rc = -EIO; - list_del_init(&cqr->blocklist); - dasd_sfree_request(cqr, device); - private->count--; - } - - /* - * in case of ENOMEM we need to retry after - * first requests are finished - */ - if (fdata->start_unit <= fdata->stop_unit) - goto retry; - - return rc; -} - static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr) { cqr->status = DASD_CQR_FILLED; @@ -4432,9 +4305,8 @@ static struct dasd_discipline dasd_eckd_discipline = { .uncheck_device = dasd_eckd_uncheck_device, .do_analysis = dasd_eckd_do_analysis, .verify_path = dasd_eckd_verify_path, - .basic_to_ready = dasd_eckd_basic_to_ready, + .ready_to_online = dasd_eckd_ready_to_online, .online_to_ready = dasd_eckd_online_to_ready, - .ready_to_basic = dasd_eckd_ready_to_basic, .fill_geometry = dasd_eckd_fill_geometry, .start_IO = dasd_start_IO, .term_IO = dasd_term_IO, diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index 0785bd9bd5b6..899e3f5a56e5 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -300,11 +300,10 @@ struct dasd_discipline { * Last things to do when a device is set online, and first things * when it is set offline. */ - int (*basic_to_ready) (struct dasd_device *); + int (*ready_to_online) (struct dasd_device *); int (*online_to_ready) (struct dasd_device *); - int (*ready_to_basic) (struct dasd_device *); - /* (struct dasd_device *); + /* * Device operation functions. build_cp creates a ccw chain for * a block device request, start_io starts the request and * term_IO cancels it (e.g. in case of a timeout). format_device @@ -318,8 +317,8 @@ struct dasd_discipline { int (*start_IO) (struct dasd_ccw_req *); int (*term_IO) (struct dasd_ccw_req *); void (*handle_terminated_request) (struct dasd_ccw_req *); - int (*format_device) (struct dasd_device *, - struct format_data_t *); + struct dasd_ccw_req *(*format_device) (struct dasd_device *, + struct format_data_t *); int (*free_cp) (struct dasd_ccw_req *, struct request *); /* @@ -673,7 +672,6 @@ int dasd_term_IO(struct dasd_ccw_req *); void dasd_schedule_device_bh(struct dasd_device *); void dasd_schedule_block_bh(struct dasd_block *); int dasd_sleep_on(struct dasd_ccw_req *); -int dasd_sleep_on_queue(struct list_head *); int dasd_sleep_on_immediatly(struct dasd_ccw_req *); int dasd_sleep_on_interruptible(struct dasd_ccw_req *); void dasd_device_set_timer(struct dasd_device *, int); diff --git a/trunk/drivers/s390/block/dasd_ioctl.c b/trunk/drivers/s390/block/dasd_ioctl.c index 8be1b51e9311..03c0e0444553 100644 --- a/trunk/drivers/s390/block/dasd_ioctl.c +++ b/trunk/drivers/s390/block/dasd_ioctl.c @@ -143,12 +143,12 @@ static int dasd_ioctl_resume(struct dasd_block *block) /* * performs formatting of _device_ according to _fdata_ * Note: The discipline's format_function is assumed to deliver formatting - * commands to format multiple units of the device. In terms of the ECKD - * devices this means CCWs are generated to format multiple tracks. + * commands to format a single unit of the device. In terms of the ECKD + * devices this means CCWs are generated to format a single track. */ -static int -dasd_format(struct dasd_block *block, struct format_data_t *fdata) +static int dasd_format(struct dasd_block *block, struct format_data_t *fdata) { + struct dasd_ccw_req *cqr; struct dasd_device *base; int rc; @@ -157,8 +157,8 @@ dasd_format(struct dasd_block *block, struct format_data_t *fdata) return -EPERM; if (base->state != DASD_STATE_BASIC) { - pr_warn("%s: The DASD cannot be formatted while it is enabled\n", - dev_name(&base->cdev->dev)); + pr_warning("%s: The DASD cannot be formatted while it is " + "enabled\n", dev_name(&base->cdev->dev)); return -EBUSY; } @@ -178,10 +178,21 @@ dasd_format(struct dasd_block *block, struct format_data_t *fdata) bdput(bdev); } - rc = base->discipline->format_device(base, fdata); - if (rc) - return rc; - + while (fdata->start_unit <= fdata->stop_unit) { + cqr = base->discipline->format_device(base, fdata); + if (IS_ERR(cqr)) + return PTR_ERR(cqr); + rc = dasd_sleep_on_interruptible(cqr); + dasd_sfree_request(cqr, cqr->memdev); + if (rc) { + if (rc != -ERESTARTSYS) + pr_err("%s: Formatting unit %d failed with " + "rc=%d\n", dev_name(&base->cdev->dev), + fdata->start_unit, rc); + return rc; + } + fdata->start_unit++; + } return 0; } diff --git a/trunk/drivers/s390/block/scm_blk.c b/trunk/drivers/s390/block/scm_blk.c index b303cab76a7f..9978ad4433cb 100644 --- a/trunk/drivers/s390/block/scm_blk.c +++ b/trunk/drivers/s390/block/scm_blk.c @@ -135,11 +135,6 @@ static const struct block_device_operations scm_blk_devops = { .release = scm_release, }; -static bool scm_permit_request(struct scm_blk_dev *bdev, struct request *req) -{ - return rq_data_dir(req) != WRITE || bdev->state != SCM_WR_PROHIBIT; -} - static void scm_request_prepare(struct scm_request *scmrq) { struct scm_blk_dev *bdev = scmrq->bdev; @@ -200,18 +195,14 @@ void scm_request_requeue(struct scm_request *scmrq) scm_release_cluster(scmrq); blk_requeue_request(bdev->rq, scmrq->request); - atomic_dec(&bdev->queued_reqs); scm_request_done(scmrq); scm_ensure_queue_restart(bdev); } void scm_request_finish(struct scm_request *scmrq) { - struct scm_blk_dev *bdev = scmrq->bdev; - scm_release_cluster(scmrq); blk_end_request_all(scmrq->request, scmrq->error); - atomic_dec(&bdev->queued_reqs); scm_request_done(scmrq); } @@ -227,10 +218,6 @@ static void scm_blk_request(struct request_queue *rq) if (req->cmd_type != REQ_TYPE_FS) continue; - if (!scm_permit_request(bdev, req)) { - scm_ensure_queue_restart(bdev); - return; - } scmrq = scm_request_fetch(); if (!scmrq) { SCM_LOG(5, "no request"); @@ -244,13 +231,11 @@ static void scm_blk_request(struct request_queue *rq) return; } if (scm_need_cluster_request(scmrq)) { - atomic_inc(&bdev->queued_reqs); blk_start_request(req); scm_initiate_cluster_request(scmrq); return; } scm_request_prepare(scmrq); - atomic_inc(&bdev->queued_reqs); blk_start_request(req); ret = scm_start_aob(scmrq->aob); @@ -259,6 +244,7 @@ static void scm_blk_request(struct request_queue *rq) scm_request_requeue(scmrq); return; } + atomic_inc(&bdev->queued_reqs); } } @@ -294,38 +280,6 @@ void scm_blk_irq(struct scm_device *scmdev, void *data, int error) tasklet_hi_schedule(&bdev->tasklet); } -static void scm_blk_handle_error(struct scm_request *scmrq) -{ - struct scm_blk_dev *bdev = scmrq->bdev; - unsigned long flags; - - if (scmrq->error != -EIO) - goto restart; - - /* For -EIO the response block is valid. */ - switch (scmrq->aob->response.eqc) { - case EQC_WR_PROHIBIT: - spin_lock_irqsave(&bdev->lock, flags); - if (bdev->state != SCM_WR_PROHIBIT) - pr_info("%lx: Write access to the SCM increment is suspended\n", - (unsigned long) bdev->scmdev->address); - bdev->state = SCM_WR_PROHIBIT; - spin_unlock_irqrestore(&bdev->lock, flags); - goto requeue; - default: - break; - } - -restart: - if (!scm_start_aob(scmrq->aob)) - return; - -requeue: - spin_lock_irqsave(&bdev->rq_lock, flags); - scm_request_requeue(scmrq); - spin_unlock_irqrestore(&bdev->rq_lock, flags); -} - static void scm_blk_tasklet(struct scm_blk_dev *bdev) { struct scm_request *scmrq; @@ -339,8 +293,11 @@ static void scm_blk_tasklet(struct scm_blk_dev *bdev) spin_unlock_irqrestore(&bdev->lock, flags); if (scmrq->error && scmrq->retries-- > 0) { - scm_blk_handle_error(scmrq); - + if (scm_start_aob(scmrq->aob)) { + spin_lock_irqsave(&bdev->rq_lock, flags); + scm_request_requeue(scmrq); + spin_unlock_irqrestore(&bdev->rq_lock, flags); + } /* Request restarted or requeued, handle next. */ spin_lock_irqsave(&bdev->lock, flags); continue; @@ -353,6 +310,7 @@ static void scm_blk_tasklet(struct scm_blk_dev *bdev) } scm_request_finish(scmrq); + atomic_dec(&bdev->queued_reqs); spin_lock_irqsave(&bdev->lock, flags); } spin_unlock_irqrestore(&bdev->lock, flags); @@ -374,7 +332,6 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) } bdev->scmdev = scmdev; - bdev->state = SCM_OPER; spin_lock_init(&bdev->rq_lock); spin_lock_init(&bdev->lock); INIT_LIST_HEAD(&bdev->finished_requests); @@ -439,18 +396,6 @@ void scm_blk_dev_cleanup(struct scm_blk_dev *bdev) put_disk(bdev->gendisk); } -void scm_blk_set_available(struct scm_blk_dev *bdev) -{ - unsigned long flags; - - spin_lock_irqsave(&bdev->lock, flags); - if (bdev->state == SCM_WR_PROHIBIT) - pr_info("%lx: Write access to the SCM increment is restored\n", - (unsigned long) bdev->scmdev->address); - bdev->state = SCM_OPER; - spin_unlock_irqrestore(&bdev->lock, flags); -} - static int __init scm_blk_init(void) { int ret = -EINVAL; @@ -463,15 +408,12 @@ static int __init scm_blk_init(void) goto out; scm_major = ret; - ret = scm_alloc_rqs(nr_requests); - if (ret) - goto out_free; + if (scm_alloc_rqs(nr_requests)) + goto out_unreg; scm_debug = debug_register("scm_log", 16, 1, 16); - if (!scm_debug) { - ret = -ENOMEM; + if (!scm_debug) goto out_free; - } debug_register_view(scm_debug, &debug_hex_ascii_view); debug_set_level(scm_debug, 2); @@ -486,6 +428,7 @@ static int __init scm_blk_init(void) debug_unregister(scm_debug); out_free: scm_free_rqs(); +out_unreg: unregister_blkdev(scm_major, "scm"); out: return ret; diff --git a/trunk/drivers/s390/block/scm_blk.h b/trunk/drivers/s390/block/scm_blk.h index 8b387b32fd62..3c1ccf494647 100644 --- a/trunk/drivers/s390/block/scm_blk.h +++ b/trunk/drivers/s390/block/scm_blk.h @@ -21,7 +21,6 @@ struct scm_blk_dev { spinlock_t rq_lock; /* guard the request queue */ spinlock_t lock; /* guard the rest of the blockdev */ atomic_t queued_reqs; - enum {SCM_OPER, SCM_WR_PROHIBIT} state; struct list_head finished_requests; #ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE struct list_head cluster_list; @@ -49,7 +48,6 @@ struct scm_request { int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *); void scm_blk_dev_cleanup(struct scm_blk_dev *); -void scm_blk_set_available(struct scm_blk_dev *); void scm_blk_irq(struct scm_device *, void *, int); void scm_request_finish(struct scm_request *); diff --git a/trunk/drivers/s390/block/scm_blk_cluster.c b/trunk/drivers/s390/block/scm_blk_cluster.c index c0d102e3a48b..f4bb61b0cea1 100644 --- a/trunk/drivers/s390/block/scm_blk_cluster.c +++ b/trunk/drivers/s390/block/scm_blk_cluster.c @@ -223,8 +223,6 @@ void scm_cluster_request_irq(struct scm_request *scmrq) bool scm_cluster_size_valid(void) { - if (write_cluster_size == 1 || write_cluster_size > 128) - return false; - - return !(write_cluster_size & (write_cluster_size - 1)); + return write_cluster_size == 0 || write_cluster_size == 32 || + write_cluster_size == 64 || write_cluster_size == 128; } diff --git a/trunk/drivers/s390/block/scm_drv.c b/trunk/drivers/s390/block/scm_drv.c index c98cf52d78d1..9fa0a908607b 100644 --- a/trunk/drivers/s390/block/scm_drv.c +++ b/trunk/drivers/s390/block/scm_drv.c @@ -13,23 +13,12 @@ #include #include "scm_blk.h" -static void scm_notify(struct scm_device *scmdev, enum scm_event event) +static void notify(struct scm_device *scmdev) { - struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev); - - switch (event) { - case SCM_CHANGE: - pr_info("%lx: The capabilities of the SCM increment changed\n", - (unsigned long) scmdev->address); - SCM_LOG(2, "State changed"); - SCM_LOG_STATE(2, scmdev); - break; - case SCM_AVAIL: - SCM_LOG(2, "Increment available"); - SCM_LOG_STATE(2, scmdev); - scm_blk_set_available(bdev); - break; - } + pr_info("%lu: The capabilities of the SCM increment changed\n", + (unsigned long) scmdev->address); + SCM_LOG(2, "State changed"); + SCM_LOG_STATE(2, scmdev); } static int scm_probe(struct scm_device *scmdev) @@ -75,7 +64,7 @@ static struct scm_driver scm_drv = { .name = "scm_block", .owner = THIS_MODULE, }, - .notify = scm_notify, + .notify = notify, .probe = scm_probe, .remove = scm_remove, .handler = scm_blk_irq, diff --git a/trunk/drivers/s390/char/con3215.c b/trunk/drivers/s390/char/con3215.c index eb5d22795c47..7b00fa634d40 100644 --- a/trunk/drivers/s390/char/con3215.c +++ b/trunk/drivers/s390/char/con3215.c @@ -502,7 +502,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length) raw3215_try_io(raw); raw->flags &= ~RAW3215_FLUSHING; #ifdef CONFIG_TN3215_CONSOLE - ccw_device_wait_idle(raw->cdev); + wait_cons_dev(); #endif /* Enough room freed up ? */ if (RAW3215_BUFFER_SIZE - raw->count >= length) @@ -858,7 +858,7 @@ static void con3215_flush(void) raw = raw3215[0]; /* console 3215 is the first one */ if (raw->port.flags & ASYNC_SUSPENDED) /* The console is still frozen for suspend. */ - if (ccw_device_force_console(raw->cdev)) + if (ccw_device_force_console()) /* Forcing didn't work, no panic message .. */ return; spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); diff --git a/trunk/drivers/s390/char/monreader.c b/trunk/drivers/s390/char/monreader.c index 0da3ae3cd63b..f4ff515db251 100644 --- a/trunk/drivers/s390/char/monreader.c +++ b/trunk/drivers/s390/char/monreader.c @@ -174,7 +174,8 @@ static void mon_free_mem(struct mon_private *monpriv) int i; for (i = 0; i < MON_MSGLIM; i++) - kfree(monpriv->msg_array[i]); + if (monpriv->msg_array[i]) + kfree(monpriv->msg_array[i]); kfree(monpriv); } diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index 24a08e8f19e1..4c9030a5b9f2 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -796,7 +796,7 @@ struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev) do { __raw3270_reset_device(rp); while (!raw3270_state_final(rp)) { - ccw_device_wait_idle(rp->cdev); + wait_cons_dev(); barrier(); } } while (rp->state != RAW3270_STATE_READY); @@ -810,7 +810,7 @@ raw3270_wait_cons_dev(struct raw3270 *rp) unsigned long flags; spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags); - ccw_device_wait_idle(rp->cdev); + wait_cons_dev(); spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); } @@ -1274,7 +1274,7 @@ void raw3270_pm_unfreeze(struct raw3270_view *view) rp = view->dev; if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) - ccw_device_force_console(rp->cdev); + ccw_device_force_console(); #endif } diff --git a/trunk/drivers/s390/char/sclp_cmd.c b/trunk/drivers/s390/char/sclp_cmd.c index 178836ec252b..30a2255389e5 100644 --- a/trunk/drivers/s390/char/sclp_cmd.c +++ b/trunk/drivers/s390/char/sclp_cmd.c @@ -561,8 +561,6 @@ static void __init sclp_add_standby_memory(void) add_memory_merged(0); } -#define MEM_SCT_SIZE (1UL << SECTION_SIZE_BITS) - static void __init insert_increment(u16 rn, int standby, int assigned) { struct memory_increment *incr, *new_incr; @@ -575,7 +573,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) new_incr->rn = rn; new_incr->standby = standby; if (!standby) - new_incr->usecount = rzm > MEM_SCT_SIZE ? rzm/MEM_SCT_SIZE : 1; + new_incr->usecount = 1; last_rn = 0; prev = &sclp_mem_list; list_for_each_entry(incr, &sclp_mem_list, list) { @@ -629,8 +627,6 @@ static int __init sclp_detect_standby_memory(void) struct read_storage_sccb *sccb; int i, id, assigned, rc; - if (OLDMEM_BASE) /* No standby memory in kdump mode */ - return 0; if (!early_read_info_sccb_valid) return 0; if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL) diff --git a/trunk/drivers/s390/char/tty3270.c b/trunk/drivers/s390/char/tty3270.c index cee69dac3e18..b907dba24025 100644 --- a/trunk/drivers/s390/char/tty3270.c +++ b/trunk/drivers/s390/char/tty3270.c @@ -915,7 +915,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) int i, rc; /* Check if the tty3270 is already there. */ - view = raw3270_find_view(&tty3270_fn, tty->index + RAW3270_FIRSTMINOR); + view = raw3270_find_view(&tty3270_fn, tty->index); if (!IS_ERR(view)) { tp = container_of(view, struct tty3270, view); tty->driver_data = tp; @@ -927,16 +927,15 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) tp->inattr = TF_INPUT; return tty_port_install(&tp->port, driver, tty); } - if (tty3270_max_index < tty->index + 1) - tty3270_max_index = tty->index + 1; + if (tty3270_max_index < tty->index) + tty3270_max_index = tty->index; /* Allocate tty3270 structure on first open. */ tp = tty3270_alloc_view(); if (IS_ERR(tp)) return PTR_ERR(tp); - rc = raw3270_add_view(&tp->view, &tty3270_fn, - tty->index + RAW3270_FIRSTMINOR); + rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index); if (rc) { tty3270_free_view(tp); return rc; @@ -1847,12 +1846,12 @@ static const struct tty_operations tty3270_ops = { void tty3270_create_cb(int minor) { - tty_register_device(tty3270_driver, minor - RAW3270_FIRSTMINOR, NULL); + tty_register_device(tty3270_driver, minor, NULL); } void tty3270_destroy_cb(int minor) { - tty_unregister_device(tty3270_driver, minor - RAW3270_FIRSTMINOR); + tty_unregister_device(tty3270_driver, minor); } struct raw3270_notifier tty3270_notifier = @@ -1885,8 +1884,7 @@ static int __init tty3270_init(void) driver->driver_name = "tty3270"; driver->name = "3270/tty"; driver->major = IBM_TTY3270_MAJOR; - driver->minor_start = RAW3270_FIRSTMINOR; - driver->name_base = RAW3270_FIRSTMINOR; + driver->minor_start = 0; driver->type = TTY_DRIVER_TYPE_SYSTEM; driver->subtype = SYSTEM_TYPE_TTY; driver->init_termios = tty_std_termios; diff --git a/trunk/drivers/s390/char/zcore.c b/trunk/drivers/s390/char/zcore.c index 22820610022c..1d61a01576d2 100644 --- a/trunk/drivers/s390/char/zcore.c +++ b/trunk/drivers/s390/char/zcore.c @@ -127,7 +127,7 @@ static int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode) } if (mode == TO_USER) { if (copy_to_user((__force __user void*) dest + offs, buf, - count - offs)) + PAGE_SIZE)) return -EFAULT; } else memcpy(dest + offs, buf, count - offs); diff --git a/trunk/drivers/s390/cio/chp.c b/trunk/drivers/s390/cio/chp.c index 21fabc6d5a9c..50ad5fdd815d 100644 --- a/trunk/drivers/s390/cio/chp.c +++ b/trunk/drivers/s390/cio/chp.c @@ -376,26 +376,6 @@ static void chp_release(struct device *dev) kfree(cp); } -/** - * chp_update_desc - update channel-path description - * @chp - channel-path - * - * Update the channel-path description of the specified channel-path. - * Return zero on success, non-zero otherwise. - */ -int chp_update_desc(struct channel_path *chp) -{ - int rc; - - rc = chsc_determine_base_channel_path_desc(chp->chpid, &chp->desc); - if (rc) - return rc; - - rc = chsc_determine_fmt1_channel_path_desc(chp->chpid, &chp->desc_fmt1); - - return rc; -} - /** * chp_new - register a new channel-path * @chpid - channel-path ID @@ -423,7 +403,7 @@ int chp_new(struct chp_id chpid) mutex_init(&chp->lock); /* Obtain channel path description and fill it in. */ - ret = chp_update_desc(chp); + ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); if (ret) goto out_free; if ((chp->desc.flags & 0x80) == 0) { diff --git a/trunk/drivers/s390/cio/chp.h b/trunk/drivers/s390/cio/chp.h index 9284b785a06f..e1399dbee834 100644 --- a/trunk/drivers/s390/cio/chp.h +++ b/trunk/drivers/s390/cio/chp.h @@ -44,7 +44,6 @@ struct channel_path { struct mutex lock; /* Serialize access to below members. */ int state; struct channel_path_desc desc; - struct channel_path_desc_fmt1 desc_fmt1; /* Channel-measurement related stuff: */ int cmg; int shared; @@ -63,7 +62,6 @@ int chp_is_registered(struct chp_id chpid); void *chp_get_chp_desc(struct chp_id chpid); void chp_remove_cmg_attr(struct channel_path *chp); int chp_add_cmg_attr(struct channel_path *chp); -int chp_update_desc(struct channel_path *chp); int chp_new(struct chp_id chpid); void chp_cfg_schedule(struct chp_id chpid, int configure); void chp_cfg_cancel_deconfigure(struct chp_id chpid); diff --git a/trunk/drivers/s390/cio/chsc.c b/trunk/drivers/s390/cio/chsc.c index 8ea7d9b2c671..31ceef1beb8b 100644 --- a/trunk/drivers/s390/cio/chsc.c +++ b/trunk/drivers/s390/cio/chsc.c @@ -376,7 +376,7 @@ static void chsc_process_sei_chp_avail(struct chsc_sei_nt0_area *sei_area) continue; } mutex_lock(&chp->lock); - chp_update_desc(chp); + chsc_determine_base_channel_path_desc(chpid, &chp->desc); mutex_unlock(&chp->lock); } } @@ -433,20 +433,6 @@ static void chsc_process_sei_scm_change(struct chsc_sei_nt0_area *sei_area) " failed (rc=%d).\n", ret); } -static void chsc_process_sei_scm_avail(struct chsc_sei_nt0_area *sei_area) -{ - int ret; - - CIO_CRW_EVENT(4, "chsc: scm available information\n"); - if (sei_area->rs != 7) - return; - - ret = scm_process_availability_information(); - if (ret) - CIO_CRW_EVENT(0, "chsc: process availability information" - " failed (rc=%d).\n", ret); -} - static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area) { switch (sei_area->cc) { @@ -482,9 +468,6 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area) case 12: /* scm change notification */ chsc_process_sei_scm_change(sei_area); break; - case 14: /* scm available notification */ - chsc_process_sei_scm_avail(sei_area); - break; default: /* other stuff */ CIO_CRW_EVENT(2, "chsc: sei nt0 unhandled cc=%d\n", sei_area->cc); @@ -631,8 +614,8 @@ int chsc_chp_vary(struct chp_id chpid, int on) * Redo PathVerification on the devices the chpid connects to */ if (on) { - /* Try to update the channel path description. */ - chp_update_desc(chp); + /* Try to update the channel path descritor. */ + chsc_determine_base_channel_path_desc(chpid, &chp->desc); for_each_subchannel_staged(s390_subchannel_vary_chpid_on, __s390_vary_chpid_on, &chpid); } else @@ -825,10 +808,9 @@ int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid, { struct chsc_response_struct *chsc_resp; struct chsc_scpd *scpd_area; - unsigned long flags; int ret; - spin_lock_irqsave(&chsc_page_lock, flags); + spin_lock_irq(&chsc_page_lock); scpd_area = chsc_page; ret = chsc_determine_channel_path_desc(chpid, 0, 0, 1, 0, scpd_area); if (ret) @@ -836,7 +818,7 @@ int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid, chsc_resp = (void *)&scpd_area->response; memcpy(desc, &chsc_resp->data, sizeof(*desc)); out: - spin_unlock_irqrestore(&chsc_page_lock, flags); + spin_unlock_irq(&chsc_page_lock); return ret; } diff --git a/trunk/drivers/s390/cio/chsc.h b/trunk/drivers/s390/cio/chsc.h index 349d5fc47196..227e05f674b3 100644 --- a/trunk/drivers/s390/cio/chsc.h +++ b/trunk/drivers/s390/cio/chsc.h @@ -156,10 +156,8 @@ int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token); #ifdef CONFIG_SCM_BUS int scm_update_information(void); -int scm_process_availability_information(void); #else /* CONFIG_SCM_BUS */ static inline int scm_update_information(void) { return 0; } -static inline int scm_process_availability_information(void) { return 0; } #endif /* CONFIG_SCM_BUS */ diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index 935d80b4e9ce..986ef6a92a41 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -471,6 +471,15 @@ int cio_disable_subchannel(struct subchannel *sch) } EXPORT_SYMBOL_GPL(cio_disable_subchannel); +int cio_create_sch_lock(struct subchannel *sch) +{ + sch->lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL); + if (!sch->lock) + return -ENOMEM; + spin_lock_init(sch->lock); + return 0; +} + static int cio_check_devno_blacklisted(struct subchannel *sch) { if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) { @@ -527,19 +536,32 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) sprintf(dbf_txt, "valsch%x", schid.sch_no); CIO_TRACE_EVENT(4, dbf_txt); + /* Nuke all fields. */ + memset(sch, 0, sizeof(struct subchannel)); + + sch->schid = schid; + if (cio_is_console(schid)) { + sch->lock = cio_get_console_lock(); + } else { + err = cio_create_sch_lock(sch); + if (err) + goto out; + } + mutex_init(&sch->reg_mutex); + /* * The first subchannel that is not-operational (ccode==3) - * indicates that there aren't any more devices available. + * indicates that there aren't any more devices available. * If stsch gets an exception, it means the current subchannel set - * is not valid. + * is not valid. */ - ccode = stsch_err(schid, &sch->schib); + ccode = stsch_err (schid, &sch->schib); if (ccode) { err = (ccode == 3) ? -ENXIO : ccode; goto out; } + /* Copy subchannel type from path management control word. */ sch->st = sch->schib.pmcw.st; - sch->schid = schid; switch (sch->st) { case SUBCHANNEL_TYPE_IO: @@ -556,7 +578,11 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n", sch->schid.ssid, sch->schid.sch_no, sch->st); + return 0; out: + if (!cio_is_console(schid)) + kfree(sch->lock); + sch->lock = NULL; return err; } @@ -624,13 +650,15 @@ void __irq_entry do_IRQ(struct pt_regs *regs) } #ifdef CONFIG_CCW_CONSOLE -static struct subchannel *console_sch; +static struct subchannel console_subchannel; +static struct io_subchannel_private console_priv; +static int console_subchannel_in_use; /* * Use cio_tsch to update the subchannel status and call the interrupt handler - * if status had been pending. Called with the subchannel's lock held. + * if status had been pending. Called with the console_subchannel lock. */ -void cio_tsch(struct subchannel *sch) +static void cio_tsch(struct subchannel *sch) { struct irb *irb; int irq_context; @@ -647,7 +675,6 @@ void cio_tsch(struct subchannel *sch) local_bh_disable(); irq_enter(); } - kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL); if (sch->driver && sch->driver->irq) sch->driver->irq(sch); else @@ -658,90 +685,135 @@ void cio_tsch(struct subchannel *sch) } } -static int cio_test_for_console(struct subchannel_id schid, void *data) +void *cio_get_console_priv(void) { - struct schib schib; + return &console_priv; +} - if (stsch_err(schid, &schib) != 0) +/* + * busy wait for the next interrupt on the console + */ +void wait_cons_dev(void) +{ + if (!console_subchannel_in_use) + return; + + while (1) { + cio_tsch(&console_subchannel); + if (console_subchannel.schib.scsw.cmd.actl == 0) + break; + udelay_simple(100); + } +} + +static int +cio_test_for_console(struct subchannel_id schid, void *data) +{ + if (stsch_err(schid, &console_subchannel.schib) != 0) return -ENXIO; - if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && - (schib.pmcw.dev == console_devno)) { + if ((console_subchannel.schib.pmcw.st == SUBCHANNEL_TYPE_IO) && + console_subchannel.schib.pmcw.dnv && + (console_subchannel.schib.pmcw.dev == console_devno)) { console_irq = schid.sch_no; return 1; /* found */ } return 0; } -static int cio_get_console_sch_no(void) + +static int +cio_get_console_sch_no(void) { struct subchannel_id schid; - struct schib schib; - + init_subchannel_id(&schid); if (console_irq != -1) { /* VM provided us with the irq number of the console. */ schid.sch_no = console_irq; - if (stsch_err(schid, &schib) != 0 || - (schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv) + if (stsch_err(schid, &console_subchannel.schib) != 0 || + (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) || + !console_subchannel.schib.pmcw.dnv) return -1; - console_devno = schib.pmcw.dev; + console_devno = console_subchannel.schib.pmcw.dev; } else if (console_devno != -1) { /* At least the console device number is known. */ for_each_subchannel(cio_test_for_console, NULL); + if (console_irq == -1) + return -1; + } else { + /* unlike in 2.4, we cannot autoprobe here, since + * the channel subsystem is not fully initialized. + * With some luck, the HWC console can take over */ + return -1; } return console_irq; } -struct subchannel *cio_probe_console(void) +struct subchannel * +cio_probe_console(void) { - struct subchannel_id schid; - struct subchannel *sch; int sch_no, ret; + struct subchannel_id schid; + if (xchg(&console_subchannel_in_use, 1) != 0) + return ERR_PTR(-EBUSY); sch_no = cio_get_console_sch_no(); if (sch_no == -1) { + console_subchannel_in_use = 0; pr_warning("No CCW console was found\n"); return ERR_PTR(-ENODEV); } + memset(&console_subchannel, 0, sizeof(struct subchannel)); init_subchannel_id(&schid); schid.sch_no = sch_no; - sch = css_alloc_subchannel(schid); - if (IS_ERR(sch)) - return sch; + ret = cio_validate_subchannel(&console_subchannel, schid); + if (ret) { + console_subchannel_in_use = 0; + return ERR_PTR(-ENODEV); + } + /* + * enable console I/O-interrupt subclass + */ isc_register(CONSOLE_ISC); - sch->config.isc = CONSOLE_ISC; - sch->config.intparm = (u32)(addr_t)sch; - ret = cio_commit_config(sch); + console_subchannel.config.isc = CONSOLE_ISC; + console_subchannel.config.intparm = (u32)(addr_t)&console_subchannel; + ret = cio_commit_config(&console_subchannel); if (ret) { isc_unregister(CONSOLE_ISC); - put_device(&sch->dev); + console_subchannel_in_use = 0; return ERR_PTR(ret); } - console_sch = sch; - return sch; + return &console_subchannel; } -int cio_is_console(struct subchannel_id schid) +void +cio_release_console(void) { - if (!console_sch) - return 0; - return schid_equal(&schid, &console_sch->schid); + console_subchannel.config.intparm = 0; + cio_commit_config(&console_subchannel); + isc_unregister(CONSOLE_ISC); + console_subchannel_in_use = 0; } -void cio_register_early_subchannels(void) +/* Bah... hack to catch console special sausages. */ +int +cio_is_console(struct subchannel_id schid) { - int ret; - - if (!console_sch) - return; + if (!console_subchannel_in_use) + return 0; + return schid_equal(&schid, &console_subchannel.schid); +} - ret = css_register_subchannel(console_sch); - if (ret) - put_device(&console_sch->dev); +struct subchannel * +cio_get_console_subchannel(void) +{ + if (!console_subchannel_in_use) + return NULL; + return &console_subchannel; } -#endif /* CONFIG_CCW_CONSOLE */ +#endif static int __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) { diff --git a/trunk/drivers/s390/cio/cio.h b/trunk/drivers/s390/cio/cio.h index d62f5e7f3cf1..4a1ff5c2eb88 100644 --- a/trunk/drivers/s390/cio/cio.h +++ b/trunk/drivers/s390/cio/cio.h @@ -121,18 +121,23 @@ extern int cio_commit_config(struct subchannel *sch); int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key); int cio_tm_intrg(struct subchannel *sch); +int cio_create_sch_lock(struct subchannel *); void do_adapter_IO(u8 isc); void do_IRQ(struct pt_regs *); /* Use with care. */ #ifdef CONFIG_CCW_CONSOLE extern struct subchannel *cio_probe_console(void); +extern void cio_release_console(void); extern int cio_is_console(struct subchannel_id); -extern void cio_register_early_subchannels(void); -extern void cio_tsch(struct subchannel *sch); +extern struct subchannel *cio_get_console_subchannel(void); +extern spinlock_t * cio_get_console_lock(void); +extern void *cio_get_console_priv(void); #else #define cio_is_console(schid) 0 -static inline void cio_register_early_subchannels(void) {} +#define cio_get_console_subchannel() NULL +#define cio_get_console_lock() NULL +#define cio_get_console_priv() NULL #endif #endif diff --git a/trunk/drivers/s390/cio/css.c b/trunk/drivers/s390/cio/css.c index 1ebe5d3ddebb..a239237d43f3 100644 --- a/trunk/drivers/s390/cio/css.c +++ b/trunk/drivers/s390/cio/css.c @@ -137,53 +137,37 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), static void css_sch_todo(struct work_struct *work); -static int css_sch_create_locks(struct subchannel *sch) -{ - sch->lock = kmalloc(sizeof(*sch->lock), GFP_KERNEL); - if (!sch->lock) - return -ENOMEM; - - spin_lock_init(sch->lock); - mutex_init(&sch->reg_mutex); - - return 0; -} - -static void css_subchannel_release(struct device *dev) -{ - struct subchannel *sch = to_subchannel(dev); - - sch->config.intparm = 0; - cio_commit_config(sch); - kfree(sch->lock); - kfree(sch); -} - -struct subchannel *css_alloc_subchannel(struct subchannel_id schid) +static struct subchannel * +css_alloc_subchannel(struct subchannel_id schid) { struct subchannel *sch; int ret; - sch = kzalloc(sizeof(*sch), GFP_KERNEL | GFP_DMA); - if (!sch) + sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA); + if (sch == NULL) return ERR_PTR(-ENOMEM); - - ret = cio_validate_subchannel(sch, schid); - if (ret < 0) - goto err; - - ret = css_sch_create_locks(sch); - if (ret) - goto err; - + ret = cio_validate_subchannel (sch, schid); + if (ret < 0) { + kfree(sch); + return ERR_PTR(ret); + } INIT_WORK(&sch->todo_work, css_sch_todo); - sch->dev.release = &css_subchannel_release; - device_initialize(&sch->dev); return sch; +} + +static void +css_subchannel_release(struct device *dev) +{ + struct subchannel *sch; -err: - kfree(sch); - return ERR_PTR(ret); + sch = to_subchannel(dev); + if (!cio_is_console(sch->schid)) { + /* Reset intparm to zeroes. */ + sch->config.intparm = 0; + cio_commit_config(sch); + kfree(sch->lock); + kfree(sch); + } } static int css_sch_device_register(struct subchannel *sch) @@ -193,7 +177,7 @@ static int css_sch_device_register(struct subchannel *sch) mutex_lock(&sch->reg_mutex); dev_set_name(&sch->dev, "0.%x.%04x", sch->schid.ssid, sch->schid.sch_no); - ret = device_add(&sch->dev); + ret = device_register(&sch->dev); mutex_unlock(&sch->reg_mutex); return ret; } @@ -244,11 +228,16 @@ void css_update_ssd_info(struct subchannel *sch) { int ret; - ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info); - if (ret) + if (cio_is_console(sch->schid)) { + /* Console is initialized too early for functions requiring + * memory allocation. */ ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw); - - ssd_register_chpids(&sch->ssd_info); + } else { + ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info); + if (ret) + ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw); + ssd_register_chpids(&sch->ssd_info); + } } static ssize_t type_show(struct device *dev, struct device_attribute *attr, @@ -286,13 +275,14 @@ static const struct attribute_group *default_subch_attr_groups[] = { NULL, }; -int css_register_subchannel(struct subchannel *sch) +static int css_register_subchannel(struct subchannel *sch) { int ret; /* Initialize the subchannel structure */ sch->dev.parent = &channel_subsystems[0]->device; sch->dev.bus = &css_bus_type; + sch->dev.release = &css_subchannel_release; sch->dev.groups = default_subch_attr_groups; /* * We don't want to generate uevents for I/O subchannels that don't @@ -324,19 +314,23 @@ int css_register_subchannel(struct subchannel *sch) return ret; } -static int css_probe_device(struct subchannel_id schid) +int css_probe_device(struct subchannel_id schid) { - struct subchannel *sch; int ret; + struct subchannel *sch; - sch = css_alloc_subchannel(schid); - if (IS_ERR(sch)) - return PTR_ERR(sch); - + if (cio_is_console(schid)) + sch = cio_get_console_subchannel(); + else { + sch = css_alloc_subchannel(schid); + if (IS_ERR(sch)) + return PTR_ERR(sch); + } ret = css_register_subchannel(sch); - if (ret) - put_device(&sch->dev); - + if (ret) { + if (!cio_is_console(schid)) + put_device(&sch->dev); + } return ret; } @@ -776,7 +770,7 @@ static int __init setup_css(int nr) css->pseudo_subchannel->dev.release = css_subchannel_release; dev_set_name(&css->pseudo_subchannel->dev, "defunct"); mutex_init(&css->pseudo_subchannel->reg_mutex); - ret = css_sch_create_locks(css->pseudo_subchannel); + ret = cio_create_sch_lock(css->pseudo_subchannel); if (ret) { kfree(css->pseudo_subchannel); return ret; @@ -876,7 +870,8 @@ static struct notifier_block css_power_notifier = { /* * Now that the driver core is running, we can setup our channel subsystem. - * The struct subchannel's are created during probing. + * The struct subchannel's are created during probing (except for the + * static console subchannel). */ static int __init css_bus_init(void) { @@ -1055,8 +1050,6 @@ int css_complete_work(void) */ static int __init channel_subsystem_init_sync(void) { - /* Register subchannels which are already in use. */ - cio_register_early_subchannels(); /* Start initial subchannel evaluation. */ css_schedule_eval_all(); css_complete_work(); @@ -1072,8 +1065,9 @@ void channel_subsystem_reinit(void) chsc_enable_facility(CHSC_SDA_OC_MSS); chp_id_for_each(&chpid) { chp = chpid_to_chp(chpid); - if (chp) - chp_update_desc(chp); + if (!chp) + continue; + chsc_determine_base_channel_path_desc(chpid, &chp->desc); } } diff --git a/trunk/drivers/s390/cio/css.h b/trunk/drivers/s390/cio/css.h index b1de60335238..4af3dfe70ef5 100644 --- a/trunk/drivers/s390/cio/css.h +++ b/trunk/drivers/s390/cio/css.h @@ -101,8 +101,7 @@ extern int css_driver_register(struct css_driver *); extern void css_driver_unregister(struct css_driver *); extern void css_sch_device_unregister(struct subchannel *); -extern int css_register_subchannel(struct subchannel *); -extern struct subchannel *css_alloc_subchannel(struct subchannel_id); +extern int css_probe_device(struct subchannel_id); extern struct subchannel *get_subchannel_by_schid(struct subchannel_id); extern int css_init_done; extern int max_ssid; @@ -110,6 +109,7 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), int (*fn_unknown)(struct subchannel_id, void *), void *data); extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); +extern void css_reiterate_subchannels(void); void css_update_ssd_info(struct subchannel *sch); struct channel_subsystem { diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 1ab5f6c36d9b..c6767f5a58b2 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -44,10 +43,6 @@ static DEFINE_SPINLOCK(recovery_lock); static int recovery_phase; static const unsigned long recovery_delay[] = { 3, 30, 300 }; -static atomic_t ccw_device_init_count = ATOMIC_INIT(0); -static DECLARE_WAIT_QUEUE_HEAD(ccw_device_init_wq); -static struct bus_type ccw_bus_type; - /******************* bus type handling ***********************/ /* The Linux driver model distinguishes between a bus type and @@ -132,6 +127,8 @@ static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env) return ret; } +static struct bus_type ccw_bus_type; + static void io_subchannel_irq(struct subchannel *); static int io_subchannel_probe(struct subchannel *); static int io_subchannel_remove(struct subchannel *); @@ -140,6 +137,8 @@ static int io_subchannel_sch_event(struct subchannel *, int); static int io_subchannel_chp_event(struct subchannel *, struct chp_link *, int); static void recovery_func(unsigned long data); +wait_queue_head_t ccw_device_init_wq; +atomic_t ccw_device_init_count; static struct css_device_id io_subchannel_ids[] = { { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, }, @@ -192,7 +191,10 @@ int __init io_subchannel_init(void) { int ret; + init_waitqueue_head(&ccw_device_init_wq); + atomic_set(&ccw_device_init_count, 0); setup_timer(&recovery_timer, recovery_func, 0); + ret = bus_register(&ccw_bus_type); if (ret) return ret; @@ -1084,14 +1086,19 @@ static int io_subchannel_probe(struct subchannel *sch) dev_set_uevent_suppress(&sch->dev, 0); kobject_uevent(&sch->dev.kobj, KOBJ_ADD); cdev = sch_get_cdev(sch); - rc = ccw_device_register(cdev); - if (rc) { - /* Release online reference. */ - put_device(&cdev->dev); - goto out_schedule; - } - if (atomic_dec_and_test(&ccw_device_init_count)) - wake_up(&ccw_device_init_wq); + cdev->dev.groups = ccwdev_attr_groups; + device_initialize(&cdev->dev); + cdev->private->flags.initialized = 1; + ccw_device_register(cdev); + /* + * Check if the device is already online. If it is + * the reference count needs to be corrected since we + * didn't obtain a reference in ccw_device_set_online. + */ + if (cdev->private->state != DEV_STATE_NOT_OPER && + cdev->private->state != DEV_STATE_OFFLINE && + cdev->private->state != DEV_STATE_BOXED) + get_device(&cdev->dev); return 0; } io_subchannel_init_fields(sch); @@ -1573,102 +1580,88 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) } #ifdef CONFIG_CCW_CONSOLE +static struct ccw_device console_cdev; +static struct ccw_device_private console_private; +static int console_cdev_in_use; + +static DEFINE_SPINLOCK(ccw_console_lock); + +spinlock_t * cio_get_console_lock(void) +{ + return &ccw_console_lock; +} + static int ccw_device_console_enable(struct ccw_device *cdev, struct subchannel *sch) { + struct io_subchannel_private *io_priv = cio_get_console_priv(); int rc; + /* Attach subchannel private data. */ + memset(io_priv, 0, sizeof(*io_priv)); + set_io_private(sch, io_priv); io_subchannel_init_fields(sch); rc = cio_commit_config(sch); if (rc) return rc; sch->driver = &io_subchannel_driver; + /* Initialize the ccw_device structure. */ + cdev->dev.parent= &sch->dev; sch_set_cdev(sch, cdev); io_subchannel_recog(cdev, sch); /* Now wait for the async. recognition to come to an end. */ spin_lock_irq(cdev->ccwlock); while (!dev_fsm_final_state(cdev)) - ccw_device_wait_idle(cdev); - - /* Hold on to an extra reference while device is online. */ - get_device(&cdev->dev); - rc = ccw_device_online(cdev); - if (rc) + wait_cons_dev(); + rc = -EIO; + if (cdev->private->state != DEV_STATE_OFFLINE) goto out_unlock; - + ccw_device_online(cdev); while (!dev_fsm_final_state(cdev)) - ccw_device_wait_idle(cdev); - - if (cdev->private->state == DEV_STATE_ONLINE) - cdev->online = 1; - else - rc = -EIO; + wait_cons_dev(); + if (cdev->private->state != DEV_STATE_ONLINE) + goto out_unlock; + rc = 0; out_unlock: spin_unlock_irq(cdev->ccwlock); - if (rc) /* Give up online reference since onlining failed. */ - put_device(&cdev->dev); return rc; } -struct ccw_device *ccw_device_probe_console(void) +struct ccw_device * +ccw_device_probe_console(void) { - struct io_subchannel_private *io_priv; - struct ccw_device *cdev; struct subchannel *sch; int ret; + if (xchg(&console_cdev_in_use, 1) != 0) + return ERR_PTR(-EBUSY); sch = cio_probe_console(); - if (IS_ERR(sch)) - return ERR_CAST(sch); - - io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA); - if (!io_priv) { - put_device(&sch->dev); - return ERR_PTR(-ENOMEM); + if (IS_ERR(sch)) { + console_cdev_in_use = 0; + return (void *) sch; } - cdev = io_subchannel_create_ccwdev(sch); - if (IS_ERR(cdev)) { - put_device(&sch->dev); - kfree(io_priv); - return cdev; - } - set_io_private(sch, io_priv); - ret = ccw_device_console_enable(cdev, sch); + memset(&console_cdev, 0, sizeof(struct ccw_device)); + memset(&console_private, 0, sizeof(struct ccw_device_private)); + console_cdev.private = &console_private; + console_private.cdev = &console_cdev; + console_private.int_class = IRQIO_CIO; + ret = ccw_device_console_enable(&console_cdev, sch); if (ret) { - set_io_private(sch, NULL); - put_device(&sch->dev); - put_device(&cdev->dev); - kfree(io_priv); + cio_release_console(); + console_cdev_in_use = 0; return ERR_PTR(ret); } - return cdev; -} - -/** - * ccw_device_wait_idle() - busy wait for device to become idle - * @cdev: ccw device - * - * Poll until activity control is zero, that is, no function or data - * transfer is pending/active. - * Called with device lock being held. - */ -void ccw_device_wait_idle(struct ccw_device *cdev) -{ - struct subchannel *sch = to_subchannel(cdev->dev.parent); - - while (1) { - cio_tsch(sch); - if (sch->schib.scsw.cmd.actl == 0) - break; - udelay_simple(100); - } + console_cdev.online = 1; + return &console_cdev; } static int ccw_device_pm_restore(struct device *dev); -int ccw_device_force_console(struct ccw_device *cdev) +int ccw_device_force_console(void) { - return ccw_device_pm_restore(&cdev->dev); + if (!console_cdev_in_use) + return -ENODEV; + return ccw_device_pm_restore(&console_cdev.dev); } EXPORT_SYMBOL_GPL(ccw_device_force_console); #endif diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index 8d1d29873172..7d4ecb65db00 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -81,6 +81,8 @@ dev_fsm_final_state(struct ccw_device *cdev) cdev->private->state == DEV_STATE_BOXED); } +extern wait_queue_head_t ccw_device_init_wq; +extern atomic_t ccw_device_init_count; int __init io_subchannel_init(void); void io_subchannel_recog_done(struct ccw_device *cdev); diff --git a/trunk/drivers/s390/cio/device_ops.c b/trunk/drivers/s390/cio/device_ops.c index 4845d64f2842..c77b6e06bf64 100644 --- a/trunk/drivers/s390/cio/device_ops.c +++ b/trunk/drivers/s390/cio/device_ops.c @@ -704,9 +704,9 @@ EXPORT_SYMBOL(ccw_device_tm_start_timeout); int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask) { struct subchannel *sch = to_subchannel(cdev->dev.parent); - struct channel_path *chp; + struct channel_path_desc_fmt1 desc; struct chp_id chpid; - int mdc = 0, i; + int mdc = 0, ret, i; /* Adjust requested path mask to excluded varied off paths. */ if (mask) @@ -719,20 +719,14 @@ int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask) if (!(mask & (0x80 >> i))) continue; chpid.id = sch->schib.pmcw.chpid[i]; - chp = chpid_to_chp(chpid); - if (!chp) - continue; - - mutex_lock(&chp->lock); - if (!chp->desc_fmt1.f) { - mutex_unlock(&chp->lock); + ret = chsc_determine_fmt1_channel_path_desc(chpid, &desc); + if (ret) + return ret; + if (!desc.f) return 0; - } - if (!chp->desc_fmt1.r) + if (!desc.r) mdc = 1; - mdc = mdc ? min_t(int, mdc, chp->desc_fmt1.mdc) : - chp->desc_fmt1.mdc; - mutex_unlock(&chp->lock); + mdc = mdc ? min(mdc, (int)desc.mdc) : desc.mdc; } return mdc; diff --git a/trunk/drivers/s390/cio/idset.c b/trunk/drivers/s390/cio/idset.c index 5a999084a229..65d13e38803f 100644 --- a/trunk/drivers/s390/cio/idset.c +++ b/trunk/drivers/s390/cio/idset.c @@ -17,7 +17,7 @@ struct idset { static inline unsigned long bitmap_size(int num_ssid, int num_id) { - return BITS_TO_LONGS(num_ssid * num_id) * sizeof(unsigned long); + return __BITOPS_WORDS(num_ssid * num_id) * sizeof(unsigned long); } static struct idset *idset_new(int num_ssid, int num_id) diff --git a/trunk/drivers/s390/cio/scm.c b/trunk/drivers/s390/cio/scm.c index 46ec25632e8b..bcf20f3aa51b 100644 --- a/trunk/drivers/s390/cio/scm.c +++ b/trunk/drivers/s390/cio/scm.c @@ -211,7 +211,7 @@ static void scmdev_update(struct scm_device *scmdev, struct sale *sale) goto out; scmdrv = to_scm_drv(scmdev->dev.driver); if (changed && scmdrv->notify) - scmdrv->notify(scmdev, SCM_CHANGE); + scmdrv->notify(scmdev); out: device_unlock(&scmdev->dev); if (changed) @@ -297,22 +297,6 @@ int scm_update_information(void) return ret; } -static int scm_dev_avail(struct device *dev, void *unused) -{ - struct scm_driver *scmdrv = to_scm_drv(dev->driver); - struct scm_device *scmdev = to_scm_dev(dev); - - if (dev->driver && scmdrv->notify) - scmdrv->notify(scmdev, SCM_AVAIL); - - return 0; -} - -int scm_process_availability_information(void) -{ - return bus_for_each_dev(&scm_bus_type, NULL, NULL, scm_dev_avail); -} - static int __init scm_init(void) { int ret; diff --git a/trunk/drivers/s390/net/qeth_core.h b/trunk/drivers/s390/net/qeth_core.h index 6ccb7457746b..d87961d4c0de 100644 --- a/trunk/drivers/s390/net/qeth_core.h +++ b/trunk/drivers/s390/net/qeth_core.h @@ -769,7 +769,6 @@ struct qeth_card { unsigned long thread_start_mask; unsigned long thread_allowed_mask; unsigned long thread_running_mask; - struct task_struct *recovery_task; spinlock_t ip_lock; struct list_head ip_list; struct list_head *ip_tbd_list; @@ -863,8 +862,6 @@ extern struct qeth_card_list_struct qeth_core_card_list; extern struct kmem_cache *qeth_core_header_cache; extern struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS]; -void qeth_set_recovery_task(struct qeth_card *); -void qeth_clear_recovery_task(struct qeth_card *); void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int); int qeth_threads_running(struct qeth_card *, unsigned long); int qeth_wait_for_threads(struct qeth_card *, unsigned long); @@ -919,7 +916,6 @@ int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *, void *reply_param); int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int); int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int); -int qeth_get_elements_for_frags(struct sk_buff *); int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *, struct sk_buff *, struct qeth_hdr *, int, int, int); int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *, diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index 451f92020599..0d8cdff81813 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -177,23 +177,6 @@ const char *qeth_get_cardname_short(struct qeth_card *card) return "n/a"; } -void qeth_set_recovery_task(struct qeth_card *card) -{ - card->recovery_task = current; -} -EXPORT_SYMBOL_GPL(qeth_set_recovery_task); - -void qeth_clear_recovery_task(struct qeth_card *card) -{ - card->recovery_task = NULL; -} -EXPORT_SYMBOL_GPL(qeth_clear_recovery_task); - -static bool qeth_is_recovery_task(const struct qeth_card *card) -{ - return card->recovery_task == current; -} - void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads, int clear_start_mask) { @@ -222,8 +205,6 @@ EXPORT_SYMBOL_GPL(qeth_threads_running); int qeth_wait_for_threads(struct qeth_card *card, unsigned long threads) { - if (qeth_is_recovery_task(card)) - return 0; return wait_event_interruptible(card->wait_q, qeth_threads_running(card, threads) == 0); } @@ -3698,25 +3679,6 @@ int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, } EXPORT_SYMBOL_GPL(qeth_get_priority_queue); -int qeth_get_elements_for_frags(struct sk_buff *skb) -{ - int cnt, length, e, elements = 0; - struct skb_frag_struct *frag; - char *data; - - for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) { - frag = &skb_shinfo(skb)->frags[cnt]; - data = (char *)page_to_phys(skb_frag_page(frag)) + - frag->page_offset; - length = frag->size; - e = PFN_UP((unsigned long)data + length - 1) - - PFN_DOWN((unsigned long)data); - elements += e; - } - return elements; -} -EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags); - int qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb, int elems) { @@ -3724,8 +3686,7 @@ int qeth_get_elements_no(struct qeth_card *card, void *hdr, int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) - PFN_DOWN((unsigned long)skb->data); - elements_needed += qeth_get_elements_for_frags(skb); - + elements_needed += skb_shinfo(skb)->nr_frags; if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) { QETH_DBF_MESSAGE(2, "Invalid size of IP packet " "(Number=%d / Length=%d). Discarded.\n", @@ -3810,23 +3771,12 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb, for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) { frag = &skb_shinfo(skb)->frags[cnt]; - data = (char *)page_to_phys(skb_frag_page(frag)) + - frag->page_offset; - length = frag->size; - while (length > 0) { - length_here = PAGE_SIZE - - ((unsigned long) data % PAGE_SIZE); - if (length < length_here) - length_here = length; - - buffer->element[element].addr = data; - buffer->element[element].length = length_here; - buffer->element[element].eflags = - SBAL_EFLAGS_MIDDLE_FRAG; - length -= length_here; - data += length_here; - element++; - } + buffer->element[element].addr = (char *) + page_to_phys(skb_frag_page(frag)) + + frag->page_offset; + buffer->element[element].length = frag->size; + buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG; + element++; } if (buffer->element[element - 1].eflags) diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index 155b101bd730..d690166efeaf 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -1143,7 +1143,6 @@ static int qeth_l2_recover(void *ptr) QETH_CARD_TEXT(card, 2, "recover2"); dev_warn(&card->gdev->dev, "A recovery process has been started for the device\n"); - qeth_set_recovery_task(card); __qeth_l2_set_offline(card->gdev, 1); rc = __qeth_l2_set_online(card->gdev, 1); if (!rc) @@ -1154,7 +1153,6 @@ static int qeth_l2_recover(void *ptr) dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } - qeth_clear_recovery_task(card); qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); return 0; diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index 1f7edf1b26c3..091ca0efa1c5 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -623,7 +623,7 @@ static int qeth_l3_send_setrouting(struct qeth_card *card, return rc; } -static int qeth_l3_correct_routing_type(struct qeth_card *card, +static void qeth_l3_correct_routing_type(struct qeth_card *card, enum qeth_routing_types *type, enum qeth_prot_versions prot) { if (card->info.type == QETH_CARD_TYPE_IQD) { @@ -632,7 +632,7 @@ static int qeth_l3_correct_routing_type(struct qeth_card *card, case PRIMARY_CONNECTOR: case SECONDARY_CONNECTOR: case MULTICAST_ROUTER: - return 0; + return; default: goto out_inval; } @@ -641,18 +641,17 @@ static int qeth_l3_correct_routing_type(struct qeth_card *card, case NO_ROUTER: case PRIMARY_ROUTER: case SECONDARY_ROUTER: - return 0; + return; case MULTICAST_ROUTER: if (qeth_is_ipafunc_supported(card, prot, IPA_OSA_MC_ROUTER)) - return 0; + return; default: goto out_inval; } } out_inval: *type = NO_ROUTER; - return -EINVAL; } int qeth_l3_setrouting_v4(struct qeth_card *card) @@ -661,10 +660,8 @@ int qeth_l3_setrouting_v4(struct qeth_card *card) QETH_CARD_TEXT(card, 3, "setrtg4"); - rc = qeth_l3_correct_routing_type(card, &card->options.route4.type, + qeth_l3_correct_routing_type(card, &card->options.route4.type, QETH_PROT_IPV4); - if (rc) - return rc; rc = qeth_l3_send_setrouting(card, card->options.route4.type, QETH_PROT_IPV4); @@ -686,10 +683,8 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) if (!qeth_is_supported(card, IPA_IPV6)) return 0; - rc = qeth_l3_correct_routing_type(card, &card->options.route6.type, + qeth_l3_correct_routing_type(card, &card->options.route6.type, QETH_PROT_IPV6); - if (rc) - return rc; rc = qeth_l3_send_setrouting(card, card->options.route6.type, QETH_PROT_IPV6); @@ -2903,9 +2898,7 @@ static inline int qeth_l3_tso_elements(struct sk_buff *skb) tcp_hdr(skb)->doff * 4; int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data); int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd); - - elements += qeth_get_elements_for_frags(skb); - + elements += skb_shinfo(skb)->nr_frags; return elements; } @@ -3355,6 +3348,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) rc = -ENODEV; goto out_remove; } + qeth_trace_features(card); if (!card->dev && qeth_l3_setup_netdev(card)) { rc = -ENODEV; @@ -3431,7 +3425,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) qeth_l3_set_multicast_list(card->dev); rtnl_unlock(); } - qeth_trace_features(card); /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); mutex_unlock(&card->conf_mutex); @@ -3515,7 +3508,6 @@ static int qeth_l3_recover(void *ptr) QETH_CARD_TEXT(card, 2, "recover2"); dev_warn(&card->gdev->dev, "A recovery process has been started for the device\n"); - qeth_set_recovery_task(card); __qeth_l3_set_offline(card->gdev, 1); rc = __qeth_l3_set_online(card->gdev, 1); if (!rc) @@ -3526,7 +3518,6 @@ static int qeth_l3_recover(void *ptr) dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } - qeth_clear_recovery_task(card); qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); return 0; diff --git a/trunk/drivers/s390/net/qeth_l3_sys.c b/trunk/drivers/s390/net/qeth_l3_sys.c index e70af2406ff9..ebc379486267 100644 --- a/trunk/drivers/s390/net/qeth_l3_sys.c +++ b/trunk/drivers/s390/net/qeth_l3_sys.c @@ -87,8 +87,6 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, rc = qeth_l3_setrouting_v6(card); } out: - if (rc) - route->type = old_route_type; mutex_unlock(&card->conf_mutex); return rc ? rc : count; } diff --git a/trunk/drivers/sbus/char/bbc_i2c.c b/trunk/drivers/sbus/char/bbc_i2c.c index c1441ed282eb..1a9d1e3ce64c 100644 --- a/trunk/drivers/sbus/char/bbc_i2c.c +++ b/trunk/drivers/sbus/char/bbc_i2c.c @@ -282,7 +282,7 @@ static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static void reset_one_i2c(struct bbc_i2c_bus *bp) +static void __init reset_one_i2c(struct bbc_i2c_bus *bp) { writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0); writeb(bp->own, bp->i2c_control_regs + 0x1); @@ -291,7 +291,7 @@ static void reset_one_i2c(struct bbc_i2c_bus *bp) writeb(I2C_PCF_IDLE, bp->i2c_control_regs + 0x0); } -static struct bbc_i2c_bus * attach_one_i2c(struct platform_device *op, int index) +static struct bbc_i2c_bus * __init attach_one_i2c(struct platform_device *op, int index) { struct bbc_i2c_bus *bp; struct device_node *dp; diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 90bc7bd00966..2daf4b0da434 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -940,7 +940,6 @@ static int bnx2fc_libfc_config(struct fc_lport *lport) fc_exch_init(lport); fc_rport_init(lport); fc_disc_init(lport); - fc_disc_config(lport, lport); return 0; } @@ -2134,7 +2133,6 @@ static int _bnx2fc_create(struct net_device *netdev, } ctlr = bnx2fc_to_ctlr(interface); - cdev = fcoe_ctlr_to_ctlr_dev(ctlr); interface->vlan_id = vlan_id; interface->timer_work_queue = @@ -2145,7 +2143,7 @@ static int _bnx2fc_create(struct net_device *netdev, goto ifput_err; } - lport = bnx2fc_if_create(interface, &cdev->dev, 0); + lport = bnx2fc_if_create(interface, &interface->hba->pcidev->dev, 0); if (!lport) { printk(KERN_ERR PFX "Failed to create interface (%s)\n", netdev->name); @@ -2161,6 +2159,8 @@ static int _bnx2fc_create(struct net_device *netdev, /* Make this master N_port */ ctlr->lp = lport; + cdev = fcoe_ctlr_to_ctlr_dev(ctlr); + if (link_state == BNX2FC_CREATE_LINK_UP) cdev->enabled = FCOE_CTLR_ENABLED; else diff --git a/trunk/drivers/scsi/fcoe/fcoe.c b/trunk/drivers/scsi/fcoe/fcoe.c index 9bfdc9a3f897..b5d92fc93c70 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.c +++ b/trunk/drivers/scsi/fcoe/fcoe.c @@ -490,6 +490,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) { struct net_device *netdev = fcoe->netdev; struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); + struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); rtnl_lock(); if (!fcoe->removed) @@ -500,6 +501,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) /* tear-down the FCoE controller */ fcoe_ctlr_destroy(fip); scsi_host_put(fip->lp->host); + fcoe_ctlr_device_delete(ctlr_dev); dev_put(netdev); module_put(THIS_MODULE); } @@ -2192,8 +2194,6 @@ static int fcoe_destroy(struct net_device *netdev) */ static void fcoe_destroy_work(struct work_struct *work) { - struct fcoe_ctlr_device *cdev; - struct fcoe_ctlr *ctlr; struct fcoe_port *port; struct fcoe_interface *fcoe; struct Scsi_Host *shost; @@ -2224,15 +2224,10 @@ static void fcoe_destroy_work(struct work_struct *work) mutex_lock(&fcoe_config_mutex); fcoe = port->priv; - ctlr = fcoe_to_ctlr(fcoe); - cdev = fcoe_ctlr_to_ctlr_dev(ctlr); - fcoe_if_destroy(port->lport); fcoe_interface_cleanup(fcoe); mutex_unlock(&fcoe_config_mutex); - - fcoe_ctlr_device_delete(cdev); } /** @@ -2340,9 +2335,7 @@ static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode, rc = -EIO; rtnl_unlock(); fcoe_interface_cleanup(fcoe); - mutex_unlock(&fcoe_config_mutex); - fcoe_ctlr_device_delete(ctlr_dev); - goto out; + goto out_nortnl; } /* Make this the "master" N_Port */ @@ -2382,8 +2375,8 @@ static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode, out_nodev: rtnl_unlock(); +out_nortnl: mutex_unlock(&fcoe_config_mutex); -out: return rc; } diff --git a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c index a76247201be5..08c3bc398da2 100644 --- a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c @@ -2814,47 +2814,6 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip) fc_lport_set_local_id(fip->lp, new_port_id); } -/** - * fcoe_ctlr_mode_set() - Set or reset the ctlr's mode - * @lport: The local port to be (re)configured - * @fip: The FCoE controller whose mode is changing - * @fip_mode: The new fip mode - * - * Note that the we shouldn't be changing the libfc discovery settings - * (fc_disc_config) while an lport is going through the libfc state - * machine. The mode can only be changed when a fcoe_ctlr device is - * disabled, so that should ensure that this routine is only called - * when nothing is happening. - */ -void fcoe_ctlr_mode_set(struct fc_lport *lport, struct fcoe_ctlr *fip, - enum fip_state fip_mode) -{ - void *priv; - - WARN_ON(lport->state != LPORT_ST_RESET && - lport->state != LPORT_ST_DISABLED); - - if (fip_mode == FIP_MODE_VN2VN) { - lport->rport_priv_size = sizeof(struct fcoe_rport); - lport->point_to_multipoint = 1; - lport->tt.disc_recv_req = fcoe_ctlr_disc_recv; - lport->tt.disc_start = fcoe_ctlr_disc_start; - lport->tt.disc_stop = fcoe_ctlr_disc_stop; - lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final; - priv = fip; - } else { - lport->rport_priv_size = 0; - lport->point_to_multipoint = 0; - lport->tt.disc_recv_req = NULL; - lport->tt.disc_start = NULL; - lport->tt.disc_stop = NULL; - lport->tt.disc_stop_final = NULL; - priv = lport; - } - - fc_disc_config(lport, priv); -} - /** * fcoe_libfc_config() - Sets up libfc related properties for local port * @lport: The local port to configure libfc for @@ -2874,9 +2833,21 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip, fc_exch_init(lport); fc_elsct_init(lport); fc_lport_init(lport); + if (fip->mode == FIP_MODE_VN2VN) + lport->rport_priv_size = sizeof(struct fcoe_rport); fc_rport_init(lport); - fc_disc_init(lport); - fcoe_ctlr_mode_set(lport, fip, fip->mode); + if (fip->mode == FIP_MODE_VN2VN) { + lport->point_to_multipoint = 1; + lport->tt.disc_recv_req = fcoe_ctlr_disc_recv; + lport->tt.disc_start = fcoe_ctlr_disc_start; + lport->tt.disc_stop = fcoe_ctlr_disc_stop; + lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final; + mutex_init(&lport->disc.disc_mutex); + INIT_LIST_HEAD(&lport->disc.rports); + lport->disc.priv = fip; + } else { + fc_disc_init(lport); + } return 0; } EXPORT_SYMBOL_GPL(fcoe_libfc_config); @@ -2904,7 +2875,6 @@ EXPORT_SYMBOL(fcoe_fcf_get_selected); void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev) { struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); - struct fc_lport *lport = ctlr->lp; mutex_lock(&ctlr->ctlr_mutex); switch (ctlr_dev->mode) { @@ -2918,7 +2888,5 @@ void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev) } mutex_unlock(&ctlr->ctlr_mutex); - - fcoe_ctlr_mode_set(lport, ctlr, ctlr->mode); } EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index d0fa4b6c551f..a044f593e8b9 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1899,8 +1899,8 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev) sdev->allow_restart = 1; blk_queue_rq_timeout(sdev->request_queue, 120 * HZ); } - spin_unlock_irqrestore(shost->host_lock, lock_flags); scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun); + spin_unlock_irqrestore(shost->host_lock, lock_flags); return 0; } diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 2197b57fb225..f328089a1060 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -5148,7 +5148,7 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) ipr_trace; } - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); + list_add_tail(&ipr_cmd->queue, &hrrq->hrrq_free_q); if (!ipr_is_naca_model(res)) res->needs_sync_complete = 1; @@ -9349,10 +9349,7 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - if (ioa_cfg->intr_flag == IPR_USE_MSIX) - rc = request_irq(ioa_cfg->vectors_info[0].vec, ipr_test_intr, 0, IPR_NAME, ioa_cfg); - else - rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg); + rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg); if (rc) { dev_err(&pdev->dev, "Can not assign irq %d\n", pdev->irq); return rc; @@ -9374,10 +9371,7 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - if (ioa_cfg->intr_flag == IPR_USE_MSIX) - free_irq(ioa_cfg->vectors_info[0].vec, ioa_cfg); - else - free_irq(pdev->irq, ioa_cfg); + free_irq(pdev->irq, ioa_cfg); LEAVE; @@ -9728,7 +9722,6 @@ static void __ipr_remove(struct pci_dev *pdev) spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); flush_work(&ioa_cfg->work_q); - INIT_LIST_HEAD(&ioa_cfg->used_res_q); spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); spin_lock(&ipr_driver_lock); diff --git a/trunk/drivers/scsi/libfc/fc_disc.c b/trunk/drivers/scsi/libfc/fc_disc.c index 880a9068ca12..8e561e6a557c 100644 --- a/trunk/drivers/scsi/libfc/fc_disc.c +++ b/trunk/drivers/scsi/libfc/fc_disc.c @@ -712,13 +712,12 @@ static void fc_disc_stop_final(struct fc_lport *lport) } /** - * fc_disc_config() - Configure the discovery layer for a local port - * @lport: The local port that needs the discovery layer to be configured - * @priv: Private data structre for users of the discovery layer + * fc_disc_init() - Initialize the discovery layer for a local port + * @lport: The local port that needs the discovery layer to be initialized */ -void fc_disc_config(struct fc_lport *lport, void *priv) +int fc_disc_init(struct fc_lport *lport) { - struct fc_disc *disc = &lport->disc; + struct fc_disc *disc; if (!lport->tt.disc_start) lport->tt.disc_start = fc_disc_start; @@ -733,21 +732,12 @@ void fc_disc_config(struct fc_lport *lport, void *priv) lport->tt.disc_recv_req = fc_disc_recv_req; disc = &lport->disc; - - disc->priv = priv; -} -EXPORT_SYMBOL(fc_disc_config); - -/** - * fc_disc_init() - Initialize the discovery layer for a local port - * @lport: The local port that needs the discovery layer to be initialized - */ -void fc_disc_init(struct fc_lport *lport) -{ - struct fc_disc *disc = &lport->disc; - INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout); mutex_init(&disc->disc_mutex); INIT_LIST_HEAD(&disc->rports); + + disc->priv = lport; + + return 0; } EXPORT_SYMBOL(fc_disc_init); diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index 55cbd0180159..aec2e0da5016 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -235,17 +235,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) linkrate = phy->linkrate; memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); - /* Handle vacant phy - rest of dr data is not valid so skip it */ - if (phy->phy_state == PHY_VACANT) { - memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - phy->attached_dev_type = NO_DEVICE; - if (!test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) { - phy->phy_id = phy_id; - goto skip; - } else - goto out; - } - phy->attached_dev_type = to_dev_type(dr); if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) goto out; @@ -283,7 +272,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) phy->phy->maximum_linkrate = dr->pmax_linkrate; phy->phy->negotiated_linkrate = phy->linkrate; - skip: if (new_phy) if (sas_phy_add(phy->phy)) { sas_phy_free(phy->phy); @@ -400,7 +388,7 @@ int sas_ex_phy_discover(struct domain_device *dev, int single) if (!disc_req) return -ENOMEM; - disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE); + disc_resp = alloc_smp_req(DISCOVER_RESP_SIZE); if (!disc_resp) { kfree(disc_req); return -ENOMEM; diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index d43faf34c1e2..74b67d98e952 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -438,12 +438,11 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, struct lpfc_rqe *temp_hrqe; struct lpfc_rqe *temp_drqe; struct lpfc_register doorbell; - int put_index; + int put_index = hq->host_index; /* sanity check on queue memory */ if (unlikely(!hq) || unlikely(!dq)) return -ENOMEM; - put_index = hq->host_index; temp_hrqe = hq->qe[hq->host_index].rqe; temp_drqe = dq->qe[dq->host_index].rqe; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index 684cc343cf09..408d2548a748 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -1488,4 +1488,7 @@ struct megasas_mgmt_info { int max_index; }; +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) + #endif /*LSI_MEGARAID_SAS_H */ diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c index 7c90d57b867e..9d53540207ec 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3984,12 +3984,12 @@ static int megasas_probe_one(struct pci_dev *pdev, if (reset_devices) { pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); if (pos) { - pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS, + pci_read_config_word(pdev, msi_control_reg(pos), &control); if (control & PCI_MSIX_FLAGS_ENABLE) { dev_info(&pdev->dev, "resetting MSI-X\n"); pci_write_config_word(pdev, - pos + PCI_MSIX_FLAGS, + msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); } diff --git a/trunk/drivers/scsi/mvsas/mv_init.c b/trunk/drivers/scsi/mvsas/mv_init.c index 74550922ad55..ce90d0546cdd 100644 --- a/trunk/drivers/scsi/mvsas/mv_init.c +++ b/trunk/drivers/scsi/mvsas/mv_init.c @@ -703,7 +703,7 @@ static struct pci_device_id mvs_pci_table[] = { { PCI_VDEVICE(TTI, 0x2744), chip_9480 }, { PCI_VDEVICE(TTI, 0x2760), chip_9480 }, { - .vendor = PCI_VENDOR_ID_MARVELL_EXT, + .vendor = 0x1b4b, .device = 0x9480, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, @@ -712,7 +712,7 @@ static struct pci_device_id mvs_pci_table[] = { .driver_data = chip_9480, }, { - .vendor = PCI_VENDOR_ID_MARVELL_EXT, + .vendor = 0x1b4b, .device = 0x9445, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, @@ -721,7 +721,7 @@ static struct pci_device_id mvs_pci_table[] = { .driver_data = chip_9445, }, { - .vendor = PCI_VENDOR_ID_MARVELL_EXT, + .vendor = 0x1b4b, .device = 0x9485, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, diff --git a/trunk/drivers/scsi/mvumi.c b/trunk/drivers/scsi/mvumi.c index c3601b57a80c..4594ccaaf49b 100644 --- a/trunk/drivers/scsi/mvumi.c +++ b/trunk/drivers/scsi/mvumi.c @@ -49,8 +49,8 @@ MODULE_AUTHOR("jyli@marvell.com"); MODULE_DESCRIPTION("Marvell UMI Driver"); static DEFINE_PCI_DEVICE_TABLE(mvumi_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, PCI_DEVICE_ID_MARVELL_MV9143) }, - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, PCI_DEVICE_ID_MARVELL_MV9580) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9143) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9580) }, { 0 } }; diff --git a/trunk/drivers/scsi/mvumi.h b/trunk/drivers/scsi/mvumi.h index 41f168702ac7..e360135fd1bd 100644 --- a/trunk/drivers/scsi/mvumi.h +++ b/trunk/drivers/scsi/mvumi.h @@ -32,6 +32,7 @@ #define VER_BUILD 1500 #define MV_DRIVER_NAME "mvumi" +#define PCI_VENDOR_ID_MARVELL_2 0x1b4b #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143 #define PCI_DEVICE_ID_MARVELL_MV9580 0x9580 diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index b3db9dcc2619..1d82eef4e1eb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -1938,6 +1938,11 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) "Timer for the VP[%d] has stopped\n", vha->vp_idx); } + /* No pending activities shall be there on the vha now */ + if (ql2xextended_error_logging & ql_dbg_user) + msleep(random32()%10); /* Just to see if something falls on + * the net we have placed below */ + BUG_ON(atomic_read(&vha->vref_count)); qla2x00_free_fcports(vha); diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.c b/trunk/drivers/scsi/qla2xxx/qla_dbg.c index fbc305f1c87c..1626de52e32a 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.c @@ -15,7 +15,6 @@ * | Mailbox commands | 0x115b | 0x111a-0x111b | * | | | 0x112c-0x112e | * | | | 0x113a | - * | | | 0x1155-0x1158 | * | Device Discovery | 0x2087 | 0x2020-0x2022, | * | | | 0x2016 | * | Queue Command and IO tracing | 0x3031 | 0x3006-0x300b | @@ -402,7 +401,7 @@ qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr, void *ring; } aq, *aqp; - if (!ha->tgt.atio_ring) + if (!ha->tgt.atio_q_length) return ptr; num_queues = 1; diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index 65c5ff75936b..c6509911772b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -863,6 +863,7 @@ typedef struct { #define MBX_1 BIT_1 #define MBX_0 BIT_0 +#define RNID_TYPE_SET_VERSION 0x9 #define RNID_TYPE_ASIC_TEMP 0xC /* diff --git a/trunk/drivers/scsi/qla2xxx/qla_gbl.h b/trunk/drivers/scsi/qla2xxx/qla_gbl.h index b310fa97b545..eb3ca21a7f17 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_gbl.h @@ -357,6 +357,9 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *, dma_addr_t, uint16_t , uint16_t *, extern int qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *); +extern int +qla2x00_set_driver_version(scsi_qla_host_t *, char *); + extern int qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *, uint16_t, uint16_t, uint16_t, uint16_t); diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index b59203393cb2..edf4d14a1335 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -619,6 +619,8 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) qla24xx_read_fcp_prio_cfg(vha); + qla2x00_set_driver_version(vha, QLA2XXX_VERSION); + return (rval); } @@ -1397,7 +1399,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) mq_size += ha->max_rsp_queues * (rsp->length * sizeof(response_t)); } - if (ha->tgt.atio_ring) + if (ha->tgt.atio_q_length) mq_size += ha->tgt.atio_q_length * sizeof(request_t); /* Allocate memory for Fibre Channel Event Buffer. */ if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha)) diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index 43345af56431..186dd59ce4fa 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -3866,6 +3866,64 @@ qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) return rval; } +int +qla2x00_set_driver_version(scsi_qla_host_t *vha, char *version) +{ + int rval; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + int len; + uint16_t dwlen; + uint8_t *str; + dma_addr_t str_dma; + struct qla_hw_data *ha = vha->hw; + + if (!IS_FWI2_CAPABLE(ha) || IS_QLA82XX(ha)) + return QLA_FUNCTION_FAILED; + + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1155, + "Entered %s.\n", __func__); + + str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma); + if (!str) { + ql_log(ql_log_warn, vha, 0x1156, + "Failed to allocate driver version param.\n"); + return QLA_MEMORY_ALLOC_FAILED; + } + + memcpy(str, "\x7\x3\x11\x0", 4); + dwlen = str[0]; + len = dwlen * sizeof(uint32_t) - 4; + memset(str + 4, 0, len); + if (len > strlen(version)) + len = strlen(version); + memcpy(str + 4, version, len); + + mcp->mb[0] = MBC_SET_RNID_PARAMS; + mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen; + mcp->mb[2] = MSW(LSD(str_dma)); + mcp->mb[3] = LSW(LSD(str_dma)); + mcp->mb[6] = MSW(MSD(str_dma)); + mcp->mb[7] = LSW(MSD(str_dma)); + mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; + mcp->in_mb = MBX_0; + mcp->tov = MBX_TOV_SECONDS; + mcp->flags = 0; + rval = qla2x00_mailbox_command(vha, mcp); + + if (rval != QLA_SUCCESS) { + ql_dbg(ql_dbg_mbx, vha, 0x1157, + "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); + } else { + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1158, + "Done %s.\n", __func__); + } + + dma_pool_free(ha->s_dma_pool, str, str_dma); + + return rval; +} + static int qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index ec54036d1e12..2b6e478d9e33 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.04.00.13-k" +#define QLA2XXX_VERSION "8.04.00.08-k" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 4 diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index c31187d79343..765398c063c7 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -71,14 +71,9 @@ struct kmem_cache *scsi_sdb_cache; #ifdef CONFIG_ACPI #include -static bool acpi_scsi_bus_match(struct device *dev) -{ - return dev->bus == &scsi_bus_type; -} - int scsi_register_acpi_bus_type(struct acpi_bus_type *bus) { - bus->match = acpi_scsi_bus_match; + bus->bus = &scsi_bus_type; return register_acpi_bus_type(bus); } EXPORT_SYMBOL_GPL(scsi_register_acpi_bus_type); diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index 2a32036a9404..86974471af68 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -4112,10 +4112,6 @@ static int st_probe(struct device *dev) tpnt->disk = disk; disk->private_data = &tpnt->driver; disk->queue = SDp->request_queue; - /* SCSI tape doesn't register this gendisk via add_disk(). Manually - * take queue reference that release_disk() expects. */ - if (!blk_get_queue(disk->queue)) - goto out_put_disk; tpnt->driver = &st_template; tpnt->device = SDp; @@ -4189,7 +4185,7 @@ static int st_probe(struct device *dev) idr_preload_end(); if (error < 0) { pr_warn("st: idr allocation failed: %d\n", error); - goto out_put_queue; + goto out_put_disk; } tpnt->index = error; sprintf(disk->disk_name, "st%d", tpnt->index); @@ -4215,8 +4211,6 @@ static int st_probe(struct device *dev) spin_lock(&st_index_lock); idr_remove(&st_index_idr, tpnt->index); spin_unlock(&st_index_lock); -out_put_queue: - blk_put_queue(disk->queue); out_put_disk: put_disk(disk); kfree(tpnt); diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index 2be0de920d67..f80eee74a311 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -55,7 +55,6 @@ comment "SPI Master Controller Drivers" config SPI_ALTERA tristate "Altera SPI Controller" - depends on GENERIC_HARDIRQS select SPI_BITBANG help This is the driver for the Altera SPI Controller. @@ -311,7 +310,7 @@ config SPI_PXA2XX_DMA config SPI_PXA2XX tristate "PXA2xx SSP SPI master" - depends on (ARCH_PXA || PCI || ACPI) && GENERIC_HARDIRQS + depends on ARCH_PXA || PCI || ACPI select PXA_SSP if ARCH_PXA help This enables using a PXA2xx or Sodaville SSP port as a SPI master diff --git a/trunk/drivers/spi/spi-bcm63xx.c b/trunk/drivers/spi/spi-bcm63xx.c index d7df435d962e..9578af782a77 100644 --- a/trunk/drivers/spi/spi-bcm63xx.c +++ b/trunk/drivers/spi/spi-bcm63xx.c @@ -152,6 +152,7 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, static int bcm63xx_spi_setup(struct spi_device *spi) { struct bcm63xx_spi *bs; + int ret; bs = spi_master_get_devdata(spi->master); @@ -489,7 +490,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) default: dev_err(dev, "unsupported MSG_CTL width: %d\n", bs->msg_ctl_width); - goto out_err; + goto out_clk_disable; } /* Initialize hardware */ diff --git a/trunk/drivers/spi/spi-mpc512x-psc.c b/trunk/drivers/spi/spi-mpc512x-psc.c index 3e490ee7f275..89480b281d74 100644 --- a/trunk/drivers/spi/spi-mpc512x-psc.c +++ b/trunk/drivers/spi/spi-mpc512x-psc.c @@ -164,7 +164,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, for (i = count; i > 0; i--) { data = tx_buf ? *tx_buf++ : 0; - if (len == EOFBYTE && t->cs_change) + if (len == EOFBYTE) setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); out_8(&fifo->txdata_8, data); len--; diff --git a/trunk/drivers/spi/spi-pxa2xx.c b/trunk/drivers/spi/spi-pxa2xx.c index 810413883c79..90b27a3508a6 100644 --- a/trunk/drivers/spi/spi-pxa2xx.c +++ b/trunk/drivers/spi/spi-pxa2xx.c @@ -1168,6 +1168,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) master->dev.parent = &pdev->dev; master->dev.of_node = pdev->dev.of_node; + ACPI_HANDLE_SET(&master->dev, ACPI_HANDLE(&pdev->dev)); /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; diff --git a/trunk/drivers/spi/spi-s3c64xx.c b/trunk/drivers/spi/spi-s3c64xx.c index 4188b2faac5c..e862ab8853aa 100644 --- a/trunk/drivers/spi/spi-s3c64xx.c +++ b/trunk/drivers/spi/spi-s3c64xx.c @@ -994,30 +994,25 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data) { struct s3c64xx_spi_driver_data *sdd = data; struct spi_master *spi = sdd->master; - unsigned int val, clr = 0; + unsigned int val; - val = readl(sdd->regs + S3C64XX_SPI_STATUS); + val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); - if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { - clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; + val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | + S3C64XX_SPI_PND_RX_UNDERRUN_CLR | + S3C64XX_SPI_PND_TX_OVERRUN_CLR | + S3C64XX_SPI_PND_TX_UNDERRUN_CLR; + + writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); + + if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) dev_err(&spi->dev, "RX overrun\n"); - } - if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { - clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; + if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) dev_err(&spi->dev, "RX underrun\n"); - } - if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { - clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; + if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) dev_err(&spi->dev, "TX overrun\n"); - } - if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { - clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; + if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) dev_err(&spi->dev, "TX underrun\n"); - } - - /* Clear the pending irq by setting and then clearing it */ - writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); - writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR); return IRQ_HANDLED; } @@ -1041,13 +1036,9 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) writel(0, regs + S3C64XX_SPI_MODE_CFG); writel(0, regs + S3C64XX_SPI_PACKET_CNT); - /* Clear any irq pending bits, should set and clear the bits */ - val = S3C64XX_SPI_PND_RX_OVERRUN_CLR | - S3C64XX_SPI_PND_RX_UNDERRUN_CLR | - S3C64XX_SPI_PND_TX_OVERRUN_CLR | - S3C64XX_SPI_PND_TX_UNDERRUN_CLR; - writel(val, regs + S3C64XX_SPI_PENDING_CLR); - writel(0, regs + S3C64XX_SPI_PENDING_CLR); + /* Clear any irq pending bits */ + writel(readl(regs + S3C64XX_SPI_PENDING_CLR), + regs + S3C64XX_SPI_PENDING_CLR); writel(0, regs + S3C64XX_SPI_SWAP_CFG); diff --git a/trunk/drivers/spi/spi-tegra20-slink.c b/trunk/drivers/spi/spi-tegra20-slink.c index a829563f4713..b8698b389ef3 100644 --- a/trunk/drivers/spi/spi-tegra20-slink.c +++ b/trunk/drivers/spi/spi-tegra20-slink.c @@ -858,6 +858,21 @@ static int tegra_slink_setup(struct spi_device *spi) return 0; } +static int tegra_slink_prepare_transfer(struct spi_master *master) +{ + struct tegra_slink_data *tspi = spi_master_get_devdata(master); + + return pm_runtime_get_sync(tspi->dev); +} + +static int tegra_slink_unprepare_transfer(struct spi_master *master) +{ + struct tegra_slink_data *tspi = spi_master_get_devdata(master); + + pm_runtime_put(tspi->dev); + return 0; +} + static int tegra_slink_transfer_one_message(struct spi_master *master, struct spi_message *msg) { @@ -870,12 +885,6 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, msg->status = 0; msg->actual_length = 0; - ret = pm_runtime_get_sync(tspi->dev); - if (ret < 0) { - dev_err(tspi->dev, "runtime get failed: %d\n", ret); - goto done; - } - single_xfer = list_is_singular(&msg->transfers); list_for_each_entry(xfer, &msg->transfers, transfer_list) { INIT_COMPLETION(tspi->xfer_completion); @@ -912,8 +921,6 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, exit: tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); - pm_runtime_put(tspi->dev); -done: msg->status = ret; spi_finalize_current_message(master); return ret; @@ -1141,7 +1148,9 @@ static int tegra_slink_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->setup = tegra_slink_setup; + master->prepare_transfer_hardware = tegra_slink_prepare_transfer; master->transfer_one_message = tegra_slink_transfer_one_message; + master->unprepare_transfer_hardware = tegra_slink_unprepare_transfer; master->num_chipselect = MAX_CHIP_SELECT; master->bus_num = -1; diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 004b10f184d4..f996c600eb8c 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -543,16 +543,17 @@ static void spi_pump_messages(struct kthread_work *work) /* Lock queue and check for queue work */ spin_lock_irqsave(&master->queue_lock, flags); if (list_empty(&master->queue) || !master->running) { - if (!master->busy) { - spin_unlock_irqrestore(&master->queue_lock, flags); - return; + if (master->busy && master->unprepare_transfer_hardware) { + ret = master->unprepare_transfer_hardware(master); + if (ret) { + spin_unlock_irqrestore(&master->queue_lock, flags); + dev_err(&master->dev, + "failed to unprepare transfer hardware\n"); + return; + } } master->busy = false; spin_unlock_irqrestore(&master->queue_lock, flags); - if (master->unprepare_transfer_hardware && - master->unprepare_transfer_hardware(master)) - dev_err(&master->dev, - "failed to unprepare transfer hardware\n"); return; } @@ -983,7 +984,7 @@ static void acpi_register_spi_devices(struct spi_master *master) acpi_status status; acpi_handle handle; - handle = ACPI_HANDLE(master->dev.parent); + handle = ACPI_HANDLE(&master->dev); if (!handle) return; diff --git a/trunk/drivers/ssb/driver_chipcommon_pmu.c b/trunk/drivers/ssb/driver_chipcommon_pmu.c index 7b0bce936762..4c0f6d883dd3 100644 --- a/trunk/drivers/ssb/driver_chipcommon_pmu.c +++ b/trunk/drivers/ssb/driver_chipcommon_pmu.c @@ -675,32 +675,3 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc) return 0; } } - -void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid) -{ - u32 pmu_ctl = 0; - - switch (cc->dev->bus->chip_id) { - case 0x4322: - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070); - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a); - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854); - if (spuravoid == 1) - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828); - else - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828); - pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; - break; - case 43222: - /* TODO: BCM43222 requires updating PLLs too */ - return; - default: - ssb_printk(KERN_ERR PFX - "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", - cc->dev->bus->chip_id); - return; - } - - chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl); -} -EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate); diff --git a/trunk/drivers/ssbi/Kconfig b/trunk/drivers/ssbi/Kconfig deleted file mode 100644 index 1ae4040afedd..000000000000 --- a/trunk/drivers/ssbi/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# -# SSBI bus support -# - -menu "Qualcomm MSM SSBI bus support" - -config SSBI - tristate "Qualcomm Single-wire Serial Bus Interface (SSBI)" - help - If you say yes to this option, support will be included for the - built-in SSBI interface on Qualcomm MSM family processors. - - This is required for communicating with Qualcomm PMICs and - other devices that have the SSBI interface. - -endmenu diff --git a/trunk/drivers/ssbi/Makefile b/trunk/drivers/ssbi/Makefile deleted file mode 100644 index 38fb70c31caf..000000000000 --- a/trunk/drivers/ssbi/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_SSBI) += ssbi.o diff --git a/trunk/drivers/ssbi/ssbi.c b/trunk/drivers/ssbi/ssbi.c deleted file mode 100644 index f32da0258a8e..000000000000 --- a/trunk/drivers/ssbi/ssbi.c +++ /dev/null @@ -1,379 +0,0 @@ -/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved. - * Copyright (c) 2010, Google Inc. - * - * Original authors: Code Aurora Forum - * - * Author: Dima Zavin - * - Largely rewritten from original to not be an i2c driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* SSBI 2.0 controller registers */ -#define SSBI2_CMD 0x0008 -#define SSBI2_RD 0x0010 -#define SSBI2_STATUS 0x0014 -#define SSBI2_MODE2 0x001C - -/* SSBI_CMD fields */ -#define SSBI_CMD_RDWRN (1 << 24) - -/* SSBI_STATUS fields */ -#define SSBI_STATUS_RD_READY (1 << 2) -#define SSBI_STATUS_READY (1 << 1) -#define SSBI_STATUS_MCHN_BUSY (1 << 0) - -/* SSBI_MODE2 fields */ -#define SSBI_MODE2_REG_ADDR_15_8_SHFT 0x04 -#define SSBI_MODE2_REG_ADDR_15_8_MASK (0x7f << SSBI_MODE2_REG_ADDR_15_8_SHFT) - -#define SET_SSBI_MODE2_REG_ADDR_15_8(MD, AD) \ - (((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \ - SSBI_MODE2_REG_ADDR_15_8_MASK)) - -/* SSBI PMIC Arbiter command registers */ -#define SSBI_PA_CMD 0x0000 -#define SSBI_PA_RD_STATUS 0x0004 - -/* SSBI_PA_CMD fields */ -#define SSBI_PA_CMD_RDWRN (1 << 24) -#define SSBI_PA_CMD_ADDR_MASK 0x7fff /* REG_ADDR_7_0, REG_ADDR_8_14*/ - -/* SSBI_PA_RD_STATUS fields */ -#define SSBI_PA_RD_STATUS_TRANS_DONE (1 << 27) -#define SSBI_PA_RD_STATUS_TRANS_DENIED (1 << 26) - -#define SSBI_TIMEOUT_US 100 - -struct ssbi { - struct device *slave; - void __iomem *base; - spinlock_t lock; - enum ssbi_controller_type controller_type; - int (*read)(struct ssbi *, u16 addr, u8 *buf, int len); - int (*write)(struct ssbi *, u16 addr, u8 *buf, int len); -}; - -#define to_ssbi(dev) platform_get_drvdata(to_platform_device(dev)) - -static inline u32 ssbi_readl(struct ssbi *ssbi, u32 reg) -{ - return readl(ssbi->base + reg); -} - -static inline void ssbi_writel(struct ssbi *ssbi, u32 val, u32 reg) -{ - writel(val, ssbi->base + reg); -} - -/* - * Via private exchange with one of the original authors, the hardware - * should generally finish a transaction in about 5us. The worst - * case, is when using the arbiter and both other CPUs have just - * started trying to use the SSBI bus will result in a time of about - * 20us. It should never take longer than this. - * - * As such, this wait merely spins, with a udelay. - */ -static int ssbi_wait_mask(struct ssbi *ssbi, u32 set_mask, u32 clr_mask) -{ - u32 timeout = SSBI_TIMEOUT_US; - u32 val; - - while (timeout--) { - val = ssbi_readl(ssbi, SSBI2_STATUS); - if (((val & set_mask) == set_mask) && ((val & clr_mask) == 0)) - return 0; - udelay(1); - } - - return -ETIMEDOUT; -} - -static int -ssbi_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len) -{ - u32 cmd = SSBI_CMD_RDWRN | ((addr & 0xff) << 16); - int ret = 0; - - if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) { - u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2); - mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr); - ssbi_writel(ssbi, mode2, SSBI2_MODE2); - } - - while (len) { - ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0); - if (ret) - goto err; - - ssbi_writel(ssbi, cmd, SSBI2_CMD); - ret = ssbi_wait_mask(ssbi, SSBI_STATUS_RD_READY, 0); - if (ret) - goto err; - *buf++ = ssbi_readl(ssbi, SSBI2_RD) & 0xff; - len--; - } - -err: - return ret; -} - -static int -ssbi_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len) -{ - int ret = 0; - - if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) { - u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2); - mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr); - ssbi_writel(ssbi, mode2, SSBI2_MODE2); - } - - while (len) { - ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0); - if (ret) - goto err; - - ssbi_writel(ssbi, ((addr & 0xff) << 16) | *buf, SSBI2_CMD); - ret = ssbi_wait_mask(ssbi, 0, SSBI_STATUS_MCHN_BUSY); - if (ret) - goto err; - buf++; - len--; - } - -err: - return ret; -} - -/* - * See ssbi_wait_mask for an explanation of the time and the - * busywait. - */ -static inline int -ssbi_pa_transfer(struct ssbi *ssbi, u32 cmd, u8 *data) -{ - u32 timeout = SSBI_TIMEOUT_US; - u32 rd_status = 0; - - ssbi_writel(ssbi, cmd, SSBI_PA_CMD); - - while (timeout--) { - rd_status = ssbi_readl(ssbi, SSBI_PA_RD_STATUS); - - if (rd_status & SSBI_PA_RD_STATUS_TRANS_DENIED) - return -EPERM; - - if (rd_status & SSBI_PA_RD_STATUS_TRANS_DONE) { - if (data) - *data = rd_status & 0xff; - return 0; - } - udelay(1); - } - - return -ETIMEDOUT; -} - -static int -ssbi_pa_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len) -{ - u32 cmd; - int ret = 0; - - cmd = SSBI_PA_CMD_RDWRN | (addr & SSBI_PA_CMD_ADDR_MASK) << 8; - - while (len) { - ret = ssbi_pa_transfer(ssbi, cmd, buf); - if (ret) - goto err; - buf++; - len--; - } - -err: - return ret; -} - -static int -ssbi_pa_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len) -{ - u32 cmd; - int ret = 0; - - while (len) { - cmd = (addr & SSBI_PA_CMD_ADDR_MASK) << 8 | *buf; - ret = ssbi_pa_transfer(ssbi, cmd, NULL); - if (ret) - goto err; - buf++; - len--; - } - -err: - return ret; -} - -int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len) -{ - struct ssbi *ssbi = to_ssbi(dev); - unsigned long flags; - int ret; - - spin_lock_irqsave(&ssbi->lock, flags); - ret = ssbi->read(ssbi, addr, buf, len); - spin_unlock_irqrestore(&ssbi->lock, flags); - - return ret; -} -EXPORT_SYMBOL_GPL(ssbi_read); - -int ssbi_write(struct device *dev, u16 addr, u8 *buf, int len) -{ - struct ssbi *ssbi = to_ssbi(dev); - unsigned long flags; - int ret; - - spin_lock_irqsave(&ssbi->lock, flags); - ret = ssbi->write(ssbi, addr, buf, len); - spin_unlock_irqrestore(&ssbi->lock, flags); - - return ret; -} -EXPORT_SYMBOL_GPL(ssbi_write); - -static int ssbi_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct resource *mem_res; - struct ssbi *ssbi; - int ret = 0; - const char *type; - - ssbi = kzalloc(sizeof(struct ssbi), GFP_KERNEL); - if (!ssbi) { - pr_err("can not allocate ssbi_data\n"); - return -ENOMEM; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - pr_err("missing mem resource\n"); - ret = -EINVAL; - goto err_get_mem_res; - } - - ssbi->base = ioremap(mem_res->start, resource_size(mem_res)); - if (!ssbi->base) { - pr_err("ioremap of 0x%p failed\n", (void *)mem_res->start); - ret = -EINVAL; - goto err_ioremap; - } - platform_set_drvdata(pdev, ssbi); - - type = of_get_property(np, "qcom,controller-type", NULL); - if (type == NULL) { - pr_err("Missing qcom,controller-type property\n"); - ret = -EINVAL; - goto err_ssbi_controller; - } - dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type); - if (strcmp(type, "ssbi") == 0) - ssbi->controller_type = MSM_SBI_CTRL_SSBI; - else if (strcmp(type, "ssbi2") == 0) - ssbi->controller_type = MSM_SBI_CTRL_SSBI2; - else if (strcmp(type, "pmic-arbiter") == 0) - ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER; - else { - pr_err("Unknown qcom,controller-type\n"); - ret = -EINVAL; - goto err_ssbi_controller; - } - - if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) { - ssbi->read = ssbi_pa_read_bytes; - ssbi->write = ssbi_pa_write_bytes; - } else { - ssbi->read = ssbi_read_bytes; - ssbi->write = ssbi_write_bytes; - } - - spin_lock_init(&ssbi->lock); - - ret = of_platform_populate(np, NULL, NULL, &pdev->dev); - if (ret) - goto err_ssbi_controller; - - return 0; - -err_ssbi_controller: - platform_set_drvdata(pdev, NULL); - iounmap(ssbi->base); -err_ioremap: -err_get_mem_res: - kfree(ssbi); - return ret; -} - -static int ssbi_remove(struct platform_device *pdev) -{ - struct ssbi *ssbi = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - iounmap(ssbi->base); - kfree(ssbi); - return 0; -} - -static struct of_device_id ssbi_match_table[] = { - { .compatible = "qcom,ssbi" }, - {} -}; - -static struct platform_driver ssbi_driver = { - .probe = ssbi_probe, - .remove = ssbi_remove, - .driver = { - .name = "ssbi", - .owner = THIS_MODULE, - .of_match_table = ssbi_match_table, - }, -}; - -static int __init ssbi_init(void) -{ - return platform_driver_register(&ssbi_driver); -} -module_init(ssbi_init); - -static void __exit ssbi_exit(void) -{ - platform_driver_unregister(&ssbi_driver); -} -module_exit(ssbi_exit) - -MODULE_LICENSE("GPL v2"); -MODULE_VERSION("1.0"); -MODULE_ALIAS("platform:ssbi"); -MODULE_AUTHOR("Dima Zavin "); diff --git a/trunk/drivers/staging/android/Kconfig b/trunk/drivers/staging/android/Kconfig index 465a28c08f20..c95aedeff3f4 100644 --- a/trunk/drivers/staging/android/Kconfig +++ b/trunk/drivers/staging/android/Kconfig @@ -72,6 +72,15 @@ config ANDROID_INTF_ALARM_DEV elapsed realtime, and a non-wakeup alarm on the monotonic clock. Also exports the alarm interface to user-space. +config SYNC + bool "Synchronization framework" + default n + select ANON_INODES + help + This option enables the framework for synchronization between multiple + drivers. Sync implementations can take advantage of hardware + synchronization built into devices like GPUs. + endif # if ANDROID endmenu diff --git a/trunk/drivers/staging/android/Makefile b/trunk/drivers/staging/android/Makefile index b35a631734d6..22c656c82c3f 100644 --- a/trunk/drivers/staging/android/Makefile +++ b/trunk/drivers/staging/android/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o +obj-$(CONFIG_SYNC) += sync.o diff --git a/trunk/drivers/staging/android/sync.c b/trunk/drivers/staging/android/sync.c new file mode 100644 index 000000000000..4a9e63df83e9 --- /dev/null +++ b/trunk/drivers/staging/android/sync.c @@ -0,0 +1,525 @@ +/* + * drivers/base/sync.c + * + * Copyright (C) 2012 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "sync.h" + +static void sync_fence_signal_pt(struct sync_pt *pt); +static int _sync_pt_has_signaled(struct sync_pt *pt); + +struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, + int size, const char *name) +{ + struct sync_timeline *obj; + + if (size < sizeof(struct sync_timeline)) + return NULL; + + obj = kzalloc(size, GFP_KERNEL); + if (obj == NULL) + return NULL; + + obj->ops = ops; + strlcpy(obj->name, name, sizeof(obj->name)); + + INIT_LIST_HEAD(&obj->child_list_head); + spin_lock_init(&obj->child_list_lock); + + INIT_LIST_HEAD(&obj->active_list_head); + spin_lock_init(&obj->active_list_lock); + + return obj; +} + +void sync_timeline_destroy(struct sync_timeline *obj) +{ + unsigned long flags; + bool needs_freeing; + + spin_lock_irqsave(&obj->child_list_lock, flags); + obj->destroyed = true; + needs_freeing = list_empty(&obj->child_list_head); + spin_unlock_irqrestore(&obj->child_list_lock, flags); + + if (needs_freeing) + kfree(obj); + else + sync_timeline_signal(obj); +} + +static void sync_timeline_add_pt(struct sync_timeline *obj, struct sync_pt *pt) +{ + unsigned long flags; + + pt->parent = obj; + + spin_lock_irqsave(&obj->child_list_lock, flags); + list_add_tail(&pt->child_list, &obj->child_list_head); + spin_unlock_irqrestore(&obj->child_list_lock, flags); +} + +static void sync_timeline_remove_pt(struct sync_pt *pt) +{ + struct sync_timeline *obj = pt->parent; + unsigned long flags; + bool needs_freeing; + + spin_lock_irqsave(&obj->active_list_lock, flags); + if (!list_empty(&pt->active_list)) + list_del_init(&pt->active_list); + spin_unlock_irqrestore(&obj->active_list_lock, flags); + + spin_lock_irqsave(&obj->child_list_lock, flags); + list_del(&pt->child_list); + needs_freeing = obj->destroyed && list_empty(&obj->child_list_head); + spin_unlock_irqrestore(&obj->child_list_lock, flags); + + if (needs_freeing) + kfree(obj); +} + +void sync_timeline_signal(struct sync_timeline *obj) +{ + unsigned long flags; + LIST_HEAD(signaled_pts); + struct list_head *pos, *n; + + spin_lock_irqsave(&obj->active_list_lock, flags); + + list_for_each_safe(pos, n, &obj->active_list_head) { + struct sync_pt *pt = + container_of(pos, struct sync_pt, active_list); + + if (_sync_pt_has_signaled(pt)) + list_move(pos, &signaled_pts); + } + + spin_unlock_irqrestore(&obj->active_list_lock, flags); + + list_for_each_safe(pos, n, &signaled_pts) { + struct sync_pt *pt = + container_of(pos, struct sync_pt, active_list); + + list_del_init(pos); + sync_fence_signal_pt(pt); + } +} + +struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size) +{ + struct sync_pt *pt; + + if (size < sizeof(struct sync_pt)) + return NULL; + + pt = kzalloc(size, GFP_KERNEL); + if (pt == NULL) + return NULL; + + INIT_LIST_HEAD(&pt->active_list); + sync_timeline_add_pt(parent, pt); + + return pt; +} + +void sync_pt_free(struct sync_pt *pt) +{ + if (pt->parent->ops->free_pt) + pt->parent->ops->free_pt(pt); + + sync_timeline_remove_pt(pt); + + kfree(pt); +} + +/* call with pt->parent->active_list_lock held */ +static int _sync_pt_has_signaled(struct sync_pt *pt) +{ + if (!pt->status) + pt->status = pt->parent->ops->has_signaled(pt); + + if (!pt->status && pt->parent->destroyed) + pt->status = -ENOENT; + + return pt->status; +} + +static struct sync_pt *sync_pt_dup(struct sync_pt *pt) +{ + return pt->parent->ops->dup(pt); +} + +/* Adds a sync pt to the active queue. Called when added to a fence */ +static void sync_pt_activate(struct sync_pt *pt) +{ + struct sync_timeline *obj = pt->parent; + unsigned long flags; + int err; + + spin_lock_irqsave(&obj->active_list_lock, flags); + + err = _sync_pt_has_signaled(pt); + if (err != 0) + goto out; + + list_add_tail(&pt->active_list, &obj->active_list_head); + +out: + spin_unlock_irqrestore(&obj->active_list_lock, flags); +} + +static int sync_fence_release(struct inode *inode, struct file *file); +static long sync_fence_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); + + +static const struct file_operations sync_fence_fops = { + .release = sync_fence_release, + .unlocked_ioctl = sync_fence_ioctl, +}; + +static struct sync_fence *sync_fence_alloc(const char *name) +{ + struct sync_fence *fence; + + fence = kzalloc(sizeof(struct sync_fence), GFP_KERNEL); + if (fence == NULL) + return NULL; + + fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, + fence, 0); + if (fence->file == NULL) + goto err; + + strlcpy(fence->name, name, sizeof(fence->name)); + + INIT_LIST_HEAD(&fence->pt_list_head); + INIT_LIST_HEAD(&fence->waiter_list_head); + spin_lock_init(&fence->waiter_list_lock); + + init_waitqueue_head(&fence->wq); + return fence; + +err: + kfree(fence); + return NULL; +} + +/* TODO: implement a create which takes more that one sync_pt */ +struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) +{ + struct sync_fence *fence; + + if (pt->fence) + return NULL; + + fence = sync_fence_alloc(name); + if (fence == NULL) + return NULL; + + pt->fence = fence; + list_add(&pt->pt_list, &fence->pt_list_head); + sync_pt_activate(pt); + + return fence; +} + +static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src) +{ + struct list_head *pos; + + list_for_each(pos, &src->pt_list_head) { + struct sync_pt *orig_pt = + container_of(pos, struct sync_pt, pt_list); + struct sync_pt *new_pt = sync_pt_dup(orig_pt); + + if (new_pt == NULL) + return -ENOMEM; + + new_pt->fence = dst; + list_add(&new_pt->pt_list, &dst->pt_list_head); + sync_pt_activate(new_pt); + } + + return 0; +} + +static void sync_fence_free_pts(struct sync_fence *fence) +{ + struct list_head *pos, *n; + + list_for_each_safe(pos, n, &fence->pt_list_head) { + struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); + sync_pt_free(pt); + } +} + +struct sync_fence *sync_fence_fdget(int fd) +{ + struct file *file = fget(fd); + + if (file == NULL) + return NULL; + + if (file->f_op != &sync_fence_fops) + goto err; + + return file->private_data; + +err: + fput(file); + return NULL; +} + +void sync_fence_put(struct sync_fence *fence) +{ + fput(fence->file); +} + +void sync_fence_install(struct sync_fence *fence, int fd) +{ + fd_install(fd, fence->file); +} + +static int sync_fence_get_status(struct sync_fence *fence) +{ + struct list_head *pos; + int status = 1; + + list_for_each(pos, &fence->pt_list_head) { + struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); + int pt_status = pt->status; + + if (pt_status < 0) { + status = pt_status; + break; + } else if (status == 1) { + status = pt_status; + } + } + + return status; +} + +struct sync_fence *sync_fence_merge(const char *name, + struct sync_fence *a, struct sync_fence *b) +{ + struct sync_fence *fence; + int err; + + fence = sync_fence_alloc(name); + if (fence == NULL) + return NULL; + + err = sync_fence_copy_pts(fence, a); + if (err < 0) + goto err; + + err = sync_fence_copy_pts(fence, b); + if (err < 0) + goto err; + + fence->status = sync_fence_get_status(fence); + + return fence; +err: + sync_fence_free_pts(fence); + kfree(fence); + return NULL; +} + +static void sync_fence_signal_pt(struct sync_pt *pt) +{ + LIST_HEAD(signaled_waiters); + struct sync_fence *fence = pt->fence; + struct list_head *pos; + struct list_head *n; + unsigned long flags; + int status; + + status = sync_fence_get_status(fence); + + spin_lock_irqsave(&fence->waiter_list_lock, flags); + /* + * this should protect against two threads racing on the signaled + * false -> true transition + */ + if (status && !fence->status) { + list_for_each_safe(pos, n, &fence->waiter_list_head) + list_move(pos, &signaled_waiters); + + fence->status = status; + } else { + status = 0; + } + spin_unlock_irqrestore(&fence->waiter_list_lock, flags); + + if (status) { + list_for_each_safe(pos, n, &signaled_waiters) { + struct sync_fence_waiter *waiter = + container_of(pos, struct sync_fence_waiter, + waiter_list); + + waiter->callback(fence, waiter->callback_data); + list_del(pos); + kfree(waiter); + } + wake_up(&fence->wq); + } +} + +int sync_fence_wait_async(struct sync_fence *fence, + void (*callback)(struct sync_fence *, void *data), + void *callback_data) +{ + struct sync_fence_waiter *waiter; + unsigned long flags; + int err = 0; + + waiter = kzalloc(sizeof(struct sync_fence_waiter), GFP_KERNEL); + if (waiter == NULL) + return -ENOMEM; + + waiter->callback = callback; + waiter->callback_data = callback_data; + + spin_lock_irqsave(&fence->waiter_list_lock, flags); + + if (fence->status) { + kfree(waiter); + err = fence->status; + goto out; + } + + list_add_tail(&waiter->waiter_list, &fence->waiter_list_head); +out: + spin_unlock_irqrestore(&fence->waiter_list_lock, flags); + + return err; +} + +int sync_fence_wait(struct sync_fence *fence, long timeout) +{ + int err; + + if (timeout) { + timeout = msecs_to_jiffies(timeout); + err = wait_event_interruptible_timeout(fence->wq, + fence->status != 0, + timeout); + } else { + err = wait_event_interruptible(fence->wq, fence->status != 0); + } + + if (err < 0) + return err; + + if (fence->status < 0) + return fence->status; + + if (fence->status == 0) + return -ETIME; + + return 0; +} + +static int sync_fence_release(struct inode *inode, struct file *file) +{ + struct sync_fence *fence = file->private_data; + + sync_fence_free_pts(fence); + kfree(fence); + + return 0; +} + +static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) +{ + __s32 value; + + if (copy_from_user(&value, (void __user *)arg, sizeof(value))) + return -EFAULT; + + return sync_fence_wait(fence, value); +} + +static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) +{ + int fd = get_unused_fd(); + int err; + struct sync_fence *fence2, *fence3; + struct sync_merge_data data; + + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) + return -EFAULT; + + fence2 = sync_fence_fdget(data.fd2); + if (fence2 == NULL) { + err = -ENOENT; + goto err_put_fd; + } + + data.name[sizeof(data.name) - 1] = '\0'; + fence3 = sync_fence_merge(data.name, fence, fence2); + if (fence3 == NULL) { + err = -ENOMEM; + goto err_put_fence2; + } + + data.fence = fd; + if (copy_to_user((void __user *)arg, &data, sizeof(data))) { + err = -EFAULT; + goto err_put_fence3; + } + + sync_fence_install(fence3, fd); + sync_fence_put(fence2); + return 0; + +err_put_fence3: + sync_fence_put(fence3); + +err_put_fence2: + sync_fence_put(fence2); + +err_put_fd: + put_unused_fd(fd); + return err; +} + + +static long sync_fence_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct sync_fence *fence = file->private_data; + switch (cmd) { + case SYNC_IOC_WAIT: + return sync_fence_ioctl_wait(fence, arg); + + case SYNC_IOC_MERGE: + return sync_fence_ioctl_merge(fence, arg); + default: + return -ENOTTY; + } +} + diff --git a/trunk/drivers/staging/android/sync.h b/trunk/drivers/staging/android/sync.h new file mode 100644 index 000000000000..388acd1ff412 --- /dev/null +++ b/trunk/drivers/staging/android/sync.h @@ -0,0 +1,314 @@ +/* + * include/linux/sync.h + * + * Copyright (C) 2012 Google, Inc. + * + * 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. + * + */ + +#ifndef _LINUX_SYNC_H +#define _LINUX_SYNC_H + +#include +#ifdef __KERNEL__ + +#include +#include +#include + +struct sync_timeline; +struct sync_pt; +struct sync_fence; + +/** + * struct sync_timeline_ops - sync object implementation ops + * @driver_name: name of the implentation + * @dup: duplicate a sync_pt + * @has_signaled: returns: + * 1 if pt has signaled + * 0 if pt has not signaled + * <0 on error + * @compare: returns: + * 1 if b will signal before a + * 0 if a and b will signal at the same time + * -1 if a will signabl before b + * @free_pt: called before sync_pt is freed + * @release_obj: called before sync_timeline is freed + */ +struct sync_timeline_ops { + const char *driver_name; + + /* required */ + struct sync_pt *(*dup)(struct sync_pt *pt); + + /* required */ + int (*has_signaled)(struct sync_pt *pt); + + /* required */ + int (*compare)(struct sync_pt *a, struct sync_pt *b); + + /* optional */ + void (*free_pt)(struct sync_pt *sync_pt); + + /* optional */ + void (*release_obj)(struct sync_timeline *sync_timeline); +}; + +/** + * struct sync_timeline - sync object + * @ops: ops that define the implementaiton of the sync_timeline + * @name: name of the sync_timeline. Useful for debugging + * @destoryed: set when sync_timeline is destroyed + * @child_list_head: list of children sync_pts for this sync_timeline + * @child_list_lock: lock protecting @child_list_head, destroyed, and + * sync_pt.status + * @active_list_head: list of active (unsignaled/errored) sync_pts + */ +struct sync_timeline { + const struct sync_timeline_ops *ops; + char name[32]; + + /* protected by child_list_lock */ + bool destroyed; + + struct list_head child_list_head; + spinlock_t child_list_lock; + + struct list_head active_list_head; + spinlock_t active_list_lock; +}; + +/** + * struct sync_pt - sync point + * @parent: sync_timeline to which this sync_pt belongs + * @child_list: membership in sync_timeline.child_list_head + * @active_list: membership in sync_timeline.active_list_head + * @fence: sync_fence to which the sync_pt belongs + * @pt_list: membership in sync_fence.pt_list_head + * @status: 1: signaled, 0:active, <0: error + */ +struct sync_pt { + struct sync_timeline *parent; + struct list_head child_list; + + struct list_head active_list; + + struct sync_fence *fence; + struct list_head pt_list; + + /* protected by parent->active_list_lock */ + int status; +}; + +/** + * struct sync_fence - sync fence + * @file: file representing this fence + * @name: name of sync_fence. Useful for debugging + * @pt_list_head: list of sync_pts in ths fence. immutable once fence + * is created + * @waiter_list_head: list of asynchronous waiters on this fence + * @waiter_list_lock: lock protecting @waiter_list_head and @status + * @status: 1: signaled, 0:active, <0: error + * + * @wq: wait queue for fence signaling + */ +struct sync_fence { + struct file *file; + char name[32]; + + /* this list is immutable once the fence is created */ + struct list_head pt_list_head; + + struct list_head waiter_list_head; + spinlock_t waiter_list_lock; /* also protects status */ + int status; + + wait_queue_head_t wq; +}; + +/** + * struct sync_fence_waiter - metadata for asynchronous waiter on a fence + * @waiter_list: membership in sync_fence.waiter_list_head + * @callback: function pointer to call when fence signals + * @callback_data: pointer to pass to @callback + */ +struct sync_fence_waiter { + struct list_head waiter_list; + + void (*callback)(struct sync_fence *fence, void *data); + void *callback_data; +}; + +/* + * API for sync_timeline implementers + */ + +/** + * sync_timeline_create() - creates a sync object + * @ops: specifies the implemention ops for the object + * @size: size to allocate for this obj + * @name: sync_timeline name + * + * Creates a new sync_timeline which will use the implemetation specified by + * @ops. @size bytes will be allocated allowing for implemntation specific + * data to be kept after the generic sync_timeline stuct. + */ +struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, + int size, const char *name); + +/** + * sync_timeline_destory() - destorys a sync object + * @obj: sync_timeline to destroy + * + * A sync implemntation should call this when the @obj is going away + * (i.e. module unload.) @obj won't actually be freed until all its childern + * sync_pts are freed. + */ +void sync_timeline_destroy(struct sync_timeline *obj); + +/** + * sync_timeline_signal() - signal a status change on a sync_timeline + * @obj: sync_timeline to signal + * + * A sync implemntation should call this any time one of it's sync_pts + * has signaled or has an error condition. + */ +void sync_timeline_signal(struct sync_timeline *obj); + +/** + * sync_pt_create() - creates a sync pt + * @parent: sync_pt's parent sync_timeline + * @size: size to allocate for this pt + * + * Creates a new sync_pt as a chiled of @parent. @size bytes will be + * allocated allowing for implemntation specific data to be kept after + * the generic sync_timeline struct. + */ +struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size); + +/** + * sync_pt_free() - frees a sync pt + * @pt: sync_pt to free + * + * This should only be called on sync_pts which have been created but + * not added to a fence. + */ +void sync_pt_free(struct sync_pt *pt); + +/** + * sync_fence_create() - creates a sync fence + * @name: name of fence to create + * @pt: sync_pt to add to the fence + * + * Creates a fence containg @pt. Once this is called, the fence takes + * ownership of @pt. + */ +struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt); + +/* + * API for sync_fence consumers + */ + +/** + * sync_fence_merge() - merge two fences + * @name: name of new fence + * @a: fence a + * @b: fence b + * + * Creates a new fence which contains copies of all the sync_pts in both + * @a and @b. @a and @b remain valid, independent fences. + */ +struct sync_fence *sync_fence_merge(const char *name, + struct sync_fence *a, struct sync_fence *b); + +/** + * sync_fence_fdget() - get a fence from an fd + * @fd: fd referencing a fence + * + * Ensures @fd references a valid fence, increments the refcount of the backing + * file, and returns the fence. + */ +struct sync_fence *sync_fence_fdget(int fd); + +/** + * sync_fence_put() - puts a refernnce of a sync fence + * @fence: fence to put + * + * Puts a reference on @fence. If this is the last reference, the fence and + * all it's sync_pts will be freed + */ +void sync_fence_put(struct sync_fence *fence); + +/** + * sync_fence_install() - installs a fence into a file descriptor + * @fence: fence to instal + * @fd: file descriptor in which to install the fence + * + * Installs @fence into @fd. @fd's should be acquired through get_unused_fd(). + */ +void sync_fence_install(struct sync_fence *fence, int fd); + +/** + * sync_fence_wait_async() - registers and async wait on the fence + * @fence: fence to wait on + * @callback: callback + * @callback_data data to pass to the callback + * + * Returns 1 if @fence has already signaled. + * + * Registers a callback to be called when @fence signals or has an error + */ +int sync_fence_wait_async(struct sync_fence *fence, + void (*callback)(struct sync_fence *, void *data), + void *callback_data); + +/** + * sync_fence_wait() - wait on fence + * @fence: fence to wait on + * @tiemout: timeout in ms + * + * Wait for @fence to be signaled or have an error. Waits indefintly + * if @timeout = 0 + */ +int sync_fence_wait(struct sync_fence *fence, long timeout); + +/* useful for sync driver's debug print handlers */ +const char *sync_status_str(int status); + +#endif /* __KERNEL__ */ + +/** + * struct sync_merge_data - data passed to merge ioctl + * @fd2: file descriptor of second fence + * @name: name of new fence + * @fence: returns the fd of the new fence to userspace + */ +struct sync_merge_data { + __s32 fd2; /* fd of second fence */ + char name[32]; /* name of new fence */ + __s32 fence; /* fd on newly created fence */ +}; + +#define SYNC_IOC_MAGIC '>' + +/** + * DOC: SYNC_IOC_WAIT - wait for a fence to signal + * + * pass timeout in milliseconds. + */ +#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __u32) + +/** + * DOC: SYNC_IOC_MERGE - merge two fences + * + * Takes a struct sync_merge_data. Creates a new fence containing copies of + * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the + * new fence's fd in sync_merge_data.fence + */ +#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) + +#endif /* _LINUX_SYNC_H */ diff --git a/trunk/drivers/staging/ccg/f_fs.c b/trunk/drivers/staging/ccg/f_fs.c index f6373dade7fb..8adc79d1b402 100644 --- a/trunk/drivers/staging/ccg/f_fs.c +++ b/trunk/drivers/staging/ccg/f_fs.c @@ -1223,7 +1223,6 @@ static struct file_system_type ffs_fs_type = { .mount = ffs_fs_mount, .kill_sb = ffs_fs_kill_sb, }; -MODULE_ALIAS_FS("functionfs"); /* Driver's main init/cleanup functions *************************************/ diff --git a/trunk/drivers/staging/comedi/drivers/dt9812.c b/trunk/drivers/staging/comedi/drivers/dt9812.c index 57b451904791..192cf088f834 100644 --- a/trunk/drivers/staging/comedi/drivers/dt9812.c +++ b/trunk/drivers/staging/comedi/drivers/dt9812.c @@ -947,13 +947,12 @@ static int dt9812_di_rinsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); int n; u8 bits = 0; dt9812_digital_in(devpriv->slot, &bits); for (n = 0; n < insn->n; n++) - data[n] = ((1 << channel) & bits) != 0; + data[n] = ((1 << insn->chanspec) & bits) != 0; return n; } @@ -962,13 +961,12 @@ static int dt9812_do_winsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); int n; u8 bits = 0; dt9812_digital_out_shadow(devpriv->slot, &bits); for (n = 0; n < insn->n; n++) { - u8 mask = 1 << channel; + u8 mask = 1 << insn->chanspec; bits &= ~mask; if (data[n]) @@ -983,13 +981,13 @@ static int dt9812_ai_rinsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); int n; for (n = 0; n < insn->n; n++) { u16 value = 0; - dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1); + dt9812_analog_in(devpriv->slot, insn->chanspec, &value, + DT9812_GAIN_1); data[n] = value; } return n; @@ -1000,13 +998,12 @@ static int dt9812_ao_rinsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); int n; u16 value; for (n = 0; n < insn->n; n++) { value = 0; - dt9812_analog_out_shadow(devpriv->slot, channel, &value); + dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value); data[n] = value; } return n; @@ -1017,11 +1014,10 @@ static int dt9812_ao_winsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; - unsigned int channel = CR_CHAN(insn->chanspec); int n; for (n = 0; n < insn->n; n++) - dt9812_analog_out(devpriv->slot, channel, data[n]); + dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]); return n; } diff --git a/trunk/drivers/staging/comedi/drivers/s626.c b/trunk/drivers/staging/comedi/drivers/s626.c index 71a73ec5af8d..81a1fe661579 100644 --- a/trunk/drivers/staging/comedi/drivers/s626.c +++ b/trunk/drivers/staging/comedi/drivers/s626.c @@ -1483,7 +1483,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) case TRIG_NONE: /* continous acquisition */ devpriv->ai_continous = 1; - devpriv->ai_sample_count = 1; + devpriv->ai_sample_count = 0; break; } diff --git a/trunk/drivers/staging/comedi/drivers/usbdux.c b/trunk/drivers/staging/comedi/drivers/usbdux.c index 6aac1f60bc42..1a0062a04456 100644 --- a/trunk/drivers/staging/comedi/drivers/usbdux.c +++ b/trunk/drivers/staging/comedi/drivers/usbdux.c @@ -730,14 +730,10 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb) static int usbduxsub_start(struct usbduxsub *usbduxsub) { int errcode = 0; - uint8_t *local_transfer_buffer; - - local_transfer_buffer = kmalloc(1, GFP_KERNEL); - if (!local_transfer_buffer) - return -ENOMEM; + uint8_t local_transfer_buffer[16]; /* 7f92 to zero */ - *local_transfer_buffer = 0; + local_transfer_buffer[0] = 0; errcode = usb_control_msg(usbduxsub->usbdev, /* create a pipe for a control transfer */ usb_sndctrlpipe(usbduxsub->usbdev, 0), @@ -755,25 +751,22 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub) 1, /* Timeout */ BULK_TIMEOUT); - if (errcode < 0) + if (errcode < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (start)\n"); - - kfree(local_transfer_buffer); - return errcode; + return errcode; + } + return 0; } static int usbduxsub_stop(struct usbduxsub *usbduxsub) { int errcode = 0; - uint8_t *local_transfer_buffer; - local_transfer_buffer = kmalloc(1, GFP_KERNEL); - if (!local_transfer_buffer) - return -ENOMEM; + uint8_t local_transfer_buffer[16]; /* 7f92 to one */ - *local_transfer_buffer = 1; + local_transfer_buffer[0] = 1; errcode = usb_control_msg(usbduxsub->usbdev, usb_sndctrlpipe(usbduxsub->usbdev, 0), /* bRequest, "Firmware" */ @@ -788,12 +781,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub) 1, /* Timeout */ BULK_TIMEOUT); - if (errcode < 0) + if (errcode < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (stop)\n"); - - kfree(local_transfer_buffer); - return errcode; + return errcode; + } + return 0; } static int usbduxsub_upload(struct usbduxsub *usbduxsub, diff --git a/trunk/drivers/staging/comedi/drivers/usbduxfast.c b/trunk/drivers/staging/comedi/drivers/usbduxfast.c index 1ba0e3df492d..4bf5dd094dc9 100644 --- a/trunk/drivers/staging/comedi/drivers/usbduxfast.c +++ b/trunk/drivers/staging/comedi/drivers/usbduxfast.c @@ -436,14 +436,10 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) { int ret; - unsigned char *local_transfer_buffer; - - local_transfer_buffer = kmalloc(1, GFP_KERNEL); - if (!local_transfer_buffer) - return -ENOMEM; + unsigned char local_transfer_buffer[16]; /* 7f92 to zero */ - *local_transfer_buffer = 0; + local_transfer_buffer[0] = 0; /* bRequest, "Firmware" */ ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, @@ -454,25 +450,22 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) local_transfer_buffer, 1, /* Length */ EZTIMEOUT); /* Timeout */ - if (ret < 0) + if (ret < 0) { dev_err(&udfs->interface->dev, "control msg failed (start)\n"); + return ret; + } - kfree(local_transfer_buffer); - return ret; + return 0; } static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) { int ret; - unsigned char *local_transfer_buffer; - - local_transfer_buffer = kmalloc(1, GFP_KERNEL); - if (!local_transfer_buffer) - return -ENOMEM; + unsigned char local_transfer_buffer[16]; /* 7f92 to one */ - *local_transfer_buffer = 1; + local_transfer_buffer[0] = 1; /* bRequest, "Firmware" */ ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, @@ -481,12 +474,13 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) 0x0000, /* Index */ local_transfer_buffer, 1, /* Length */ EZTIMEOUT); /* Timeout */ - if (ret < 0) + if (ret < 0) { dev_err(&udfs->interface->dev, "control msg failed (stop)\n"); + return ret; + } - kfree(local_transfer_buffer); - return ret; + return 0; } static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs, diff --git a/trunk/drivers/staging/comedi/drivers/usbduxsigma.c b/trunk/drivers/staging/comedi/drivers/usbduxsigma.c index a728c8fc32a2..d066351a71b2 100644 --- a/trunk/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/trunk/drivers/staging/comedi/drivers/usbduxsigma.c @@ -681,11 +681,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb) static int usbduxsub_start(struct usbduxsub *usbduxsub) { int errcode = 0; - uint8_t *local_transfer_buffer; - - local_transfer_buffer = kmalloc(16, GFP_KERNEL); - if (!local_transfer_buffer) - return -ENOMEM; + uint8_t local_transfer_buffer[16]; /* 7f92 to zero */ local_transfer_buffer[0] = 0; @@ -706,22 +702,19 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub) 1, /* Timeout */ BULK_TIMEOUT); - if (errcode < 0) + if (errcode < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (start)\n"); - - kfree(local_transfer_buffer); - return errcode; + return errcode; + } + return 0; } static int usbduxsub_stop(struct usbduxsub *usbduxsub) { int errcode = 0; - uint8_t *local_transfer_buffer; - local_transfer_buffer = kmalloc(16, GFP_KERNEL); - if (!local_transfer_buffer) - return -ENOMEM; + uint8_t local_transfer_buffer[16]; /* 7f92 to one */ local_transfer_buffer[0] = 1; @@ -739,12 +732,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub) 1, /* Timeout */ BULK_TIMEOUT); - if (errcode < 0) + if (errcode < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (stop)\n"); - - kfree(local_transfer_buffer); - return errcode; + return errcode; + } + return 0; } static int usbduxsub_upload(struct usbduxsub *usbduxsub, diff --git a/trunk/drivers/staging/imx-drm/ipuv3-crtc.c b/trunk/drivers/staging/imx-drm/ipuv3-crtc.c index b028b0d1317b..4b3a019409b5 100644 --- a/trunk/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/trunk/drivers/staging/imx-drm/ipuv3-crtc.c @@ -483,6 +483,17 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc, goto err_out; } + ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch, + IPU_IRQ_EOF); + ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, + "imx_drm", ipu_crtc); + if (ret < 0) { + dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); + goto err_out; + } + + disable_irq(ipu_crtc->irq); + return 0; err_out: ipu_put_resources(ipu_crtc); @@ -493,7 +504,6 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc, static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, struct ipu_client_platformdata *pdata) { - struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); int ret; ret = ipu_get_resources(ipu_crtc, pdata); @@ -512,17 +522,6 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, goto err_put_resources; } - ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch, - IPU_IRQ_EOF); - ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, - "imx_drm", ipu_crtc); - if (ret < 0) { - dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); - goto err_put_resources; - } - - disable_irq(ipu_crtc->irq); - return 0; err_put_resources: diff --git a/trunk/drivers/staging/tidspbridge/rmgr/drv.c b/trunk/drivers/staging/tidspbridge/rmgr/drv.c index be26917a6896..db1da28cecba 100644 --- a/trunk/drivers/staging/tidspbridge/rmgr/drv.c +++ b/trunk/drivers/staging/tidspbridge/rmgr/drv.c @@ -76,28 +76,37 @@ int drv_insert_node_res_element(void *hnode, void *node_resource, struct node_res_object **node_res_obj = (struct node_res_object **)node_resource; struct process_context *ctxt = (struct process_context *)process_ctxt; + int status = 0; int retval; *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL); - if (!*node_res_obj) - return -ENOMEM; - - (*node_res_obj)->node = hnode; - retval = idr_alloc(ctxt->node_id, *node_res_obj, 0, 0, GFP_KERNEL); - if (retval >= 0) { - (*node_res_obj)->id = retval; - return 0; + if (!*node_res_obj) { + status = -ENOMEM; + goto func_end; } - kfree(*node_res_obj); + (*node_res_obj)->node = hnode; + retval = idr_get_new(ctxt->node_id, *node_res_obj, + &(*node_res_obj)->id); + if (retval == -EAGAIN) { + if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) { + pr_err("%s: OUT OF MEMORY\n", __func__); + status = -ENOMEM; + goto func_end; + } - if (retval == -ENOSPC) { + retval = idr_get_new(ctxt->node_id, *node_res_obj, + &(*node_res_obj)->id); + } + if (retval) { pr_err("%s: FAILED, IDR is FULL\n", __func__); - return -EFAULT; - } else { - pr_err("%s: OUT OF MEMORY\n", __func__); - return -ENOMEM; + status = -EFAULT; } +func_end: + if (status) + kfree(*node_res_obj); + + return status; } /* Release all Node resources and its context @@ -192,26 +201,35 @@ int drv_proc_insert_strm_res_element(void *stream_obj, struct strm_res_object **pstrm_res = (struct strm_res_object **)strm_res; struct process_context *ctxt = (struct process_context *)process_ctxt; + int status = 0; int retval; *pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL); - if (*pstrm_res == NULL) - return -EFAULT; + if (*pstrm_res == NULL) { + status = -EFAULT; + goto func_end; + } (*pstrm_res)->stream = stream_obj; - retval = idr_alloc(ctxt->stream_id, *pstrm_res, 0, 0, GFP_KERNEL); - if (retval >= 0) { - (*pstrm_res)->id = retval; - return 0; - } + retval = idr_get_new(ctxt->stream_id, *pstrm_res, + &(*pstrm_res)->id); + if (retval == -EAGAIN) { + if (!idr_pre_get(ctxt->stream_id, GFP_KERNEL)) { + pr_err("%s: OUT OF MEMORY\n", __func__); + status = -ENOMEM; + goto func_end; + } - if (retval == -ENOSPC) { + retval = idr_get_new(ctxt->stream_id, *pstrm_res, + &(*pstrm_res)->id); + } + if (retval) { pr_err("%s: FAILED, IDR is FULL\n", __func__); - return -EPERM; - } else { - pr_err("%s: OUT OF MEMORY\n", __func__); - return -ENOMEM; + status = -EPERM; } + +func_end: + return status; } static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt) diff --git a/trunk/drivers/staging/vt6656/card.c b/trunk/drivers/staging/vt6656/card.c index d2479b766450..22918a106d73 100644 --- a/trunk/drivers/staging/vt6656/card.c +++ b/trunk/drivers/staging/vt6656/card.c @@ -790,7 +790,7 @@ u64 CARDqGetNextTBTT(u64 qwTSF, WORD wBeaconInterval) if ((~uLowNextTBTT) < uLowRemain) qwTSF = ((qwTSF >> 32) + 1) << 32; - qwTSF = (qwTSF & 0xffffffff00000000ULL) | + qwTSF = (qwTSF & 0xffffffff00000000UL) | (u64)(uLowNextTBTT + uLowRemain); return (qwTSF); diff --git a/trunk/drivers/staging/vt6656/main_usb.c b/trunk/drivers/staging/vt6656/main_usb.c index a5063a6f64d9..d5f53e1a74a2 100644 --- a/trunk/drivers/staging/vt6656/main_usb.c +++ b/trunk/drivers/staging/vt6656/main_usb.c @@ -669,6 +669,8 @@ static int vt6656_suspend(struct usb_interface *intf, pm_message_t message) if (device->flags & DEVICE_FLAGS_OPENED) device_close(device->dev); + usb_put_dev(interface_to_usbdev(intf)); + return 0; } @@ -679,6 +681,8 @@ static int vt6656_resume(struct usb_interface *intf) if (!device || !device->dev) return -ENODEV; + usb_get_dev(interface_to_usbdev(intf)); + if (!(device->flags & DEVICE_FLAGS_OPENED)) device_open(device->dev); diff --git a/trunk/drivers/staging/zcache/Kconfig b/trunk/drivers/staging/zcache/Kconfig index 5c3714530961..73582705e8c5 100644 --- a/trunk/drivers/staging/zcache/Kconfig +++ b/trunk/drivers/staging/zcache/Kconfig @@ -15,7 +15,7 @@ config RAMSTER depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE=y depends on NET # must ensure struct page is 8-byte aligned - select HAVE_ALIGNED_STRUCT_PAGE if !64BIT + select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT default n help RAMster allows RAM on other machines in a cluster to be utilized diff --git a/trunk/drivers/staging/zcache/ramster/tcp.c b/trunk/drivers/staging/zcache/ramster/tcp.c index f6e1e5209d88..aa2a1a763aa4 100644 --- a/trunk/drivers/staging/zcache/ramster/tcp.c +++ b/trunk/drivers/staging/zcache/ramster/tcp.c @@ -300,22 +300,27 @@ static u8 r2net_num_from_nn(struct r2net_node *nn) static int r2net_prep_nsw(struct r2net_node *nn, struct r2net_status_wait *nsw) { - int ret; + int ret = 0; - spin_lock(&nn->nn_lock); - ret = idr_alloc(&nn->nn_status_idr, nsw, 0, 0, GFP_ATOMIC); - if (ret >= 0) { - nsw->ns_id = ret; - list_add_tail(&nsw->ns_node_item, &nn->nn_status_list); - } - spin_unlock(&nn->nn_lock); + do { + if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) { + ret = -EAGAIN; + break; + } + spin_lock(&nn->nn_lock); + ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id); + if (ret == 0) + list_add_tail(&nsw->ns_node_item, + &nn->nn_status_list); + spin_unlock(&nn->nn_lock); + } while (ret == -EAGAIN); - if (ret >= 0) { + if (ret == 0) { init_waitqueue_head(&nsw->ns_wq); nsw->ns_sys_status = R2NET_ERR_NONE; nsw->ns_status = 0; - return 0; } + return ret; } diff --git a/trunk/drivers/target/iscsi/iscsi_target_auth.c b/trunk/drivers/target/iscsi/iscsi_target_auth.c index a0fc7b9eea65..db0cf7c8adde 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_auth.c +++ b/trunk/drivers/target/iscsi/iscsi_target_auth.c @@ -166,7 +166,6 @@ static int chap_server_compute_md5( { char *endptr; unsigned long id; - unsigned char id_as_uchar; unsigned char digest[MD5_SIGNATURE_SIZE]; unsigned char type, response[MD5_SIGNATURE_SIZE * 2 + 2]; unsigned char identifier[10], *challenge = NULL; @@ -356,9 +355,7 @@ static int chap_server_compute_md5( goto out; } - /* To handle both endiannesses */ - id_as_uchar = id; - sg_init_one(&sg, &id_as_uchar, 1); + sg_init_one(&sg, &id, 1); ret = crypto_hash_update(&desc, &sg, 1); if (ret < 0) { pr_err("crypto_hash_update() failed for id\n"); diff --git a/trunk/drivers/target/target_core_alua.c b/trunk/drivers/target/target_core_alua.c index cbe48ab41745..ff1c5ee352cb 100644 --- a/trunk/drivers/target/target_core_alua.c +++ b/trunk/drivers/target/target_core_alua.c @@ -409,7 +409,6 @@ static inline int core_alua_state_standby( case REPORT_LUNS: case RECEIVE_DIAGNOSTIC: case SEND_DIAGNOSTIC: - return 0; case MAINTENANCE_IN: switch (cdb[1] & 0x1f) { case MI_REPORT_TARGET_PGS: @@ -452,7 +451,6 @@ static inline int core_alua_state_unavailable( switch (cdb[0]) { case INQUIRY: case REPORT_LUNS: - return 0; case MAINTENANCE_IN: switch (cdb[1] & 0x1f) { case MI_REPORT_TARGET_PGS: @@ -493,7 +491,6 @@ static inline int core_alua_state_transition( switch (cdb[0]) { case INQUIRY: case REPORT_LUNS: - return 0; case MAINTENANCE_IN: switch (cdb[1] & 0x1f) { case MI_REPORT_TARGET_PGS: diff --git a/trunk/drivers/target/target_core_file.h b/trunk/drivers/target/target_core_file.h index 37ffc5bd2399..bc02b018ae46 100644 --- a/trunk/drivers/target/target_core_file.h +++ b/trunk/drivers/target/target_core_file.h @@ -7,7 +7,7 @@ #define FD_DEVICE_QUEUE_DEPTH 32 #define FD_MAX_DEVICE_QUEUE_DEPTH 128 #define FD_BLOCKSIZE 512 -#define FD_MAX_SECTORS 2048 +#define FD_MAX_SECTORS 1024 #define RRF_EMULATE_CDB 0x01 #define RRF_GOT_LBA 0x02 diff --git a/trunk/drivers/target/target_core_pscsi.c b/trunk/drivers/target/target_core_pscsi.c index e992b27aa090..82e78d72fdb6 100644 --- a/trunk/drivers/target/target_core_pscsi.c +++ b/trunk/drivers/target/target_core_pscsi.c @@ -883,14 +883,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, pr_debug("PSCSI: i: %d page: %p len: %d off: %d\n", i, page, len, off); - /* - * We only have one page of data in each sg element, - * we can not cross a page boundary. - */ - if (off + len > PAGE_SIZE) - goto fail; - - if (len > 0 && data_len > 0) { + while (len > 0 && data_len > 0) { bytes = min_t(unsigned int, len, PAGE_SIZE - off); bytes = min(bytes, data_len); @@ -947,7 +940,9 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, bio = NULL; } + len -= bytes; data_len -= bytes; + off = 0; } } diff --git a/trunk/drivers/target/target_core_sbc.c b/trunk/drivers/target/target_core_sbc.c index 60d4b5185f32..290230de2c53 100644 --- a/trunk/drivers/target/target_core_sbc.c +++ b/trunk/drivers/target/target_core_sbc.c @@ -464,11 +464,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) break; case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: - if (!ops->execute_sync_cache) { - size = 0; - cmd->execute_cmd = sbc_emulate_noop; - break; - } + if (!ops->execute_sync_cache) + return TCM_UNSUPPORTED_SCSI_OPCODE; /* * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE diff --git a/trunk/drivers/target/target_core_tpg.c b/trunk/drivers/target/target_core_tpg.c index aac9d2727e3c..9169d6a5d7e4 100644 --- a/trunk/drivers/target/target_core_tpg.c +++ b/trunk/drivers/target/target_core_tpg.c @@ -711,8 +711,7 @@ int core_tpg_register( if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) { if (core_tpg_setup_virtual_lun0(se_tpg) < 0) { - array_free(se_tpg->tpg_lun_list, - TRANSPORT_MAX_LUNS_PER_TPG); + kfree(se_tpg); return -ENOMEM; } } diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 3243ea790eab..2030b608136d 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -1139,10 +1139,8 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) return ret; ret = target_check_reservation(cmd); - if (ret) { - cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; + if (ret) return ret; - } ret = dev->transport->parse_cdb(cmd); if (ret) diff --git a/trunk/drivers/thermal/dove_thermal.c b/trunk/drivers/thermal/dove_thermal.c index 3078c403b42d..7b0bfa0e7a9c 100644 --- a/trunk/drivers/thermal/dove_thermal.c +++ b/trunk/drivers/thermal/dove_thermal.c @@ -143,18 +143,22 @@ static int dove_thermal_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->sensor = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->sensor)) - return PTR_ERR(priv->sensor); + priv->sensor = devm_request_and_ioremap(&pdev->dev, res); + if (!priv->sensor) { + dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); + return -EADDRNOTAVAIL; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res) { dev_err(&pdev->dev, "Failed to get platform resource\n"); return -ENODEV; } - priv->control = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->control)) - return PTR_ERR(priv->control); + priv->control = devm_request_and_ioremap(&pdev->dev, res); + if (!priv->control) { + dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); + return -EADDRNOTAVAIL; + } ret = dove_init_sensor(priv); if (ret) { diff --git a/trunk/drivers/thermal/exynos_thermal.c b/trunk/drivers/thermal/exynos_thermal.c index 46568c078dee..e04ebd8671ac 100644 --- a/trunk/drivers/thermal/exynos_thermal.c +++ b/trunk/drivers/thermal/exynos_thermal.c @@ -476,7 +476,7 @@ static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) if (IS_ERR(th_zone->therm_dev)) { pr_err("Failed to register thermal zone device\n"); - ret = PTR_ERR(th_zone->therm_dev); + ret = -EINVAL; goto err_unregister; } th_zone->mode = THERMAL_DEVICE_ENABLED; diff --git a/trunk/drivers/thermal/kirkwood_thermal.c b/trunk/drivers/thermal/kirkwood_thermal.c index e5500edb5285..65cb4f09e8f6 100644 --- a/trunk/drivers/thermal/kirkwood_thermal.c +++ b/trunk/drivers/thermal/kirkwood_thermal.c @@ -85,9 +85,11 @@ static int kirkwood_thermal_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->sensor = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->sensor)) - return PTR_ERR(priv->sensor); + priv->sensor = devm_request_and_ioremap(&pdev->dev, res); + if (!priv->sensor) { + dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); + return -EADDRNOTAVAIL; + } thermal = thermal_zone_device_register("kirkwood_thermal", 0, 0, priv, &ops, NULL, 0, 0); diff --git a/trunk/drivers/thermal/rcar_thermal.c b/trunk/drivers/thermal/rcar_thermal.c index 2cc5b6115e3e..28f091994013 100644 --- a/trunk/drivers/thermal/rcar_thermal.c +++ b/trunk/drivers/thermal/rcar_thermal.c @@ -145,7 +145,6 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) struct device *dev = rcar_priv_to_dev(priv); int i; int ctemp, old, new; - int ret = -EINVAL; mutex_lock(&priv->lock); @@ -175,7 +174,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) if (!ctemp) { dev_err(dev, "thermal sensor was broken\n"); - goto err_out_unlock; + return -EINVAL; } /* @@ -193,10 +192,10 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) dev_dbg(dev, "thermal%d %d -> %d\n", priv->id, priv->ctemp, ctemp); priv->ctemp = ctemp; - ret = 0; -err_out_unlock: + mutex_unlock(&priv->lock); - return ret; + + return 0; } static int rcar_thermal_get_temp(struct thermal_zone_device *zone, @@ -364,7 +363,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) struct resource *res, *irq; int mres = 0; int i; - int ret = -ENODEV; int idle = IDLE_INTERVAL; common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); @@ -401,9 +399,11 @@ static int rcar_thermal_probe(struct platform_device *pdev) /* * rcar_has_irq_support() will be enabled */ - common->base = devm_ioremap_resource(dev, res); - if (IS_ERR(common->base)) - return PTR_ERR(common->base); + common->base = devm_request_and_ioremap(dev, res); + if (!common->base) { + dev_err(dev, "Unable to ioremap thermal register\n"); + return -ENOMEM; + } /* enable temperature comparation */ rcar_thermal_common_write(common, ENR, 0x00030303); @@ -422,9 +422,11 @@ static int rcar_thermal_probe(struct platform_device *pdev) return -ENOMEM; } - priv->base = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); + priv->base = devm_request_and_ioremap(dev, res); + if (!priv->base) { + dev_err(dev, "Unable to ioremap priv register\n"); + return -ENOMEM; + } priv->common = common; priv->id = i; @@ -439,7 +441,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) idle); if (IS_ERR(priv->zone)) { dev_err(dev, "can't register thermal zone\n"); - ret = PTR_ERR(priv->zone); goto error_unregister; } @@ -459,7 +460,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) rcar_thermal_for_each_priv(priv, common) thermal_zone_device_unregister(priv->zone); - return ret; + return -ENODEV; } static int rcar_thermal_remove(struct platform_device *pdev) diff --git a/trunk/drivers/tty/hvc/hvcs.c b/trunk/drivers/tty/hvc/hvcs.c index 81e939e90c4c..1956593ee89d 100644 --- a/trunk/drivers/tty/hvc/hvcs.c +++ b/trunk/drivers/tty/hvc/hvcs.c @@ -881,12 +881,17 @@ static struct vio_driver hvcs_vio_driver = { /* Only called from hvcs_get_pi please */ static void hvcs_set_pi(struct hvcs_partner_info *pi, struct hvcs_struct *hvcsd) { + int clclength; + hvcsd->p_unit_address = pi->unit_address; hvcsd->p_partition_ID = pi->partition_ID; + clclength = strlen(&pi->location_code[0]); + if (clclength > HVCS_CLC_LENGTH) + clclength = HVCS_CLC_LENGTH; /* copy the null-term char too */ - strlcpy(&hvcsd->p_location_code[0], - &pi->location_code[0], sizeof(hvcsd->p_location_code)); + strncpy(&hvcsd->p_location_code[0], + &pi->location_code[0], clclength + 1); } /* diff --git a/trunk/drivers/tty/mxser.c b/trunk/drivers/tty/mxser.c index 302909ccf183..484b6a3c9b03 100644 --- a/trunk/drivers/tty/mxser.c +++ b/trunk/drivers/tty/mxser.c @@ -2643,9 +2643,9 @@ static int mxser_probe(struct pci_dev *pdev, mxvar_sdriver, brd->idx + i, &pdev->dev); if (IS_ERR(tty_dev)) { retval = PTR_ERR(tty_dev); - for (; i > 0; i--) + for (i--; i >= 0; i--) tty_unregister_device(mxvar_sdriver, - brd->idx + i - 1); + brd->idx + i); goto err_relbrd; } } @@ -2751,9 +2751,9 @@ static int __init mxser_module_init(void) tty_dev = tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, brd->idx + i, NULL); if (IS_ERR(tty_dev)) { - for (; i > 0; i--) + for (i--; i >= 0; i--) tty_unregister_device(mxvar_sdriver, - brd->idx + i - 1); + brd->idx + i); for (i = 0; i < brd->info->nports; i++) tty_port_destroy(&brd->ports[i].port); free_irq(brd->irq, brd); diff --git a/trunk/drivers/tty/serial/8250/8250_core.c b/trunk/drivers/tty/serial/8250/8250.c similarity index 98% rename from trunk/drivers/tty/serial/8250/8250_core.c rename to trunk/drivers/tty/serial/8250/8250.c index 35f9c96aada9..0efc815a4968 100644 --- a/trunk/drivers/tty/serial/8250/8250_core.c +++ b/trunk/drivers/tty/serial/8250/8250.c @@ -301,28 +301,7 @@ static const struct serial8250_config uart_config[] = { }, [PORT_8250_CIR] = { .name = "CIR port" - }, - [PORT_ALTR_16550_F32] = { - .name = "Altera 16550 FIFO32", - .fifo_size = 32, - .tx_loadsz = 32, - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO | UART_CAP_AFE, - }, - [PORT_ALTR_16550_F64] = { - .name = "Altera 16550 FIFO64", - .fifo_size = 64, - .tx_loadsz = 64, - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO | UART_CAP_AFE, - }, - [PORT_ALTR_16550_F128] = { - .name = "Altera 16550 FIFO128", - .fifo_size = 128, - .tx_loadsz = 128, - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO | UART_CAP_AFE, - }, + } }; /* Uart divisor latch read */ @@ -3417,34 +3396,3 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); #endif MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); - -#ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS -#ifndef MODULE -/* This module was renamed to 8250_core in 3.7. Keep the old "8250" name - * working as well for the module options so we don't break people. We - * need to keep the names identical and the convenient macros will happily - * refuse to let us do that by failing the build with redefinition errors - * of global variables. So we stick them inside a dummy function to avoid - * those conflicts. The options still get parsed, and the redefined - * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive. - * - * This is hacky. I'm sorry. - */ -static void __used s8250_options(void) -{ -#undef MODULE_PARAM_PREFIX -#define MODULE_PARAM_PREFIX "8250_core." - - module_param_cb(share_irqs, ¶m_ops_uint, &share_irqs, 0644); - module_param_cb(nr_uarts, ¶m_ops_uint, &nr_uarts, 0644); - module_param_cb(skip_txen_test, ¶m_ops_uint, &skip_txen_test, 0644); -#ifdef CONFIG_SERIAL_8250_RSA - __module_param_call(MODULE_PARAM_PREFIX, probe_rsa, - ¶m_array_ops, .arr = &__param_arr_probe_rsa, - 0444, -1); -#endif -} -#else -MODULE_ALIAS("8250_core"); -#endif -#endif diff --git a/trunk/drivers/tty/serial/8250/8250_pci.c b/trunk/drivers/tty/serial/8250/8250_pci.c index 26e3a97ab157..791c5a77ec61 100644 --- a/trunk/drivers/tty/serial/8250/8250_pci.c +++ b/trunk/drivers/tty/serial/8250/8250_pci.c @@ -1554,7 +1554,6 @@ pci_wch_ch353_setup(struct serial_private *priv, #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d #define PCI_VENDOR_ID_WCH 0x4348 -#define PCI_DEVICE_ID_WCH_CH352_2S 0x3253 #define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 #define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 #define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 @@ -1572,7 +1571,6 @@ pci_wch_ch353_setup(struct serial_private *priv, /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 -#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 /* * Master list of serial port init/setup/exit quirks. @@ -1852,6 +1850,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .setup = pci_default_setup, .exit = pci_plx9050_exit, }, + { + .vendor = PCI_VENDOR_ID_PLX, + .device = PCI_DEVICE_ID_PLX_9050, + .subvendor = PCI_VENDOR_ID_PLX, + .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584, + .init = pci_plx9050_init, + .setup = pci_default_setup, + .exit = pci_plx9050_exit, + }, { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_ROMULUS, @@ -2173,14 +2180,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_wch_ch353_setup, }, - /* WCH CH352 2S card (16550 clone) */ - { - .vendor = PCI_VENDOR_ID_WCH, - .device = PCI_DEVICE_ID_WCH_CH352_2S, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_wch_ch353_setup, - }, /* * ASIX devices with FIFO bug */ @@ -3734,12 +3733,7 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX, PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0, - pbn_b2_4_115200 }, - /* Unknown card - subdevice 0x1588 */ - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, - PCI_VENDOR_ID_PLX, - PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0, - pbn_b2_8_115200 }, + pbn_b0_4_115200 }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_SUBVENDOR_ID_KEYSPAN, PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0, @@ -4797,10 +4791,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_VENDOR_ID_IBM, 0x0299, 0, 0, pbn_b0_bt_2_115200 }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, - 0x1000, 0x0012, - 0, 0, pbn_b0_bt_2_115200 }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, 0xA000, 0x1000, 0, 0, pbn_b0_1_115200 }, @@ -4879,10 +4869,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_115200 }, - { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH352_2S, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, pbn_b0_bt_2_115200 }, - /* * Commtech, Inc. Fastcom adapters */ diff --git a/trunk/drivers/tty/serial/8250/Kconfig b/trunk/drivers/tty/serial/8250/Kconfig index 80fe91e64a52..2ef9537bcb2c 100644 --- a/trunk/drivers/tty/serial/8250/Kconfig +++ b/trunk/drivers/tty/serial/8250/Kconfig @@ -33,23 +33,6 @@ config SERIAL_8250 Most people will say Y or M here, so that they can use serial mice, modems and similar devices connecting to the standard serial ports. -config SERIAL_8250_DEPRECATED_OPTIONS - bool "Support 8250_core.* kernel options (DEPRECATED)" - depends on SERIAL_8250 - default y - ---help--- - In 3.7 we renamed 8250 to 8250_core by mistake, so now we have to - accept kernel parameters in both forms like 8250_core.nr_uarts=4 and - 8250.nr_uarts=4. We now renamed the module back to 8250, but if - anybody noticed in 3.7 and changed their userspace we still have to - keep the 8350_core.* options around until they revert the changes - they already did. - - If 8250 is built as a module, this adds 8250_core alias instead. - - If you did not notice yet and/or you have userspace from pre-3.7, it - is safe (and recommended) to say N here. - config SERIAL_8250_PNP bool "8250/16550 PNP device support" if EXPERT depends on SERIAL_8250 && PNP diff --git a/trunk/drivers/tty/serial/8250/Makefile b/trunk/drivers/tty/serial/8250/Makefile index 36d68d054307..a23838a4d535 100644 --- a/trunk/drivers/tty/serial/8250/Makefile +++ b/trunk/drivers/tty/serial/8250/Makefile @@ -2,10 +2,10 @@ # Makefile for the 8250 serial device drivers. # -obj-$(CONFIG_SERIAL_8250) += 8250.o -8250-y := 8250_core.o -8250-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o -8250-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o +obj-$(CONFIG_SERIAL_8250) += 8250_core.o +8250_core-y := 8250.o +8250_core-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o +8250_core-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o diff --git a/trunk/drivers/tty/serial/8250/serial_cs.c b/trunk/drivers/tty/serial/8250/serial_cs.c index 1b74b88e1e1e..b7d48b346393 100644 --- a/trunk/drivers/tty/serial/8250/serial_cs.c +++ b/trunk/drivers/tty/serial/8250/serial_cs.c @@ -852,6 +852,18 @@ static struct pcmcia_driver serial_cs_driver = { .suspend = serial_suspend, .resume = serial_resume, }; -module_pcmcia_driver(serial_cs_driver); + +static int __init init_serial_cs(void) +{ + return pcmcia_register_driver(&serial_cs_driver); +} + +static void __exit exit_serial_cs(void) +{ + pcmcia_unregister_driver(&serial_cs_driver); +} + +module_init(init_serial_cs); +module_exit(exit_serial_cs); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/tty/serial/Kconfig b/trunk/drivers/tty/serial/Kconfig index 7e7006fd404e..cf9210db9fa9 100644 --- a/trunk/drivers/tty/serial/Kconfig +++ b/trunk/drivers/tty/serial/Kconfig @@ -211,14 +211,14 @@ config SERIAL_SAMSUNG config SERIAL_SAMSUNG_UARTS_4 bool depends on PLAT_SAMSUNG - default y if !(CPU_S3C2410 || CPU_S3C2412 || CPU_S3C2440 || CPU_S3C2442) + default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442) help Internal node for the common case of 4 Samsung compatible UARTs config SERIAL_SAMSUNG_UARTS int depends on PLAT_SAMSUNG - default 6 if CPU_S5P6450 + default 6 if ARCH_S5P6450 default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416 default 3 help diff --git a/trunk/drivers/tty/serial/atmel_serial.c b/trunk/drivers/tty/serial/atmel_serial.c index 3467462869ce..d4a7c241b751 100644 --- a/trunk/drivers/tty/serial/atmel_serial.c +++ b/trunk/drivers/tty/serial/atmel_serial.c @@ -158,7 +158,7 @@ struct atmel_uart_port { }; static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; -static DECLARE_BITMAP(atmel_ports_in_use, ATMEL_MAX_UART); +static unsigned long atmel_ports_in_use; #ifdef SUPPORT_SYSRQ static struct console atmel_console; @@ -1769,14 +1769,15 @@ static int atmel_serial_probe(struct platform_device *pdev) if (ret < 0) /* port id not found in platform data nor device-tree aliases: * auto-enumerate it */ - ret = find_first_zero_bit(atmel_ports_in_use, ATMEL_MAX_UART); + ret = find_first_zero_bit(&atmel_ports_in_use, + sizeof(atmel_ports_in_use)); - if (ret >= ATMEL_MAX_UART) { + if (ret > ATMEL_MAX_UART) { ret = -ENODEV; goto err; } - if (test_and_set_bit(ret, atmel_ports_in_use)) { + if (test_and_set_bit(ret, &atmel_ports_in_use)) { /* port already in use */ ret = -EBUSY; goto err; @@ -1856,7 +1857,7 @@ static int atmel_serial_remove(struct platform_device *pdev) /* "port" is allocated statically, so we shouldn't free it */ - clear_bit(port->line, atmel_ports_in_use); + clear_bit(port->line, &atmel_ports_in_use); clk_put(atmel_port->clk); diff --git a/trunk/drivers/tty/serial/bcm63xx_uart.c b/trunk/drivers/tty/serial/bcm63xx_uart.c index 52a3ecd40421..719594e5fc21 100644 --- a/trunk/drivers/tty/serial/bcm63xx_uart.c +++ b/trunk/drivers/tty/serial/bcm63xx_uart.c @@ -235,7 +235,7 @@ static const char *bcm_uart_type(struct uart_port *port) */ static void bcm_uart_do_rx(struct uart_port *port) { - struct tty_port *tty_port = &port->state->port; + struct tty_port *port = &port->state->port; unsigned int max_count; /* limit number of char read in interrupt, should not be @@ -260,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port) bcm_uart_writel(port, val, UART_CTL_REG); port->icount.overrun++; - tty_insert_flip_char(tty_port, 0, TTY_OVERRUN); + tty_insert_flip_char(port, 0, TTY_OVERRUN); } if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) @@ -299,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port) if ((cstat & port->ignore_status_mask) == 0) - tty_insert_flip_char(tty_port, c, flag); + tty_insert_flip_char(port, c, flag); } while (--max_count); - tty_flip_buffer_push(tty_port); + tty_flip_buffer_push(port); } /* diff --git a/trunk/drivers/tty/serial/mpc52xx_uart.c b/trunk/drivers/tty/serial/mpc52xx_uart.c index 018bad922554..c0e1fad51be7 100644 --- a/trunk/drivers/tty/serial/mpc52xx_uart.c +++ b/trunk/drivers/tty/serial/mpc52xx_uart.c @@ -550,7 +550,7 @@ static int mpc512x_psc_clock(struct uart_port *port, int enable) return 0; psc_num = (port->mapbase & 0xf00) >> 8; - snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); + snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num); psc_clk = clk_get(port->dev, clk_name); if (IS_ERR(psc_clk)) { dev_err(port->dev, "Failed to get PSC clock entry!\n"); diff --git a/trunk/drivers/tty/serial/of_serial.c b/trunk/drivers/tty/serial/of_serial.c index b025d5438275..d5874605682b 100644 --- a/trunk/drivers/tty/serial/of_serial.c +++ b/trunk/drivers/tty/serial/of_serial.c @@ -241,12 +241,6 @@ static struct of_device_id of_platform_serial_table[] = { { .compatible = "ns16850", .data = (void *)PORT_16850, }, { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, - { .compatible = "altr,16550-FIFO32", - .data = (void *)PORT_ALTR_16550_F32, }, - { .compatible = "altr,16550-FIFO64", - .data = (void *)PORT_ALTR_16550_F64, }, - { .compatible = "altr,16550-FIFO128", - .data = (void *)PORT_ALTR_16550_F128, }, #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL { .compatible = "ibm,qpace-nwp-serial", .data = (void *)PORT_NWPSERIAL, }, diff --git a/trunk/drivers/tty/serial/omap-serial.c b/trunk/drivers/tty/serial/omap-serial.c index 30d4f7a783cd..4dc41408ecb7 100644 --- a/trunk/drivers/tty/serial/omap-serial.c +++ b/trunk/drivers/tty/serial/omap-serial.c @@ -886,17 +886,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ - up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; - /* - * NOTE: Setting OMAP_UART_SCR_RX_TRIG_GRANU1_MASK - * sets Enables the granularity of 1 for TRIGGER RX - * level. Along with setting RX FIFO trigger level - * to 1 (as noted below, 16 characters) and TLR[3:0] - * to zero this will result RX FIFO threshold level - * to 1 character, instead of 16 as noted in comment - * below. - */ - /* Set receive FIFO threshold to 16 characters and * transmit FIFO threshold to 16 spaces */ diff --git a/trunk/drivers/tty/serial/sunsu.c b/trunk/drivers/tty/serial/sunsu.c index 451687cb9685..e343d6670854 100644 --- a/trunk/drivers/tty/serial/sunsu.c +++ b/trunk/drivers/tty/serial/sunsu.c @@ -968,7 +968,6 @@ static struct uart_ops sunsu_pops = { #define UART_NR 4 static struct uart_sunsu_port sunsu_ports[UART_NR]; -static int nr_inst; /* Number of already registered ports */ #ifdef CONFIG_SERIO @@ -1338,8 +1337,13 @@ static int __init sunsu_console_setup(struct console *co, char *options) printk("Console: ttyS%d (SU)\n", (sunsu_reg.minor - 64) + co->index); - if (co->index > nr_inst) - return -ENODEV; + /* + * Check whether an invalid uart number has been specified, and + * if so, search for the first available port that does have + * console support. + */ + if (co->index >= UART_NR) + co->index = 0; port = &sunsu_ports[co->index].port; /* @@ -1404,6 +1408,7 @@ static enum su_type su_get_type(struct device_node *dp) static int su_probe(struct platform_device *op) { + static int inst; struct device_node *dp = op->dev.of_node; struct uart_sunsu_port *up; struct resource *rp; @@ -1413,16 +1418,16 @@ static int su_probe(struct platform_device *op) type = su_get_type(dp); if (type == SU_PORT_PORT) { - if (nr_inst >= UART_NR) + if (inst >= UART_NR) return -EINVAL; - up = &sunsu_ports[nr_inst]; + up = &sunsu_ports[inst]; } else { up = kzalloc(sizeof(*up), GFP_KERNEL); if (!up) return -ENOMEM; } - up->port.line = nr_inst; + up->port.line = inst; spin_lock_init(&up->port.lock); @@ -1456,8 +1461,6 @@ static int su_probe(struct platform_device *op) } dev_set_drvdata(&op->dev, up); - nr_inst++; - return 0; } @@ -1485,7 +1488,7 @@ static int su_probe(struct platform_device *op) dev_set_drvdata(&op->dev, up); - nr_inst++; + inst++; return 0; diff --git a/trunk/drivers/tty/serial/vt8500_serial.c b/trunk/drivers/tty/serial/vt8500_serial.c index 705240e6c4ec..a3f9dd5c9dff 100644 --- a/trunk/drivers/tty/serial/vt8500_serial.c +++ b/trunk/drivers/tty/serial/vt8500_serial.c @@ -611,7 +611,14 @@ static int vt8500_serial_probe(struct platform_device *pdev) vt8500_port->uart.dev = &pdev->dev; vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk); + vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); + if (!IS_ERR(vt8500_port->clk)) { + vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk); + } else { + /* use the default of 24Mhz if not specified and warn */ + pr_warn("%s: serial clock source not specified\n", __func__); + vt8500_port->uart.uartclk = 24000000; + } snprintf(vt8500_port->name, sizeof(vt8500_port->name), "VT8500 UART%d", pdev->id); diff --git a/trunk/drivers/tty/serial/xilinx_uartps.c b/trunk/drivers/tty/serial/xilinx_uartps.c index f36bbba1ac8b..ba451c7209fc 100644 --- a/trunk/drivers/tty/serial/xilinx_uartps.c +++ b/trunk/drivers/tty/serial/xilinx_uartps.c @@ -578,8 +578,6 @@ static int xuartps_startup(struct uart_port *port) /* Receive Timeout register is enabled with value of 10 */ xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); - /* Clear out any pending interrupts before enabling them */ - xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET); /* Set the Interrupt Registers with desired interrupts */ xuartps_writel(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | diff --git a/trunk/drivers/tty/tty_buffer.c b/trunk/drivers/tty/tty_buffer.c index 578aa7594b11..bb119934e76c 100644 --- a/trunk/drivers/tty/tty_buffer.c +++ b/trunk/drivers/tty/tty_buffer.c @@ -425,7 +425,7 @@ static void flush_to_ldisc(struct work_struct *work) struct tty_ldisc *disc; tty = port->itty; - if (tty == NULL) + if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n")) return; disc = tty_ldisc_ref(tty); diff --git a/trunk/drivers/tty/tty_io.c b/trunk/drivers/tty/tty_io.c index b0452688308c..05400acbc456 100644 --- a/trunk/drivers/tty/tty_io.c +++ b/trunk/drivers/tty/tty_io.c @@ -941,14 +941,6 @@ void start_tty(struct tty_struct *tty) EXPORT_SYMBOL(start_tty); -static void tty_update_time(struct timespec *time) -{ - unsigned long sec = get_seconds(); - sec -= sec % 60; - if ((long)(sec - time->tv_sec) > 0) - time->tv_sec = sec; -} - /** * tty_read - read method for tty device files * @file: pointer to tty file @@ -968,11 +960,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int i; - struct inode *inode = file_inode(file); struct tty_struct *tty = file_tty(file); struct tty_ldisc *ld; - if (tty_paranoia_check(tty, inode, "tty_read")) + if (tty_paranoia_check(tty, file_inode(file), "tty_read")) return -EIO; if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) return -EIO; @@ -986,9 +977,6 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, i = -EIO; tty_ldisc_deref(ld); - if (i > 0) - tty_update_time(&inode->i_atime); - return i; } @@ -1089,10 +1077,8 @@ static inline ssize_t do_tty_write( break; cond_resched(); } - if (written) { - tty_update_time(&file_inode(file)->i_mtime); + if (written) ret = written; - } out: tty_write_unlock(tty); return ret; diff --git a/trunk/drivers/tty/vt/vc_screen.c b/trunk/drivers/tty/vt/vc_screen.c index d7799deacb21..e4ca345873c3 100644 --- a/trunk/drivers/tty/vt/vc_screen.c +++ b/trunk/drivers/tty/vt/vc_screen.c @@ -93,7 +93,7 @@ vcs_poll_data_free(struct vcs_poll_data *poll) static struct vcs_poll_data * vcs_poll_data_get(struct file *file) { - struct vcs_poll_data *poll = file->private_data, *kill = NULL; + struct vcs_poll_data *poll = file->private_data; if (poll) return poll; @@ -122,12 +122,10 @@ vcs_poll_data_get(struct file *file) file->private_data = poll; } else { /* someone else raced ahead of us */ - kill = poll; + vcs_poll_data_free(poll); poll = file->private_data; } spin_unlock(&file->f_lock); - if (kill) - vcs_poll_data_free(kill); return poll; } diff --git a/trunk/drivers/uio/uio.c b/trunk/drivers/uio/uio.c index b645c47501b4..c8b926291e28 100644 --- a/trunk/drivers/uio/uio.c +++ b/trunk/drivers/uio/uio.c @@ -374,7 +374,6 @@ static int uio_get_minor(struct uio_device *idev) retval = idr_alloc(&uio_idr, idev, 0, UIO_MAX_DEVICES, GFP_KERNEL); if (retval >= 0) { idev->minor = retval; - retval = 0; } else if (retval == -ENOSPC) { dev_err(idev->dev, "too many uio devices\n"); retval = -EINVAL; diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index 8f5ebced5df0..f5ed3d75fa5a 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB) += misc/ -obj-$(CONFIG_USB_OTG_UTILS) += phy/ +obj-$(CONFIG_USB_COMMON) += phy/ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ diff --git a/trunk/drivers/usb/c67x00/c67x00-sched.c b/trunk/drivers/usb/c67x00/c67x00-sched.c index aa491627a45b..a03fbc15fa9c 100644 --- a/trunk/drivers/usb/c67x00/c67x00-sched.c +++ b/trunk/drivers/usb/c67x00/c67x00-sched.c @@ -100,7 +100,7 @@ struct c67x00_urb_priv { #define TD_PIDEP_OFFSET 0x04 #define TD_PIDEPMASK_PID 0xF0 #define TD_PIDEPMASK_EP 0x0F -#define TD_PORTLENMASK_DL 0x03FF +#define TD_PORTLENMASK_DL 0x02FF #define TD_PORTLENMASK_PN 0xC000 #define TD_STATUS_OFFSET 0x07 @@ -590,7 +590,7 @@ static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb, { struct c67x00_td *td; struct c67x00_urb_priv *urbp = urb->hcpriv; - const __u8 active_flag = 1, retry_cnt = 3; + const __u8 active_flag = 1, retry_cnt = 1; __u8 cmd = 0; int tt = 0; diff --git a/trunk/drivers/usb/chipidea/udc.c b/trunk/drivers/usb/chipidea/udc.c index f64fbea1cf20..2f45bba8561d 100644 --- a/trunk/drivers/usb/chipidea/udc.c +++ b/trunk/drivers/usb/chipidea/udc.c @@ -1767,7 +1767,7 @@ static int udc_start(struct ci13xxx *ci) goto put_transceiver; } - retval = dbg_create_files(ci->dev); + retval = dbg_create_files(&ci->gadget.dev); if (retval) goto unreg_device; @@ -1796,7 +1796,7 @@ static int udc_start(struct ci13xxx *ci) dev_err(dev, "error = %i\n", retval); remove_dbg: - dbg_remove_files(ci->dev); + dbg_remove_files(&ci->gadget.dev); unreg_device: device_unregister(&ci->gadget.dev); put_transceiver: @@ -1836,7 +1836,7 @@ static void udc_stop(struct ci13xxx *ci) if (ci->global_phy) usb_put_phy(ci->transceiver); } - dbg_remove_files(ci->dev); + dbg_remove_files(&ci->gadget.dev); device_unregister(&ci->gadget.dev); /* my kobject is dynamic, I swear! */ memset(&ci->gadget, 0, sizeof(ci->gadget)); diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 387dc6c8ad25..8ac25adf31b4 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -593,6 +593,7 @@ static void acm_port_destruct(struct tty_port *port) dev_dbg(&acm->control->dev, "%s\n", __func__); + tty_unregister_device(acm_tty_driver, acm->minor); acm_release_minor(acm); usb_put_intf(acm->control); kfree(acm->country_codes); @@ -976,8 +977,6 @@ static int acm_probe(struct usb_interface *intf, int num_rx_buf; int i; int combined_interfaces = 0; - struct device *tty_dev; - int rv = -ENOMEM; /* normal quirks */ quirks = (unsigned long)id->driver_info; @@ -1340,24 +1339,11 @@ static int acm_probe(struct usb_interface *intf, usb_set_intfdata(data_interface, acm); usb_get_intf(control_interface); - tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, + tty_port_register_device(&acm->port, acm_tty_driver, minor, &control_interface->dev); - if (IS_ERR(tty_dev)) { - rv = PTR_ERR(tty_dev); - goto alloc_fail8; - } return 0; -alloc_fail8: - if (acm->country_codes) { - device_remove_file(&acm->control->dev, - &dev_attr_wCountryCodes); - device_remove_file(&acm->control->dev, - &dev_attr_iCountryCodeRelDate); - } - device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); alloc_fail7: - usb_set_intfdata(intf, NULL); for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); alloc_fail6: @@ -1373,7 +1359,7 @@ static int acm_probe(struct usb_interface *intf, acm_release_minor(acm); kfree(acm); alloc_fail: - return rv; + return -ENOMEM; } static void stop_data_traffic(struct acm *acm) @@ -1425,8 +1411,6 @@ static void acm_disconnect(struct usb_interface *intf) stop_data_traffic(acm); - tty_unregister_device(acm_tty_driver, acm->minor); - usb_free_urb(acm->ctrlurb); for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index 122d056d96d5..5f0cb417b736 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -56,7 +56,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_RESPONDING 7 #define WDM_SUSPENDING 8 #define WDM_RESETTING 9 -#define WDM_OVERFLOW 10 #define WDM_MAX 16 @@ -156,7 +155,6 @@ static void wdm_in_callback(struct urb *urb) { struct wdm_device *desc = urb->context; int status = urb->status; - int length = urb->actual_length; spin_lock(&desc->iuspin); clear_bit(WDM_RESPONDING, &desc->flags); @@ -187,17 +185,9 @@ static void wdm_in_callback(struct urb *urb) } desc->rerr = status; - if (length + desc->length > desc->wMaxCommand) { - /* The buffer would overflow */ - set_bit(WDM_OVERFLOW, &desc->flags); - } else { - /* we may already be in overflow */ - if (!test_bit(WDM_OVERFLOW, &desc->flags)) { - memmove(desc->ubuf + desc->length, desc->inbuf, length); - desc->length += length; - desc->reslength = length; - } - } + desc->reslength = urb->actual_length; + memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); + desc->length += desc->reslength; skip_error: wake_up(&desc->wait); @@ -445,11 +435,6 @@ static ssize_t wdm_read rv = -ENODEV; goto err; } - if (test_bit(WDM_OVERFLOW, &desc->flags)) { - clear_bit(WDM_OVERFLOW, &desc->flags); - rv = -ENOBUFS; - goto err; - } i++; if (file->f_flags & O_NONBLOCK) { if (!test_bit(WDM_READ, &desc->flags)) { @@ -493,7 +478,6 @@ static ssize_t wdm_read spin_unlock_irq(&desc->iuspin); goto retry; } - if (!desc->reslength) { /* zero length read */ dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); clear_bit(WDM_READ, &desc->flags); @@ -1020,7 +1004,6 @@ static int wdm_post_reset(struct usb_interface *intf) struct wdm_device *desc = wdm_find_device(intf); int rv; - clear_bit(WDM_OVERFLOW, &desc->flags); clear_bit(WDM_RESETTING, &desc->flags); rv = recover_from_urb_loss(desc); mutex_unlock(&desc->wlock); diff --git a/trunk/drivers/usb/core/hcd-pci.c b/trunk/drivers/usb/core/hcd-pci.c index 2b487d4797bd..622b4a48e732 100644 --- a/trunk/drivers/usb/core/hcd-pci.c +++ b/trunk/drivers/usb/core/hcd-pci.c @@ -173,7 +173,6 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) struct hc_driver *driver; struct usb_hcd *hcd; int retval; - int hcd_irq = 0; if (usb_disabled()) return -ENODEV; @@ -188,19 +187,15 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return -ENODEV; dev->current_state = PCI_D0; - /* - * The xHCI driver has its own irq management - * make sure irq setup is not touched for xhci in generic hcd code + /* The xHCI driver supports MSI and MSI-X, + * so don't fail if the BIOS doesn't provide a legacy IRQ. */ - if ((driver->flags & HCD_MASK) != HCD_USB3) { - if (!dev->irq) { - dev_err(&dev->dev, - "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", - pci_name(dev)); - retval = -ENODEV; - goto disable_pci; - } - hcd_irq = dev->irq; + if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) { + dev_err(&dev->dev, + "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", + pci_name(dev)); + retval = -ENODEV; + goto disable_pci; } hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev)); @@ -250,7 +245,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) pci_set_master(dev); - retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED); + retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED); if (retval != 0) goto unmap_registers; set_hs_companion(dev, hcd); diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index f9ec44cbb82f..99b34a30354f 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -2412,14 +2412,6 @@ int usb_hcd_is_primary_hcd(struct usb_hcd *hcd) } EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd); -int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1) -{ - if (!hcd->driver->find_raw_port_number) - return port1; - - return hcd->driver->find_raw_port_number(hcd, port1); -} - static int usb_hcd_request_irqs(struct usb_hcd *hcd, unsigned int irqnum, unsigned long irqflags) { diff --git a/trunk/drivers/usb/core/port.c b/trunk/drivers/usb/core/port.c index 65d4e55552c6..797f9d514732 100644 --- a/trunk/drivers/usb/core/port.c +++ b/trunk/drivers/usb/core/port.c @@ -67,6 +67,7 @@ static void usb_port_device_release(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); + dev_pm_qos_hide_flags(dev); kfree(port_dev); } diff --git a/trunk/drivers/usb/core/usb-acpi.c b/trunk/drivers/usb/core/usb-acpi.c index 255c14464bf2..cef4252bb31a 100644 --- a/trunk/drivers/usb/core/usb-acpi.c +++ b/trunk/drivers/usb/core/usb-acpi.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include "usb.h" @@ -189,13 +188,8 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle) * connected to. */ if (!udev->parent) { - struct usb_hcd *hcd = bus_to_hcd(udev->bus); - int raw_port_num; - - raw_port_num = usb_hcd_find_raw_port_number(hcd, - port_num); *handle = acpi_get_child(DEVICE_ACPI_HANDLE(&udev->dev), - raw_port_num); + port_num); if (!*handle) return -ENODEV; } else { @@ -216,14 +210,9 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle) return 0; } -static bool usb_acpi_bus_match(struct device *dev) -{ - return is_usb_device(dev) || is_usb_port(dev); -} - static struct acpi_bus_type usb_acpi_bus = { - .name = "USB", - .match = usb_acpi_bus_match, + .bus = &usb_bus_type, + .find_bridge = usb_acpi_find_device, .find_device = usb_acpi_find_device, }; diff --git a/trunk/drivers/usb/core/usb.c b/trunk/drivers/usb/core/usb.c index e092b414dc50..f81b92572735 100644 --- a/trunk/drivers/usb/core/usb.c +++ b/trunk/drivers/usb/core/usb.c @@ -317,8 +317,7 @@ static const struct dev_pm_ops usb_device_pm_ops = { #endif /* CONFIG_PM */ -static char *usb_devnode(struct device *dev, - umode_t *mode, kuid_t *uid, kgid_t *gid) +static char *usb_devnode(struct device *dev, umode_t *mode) { struct usb_device *usb_dev; diff --git a/trunk/drivers/usb/dwc3/core.c b/trunk/drivers/usb/dwc3/core.c index ffa6b004a84b..999909451e37 100644 --- a/trunk/drivers/usb/dwc3/core.c +++ b/trunk/drivers/usb/dwc3/core.c @@ -583,7 +583,6 @@ static int dwc3_remove(struct platform_device *pdev) break; } - dwc3_free_event_buffers(dwc); dwc3_core_exit(dwc); return 0; diff --git a/trunk/drivers/usb/dwc3/dwc3-exynos.c b/trunk/drivers/usb/dwc3/dwc3-exynos.c index b082bec7343e..b50da53e9a52 100644 --- a/trunk/drivers/usb/dwc3/dwc3-exynos.c +++ b/trunk/drivers/usb/dwc3/dwc3-exynos.c @@ -23,6 +23,8 @@ #include #include +#include "core.h" + struct dwc3_exynos { struct platform_device *dwc3; struct platform_device *usb2_phy; diff --git a/trunk/drivers/usb/dwc3/dwc3-omap.c b/trunk/drivers/usb/dwc3/dwc3-omap.c index afa05e3c9cf4..22f337f57219 100644 --- a/trunk/drivers/usb/dwc3/dwc3-omap.c +++ b/trunk/drivers/usb/dwc3/dwc3-omap.c @@ -54,6 +54,8 @@ #include #include +#include "core.h" + /* * All these registers belong to OMAP's Wrapper around the * DesignWare USB3 Core. @@ -463,20 +465,20 @@ static int dwc3_omap_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id of_dwc3_match[] = { +static const struct of_device_id of_dwc3_matach[] = { { "ti,dwc3", }, { }, }; -MODULE_DEVICE_TABLE(of, of_dwc3_match); +MODULE_DEVICE_TABLE(of, of_dwc3_matach); static struct platform_driver dwc3_omap_driver = { .probe = dwc3_omap_probe, .remove = dwc3_omap_remove, .driver = { .name = "omap-dwc3", - .of_match_table = of_dwc3_match, + .of_match_table = of_dwc3_matach, }, }; diff --git a/trunk/drivers/usb/dwc3/dwc3-pci.c b/trunk/drivers/usb/dwc3/dwc3-pci.c index e8d77689a322..7d70f44567d2 100644 --- a/trunk/drivers/usb/dwc3/dwc3-pci.c +++ b/trunk/drivers/usb/dwc3/dwc3-pci.c @@ -45,6 +45,8 @@ #include #include +#include "core.h" + /* FIXME define these in */ #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd diff --git a/trunk/drivers/usb/dwc3/ep0.c b/trunk/drivers/usb/dwc3/ep0.c index 1d139ca05ef1..d7da073a23fe 100644 --- a/trunk/drivers/usb/dwc3/ep0.c +++ b/trunk/drivers/usb/dwc3/ep0.c @@ -891,8 +891,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA); } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) && (dep->number == 0)) { - u32 transfer_size; - u32 maxpacket; + u32 transfer_size; ret = usb_gadget_map_request(&dwc->gadget, &req->request, dep->number); @@ -903,8 +902,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE); - maxpacket = dep->endpoint.maxpacket; - transfer_size = roundup(req->request.length, maxpacket); + transfer_size = roundup(req->request.length, + (u32) dep->endpoint.maxpacket); dwc->ep0_bounced = true; diff --git a/trunk/drivers/usb/dwc3/gadget.c b/trunk/drivers/usb/dwc3/gadget.c index 82e160e96fca..a04342f6cbfa 100644 --- a/trunk/drivers/usb/dwc3/gadget.c +++ b/trunk/drivers/usb/dwc3/gadget.c @@ -2159,6 +2159,7 @@ static void dwc3_gadget_phy_suspend(struct dwc3 *dwc, u8 speed) static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) { + struct dwc3_gadget_ep_cmd_params params; struct dwc3_ep *dep; int ret; u32 reg; @@ -2166,6 +2167,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) dev_vdbg(dwc->dev, "%s\n", __func__); + memset(¶ms, 0x00, sizeof(params)); + reg = dwc3_readl(dwc->regs, DWC3_DSTS); speed = reg & DWC3_DSTS_CONNECTSPD; dwc->speed = speed; diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index c7525b1cad74..5a0c541daf89 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -145,7 +145,6 @@ config USB_LPC32XX tristate "LPC32XX USB Peripheral Controller" depends on ARCH_LPC32XX select USB_ISP1301 - select USB_OTG_UTILS help This option selects the USB device controller in the LPC32xx SoC. diff --git a/trunk/drivers/usb/gadget/Makefile b/trunk/drivers/usb/gadget/Makefile index 82fb22511356..97a13c349cc5 100644 --- a/trunk/drivers/usb/gadget/Makefile +++ b/trunk/drivers/usb/gadget/Makefile @@ -35,12 +35,6 @@ mv_udc-y := mv_udc_core.o obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o -# USB Functions -obj-$(CONFIG_USB_F_ACM) += f_acm.o -f_ss_lb-y := f_loopback.o f_sourcesink.o -obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o -obj-$(CONFIG_USB_U_SERIAL) += u_serial.o - # # USB gadget drivers # @@ -80,3 +74,9 @@ obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o obj-$(CONFIG_USB_G_NCM) += g_ncm.o obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o + +# USB Functions +obj-$(CONFIG_USB_F_ACM) += f_acm.o +f_ss_lb-y := f_loopback.o f_sourcesink.o +obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o +obj-$(CONFIG_USB_U_SERIAL) += u_serial.o diff --git a/trunk/drivers/usb/gadget/composite.c b/trunk/drivers/usb/gadget/composite.c index c0d62b278610..7c821de8ce3d 100644 --- a/trunk/drivers/usb/gadget/composite.c +++ b/trunk/drivers/usb/gadget/composite.c @@ -1757,7 +1757,10 @@ static const struct usb_gadget_driver composite_driver_template = { /** * usb_composite_probe() - register a composite driver * @driver: the driver to register - * + * @bind: the callback used to allocate resources that are shared across the + * whole device, such as string IDs, and add its configurations using + * @usb_add_config(). This may fail by returning a negative errno + * value; it should return zero on successful initialization. * Context: single threaded during gadget setup * * This function is used to register drivers using the composite driver diff --git a/trunk/drivers/usb/gadget/f_fs.c b/trunk/drivers/usb/gadget/f_fs.c index c377ff84bf2c..38388d7844fc 100644 --- a/trunk/drivers/usb/gadget/f_fs.c +++ b/trunk/drivers/usb/gadget/f_fs.c @@ -1235,7 +1235,6 @@ static struct file_system_type ffs_fs_type = { .mount = ffs_fs_mount, .kill_sb = ffs_fs_kill_sb, }; -MODULE_ALIAS_FS("functionfs"); /* Driver's main init/cleanup functions *************************************/ diff --git a/trunk/drivers/usb/gadget/f_rndis.c b/trunk/drivers/usb/gadget/f_rndis.c index cc9c49c57c80..71beeb833558 100644 --- a/trunk/drivers/usb/gadget/f_rndis.c +++ b/trunk/drivers/usb/gadget/f_rndis.c @@ -447,13 +447,14 @@ static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req) static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req) { struct f_rndis *rndis = req->context; + struct usb_composite_dev *cdev = rndis->port.func.config->cdev; int status; /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */ // spin_lock(&dev->lock); status = rndis_msg_parser(rndis->config, (u8 *) req->buf); if (status < 0) - pr_err("RNDIS command error %d, %d/%d\n", + ERROR(cdev, "RNDIS command error %d, %d/%d\n", status, req->actual, req->length); // spin_unlock(&dev->lock); } diff --git a/trunk/drivers/usb/gadget/f_uac1.c b/trunk/drivers/usb/gadget/f_uac1.c index fa8ea4ea00c1..f570e667a640 100644 --- a/trunk/drivers/usb/gadget/f_uac1.c +++ b/trunk/drivers/usb/gadget/f_uac1.c @@ -418,7 +418,6 @@ static int audio_get_intf_req(struct usb_function *f, req->context = audio; req->complete = f_audio_complete; - len = min_t(size_t, sizeof(value), len); memcpy(req->buf, &value, len); return len; diff --git a/trunk/drivers/usb/gadget/g_ffs.c b/trunk/drivers/usb/gadget/g_ffs.c index 3b343b23e4b0..3953dd4d7186 100644 --- a/trunk/drivers/usb/gadget/g_ffs.c +++ b/trunk/drivers/usb/gadget/g_ffs.c @@ -357,7 +357,7 @@ static int gfs_bind(struct usb_composite_dev *cdev) goto error; gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id; - for (i = func_num; i--; ) { + for (i = func_num; --i; ) { ret = functionfs_bind(ffs_tab[i].ffs_data, cdev); if (unlikely(ret < 0)) { while (++i < func_num) @@ -413,7 +413,7 @@ static int gfs_unbind(struct usb_composite_dev *cdev) gether_cleanup(); gfs_ether_setup = false; - for (i = func_num; i--; ) + for (i = func_num; --i; ) if (ffs_tab[i].ffs_data) functionfs_unbind(ffs_tab[i].ffs_data); diff --git a/trunk/drivers/usb/gadget/imx_udc.c b/trunk/drivers/usb/gadget/imx_udc.c index 5bd930d779b9..8efd7555fa21 100644 --- a/trunk/drivers/usb/gadget/imx_udc.c +++ b/trunk/drivers/usb/gadget/imx_udc.c @@ -1334,18 +1334,27 @@ static int imx_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct imx_udc_struct *imx_usb; + int retval; imx_usb = container_of(gadget, struct imx_udc_struct, gadget); /* first hook up the driver ... */ imx_usb->driver = driver; imx_usb->gadget.dev.driver = &driver->driver; + retval = device_add(&imx_usb->gadget.dev); + if (retval) + goto fail; + D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n", __func__, driver->driver.name); imx_udc_enable(imx_usb); return 0; +fail: + imx_usb->driver = NULL; + imx_usb->gadget.dev.driver = NULL; + return retval; } static int imx_udc_stop(struct usb_gadget *gadget, @@ -1361,6 +1370,8 @@ static int imx_udc_stop(struct usb_gadget *gadget, imx_usb->gadget.dev.driver = NULL; imx_usb->driver = NULL; + device_del(&imx_usb->gadget.dev); + D_INI(imx_usb->dev, "<%s> unregistered gadget driver '%s'\n", __func__, driver->driver.name); @@ -1466,10 +1477,6 @@ static int __init imx_udc_probe(struct platform_device *pdev) imx_usb->gadget.dev.parent = &pdev->dev; imx_usb->gadget.dev.dma_mask = pdev->dev.dma_mask; - ret = device_add(&imx_usb->gadget.dev); - if (retval) - goto fail4; - platform_set_drvdata(pdev, imx_usb); usb_init_data(imx_usb); @@ -1481,11 +1488,9 @@ static int __init imx_udc_probe(struct platform_device *pdev) ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget); if (ret) - goto fail5; + goto fail4; return 0; -fail5: - device_unregister(&imx_usb->gadget.dev); fail4: for (i = 0; i < IMX_USB_NB_EP + 1; i++) free_irq(imx_usb->usbd_int[i], imx_usb); @@ -1509,7 +1514,6 @@ static int __exit imx_udc_remove(struct platform_device *pdev) int i; usb_del_gadget_udc(&imx_usb->gadget); - device_unregister(&imx_usb->gadget.dev); imx_udc_disable(imx_usb); del_timer(&imx_usb->timer); diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index e2b2e9cf254a..8ac840f25ba9 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -2105,7 +2105,6 @@ static struct file_system_type gadgetfs_type = { .mount = gadgetfs_mount, .kill_sb = gadgetfs_kill_sb, }; -MODULE_ALIAS_FS("gadgetfs"); /*----------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/gadget/net2272.c b/trunk/drivers/usb/gadget/net2272.c index 32524b631959..d226058e3b88 100644 --- a/trunk/drivers/usb/gadget/net2272.c +++ b/trunk/drivers/usb/gadget/net2272.c @@ -59,7 +59,7 @@ static const char * const ep_name[] = { }; #define DMA_ADDR_INVALID (~(dma_addr_t)0) -#ifdef CONFIG_USB_NET2272_DMA +#ifdef CONFIG_USB_GADGET_NET2272_DMA /* * use_dma: the NET2272 can use an external DMA controller. * Note that since there is no generic DMA api, some functions, @@ -1495,13 +1495,6 @@ stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver) for (i = 0; i < 4; ++i) net2272_dequeue_all(&dev->ep[i]); - /* report disconnect; the driver is already quiesced */ - if (driver) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - net2272_usb_reinit(dev); } diff --git a/trunk/drivers/usb/gadget/net2280.c b/trunk/drivers/usb/gadget/net2280.c index 3bd0f992fb49..a1b650e11339 100644 --- a/trunk/drivers/usb/gadget/net2280.c +++ b/trunk/drivers/usb/gadget/net2280.c @@ -1924,6 +1924,7 @@ static int net2280_start(struct usb_gadget *_gadget, err_func: device_remove_file (&dev->pdev->dev, &dev_attr_function); err_unbind: + driver->unbind (&dev->gadget); dev->gadget.dev.driver = NULL; dev->driver = NULL; return retval; @@ -1945,13 +1946,6 @@ stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver) for (i = 0; i < 7; i++) nuke (&dev->ep [i]); - /* report disconnect; the driver is already quiesced */ - if (driver) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - usb_reinit (dev); } diff --git a/trunk/drivers/usb/gadget/omap_udc.c b/trunk/drivers/usb/gadget/omap_udc.c index f8445653577f..06be85c2b233 100644 --- a/trunk/drivers/usb/gadget/omap_udc.c +++ b/trunk/drivers/usb/gadget/omap_udc.c @@ -62,7 +62,6 @@ #define DRIVER_VERSION "4 October 2004" #define OMAP_DMA_USB_W2FC_TX0 29 -#define OMAP_DMA_USB_W2FC_RX0 26 /* * The OMAP UDC needs _very_ early endpoint setup: before enabling the @@ -1311,7 +1310,7 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on) } static int omap_udc_start(struct usb_gadget *g, - struct usb_gadget_driver *driver); + struct usb_gadget_driver *driver) static int omap_udc_stop(struct usb_gadget *g, struct usb_gadget_driver *driver); diff --git a/trunk/drivers/usb/gadget/pxa25x_udc.c b/trunk/drivers/usb/gadget/pxa25x_udc.c index d0f37484b6b0..2bbcdce942dc 100644 --- a/trunk/drivers/usb/gadget/pxa25x_udc.c +++ b/trunk/drivers/usb/gadget/pxa25x_udc.c @@ -1266,6 +1266,13 @@ static int pxa25x_udc_start(struct usb_gadget *g, dev->gadget.dev.driver = &driver->driver; dev->pullup = 1; + retval = device_add (&dev->gadget.dev); + if (retval) { + dev->driver = NULL; + dev->gadget.dev.driver = NULL; + return retval; + } + /* ... then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. */ @@ -1303,10 +1310,6 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) } del_timer_sync(&dev->timer); - /* report disconnect; the driver is already quiesced */ - if (driver) - driver->disconnect(&dev->gadget); - /* re-init driver-visible data structures */ udc_reinit(dev); } @@ -1328,6 +1331,7 @@ static int pxa25x_udc_stop(struct usb_gadget*g, dev->gadget.dev.driver = NULL; dev->driver = NULL; + device_del (&dev->gadget.dev); dump_state(dev); return 0; @@ -2142,13 +2146,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->gadget.dev.parent = &pdev->dev; dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - retval = device_add(&dev->gadget.dev); - if (retval) { - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - goto err_device_add; - } - the_controller = dev; platform_set_drvdata(pdev, dev); @@ -2199,8 +2196,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) free_irq(irq, dev); #endif err_irq1: - device_unregister(&dev->gadget.dev); - err_device_add: if (gpio_is_valid(dev->mach->gpio_pullup)) gpio_free(dev->mach->gpio_pullup); err_gpio_pullup: @@ -2222,11 +2217,10 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) { struct pxa25x_udc *dev = platform_get_drvdata(pdev); + usb_del_gadget_udc(&dev->gadget); if (dev->driver) return -EBUSY; - usb_del_gadget_udc(&dev->gadget); - device_unregister(&dev->gadget.dev); dev->pullup = 0; pullup(dev); diff --git a/trunk/drivers/usb/gadget/pxa27x_udc.c b/trunk/drivers/usb/gadget/pxa27x_udc.c index 2fc867652ef5..f7d25795821a 100644 --- a/trunk/drivers/usb/gadget/pxa27x_udc.c +++ b/trunk/drivers/usb/gadget/pxa27x_udc.c @@ -1814,6 +1814,11 @@ static int pxa27x_udc_start(struct usb_gadget *g, udc->gadget.dev.driver = &driver->driver; dplus_pullup(udc, 1); + retval = device_add(&udc->gadget.dev); + if (retval) { + dev_err(udc->dev, "device_add error %d\n", retval); + goto fail; + } if (!IS_ERR_OR_NULL(udc->transceiver)) { retval = otg_set_peripheral(udc->transceiver->otg, &udc->gadget); @@ -1871,6 +1876,7 @@ static int pxa27x_udc_stop(struct usb_gadget *g, udc->driver = NULL; + device_del(&udc->gadget.dev); if (!IS_ERR_OR_NULL(udc->transceiver)) return otg_set_peripheral(udc->transceiver->otg, NULL); @@ -2474,24 +2480,13 @@ static int __init pxa_udc_probe(struct platform_device *pdev) driver_name, udc->irq, retval); goto err_irq; } - - retval = device_add(&udc->gadget.dev); - if (retval) { - dev_err(udc->dev, "device_add error %d\n", retval); - goto err_dev_add; - } - retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (retval) goto err_add_udc; pxa_init_debugfs(udc); - return 0; - err_add_udc: - device_unregister(&udc->gadget.dev); -err_dev_add: free_irq(udc->irq, udc); err_irq: iounmap(udc->regs); @@ -2512,7 +2507,6 @@ static int __exit pxa_udc_remove(struct platform_device *_dev) int gpio = udc->mach->gpio_pullup; usb_del_gadget_udc(&udc->gadget); - device_del(&udc->gadget.dev); usb_gadget_unregister_driver(udc->driver); free_irq(udc->irq, udc); pxa_cleanup_debugfs(udc); diff --git a/trunk/drivers/usb/gadget/s3c2410_udc.c b/trunk/drivers/usb/gadget/s3c2410_udc.c index 08f89652533b..fc07b4381286 100644 --- a/trunk/drivers/usb/gadget/s3c2410_udc.c +++ b/trunk/drivers/usb/gadget/s3c2410_udc.c @@ -1668,7 +1668,8 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev) static int s3c2410_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver) { - struct s3c2410_udc *udc = to_s3c2410(g); + struct s3c2410_udc *udc = to_s3c2410(g) + int retval; dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name); @@ -1676,10 +1677,22 @@ static int s3c2410_udc_start(struct usb_gadget *g, udc->driver = driver; udc->gadget.dev.driver = &driver->driver; + /* Bind the driver */ + retval = device_add(&udc->gadget.dev); + if (retval) { + dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval); + goto register_error; + } + /* Enable udc */ s3c2410_udc_enable(udc); return 0; + +register_error: + udc->driver = NULL; + udc->gadget.dev.driver = NULL; + return retval; } static int s3c2410_udc_stop(struct usb_gadget *g, @@ -1687,6 +1700,7 @@ static int s3c2410_udc_stop(struct usb_gadget *g, { struct s3c2410_udc *udc = to_s3c2410(g); + device_del(&udc->gadget.dev); udc->driver = NULL; /* Disable udc */ @@ -1828,13 +1842,6 @@ static int s3c2410_udc_probe(struct platform_device *pdev) udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = pdev->dev.dma_mask; - /* Bind the driver */ - retval = device_add(&udc->gadget.dev); - if (retval) { - dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval); - goto err_device_add; - } - the_controller = udc; platform_set_drvdata(pdev, udc); @@ -1923,8 +1930,6 @@ static int s3c2410_udc_probe(struct platform_device *pdev) err_int: free_irq(IRQ_USBD, udc); err_map: - device_unregister(&udc->gadget.dev); -err_device_add: iounmap(base_addr); err_mem: release_mem_region(rsrc_start, rsrc_len); @@ -1942,11 +1947,10 @@ static int s3c2410_udc_remove(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s()\n", __func__); + usb_del_gadget_udc(&udc->gadget); if (udc->driver) return -EBUSY; - usb_del_gadget_udc(&udc->gadget); - device_unregister(&udc->gadget.dev); debugfs_remove(udc->regs_info); if (udc_info && !udc_info->udc_command && diff --git a/trunk/drivers/usb/gadget/u_serial.c b/trunk/drivers/usb/gadget/u_serial.c index b369292d4b90..c5034d9c946b 100644 --- a/trunk/drivers/usb/gadget/u_serial.c +++ b/trunk/drivers/usb/gadget/u_serial.c @@ -136,7 +136,7 @@ static struct portmaster { pr_debug(fmt, ##arg) #endif /* pr_vdebug */ #else -#ifndef pr_vdebug +#ifndef pr_vdebig #define pr_vdebug(fmt, arg...) \ ({ if (0) pr_debug(fmt, ##arg); }) #endif /* pr_vdebug */ diff --git a/trunk/drivers/usb/gadget/u_uac1.c b/trunk/drivers/usb/gadget/u_uac1.c index c7d460f43390..e0c5e88e03ed 100644 --- a/trunk/drivers/usb/gadget/u_uac1.c +++ b/trunk/drivers/usb/gadget/u_uac1.c @@ -240,11 +240,8 @@ static int gaudio_open_snd_dev(struct gaudio *card) snd = &card->playback; snd->filp = filp_open(fn_play, O_WRONLY, 0); if (IS_ERR(snd->filp)) { - int ret = PTR_ERR(snd->filp); - ERROR(card, "No such PCM playback device: %s\n", fn_play); snd->filp = NULL; - return ret; } pcm_file = snd->filp->private_data; snd->substream = pcm_file->substream; diff --git a/trunk/drivers/usb/gadget/udc-core.c b/trunk/drivers/usb/gadget/udc-core.c index f8f62c3ed65e..2a9cd369f71c 100644 --- a/trunk/drivers/usb/gadget/udc-core.c +++ b/trunk/drivers/usb/gadget/udc-core.c @@ -216,7 +216,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) usb_gadget_disconnect(udc->gadget); udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); - usb_gadget_udc_stop(udc->gadget, NULL); + usb_gadget_udc_stop(udc->gadget, udc->driver); udc->driver = NULL; udc->dev.driver = NULL; diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 416a6dce5e11..b416a3fc9959 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -302,7 +302,6 @@ static void ehci_quiesce (struct ehci_hcd *ehci) static void end_unlink_async(struct ehci_hcd *ehci); static void unlink_empty_async(struct ehci_hcd *ehci); -static void unlink_empty_async_suspended(struct ehci_hcd *ehci); static void ehci_work(struct ehci_hcd *ehci); static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); @@ -749,9 +748,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* guard against (alleged) silicon errata */ if (cmd & CMD_IAAD) ehci_dbg(ehci, "IAA with IAAD still set?\n"); - if (ehci->async_iaa) + if (ehci->async_iaa) { COUNT(ehci->stats.iaa); - end_unlink_async(ehci); + end_unlink_async(ehci); + } else + ehci_dbg(ehci, "IAA with nothing unlinked?\n"); } /* remote wakeup [4.3.1] */ diff --git a/trunk/drivers/usb/host/ehci-hub.c b/trunk/drivers/usb/host/ehci-hub.c index 7d06e77f6c4f..4d3b294f203e 100644 --- a/trunk/drivers/usb/host/ehci-hub.c +++ b/trunk/drivers/usb/host/ehci-hub.c @@ -328,7 +328,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ehci->rh_state = EHCI_RH_SUSPENDED; end_unlink_async(ehci); - unlink_empty_async_suspended(ehci); + unlink_empty_async(ehci); ehci_handle_intr_unlinks(ehci); end_free_itds(ehci); diff --git a/trunk/drivers/usb/host/ehci-q.c b/trunk/drivers/usb/host/ehci-q.c index 23d136904285..fd252f0cfb3a 100644 --- a/trunk/drivers/usb/host/ehci-q.c +++ b/trunk/drivers/usb/host/ehci-q.c @@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) * qtd is updated in qh_completions(). Update the QH * overlay here. */ - if (qh->hw->hw_token & ACTIVE_BIT(ehci)) { + if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { qh->hw->hw_qtd_next = qtd->hw_next; qtd = NULL; } @@ -449,19 +449,11 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) else if (last_status == -EINPROGRESS && !urb->unlinked) continue; - /* - * If this was the active qtd when the qh was unlinked - * and the overlay's token is active, then the overlay - * hasn't been written back to the qtd yet so use its - * token instead of the qtd's. After the qtd is - * processed and removed, the overlay won't be valid - * any more. - */ - if (state == QH_STATE_IDLE && - qh->qtd_list.next == &qtd->qtd_list && - (hw->hw_token & ACTIVE_BIT(ehci))) { + /* qh unlinked; token in overlay may be most current */ + if (state == QH_STATE_IDLE + && cpu_to_hc32(ehci, qtd->qtd_dma) + == hw->hw_current) { token = hc32_to_cpu(ehci, hw->hw_token); - hw->hw_token &= ~ACTIVE_BIT(ehci); /* An unlink may leave an incomplete * async transaction in the TT buffer. @@ -1178,7 +1170,7 @@ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh) struct ehci_qh *prev; /* Add to the end of the list of QHs waiting for the next IAAD */ - qh->qh_state = QH_STATE_UNLINK_WAIT; + qh->qh_state = QH_STATE_UNLINK; if (ehci->async_unlink) ehci->async_unlink_last->unlink_next = qh; else @@ -1221,19 +1213,9 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested) /* Do only the first waiting QH (nVidia bug?) */ qh = ehci->async_unlink; - - /* - * Intel (?) bug: The HC can write back the overlay region - * even after the IAA interrupt occurs. In self-defense, - * always go through two IAA cycles for each QH. - */ - if (qh->qh_state == QH_STATE_UNLINK_WAIT) { - qh->qh_state = QH_STATE_UNLINK; - } else { - ehci->async_iaa = qh; - ehci->async_unlink = qh->unlink_next; - qh->unlink_next = NULL; - } + ehci->async_iaa = qh; + ehci->async_unlink = qh->unlink_next; + qh->unlink_next = NULL; /* Make sure the unlinks are all visible to the hardware */ wmb(); @@ -1316,19 +1298,6 @@ static void unlink_empty_async(struct ehci_hcd *ehci) } } -/* The root hub is suspended; unlink all the async QHs */ -static void unlink_empty_async_suspended(struct ehci_hcd *ehci) -{ - struct ehci_qh *qh; - - while (ehci->async->qh_next.qh) { - qh = ehci->async->qh_next.qh; - WARN_ON(!list_empty(&qh->qtd_list)); - single_unlink_async(ehci, qh); - } - start_iaa_cycle(ehci, false); -} - /* makes sure the async qh will become idle */ /* caller must own ehci->lock */ diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index 010f686d8881..b476daf49f6f 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -1214,7 +1214,6 @@ itd_urb_transaction ( memset (itd, 0, sizeof *itd); itd->itd_dma = itd_dma; - itd->frame = 9999; /* an invalid value */ list_add (&itd->itd_list, &sched->td_list); } spin_unlock_irqrestore (&ehci->lock, flags); @@ -1916,7 +1915,6 @@ sitd_urb_transaction ( memset (sitd, 0, sizeof *sitd); sitd->sitd_dma = sitd_dma; - sitd->frame = 9999; /* an invalid value */ list_add (&sitd->sitd_list, &iso_sched->td_list); } diff --git a/trunk/drivers/usb/host/ehci-timer.c b/trunk/drivers/usb/host/ehci-timer.c index c3fa1305f830..20dbdcbe9b0f 100644 --- a/trunk/drivers/usb/host/ehci-timer.c +++ b/trunk/drivers/usb/host/ehci-timer.c @@ -304,7 +304,7 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci) * (a) SMP races against real IAA firing and retriggering, and * (b) clean HC shutdown, when IAA watchdog was pending. */ - if (1) { + if (ehci->async_iaa) { u32 cmd, status; /* If we get here, IAA is *REALLY* late. It's barely diff --git a/trunk/drivers/usb/host/sl811_cs.c b/trunk/drivers/usb/host/sl811_cs.c index 469564e57a52..3b6f50eaec91 100644 --- a/trunk/drivers/usb/host/sl811_cs.c +++ b/trunk/drivers/usb/host/sl811_cs.c @@ -200,4 +200,17 @@ static struct pcmcia_driver sl811_cs_driver = { .remove = sl811_cs_detach, .id_table = sl811_ids, }; -module_pcmcia_driver(sl811_cs_driver); + +/*====================================================================*/ + +static int __init init_sl811_cs(void) +{ + return pcmcia_register_driver(&sl811_cs_driver); +} +module_init(init_sl811_cs); + +static void __exit exit_sl811_cs(void) +{ + pcmcia_unregister_driver(&sl811_cs_driver); +} +module_exit(exit_sl811_cs); diff --git a/trunk/drivers/usb/host/xhci-mem.c b/trunk/drivers/usb/host/xhci-mem.c index 6dc238c592bc..35616ffbe3ae 100644 --- a/trunk/drivers/usb/host/xhci-mem.c +++ b/trunk/drivers/usb/host/xhci-mem.c @@ -1022,24 +1022,44 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, * is attached to (or the roothub port its ancestor hub is attached to). All we * know is the index of that port under either the USB 2.0 or the USB 3.0 * roothub, but that doesn't give us the real index into the HW port status - * registers. Call xhci_find_raw_port_number() to get real index. + * registers. Scan through the xHCI roothub port array, looking for the Nth + * entry of the correct port speed. Return the port number of that entry. */ static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, struct usb_device *udev) { struct usb_device *top_dev; - struct usb_hcd *hcd; - - if (udev->speed == USB_SPEED_SUPER) - hcd = xhci->shared_hcd; - else - hcd = xhci->main_hcd; + unsigned int num_similar_speed_ports; + unsigned int faked_port_num; + int i; for (top_dev = udev; top_dev->parent && top_dev->parent->parent; top_dev = top_dev->parent) /* Found device below root hub */; + faked_port_num = top_dev->portnum; + for (i = 0, num_similar_speed_ports = 0; + i < HCS_MAX_PORTS(xhci->hcs_params1); i++) { + u8 port_speed = xhci->port_array[i]; + + /* + * Skip ports that don't have known speeds, or have duplicate + * Extended Capabilities port speed entries. + */ + if (port_speed == 0 || port_speed == DUPLICATE_ENTRY) + continue; - return xhci_find_raw_port_number(hcd, top_dev->portnum); + /* + * USB 3.0 ports are always under a USB 3.0 hub. USB 2.0 and + * 1.1 ports are under the USB 2.0 hub. If the port speed + * matches the device speed, it's a similar speed port. + */ + if ((port_speed == 0x03) == (udev->speed == USB_SPEED_SUPER)) + num_similar_speed_ports++; + if (num_similar_speed_ports == faked_port_num) + /* Roothub ports are numbered from 1 to N */ + return i+1; + } + return 0; } /* Setup an xHCI virtual device for a Set Address command */ diff --git a/trunk/drivers/usb/host/xhci-pci.c b/trunk/drivers/usb/host/xhci-pci.c index 1a30c380043c..af259e0ec172 100644 --- a/trunk/drivers/usb/host/xhci-pci.c +++ b/trunk/drivers/usb/host/xhci-pci.c @@ -313,7 +313,6 @@ static const struct hc_driver xhci_pci_hc_driver = { .set_usb2_hw_lpm = xhci_set_usb2_hardware_lpm, .enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout, .disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout, - .find_raw_port_number = xhci_find_raw_port_number, }; /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 1969c001b3f9..882875465301 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -1599,20 +1599,14 @@ static void handle_port_status(struct xhci_hcd *xhci, max_ports = HCS_MAX_PORTS(xhci->hcs_params1); if ((port_id <= 0) || (port_id > max_ports)) { xhci_warn(xhci, "Invalid port id %d\n", port_id); - inc_deq(xhci, xhci->event_ring); - return; + bogus_port_status = true; + goto cleanup; } /* Figure out which usb_hcd this port is attached to: * is it a USB 3.0 port or a USB 2.0/1.1 port? */ major_revision = xhci->port_array[port_id - 1]; - - /* Find the right roothub. */ - hcd = xhci_to_hcd(xhci); - if ((major_revision == 0x03) != (hcd->speed == HCD_USB3)) - hcd = xhci->shared_hcd; - if (major_revision == 0) { xhci_warn(xhci, "Event for port %u not in " "Extended Capabilities, ignoring.\n", @@ -1635,6 +1629,10 @@ static void handle_port_status(struct xhci_hcd *xhci, * into the index into the ports on the correct split roothub, and the * correct bus_state structure. */ + /* Find the right roothub. */ + hcd = xhci_to_hcd(xhci); + if ((major_revision == 0x03) != (hcd->speed == HCD_USB3)) + hcd = xhci->shared_hcd; bus_state = &xhci->bus_state[hcd_index(hcd)]; if (hcd->speed == HCD_USB3) port_array = xhci->usb3_ports; @@ -2029,8 +2027,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, if (event_trb != ep_ring->dequeue && event_trb != td->last_trb) td->urb->actual_length = - td->urb->transfer_buffer_length - - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); + td->urb->transfer_buffer_length + - TRB_LEN(le32_to_cpu(event->transfer_len)); else td->urb->actual_length = 0; @@ -2062,7 +2060,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, /* Maybe the event was for the data stage? */ td->urb->actual_length = td->urb->transfer_buffer_length - - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); + TRB_LEN(le32_to_cpu(event->transfer_len)); xhci_dbg(xhci, "Waiting for status " "stage event\n"); return 0; @@ -2098,7 +2096,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, /* handle completion code */ switch (trb_comp_code) { case COMP_SUCCESS: - if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { + if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { frame->status = 0; break; } @@ -2143,7 +2141,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])); } len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); + TRB_LEN(le32_to_cpu(event->transfer_len)); if (trb_comp_code != COMP_STOP_INVAL) { frame->actual_length = len; @@ -2201,7 +2199,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, case COMP_SUCCESS: /* Double check that the HW transferred everything. */ if (event_trb != td->last_trb || - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { + TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { xhci_warn(xhci, "WARN Successful completion " "on short TX\n"); if (td->urb->transfer_flags & URB_SHORT_NOT_OK) @@ -2229,18 +2227,18 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, "%d bytes untransferred\n", td->urb->ep->desc.bEndpointAddress, td->urb->transfer_buffer_length, - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); + TRB_LEN(le32_to_cpu(event->transfer_len))); /* Fast path - was this the last TRB in the TD for this URB? */ if (event_trb == td->last_trb) { - if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { + if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { td->urb->actual_length = td->urb->transfer_buffer_length - - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); + TRB_LEN(le32_to_cpu(event->transfer_len)); if (td->urb->transfer_buffer_length < td->urb->actual_length) { xhci_warn(xhci, "HC gave bad length " "of %d bytes left\n", - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); + TRB_LEN(le32_to_cpu(event->transfer_len))); td->urb->actual_length = 0; if (td->urb->transfer_flags & URB_SHORT_NOT_OK) *status = -EREMOTEIO; @@ -2282,7 +2280,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, if (trb_comp_code != COMP_STOP_INVAL) td->urb->actual_length += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); + TRB_LEN(le32_to_cpu(event->transfer_len)); } return finish_td(xhci, td, event_trb, event, ep, status, false); @@ -2370,7 +2368,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, * transfer type */ case COMP_SUCCESS: - if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) + if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) break; if (xhci->quirks & XHCI_TRUST_TX_LENGTH) trb_comp_code = COMP_SHORT_TX; @@ -2463,21 +2461,14 @@ static int handle_tx_event(struct xhci_hcd *xhci, * TD list. */ if (list_empty(&ep_ring->td_list)) { - /* - * A stopped endpoint may generate an extra completion - * event if the device was suspended. Don't print - * warnings. - */ - if (!(trb_comp_code == COMP_STOP || - trb_comp_code == COMP_STOP_INVAL)) { - xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n", - TRB_TO_SLOT_ID(le32_to_cpu(event->flags)), - ep_index); - xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", - (le32_to_cpu(event->flags) & - TRB_TYPE_BITMASK)>>10); - xhci_print_trb_offsets(xhci, (union xhci_trb *) event); - } + xhci_warn(xhci, "WARN Event TRB for slot %d ep %d " + "with no TDs queued?\n", + TRB_TO_SLOT_ID(le32_to_cpu(event->flags)), + ep_index); + xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", + (le32_to_cpu(event->flags) & + TRB_TYPE_BITMASK)>>10); + xhci_print_trb_offsets(xhci, (union xhci_trb *) event); if (ep->skip) { ep->skip = false; xhci_dbg(xhci, "td_list is empty while skip " diff --git a/trunk/drivers/usb/host/xhci.c b/trunk/drivers/usb/host/xhci.c index 53b8f89a0b1c..f1f01a834ba7 100644 --- a/trunk/drivers/usb/host/xhci.c +++ b/trunk/drivers/usb/host/xhci.c @@ -350,7 +350,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) * generate interrupts. Don't even try to enable MSI. */ if (xhci->quirks & XHCI_BROKEN_MSI) - goto legacy_irq; + return 0; /* unregister the legacy interrupt */ if (hcd->irq) @@ -371,7 +371,6 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) return -EINVAL; } - legacy_irq: /* fall back to legacy interrupt*/ ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, hcd->irq_descr, hcd); @@ -3779,28 +3778,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) return 0; } -/* - * Transfer the port index into real index in the HW port status - * registers. Caculate offset between the port's PORTSC register - * and port status base. Divide the number of per port register - * to get the real index. The raw port number bases 1. - */ -int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - __le32 __iomem *base_addr = &xhci->op_regs->port_status_base; - __le32 __iomem *addr; - int raw_port; - - if (hcd->speed != HCD_USB3) - addr = xhci->usb2_ports[port1 - 1]; - else - addr = xhci->usb3_ports[port1 - 1]; - - raw_port = (addr - base_addr)/NUM_PORT_REGS + 1; - return raw_port; -} - #ifdef CONFIG_USB_SUSPEND /* BESL to HIRD Encoding array for USB2 LPM */ diff --git a/trunk/drivers/usb/host/xhci.h b/trunk/drivers/usb/host/xhci.h index 63582719e0fb..f791bd0aee6c 100644 --- a/trunk/drivers/usb/host/xhci.h +++ b/trunk/drivers/usb/host/xhci.h @@ -206,8 +206,8 @@ struct xhci_op_regs { /* bits 12:31 are reserved (and should be preserved on writes). */ /* IMAN - Interrupt Management Register */ -#define IMAN_IE (1 << 1) -#define IMAN_IP (1 << 0) +#define IMAN_IP (1 << 1) +#define IMAN_IE (1 << 0) /* USBSTS - USB status - status bitmasks */ /* HC not running - set to 1 when run/stop bit is cleared. */ @@ -972,10 +972,6 @@ struct xhci_transfer_event { __le32 flags; }; -/* Transfer event TRB length bit mask */ -/* bits 0:23 */ -#define EVENT_TRB_LEN(p) ((p) & 0xffffff) - /** Transfer Event bit fields **/ #define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f) @@ -1833,7 +1829,6 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength); int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); -int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1); #ifdef CONFIG_PM int xhci_bus_suspend(struct usb_hcd *hcd); diff --git a/trunk/drivers/usb/musb/Kconfig b/trunk/drivers/usb/musb/Kconfig index 05e51432dd2f..45b19e2c60ba 100644 --- a/trunk/drivers/usb/musb/Kconfig +++ b/trunk/drivers/usb/musb/Kconfig @@ -7,6 +7,11 @@ config USB_MUSB_HDRC tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' depends on USB && USB_GADGET + select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) + select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) + select TWL4030_USB if MACH_OMAP_3430SDP + select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA + select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA select USB_OTG_UTILS help Say Y here if your system has a dual role high speed USB diff --git a/trunk/drivers/usb/musb/da8xx.c b/trunk/drivers/usb/musb/da8xx.c index 41613a2b35e8..7c71769d71ff 100644 --- a/trunk/drivers/usb/musb/da8xx.c +++ b/trunk/drivers/usb/musb/da8xx.c @@ -327,7 +327,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) u8 devctl = musb_readb(mregs, MUSB_DEVCTL); int err; - err = musb->int_usb & MUSB_INTR_VBUSERROR; + err = musb->int_usb & USB_INTR_VBUSERROR; if (err) { /* * The Mentor core doesn't debounce VBUS as needed diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index daec6e0f7e38..60b41cc28da4 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -1624,6 +1624,8 @@ EXPORT_SYMBOL_GPL(musb_dma_completion); /*-------------------------------------------------------------------------*/ +#ifdef CONFIG_SYSFS + static ssize_t musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1740,6 +1742,8 @@ static const struct attribute_group musb_attr_group = { .attrs = musb_attributes, }; +#endif /* sysfs */ + /* Only used to provide driver mode change events */ static void musb_irq_work(struct work_struct *data) { @@ -1964,9 +1968,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (status < 0) goto fail4; +#ifdef CONFIG_SYSFS status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); if (status) goto fail5; +#endif pm_runtime_put(musb->controller); diff --git a/trunk/drivers/usb/musb/musb_gadget.c b/trunk/drivers/usb/musb/musb_gadget.c index 83eddedcd9be..be18537c5f14 100644 --- a/trunk/drivers/usb/musb/musb_gadget.c +++ b/trunk/drivers/usb/musb/musb_gadget.c @@ -141,9 +141,7 @@ static inline void map_dma_buffer(struct musb_request *request, static inline void unmap_dma_buffer(struct musb_request *request, struct musb *musb) { - struct musb_ep *musb_ep = request->ep; - - if (!is_buffer_mapped(request) || !musb_ep->dma) + if (!is_buffer_mapped(request)) return; if (request->request.dma == DMA_ADDR_INVALID) { @@ -197,10 +195,7 @@ __acquires(ep->musb->lock) ep->busy = 1; spin_unlock(&musb->lock); - - if (!dma_mapping_error(&musb->g.dev, request->dma)) - unmap_dma_buffer(req, musb); - + unmap_dma_buffer(req, musb); if (request->status == 0) dev_dbg(musb->controller, "%s done request %p, %d/%d\n", ep->end_point.name, request, diff --git a/trunk/drivers/usb/musb/omap2430.c b/trunk/drivers/usb/musb/omap2430.c index 1a42a458f2c4..1762354fe793 100644 --- a/trunk/drivers/usb/musb/omap2430.c +++ b/trunk/drivers/usb/musb/omap2430.c @@ -51,7 +51,7 @@ struct omap2430_glue { }; #define glue_to_musb(g) platform_get_drvdata(g->musb) -static struct omap2430_glue *_glue; +struct omap2430_glue *_glue; static struct timer_list musb_idle_timer; @@ -237,13 +237,9 @@ void omap_musb_mailbox(enum omap_musb_vbus_id_status status) { struct omap2430_glue *glue = _glue; - if (!glue) { - pr_err("%s: musb core is not yet initialized\n", __func__); - return; - } - glue->status = status; - - if (!glue_to_musb(glue)) { + if (glue && glue_to_musb(glue)) { + glue->status = status; + } else { pr_err("%s: musb core is not yet ready\n", __func__); return; } diff --git a/trunk/drivers/usb/otg/otg.c b/trunk/drivers/usb/otg/otg.c index 2bd03d261a50..e1814397ca3a 100644 --- a/trunk/drivers/usb/otg/otg.c +++ b/trunk/drivers/usb/otg/otg.c @@ -130,7 +130,7 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type) spin_lock_irqsave(&phy_lock, flags); phy = __usb_find_phy(&phy_list, type); - if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { + if (IS_ERR(phy)) { pr_err("unable to find transceiver of type %s\n", usb_phy_type_string(type)); goto err0; @@ -228,7 +228,7 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) spin_lock_irqsave(&phy_lock, flags); phy = __usb_find_phy_dev(dev, &phy_bind_list, index); - if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { + if (IS_ERR(phy)) { pr_err("unable to find transceiver\n"); goto err0; } @@ -301,12 +301,8 @@ EXPORT_SYMBOL(devm_usb_put_phy); */ void usb_put_phy(struct usb_phy *x) { - if (x) { - struct module *owner = x->dev->driver->owner; - + if (x) put_device(x->dev); - module_put(owner); - } } EXPORT_SYMBOL(usb_put_phy); diff --git a/trunk/drivers/usb/phy/Kconfig b/trunk/drivers/usb/phy/Kconfig index 90549382eba5..65217a590068 100644 --- a/trunk/drivers/usb/phy/Kconfig +++ b/trunk/drivers/usb/phy/Kconfig @@ -38,7 +38,6 @@ config USB_ISP1301 tristate "NXP ISP1301 USB transceiver support" depends on USB || USB_GADGET depends on I2C - select USB_OTG_UTILS help Say Y here to add support for the NXP ISP1301 USB transceiver driver. This chip is typically used as USB transceiver for USB host, gadget diff --git a/trunk/drivers/usb/phy/omap-control-usb.c b/trunk/drivers/usb/phy/omap-control-usb.c index 1419ceda9759..5323b71c3521 100644 --- a/trunk/drivers/usb/phy/omap-control-usb.c +++ b/trunk/drivers/usb/phy/omap-control-usb.c @@ -219,26 +219,32 @@ static int omap_control_usb_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control_dev_conf"); - control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(control_usb->dev_conf)) - return PTR_ERR(control_usb->dev_conf); + control_usb->dev_conf = devm_request_and_ioremap(&pdev->dev, res); + if (!control_usb->dev_conf) { + dev_err(&pdev->dev, "Failed to obtain io memory\n"); + return -EADDRNOTAVAIL; + } if (control_usb->type == OMAP_CTRL_DEV_TYPE1) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otghs_control"); - control_usb->otghs_control = devm_ioremap_resource( + control_usb->otghs_control = devm_request_and_ioremap( &pdev->dev, res); - if (IS_ERR(control_usb->otghs_control)) - return PTR_ERR(control_usb->otghs_control); + if (!control_usb->otghs_control) { + dev_err(&pdev->dev, "Failed to obtain io memory\n"); + return -EADDRNOTAVAIL; + } } if (control_usb->type == OMAP_CTRL_DEV_TYPE2) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_power_usb"); - control_usb->phy_power = devm_ioremap_resource( + control_usb->phy_power = devm_request_and_ioremap( &pdev->dev, res); - if (IS_ERR(control_usb->phy_power)) - return PTR_ERR(control_usb->phy_power); + if (!control_usb->phy_power) { + dev_dbg(&pdev->dev, "Failed to obtain io memory\n"); + return -EADDRNOTAVAIL; + } control_usb->sys_clk = devm_clk_get(control_usb->dev, "sys_clkin"); diff --git a/trunk/drivers/usb/phy/omap-usb3.c b/trunk/drivers/usb/phy/omap-usb3.c index a6e60b1e102e..fadc0c2b65bb 100644 --- a/trunk/drivers/usb/phy/omap-usb3.c +++ b/trunk/drivers/usb/phy/omap-usb3.c @@ -212,9 +212,11 @@ static int omap_usb3_probe(struct platform_device *pdev) } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); - phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(phy->pll_ctrl_base)) - return PTR_ERR(phy->pll_ctrl_base); + phy->pll_ctrl_base = devm_request_and_ioremap(&pdev->dev, res); + if (!phy->pll_ctrl_base) { + dev_err(&pdev->dev, "ioremap of pll_ctrl failed\n"); + return -ENOMEM; + } phy->dev = &pdev->dev; diff --git a/trunk/drivers/usb/phy/samsung-usbphy.c b/trunk/drivers/usb/phy/samsung-usbphy.c index 967101ec15fd..6ea553733832 100644 --- a/trunk/drivers/usb/phy/samsung-usbphy.c +++ b/trunk/drivers/usb/phy/samsung-usbphy.c @@ -787,9 +787,11 @@ static int samsung_usbphy_probe(struct platform_device *pdev) return -ENODEV; } - phy_base = devm_ioremap_resource(dev, phy_mem); - if (IS_ERR(phy_base)) - return PTR_ERR(phy_base); + phy_base = devm_request_and_ioremap(dev, phy_mem); + if (!phy_base) { + dev_err(dev, "%s: register mapping failed\n", __func__); + return -ENXIO; + } sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); if (!sphy) diff --git a/trunk/drivers/usb/serial/ark3116.c b/trunk/drivers/usb/serial/ark3116.c index 4775f8209e55..cbd904b8fba5 100644 --- a/trunk/drivers/usb/serial/ark3116.c +++ b/trunk/drivers/usb/serial/ark3116.c @@ -62,6 +62,7 @@ static int is_irda(struct usb_serial *serial) } struct ark3116_private { + wait_queue_head_t delta_msr_wait; struct async_icount icount; int irda; /* 1 for irda device */ @@ -145,6 +146,7 @@ static int ark3116_port_probe(struct usb_serial_port *port) if (!priv) return -ENOMEM; + init_waitqueue_head(&priv->delta_msr_wait); mutex_init(&priv->hw_lock); spin_lock_init(&priv->status_lock); @@ -454,14 +456,10 @@ static int ark3116_ioctl(struct tty_struct *tty, case TIOCMIWAIT: for (;;) { struct async_icount prev = priv->icount; - interruptible_sleep_on(&port->delta_msr_wait); + interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - if ((prev.rng == priv->icount.rng) && (prev.dsr == priv->icount.dsr) && (prev.dcd == priv->icount.dcd) && @@ -582,7 +580,7 @@ static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr) priv->icount.dcd++; if (msr & UART_MSR_TERI) priv->icount.rng++; - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); } } diff --git a/trunk/drivers/usb/serial/ch341.c b/trunk/drivers/usb/serial/ch341.c index 07d4650a32ab..d255f66e708e 100644 --- a/trunk/drivers/usb/serial/ch341.c +++ b/trunk/drivers/usb/serial/ch341.c @@ -80,6 +80,7 @@ MODULE_DEVICE_TABLE(usb, id_table); struct ch341_private { spinlock_t lock; /* access lock */ + wait_queue_head_t delta_msr_wait; /* wait queue for modem status */ unsigned baud_rate; /* set baud rate */ u8 line_control; /* set line control value RTS/DTR */ u8 line_status; /* active status of modem control inputs */ @@ -251,6 +252,7 @@ static int ch341_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); priv->baud_rate = DEFAULT_BAUD_RATE; priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; @@ -296,7 +298,7 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on) priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR); spin_unlock_irqrestore(&priv->lock, flags); ch341_set_handshake(port->serial->dev, priv->line_control); - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); } static void ch341_close(struct usb_serial_port *port) @@ -489,7 +491,7 @@ static void ch341_read_int_callback(struct urb *urb) tty_kref_put(tty); } - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); } exit: @@ -515,14 +517,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) spin_unlock_irqrestore(&priv->lock, flags); while (!multi_change) { - interruptible_sleep_on(&port->delta_msr_wait); + interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - if (port->serial->disconnected) - return -EIO; - spin_lock_irqsave(&priv->lock, flags); status = priv->line_status; multi_change = priv->multi_status_change; diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index 4747d1c328ff..edc0f0dcad83 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -85,7 +85,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ - { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ @@ -151,25 +150,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ - { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */ - { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */ - { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */ - { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */ - { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */ - { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */ - { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */ - { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */ - { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */ - { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */ - { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */ - { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */ - { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */ - { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */ - { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */ - { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */ - { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ - { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ - { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ diff --git a/trunk/drivers/usb/serial/cypress_m8.c b/trunk/drivers/usb/serial/cypress_m8.c index ba7352e4187e..8efa19d0e9fb 100644 --- a/trunk/drivers/usb/serial/cypress_m8.c +++ b/trunk/drivers/usb/serial/cypress_m8.c @@ -111,6 +111,7 @@ struct cypress_private { int baud_rate; /* stores current baud rate in integer form */ int isthrottled; /* if throttled, discard reads */ + wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ char prev_status, diff_status; /* used for TIOCMIWAIT */ /* we pass a pointer to this as the argument sent to cypress_set_termios old_termios */ @@ -448,6 +449,7 @@ static int cypress_generic_port_probe(struct usb_serial_port *port) kfree(priv); return -ENOMEM; } + init_waitqueue_head(&priv->delta_msr_wait); usb_reset_configuration(serial->dev); @@ -866,16 +868,12 @@ static int cypress_ioctl(struct tty_struct *tty, switch (cmd) { /* This code comes from drivers/char/serial.c and ftdi_sio.c */ case TIOCMIWAIT: - for (;;) { - interruptible_sleep_on(&port->delta_msr_wait); + while (priv != NULL) { + interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - - { + else { char diff = priv->diff_status; if (diff == 0) return -EIO; /* no change => error */ @@ -1189,7 +1187,7 @@ static void cypress_read_int_callback(struct urb *urb) if (priv->current_status != priv->prev_status) { priv->diff_status |= priv->current_status ^ priv->prev_status; - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); priv->prev_status = priv->current_status; } spin_unlock_irqrestore(&priv->lock, flags); diff --git a/trunk/drivers/usb/serial/f81232.c b/trunk/drivers/usb/serial/f81232.c index a172ad5c5ce8..b1b2dc64b50b 100644 --- a/trunk/drivers/usb/serial/f81232.c +++ b/trunk/drivers/usb/serial/f81232.c @@ -47,6 +47,7 @@ MODULE_DEVICE_TABLE(usb, id_table); struct f81232_private { spinlock_t lock; + wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; }; @@ -110,7 +111,7 @@ static void f81232_process_read_urb(struct urb *urb) line_status = priv->line_status; priv->line_status &= ~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(&priv->lock, flags); - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); if (!urb->actual_length) return; @@ -255,14 +256,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) spin_unlock_irqrestore(&priv->lock, flags); while (1) { - interruptible_sleep_on(&port->delta_msr_wait); + interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - if (port->serial->disconnected) - return -EIO; - spin_lock_irqsave(&priv->lock, flags); status = priv->line_status; spin_unlock_irqrestore(&priv->lock, flags); @@ -324,6 +322,7 @@ static int f81232_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); usb_set_serial_port_data(port, priv); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 9886180e45f1..edd162df49ca 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -69,7 +69,9 @@ struct ftdi_private { int flags; /* some ASYNC_xxxx flags are supported */ unsigned long last_dtr_rts; /* saved modem control outputs */ struct async_icount icount; + wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ char prev_status; /* Used for TIOCMIWAIT */ + bool dev_gone; /* Used to abort TIOCMIWAIT */ char transmit_empty; /* If transmitter is empty or not */ __u16 interface; /* FT2232C, FT2232H or FT4232H port interface (0 for FT232/245) */ @@ -640,7 +642,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) }, { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, - { USB_DEVICE(MITSUBISHI_VID, MITSUBISHI_FXUSB_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, @@ -1690,8 +1691,10 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) kref_init(&priv->kref); mutex_init(&priv->cfg_lock); + init_waitqueue_head(&priv->delta_msr_wait); priv->flags = ASYNC_LOW_LATENCY; + priv->dev_gone = false; if (quirk && quirk->port_probe) quirk->port_probe(priv); @@ -1837,7 +1840,8 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) { struct ftdi_private *priv = usb_get_serial_port_data(port); - wake_up_interruptible(&port->delta_msr_wait); + priv->dev_gone = true; + wake_up_interruptible_all(&priv->delta_msr_wait); remove_sysfs_attrs(port); @@ -1985,7 +1989,7 @@ static int ftdi_process_packet(struct usb_serial_port *port, if (diff_status & FTDI_RS0_RLSD) priv->icount.dcd++; - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible_all(&priv->delta_msr_wait); priv->prev_status = status; } @@ -2436,15 +2440,11 @@ static int ftdi_ioctl(struct tty_struct *tty, */ case TIOCMIWAIT: cprev = priv->icount; - for (;;) { - interruptible_sleep_on(&port->delta_msr_wait); + while (!priv->dev_gone) { + interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - cnow = priv->icount; if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || @@ -2454,6 +2454,8 @@ static int ftdi_ioctl(struct tty_struct *tty, } cprev = cnow; } + return -EIO; + break; case TIOCSERGETLSR: return get_lsr_info(port, (struct serial_struct __user *)arg); break; diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index e79861eeed4c..9d359e189a64 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -583,13 +583,6 @@ #define CONTEC_VID 0x06CE /* Vendor ID */ #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ -/* - * Mitsubishi Electric Corp. (http://www.meau.com) - * Submitted by Konstantin Holoborodko - */ -#define MITSUBISHI_VID 0x06D3 -#define MITSUBISHI_FXUSB_PID 0x0284 /* USB/RS422 converters: FX-USB-AW/-BD */ - /* * Definitions for B&B Electronics products. */ diff --git a/trunk/drivers/usb/serial/garmin_gps.c b/trunk/drivers/usb/serial/garmin_gps.c index 81caf5623ee2..1a07b12ef341 100644 --- a/trunk/drivers/usb/serial/garmin_gps.c +++ b/trunk/drivers/usb/serial/garmin_gps.c @@ -956,7 +956,10 @@ static void garmin_close(struct usb_serial_port *port) if (!serial) return; - garmin_clear(garmin_data_p); + mutex_lock(&port->serial->disc_mutex); + + if (!port->serial->disconnected) + garmin_clear(garmin_data_p); /* shutdown our urbs */ usb_kill_urb(port->read_urb); @@ -965,6 +968,8 @@ static void garmin_close(struct usb_serial_port *port) /* keep reset state so we know that we must start a new session */ if (garmin_data_p->state != STATE_RESET) garmin_data_p->state = STATE_DISCONNECTED; + + mutex_unlock(&port->serial->disc_mutex); } diff --git a/trunk/drivers/usb/serial/io_edgeport.c b/trunk/drivers/usb/serial/io_edgeport.c index efd8b978128c..b00e5cbf741f 100644 --- a/trunk/drivers/usb/serial/io_edgeport.c +++ b/trunk/drivers/usb/serial/io_edgeport.c @@ -110,6 +110,7 @@ struct edgeport_port { wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */ wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */ + wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ struct async_icount icount; struct usb_serial_port *port; /* loop back to the owner of this object */ @@ -883,6 +884,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) /* initialize our wait queues */ init_waitqueue_head(&edge_port->wait_open); init_waitqueue_head(&edge_port->wait_chase); + init_waitqueue_head(&edge_port->delta_msr_wait); init_waitqueue_head(&edge_port->wait_command); /* initialize our icount structure */ @@ -1667,17 +1669,13 @@ static int edge_ioctl(struct tty_struct *tty, dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__, port->number); cprev = edge_port->icount; while (1) { - prepare_to_wait(&port->delta_msr_wait, + prepare_to_wait(&edge_port->delta_msr_wait, &wait, TASK_INTERRUPTIBLE); schedule(); - finish_wait(&port->delta_msr_wait, &wait); + finish_wait(&edge_port->delta_msr_wait, &wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - cnow = edge_port->icount; if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) @@ -2053,7 +2051,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr) icount->dcd++; if (newMsr & EDGEPORT_MSR_DELTA_RI) icount->rng++; - wake_up_interruptible(&edge_port->port->delta_msr_wait); + wake_up_interruptible(&edge_port->delta_msr_wait); } /* Save the new modem status */ diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index 7777172206de..c23776679f70 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -87,6 +87,9 @@ struct edgeport_port { int close_pending; int lsr_event; struct async_icount icount; + wait_queue_head_t delta_msr_wait; /* for handling sleeping while + waiting for msr change to + happen */ struct edgeport_serial *edge_serial; struct usb_serial_port *port; __u8 bUartMode; /* Port type, 0: RS232, etc. */ @@ -1456,7 +1459,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) icount->dcd++; if (msr & EDGEPORT_MSR_DELTA_RI) icount->rng++; - wake_up_interruptible(&edge_port->port->delta_msr_wait); + wake_up_interruptible(&edge_port->delta_msr_wait); } /* Save the new modem status */ @@ -1751,6 +1754,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) dev = port->serial->dev; memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount)); + init_waitqueue_head(&edge_port->delta_msr_wait); /* turn off loopback */ status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0); @@ -2430,14 +2434,10 @@ static int edge_ioctl(struct tty_struct *tty, dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__); cprev = edge_port->icount; while (1) { - interruptible_sleep_on(&port->delta_msr_wait); + interruptible_sleep_on(&edge_port->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - cnow = edge_port->icount; if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) @@ -2649,7 +2649,6 @@ static struct usb_serial_driver edgeport_2port_device = { .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, - .get_icount = edge_get_icount, .write = edge_write, .write_room = edge_write_room, .chars_in_buffer = edge_chars_in_buffer, diff --git a/trunk/drivers/usb/serial/mct_u232.c b/trunk/drivers/usb/serial/mct_u232.c index 06d5a60be2c4..a64d420f687b 100644 --- a/trunk/drivers/usb/serial/mct_u232.c +++ b/trunk/drivers/usb/serial/mct_u232.c @@ -114,6 +114,8 @@ struct mct_u232_private { unsigned char last_msr; /* Modem Status Register */ unsigned int rx_flags; /* Throttling flags */ struct async_icount icount; + wait_queue_head_t msr_wait; /* for handling sleeping while waiting + for msr change to happen */ }; #define THROTTLED 0x01 @@ -407,6 +409,7 @@ static int mct_u232_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->msr_wait); usb_set_serial_port_data(port, priv); @@ -598,7 +601,7 @@ static void mct_u232_read_int_callback(struct urb *urb) tty_kref_put(tty); } #endif - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->msr_wait); spin_unlock_irqrestore(&priv->lock, flags); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -807,17 +810,13 @@ static int mct_u232_ioctl(struct tty_struct *tty, cprev = mct_u232_port->icount; spin_unlock_irqrestore(&mct_u232_port->lock, flags); for ( ; ; ) { - prepare_to_wait(&port->delta_msr_wait, + prepare_to_wait(&mct_u232_port->msr_wait, &wait, TASK_INTERRUPTIBLE); schedule(); - finish_wait(&port->delta_msr_wait, &wait); + finish_wait(&mct_u232_port->msr_wait, &wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - spin_lock_irqsave(&mct_u232_port->lock, flags); cnow = mct_u232_port->icount; spin_unlock_irqrestore(&mct_u232_port->lock, flags); diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index b8051fa61911..809fb329eca5 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -219,6 +219,7 @@ struct moschip_port { char open; char open_ports; wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ + wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ int delta_msr_cond; struct async_icount icount; struct usb_serial_port *port; /* loop back to the owner of this object */ @@ -422,9 +423,6 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) icount->rng++; smp_wmb(); } - - mos7840_port->delta_msr_cond = 1; - wake_up_interruptible(&port->port->delta_msr_wait); } } @@ -1129,6 +1127,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) /* initialize our wait queues */ init_waitqueue_head(&mos7840_port->wait_chase); + init_waitqueue_head(&mos7840_port->delta_msr_wait); /* initialize our icount structure */ memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount)); @@ -2018,6 +2017,8 @@ static void mos7840_change_port_settings(struct tty_struct *tty, mos7840_port->read_urb_busy = false; } } + wake_up(&mos7840_port->delta_msr_wait); + mos7840_port->delta_msr_cond = 1; dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__, mos7840_port->shadowLCR); } @@ -2218,18 +2219,13 @@ static int mos7840_ioctl(struct tty_struct *tty, while (1) { /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */ mos7840_port->delta_msr_cond = 0; - wait_event_interruptible(port->delta_msr_wait, - (port->serial->disconnected || - mos7840_port-> + wait_event_interruptible(mos7840_port->delta_msr_wait, + (mos7840_port-> delta_msr_cond == 1)); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - cnow = mos7840_port->icount; smp_rmb(); if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 558adfc05007..f7d339d8187b 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -341,8 +341,6 @@ static void option_instat_callback(struct urb *urb); #define CINTERION_PRODUCT_EU3_E 0x0051 #define CINTERION_PRODUCT_EU3_P 0x0052 #define CINTERION_PRODUCT_PH8 0x0053 -#define CINTERION_PRODUCT_AH6 0x0055 -#define CINTERION_PRODUCT_PLS8 0x0060 /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c @@ -581,7 +579,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, @@ -1263,8 +1260,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, diff --git a/trunk/drivers/usb/serial/oti6858.c b/trunk/drivers/usb/serial/oti6858.c index 87c71ccfee87..a958fd41b5b3 100644 --- a/trunk/drivers/usb/serial/oti6858.c +++ b/trunk/drivers/usb/serial/oti6858.c @@ -188,6 +188,7 @@ struct oti6858_private { u8 setup_done; struct delayed_work delayed_setup_work; + wait_queue_head_t intr_wait; struct usb_serial_port *port; /* USB port with which associated */ }; @@ -338,6 +339,7 @@ static int oti6858_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->intr_wait); priv->port = port; INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); @@ -662,15 +664,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) spin_unlock_irqrestore(&priv->lock, flags); while (1) { - wait_event_interruptible(port->delta_msr_wait, - port->serial->disconnected || + wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev); if (signal_pending(current)) return -ERESTARTSYS; - if (port->serial->disconnected) - return -EIO; - spin_lock_irqsave(&priv->lock, flags); status = priv->status.pin_state & PIN_MASK; spin_unlock_irqrestore(&priv->lock, flags); @@ -765,7 +763,7 @@ static void oti6858_read_int_callback(struct urb *urb) if (!priv->transient) { if (xs->pin_state != priv->status.pin_state) - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->intr_wait); memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE); } diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index 3b10018d89a3..54adc9125e5c 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -139,6 +139,7 @@ struct pl2303_serial_private { struct pl2303_private { spinlock_t lock; + wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; }; @@ -232,6 +233,7 @@ static int pl2303_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); usb_set_serial_port_data(port, priv); @@ -605,14 +607,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) spin_unlock_irqrestore(&priv->lock, flags); while (1) { - interruptible_sleep_on(&port->delta_msr_wait); + interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - if (port->serial->disconnected) - return -EIO; - spin_lock_irqsave(&priv->lock, flags); status = priv->line_status; spin_unlock_irqrestore(&priv->lock, flags); @@ -720,7 +719,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port, spin_unlock_irqrestore(&priv->lock, flags); if (priv->line_status & UART_BREAK_ERROR) usb_serial_handle_break(port); - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); tty = tty_port_tty_get(&port->port); if (!tty) @@ -784,7 +783,7 @@ static void pl2303_process_read_urb(struct urb *urb) line_status = priv->line_status; priv->line_status &= ~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(&priv->lock, flags); - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); if (!urb->actual_length) return; diff --git a/trunk/drivers/usb/serial/qcaux.c b/trunk/drivers/usb/serial/qcaux.c index 31f81c3c15eb..9b1b96f2d095 100644 --- a/trunk/drivers/usb/serial/qcaux.c +++ b/trunk/drivers/usb/serial/qcaux.c @@ -69,7 +69,6 @@ static struct usb_device_id id_table[] = { { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) }, /* NMEA */ { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) }, /* WMC */ { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) }, /* DIAG */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1fac, 0x0151, 0xff, 0xff, 0xff) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/trunk/drivers/usb/serial/qcserial.c b/trunk/drivers/usb/serial/qcserial.c index 59b32b782126..24662547dc5b 100644 --- a/trunk/drivers/usb/serial/qcserial.c +++ b/trunk/drivers/usb/serial/qcserial.c @@ -197,15 +197,12 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) if (is_gobi1k) { /* Gobi 1K USB layout: - * 0: DM/DIAG (use libqcdm from ModemManager for communication) + * 0: serial port (doesn't respond) * 1: serial port (doesn't respond) * 2: AT-capable modem port * 3: QMI/net */ - if (ifnum == 0) { - dev_dbg(dev, "Gobi 1K DM/DIAG interface found\n"); - altsetting = 1; - } else if (ifnum == 2) + if (ifnum == 2) dev_dbg(dev, "Modem port found\n"); else altsetting = -1; diff --git a/trunk/drivers/usb/serial/quatech2.c b/trunk/drivers/usb/serial/quatech2.c index 75f125ddb0c9..00e6c9bac8a3 100644 --- a/trunk/drivers/usb/serial/quatech2.c +++ b/trunk/drivers/usb/serial/quatech2.c @@ -128,6 +128,7 @@ struct qt2_port_private { u8 shadowLSR; u8 shadowMSR; + wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ struct async_icount icount; struct usb_serial_port *port; @@ -505,9 +506,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) spin_unlock_irqrestore(&priv->lock, flags); while (1) { - wait_event_interruptible(port->delta_msr_wait, - (port->serial->disconnected || - (priv->icount.rng != prev.rng) || + wait_event_interruptible(priv->delta_msr_wait, + ((priv->icount.rng != prev.rng) || (priv->icount.dsr != prev.dsr) || (priv->icount.dcd != prev.dcd) || (priv->icount.cts != prev.cts))); @@ -515,9 +515,6 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) if (signal_pending(current)) return -ERESTARTSYS; - if (port->serial->disconnected) - return -EIO; - spin_lock_irqsave(&priv->lock, flags); cur = priv->icount; spin_unlock_irqrestore(&priv->lock, flags); @@ -664,9 +661,7 @@ void qt2_process_read_urb(struct urb *urb) __func__); break; } - - if (port_priv->is_open) - tty_flip_buffer_push(&port->port); + tty_flip_buffer_push(&port->port); newport = *(ch + 3); @@ -709,8 +704,7 @@ void qt2_process_read_urb(struct urb *urb) tty_insert_flip_string(&port->port, ch, 1); } - if (port_priv->is_open) - tty_flip_buffer_push(&port->port); + tty_flip_buffer_push(&port->port); } static void qt2_write_bulk_callback(struct urb *urb) @@ -830,6 +824,7 @@ static int qt2_port_probe(struct usb_serial_port *port) spin_lock_init(&port_priv->lock); spin_lock_init(&port_priv->urb_lock); + init_waitqueue_head(&port_priv->delta_msr_wait); port_priv->port = port; port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); @@ -972,7 +967,7 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) if (newMSR & UART_MSR_TERI) port_priv->icount.rng++; - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&port_priv->delta_msr_wait); } } diff --git a/trunk/drivers/usb/serial/spcp8x5.c b/trunk/drivers/usb/serial/spcp8x5.c index 549ef68ff5fa..91ff8e3bddbd 100644 --- a/trunk/drivers/usb/serial/spcp8x5.c +++ b/trunk/drivers/usb/serial/spcp8x5.c @@ -149,6 +149,7 @@ enum spcp8x5_type { struct spcp8x5_private { spinlock_t lock; enum spcp8x5_type type; + wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; }; @@ -178,6 +179,7 @@ static int spcp8x5_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); priv->type = type; usb_set_serial_port_data(port , priv); @@ -473,7 +475,7 @@ static void spcp8x5_process_read_urb(struct urb *urb) priv->line_status &= ~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(&priv->lock, flags); /* wake up the wait for termios */ - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); if (!urb->actual_length) return; @@ -524,15 +526,12 @@ static int spcp8x5_wait_modem_info(struct usb_serial_port *port, while (1) { /* wake up in bulk read */ - interruptible_sleep_on(&port->delta_msr_wait); + interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; - if (port->serial->disconnected) - return -EIO; - spin_lock_irqsave(&priv->lock, flags); status = priv->line_status; spin_unlock_irqrestore(&priv->lock, flags); diff --git a/trunk/drivers/usb/serial/ssu100.c b/trunk/drivers/usb/serial/ssu100.c index 4b2a19757b4d..b57cf841c5b6 100644 --- a/trunk/drivers/usb/serial/ssu100.c +++ b/trunk/drivers/usb/serial/ssu100.c @@ -61,6 +61,7 @@ struct ssu100_port_private { spinlock_t status_lock; u8 shadowLSR; u8 shadowMSR; + wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ struct async_icount icount; }; @@ -354,9 +355,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) spin_unlock_irqrestore(&priv->status_lock, flags); while (1) { - wait_event_interruptible(port->delta_msr_wait, - (port->serial->disconnected || - (priv->icount.rng != prev.rng) || + wait_event_interruptible(priv->delta_msr_wait, + ((priv->icount.rng != prev.rng) || (priv->icount.dsr != prev.dsr) || (priv->icount.dcd != prev.dcd) || (priv->icount.cts != prev.cts))); @@ -364,9 +364,6 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) if (signal_pending(current)) return -ERESTARTSYS; - if (port->serial->disconnected) - return -EIO; - spin_lock_irqsave(&priv->status_lock, flags); cur = priv->icount; spin_unlock_irqrestore(&priv->status_lock, flags); @@ -448,6 +445,7 @@ static int ssu100_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->status_lock); + init_waitqueue_head(&priv->delta_msr_wait); usb_set_serial_port_data(port, priv); @@ -539,7 +537,7 @@ static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) priv->icount.dcd++; if (msr & UART_MSR_TERI) priv->icount.rng++; - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&priv->delta_msr_wait); } } diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.c b/trunk/drivers/usb/serial/ti_usb_3410_5052.c index 73deb029fc05..39cb9b807c3c 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.c +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.c @@ -74,6 +74,7 @@ struct ti_port { int tp_flags; int tp_closing_wait;/* in .01 secs */ struct async_icount tp_icount; + wait_queue_head_t tp_msr_wait; /* wait for msr change */ wait_queue_head_t tp_write_wait; struct ti_device *tp_tdev; struct usb_serial_port *tp_port; @@ -431,6 +432,7 @@ static int ti_port_probe(struct usb_serial_port *port) else tport->tp_uart_base_addr = TI_UART2_BASE_ADDR; tport->tp_closing_wait = closing_wait; + init_waitqueue_head(&tport->tp_msr_wait); init_waitqueue_head(&tport->tp_write_wait); if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) { kfree(tport); @@ -782,13 +784,9 @@ static int ti_ioctl(struct tty_struct *tty, dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__); cprev = tport->tp_icount; while (1) { - interruptible_sleep_on(&port->delta_msr_wait); + interruptible_sleep_on(&tport->tp_msr_wait); if (signal_pending(current)) return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - cnow = tport->tp_icount; if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) @@ -1394,7 +1392,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) icount->dcd++; if (msr & TI_MSR_DELTA_RI) icount->rng++; - wake_up_interruptible(&tport->tp_port->delta_msr_wait); + wake_up_interruptible(&tport->tp_msr_wait); spin_unlock_irqrestore(&tport->tp_lock, flags); } diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 5d9b178484fd..a19ed74d770d 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -151,7 +151,6 @@ static void destroy_serial(struct kref *kref) } } - usb_put_intf(serial->interface); usb_put_dev(serial->dev); kfree(serial); } @@ -621,7 +620,7 @@ static struct usb_serial *create_serial(struct usb_device *dev, } serial->dev = usb_get_dev(dev); serial->type = driver; - serial->interface = usb_get_intf(interface); + serial->interface = interface; kref_init(&serial->kref); mutex_init(&serial->disc_mutex); serial->minor = SERIAL_TTY_NO_MINOR; @@ -903,7 +902,6 @@ static int usb_serial_probe(struct usb_interface *interface, port->port.ops = &serial_port_ops; port->serial = serial; spin_lock_init(&port->lock); - init_waitqueue_head(&port->delta_msr_wait); /* Keep this for private driver use for the moment but should probably go away */ INIT_WORK(&port->work, usb_serial_port_work); diff --git a/trunk/drivers/usb/storage/initializers.c b/trunk/drivers/usb/storage/initializers.c index 105d900150c1..7ab9046ae0ec 100644 --- a/trunk/drivers/usb/storage/initializers.c +++ b/trunk/drivers/usb/storage/initializers.c @@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) return 0; } -/* This places the HUAWEI E220 devices in multi-port mode */ -int usb_stor_huawei_e220_init(struct us_data *us) +/* This places the HUAWEI usb dongles in multi-port mode */ +static int usb_stor_huawei_feature_init(struct us_data *us) { int result; @@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us) US_DEBUGP("Huawei mode set result is %d\n", result); return 0; } + +/* + * It will send a scsi switch command called rewind' to huawei dongle. + * When the dongle receives this command at the first time, + * it will reboot immediately. After rebooted, it will ignore this command. + * So it is unnecessary to read its response. + */ +static int usb_stor_huawei_scsi_init(struct us_data *us) +{ + int result = 0; + int act_len = 0; + struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; + char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcbw->Tag = 0; + bcbw->DataTransferLength = 0; + bcbw->Flags = bcbw->Lun = 0; + bcbw->Length = sizeof(rewind_cmd); + memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); + memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); + + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, + US_BULK_CB_WRAP_LEN, &act_len); + US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); + return result; +} + +/* + * It tries to find the supported Huawei USB dongles. + * In Huawei, they assign the following product IDs + * for all of their mobile broadband dongles, + * including the new dongles in the future. + * So if the product ID is not included in this list, + * it means it is not Huawei's mobile broadband dongles. + */ +static int usb_stor_huawei_dongles_pid(struct us_data *us) +{ + struct usb_interface_descriptor *idesc; + int idProduct; + + idesc = &us->pusb_intf->cur_altsetting->desc; + idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); + /* The first port is CDROM, + * means the dongle in the single port mode, + * and a switch command is required to be sent. */ + if (idesc && idesc->bInterfaceNumber == 0) { + if ((idProduct == 0x1001) + || (idProduct == 0x1003) + || (idProduct == 0x1004) + || (idProduct >= 0x1401 && idProduct <= 0x1500) + || (idProduct >= 0x1505 && idProduct <= 0x1600) + || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { + return 1; + } + } + return 0; +} + +int usb_stor_huawei_init(struct us_data *us) +{ + int result = 0; + + if (usb_stor_huawei_dongles_pid(us)) { + if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) + result = usb_stor_huawei_scsi_init(us); + else + result = usb_stor_huawei_feature_init(us); + } + return result; +} diff --git a/trunk/drivers/usb/storage/initializers.h b/trunk/drivers/usb/storage/initializers.h index 529327fbb06b..5376d4fc76f0 100644 --- a/trunk/drivers/usb/storage/initializers.h +++ b/trunk/drivers/usb/storage/initializers.h @@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us); * flash reader */ int usb_stor_ucr61s2b_init(struct us_data *us); -/* This places the HUAWEI E220 devices in multi-port mode */ -int usb_stor_huawei_e220_init(struct us_data *us); +/* This places the HUAWEI usb dongles in multi-port mode */ +int usb_stor_huawei_init(struct us_data *us); diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index 1799335288bd..72923b56bbf6 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -53,14 +53,6 @@ * as opposed to devices that do something strangely or wrongly. */ -/* In-kernel mode switching is deprecated. Do not add new devices to - * this list for the sole purpose of switching them to a different - * mode. Existing userspace solutions are superior. - * - * New mode switching devices should instead be added to the database - * maintained at http://www.draisberghof.de/usb_modeswitch/ - */ - #if !defined(CONFIG_USB_STORAGE_SDDR09) && \ !defined(CONFIG_USB_STORAGE_SDDR09_MODULE) #define NO_SDDR09 @@ -496,13 +488,6 @@ UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG), -/* Added by Dmitry Artamonow */ -UNUSUAL_DEV( 0x04e8, 0x5136, 0x0000, 0x9999, - "Samsung", - "YP-Z3", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_MAX_SECTORS_64), - /* Entry and supporting patch by Theodore Kilgore . * Device uses standards-violating 32-byte Bulk Command Block Wrappers and * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. @@ -1542,335 +1527,10 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, /* Reported by fangxiaozhi * This brings the HUAWEI data card devices into multi-port mode */ -UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000, - "HUAWEI MOBILE", - "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, - 0), -UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, +UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50, "HUAWEI MOBILE", "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init, 0), /* Reported by Vilius Bilinkevicius msix_cap; + msix_pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); if (msix_pos) { u16 flags; u32 table; @@ -78,8 +78,8 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev) pci_read_config_word(pdev, msix_pos + PCI_MSIX_FLAGS, &flags); pci_read_config_dword(pdev, msix_pos + PCI_MSIX_TABLE, &table); - vdev->msix_bar = table & PCI_MSIX_TABLE_BIR; - vdev->msix_offset = table & PCI_MSIX_TABLE_OFFSET; + vdev->msix_bar = table & PCI_MSIX_FLAGS_BIRMASK; + vdev->msix_offset = table & ~PCI_MSIX_FLAGS_BIRMASK; vdev->msix_size = ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) * 16; } else vdev->msix_bar = 0xFF; @@ -183,7 +183,7 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) u8 pos; u16 flags; - pos = vdev->pdev->msi_cap; + pos = pci_find_capability(vdev->pdev, PCI_CAP_ID_MSI); if (pos) { pci_read_config_word(vdev->pdev, pos + PCI_MSI_FLAGS, &flags); @@ -194,7 +194,7 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) u8 pos; u16 flags; - pos = vdev->pdev->msix_cap; + pos = pci_find_capability(vdev->pdev, PCI_CAP_ID_MSIX); if (pos) { pci_read_config_word(vdev->pdev, pos + PCI_MSIX_FLAGS, &flags); @@ -346,7 +346,6 @@ static long vfio_pci_ioctl(void *device_data, if (!(hdr.flags & VFIO_IRQ_SET_DATA_NONE)) { size_t size; - int max = vfio_pci_get_irq_count(vdev, hdr.index); if (hdr.flags & VFIO_IRQ_SET_DATA_BOOL) size = sizeof(uint8_t); @@ -356,7 +355,7 @@ static long vfio_pci_ioctl(void *device_data, return -EINVAL; if (hdr.argsz - minsz < hdr.count * size || - hdr.start >= max || hdr.start + hdr.count > max) + hdr.count > vfio_pci_get_irq_count(vdev, hdr.index)) return -EINVAL; data = memdup_user((void __user *)(arg + minsz), diff --git a/trunk/drivers/vfio/pci/vfio_pci_config.c b/trunk/drivers/vfio/pci/vfio_pci_config.c index aeb00fc2d3be..964ff22bf281 100644 --- a/trunk/drivers/vfio/pci/vfio_pci_config.c +++ b/trunk/drivers/vfio/pci/vfio_pci_config.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "vfio_pci_private.h" diff --git a/trunk/drivers/vfio/pci/vfio_pci_intrs.c b/trunk/drivers/vfio/pci/vfio_pci_intrs.c index a96509187deb..3639371fa697 100644 --- a/trunk/drivers/vfio/pci/vfio_pci_intrs.c +++ b/trunk/drivers/vfio/pci/vfio_pci_intrs.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "vfio_pci_private.h" diff --git a/trunk/drivers/vhost/net.c b/trunk/drivers/vhost/net.c index ec6fb3fa59bb..959b1cd89e6a 100644 --- a/trunk/drivers/vhost/net.c +++ b/trunk/drivers/vhost/net.c @@ -339,8 +339,7 @@ static void handle_tx(struct vhost_net *net) msg.msg_controllen = 0; ubufs = NULL; } else { - struct ubuf_info *ubuf; - ubuf = vq->ubuf_info + vq->upend_idx; + struct ubuf_info *ubuf = &vq->ubuf_info[head]; vq->heads[vq->upend_idx].len = VHOST_DMA_IN_PROGRESS; diff --git a/trunk/drivers/vhost/tcm_vhost.c b/trunk/drivers/vhost/tcm_vhost.c index 957a0b98a5d9..9951297b2427 100644 --- a/trunk/drivers/vhost/tcm_vhost.c +++ b/trunk/drivers/vhost/tcm_vhost.c @@ -60,22 +60,14 @@ enum { VHOST_SCSI_VQ_IO = 2, }; -/* - * VIRTIO_RING_F_EVENT_IDX seems broken. Not sure the bug is in - * kernel but disabling it helps. - * TODO: debug and remove the workaround. - */ -enum { - VHOST_SCSI_FEATURES = VHOST_FEATURES & (~VIRTIO_RING_F_EVENT_IDX) -}; - #define VHOST_SCSI_MAX_TARGET 256 #define VHOST_SCSI_MAX_VQ 128 struct vhost_scsi { /* Protected by vhost_scsi->dev.mutex */ - struct tcm_vhost_tpg **vs_tpg; + struct tcm_vhost_tpg *vs_tpg[VHOST_SCSI_MAX_TARGET]; char vs_vhost_wwpn[TRANSPORT_IQN_LEN]; + bool vs_endpoint; struct vhost_dev dev; struct vhost_virtqueue vqs[VHOST_SCSI_MAX_VQ]; @@ -578,27 +570,9 @@ static void tcm_vhost_submission_work(struct work_struct *work) } } -static void vhost_scsi_send_bad_target(struct vhost_scsi *vs, - struct vhost_virtqueue *vq, int head, unsigned out) -{ - struct virtio_scsi_cmd_resp __user *resp; - struct virtio_scsi_cmd_resp rsp; - int ret; - - memset(&rsp, 0, sizeof(rsp)); - rsp.response = VIRTIO_SCSI_S_BAD_TARGET; - resp = vq->iov[out].iov_base; - ret = __copy_to_user(resp, &rsp, sizeof(rsp)); - if (!ret) - vhost_add_used_and_signal(&vs->dev, vq, head, 0); - else - pr_err("Faulted on virtio_scsi_cmd_resp\n"); -} - static void vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) { - struct tcm_vhost_tpg **vs_tpg; struct virtio_scsi_cmd_req v_req; struct tcm_vhost_tpg *tv_tpg; struct tcm_vhost_cmd *tv_cmd; @@ -607,16 +581,8 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, int head, ret; u8 target; - /* - * We can handle the vq only after the endpoint is setup by calling the - * VHOST_SCSI_SET_ENDPOINT ioctl. - * - * TODO: Check that we are running from vhost_worker which acts - * as read-side critical section for vhost kind of RCU. - * See the comments in struct vhost_virtqueue in drivers/vhost/vhost.h - */ - vs_tpg = rcu_dereference_check(vq->private_data, 1); - if (!vs_tpg) + /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */ + if (unlikely(!vs->vs_endpoint)) return; mutex_lock(&vq->mutex); @@ -686,11 +652,23 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, /* Extract the tpgt */ target = v_req.lun[1]; - tv_tpg = ACCESS_ONCE(vs_tpg[target]); + tv_tpg = vs->vs_tpg[target]; /* Target does not exist, fail the request */ if (unlikely(!tv_tpg)) { - vhost_scsi_send_bad_target(vs, vq, head, out); + struct virtio_scsi_cmd_resp __user *resp; + struct virtio_scsi_cmd_resp rsp; + + memset(&rsp, 0, sizeof(rsp)); + rsp.response = VIRTIO_SCSI_S_BAD_TARGET; + resp = vq->iov[out].iov_base; + ret = __copy_to_user(resp, &rsp, sizeof(rsp)); + if (!ret) + vhost_add_used_and_signal(&vs->dev, + vq, head, 0); + else + pr_err("Faulted on virtio_scsi_cmd_resp\n"); + continue; } @@ -703,13 +681,22 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, if (IS_ERR(tv_cmd)) { vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n", PTR_ERR(tv_cmd)); - goto err_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; tv_cmd->tvc_vq = vq; + + 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; /* @@ -729,7 +716,7 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", scsi_command_size(tv_cmd->tvc_cdb), TCM_VHOST_MAX_CDB_SIZE); - goto err_free; + break; /* TODO */ } tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF; @@ -742,7 +729,7 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, data_direction == DMA_TO_DEVICE); if (unlikely(ret)) { vq_err(vq, "Failed to map iov to sgl\n"); - goto err_free; + break; /* TODO */ } } @@ -763,13 +750,6 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, } mutex_unlock(&vq->mutex); - return; - -err_free: - vhost_scsi_free_cmd(tv_cmd); -err_cmd: - vhost_scsi_send_bad_target(vs, vq, head, out); - mutex_unlock(&vq->mutex); } static void vhost_scsi_ctl_handle_kick(struct vhost_work *work) @@ -791,20 +771,6 @@ static void vhost_scsi_handle_kick(struct vhost_work *work) vhost_scsi_handle_vq(vs, vq); } -static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index) -{ - vhost_poll_flush(&vs->dev.vqs[index].poll); -} - -static void vhost_scsi_flush(struct vhost_scsi *vs) -{ - int i; - - for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) - vhost_scsi_flush_vq(vs, i); - vhost_work_flush(&vs->dev, &vs->vs_completion_work); -} - /* * Called from vhost_scsi_ioctl() context to walk the list of available * tcm_vhost_tpg with an active struct tcm_vhost_nexus @@ -815,10 +781,8 @@ static int vhost_scsi_set_endpoint( { struct tcm_vhost_tport *tv_tport; struct tcm_vhost_tpg *tv_tpg; - struct tcm_vhost_tpg **vs_tpg; - struct vhost_virtqueue *vq; - int index, ret, i, len; bool match = false; + int index, ret; mutex_lock(&vs->dev.mutex); /* Verify that ring has been setup correctly. */ @@ -830,15 +794,6 @@ static int vhost_scsi_set_endpoint( } } - len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET; - vs_tpg = kzalloc(len, GFP_KERNEL); - if (!vs_tpg) { - mutex_unlock(&vs->dev.mutex); - return -ENOMEM; - } - if (vs->vs_tpg) - memcpy(vs_tpg, vs->vs_tpg, len); - mutex_lock(&tcm_vhost_mutex); list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { mutex_lock(&tv_tpg->tv_tpg_mutex); @@ -853,15 +808,14 @@ static int vhost_scsi_set_endpoint( tv_tport = tv_tpg->tport; if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) { - if (vs->vs_tpg && vs->vs_tpg[tv_tpg->tport_tpgt]) { + if (vs->vs_tpg[tv_tpg->tport_tpgt]) { mutex_unlock(&tv_tpg->tv_tpg_mutex); mutex_unlock(&tcm_vhost_mutex); mutex_unlock(&vs->dev.mutex); - kfree(vs_tpg); return -EEXIST; } tv_tpg->tv_tpg_vhost_count++; - vs_tpg[tv_tpg->tport_tpgt] = tv_tpg; + vs->vs_tpg[tv_tpg->tport_tpgt] = tv_tpg; smp_mb__after_atomic_inc(); match = true; } @@ -872,27 +826,12 @@ static int vhost_scsi_set_endpoint( if (match) { memcpy(vs->vs_vhost_wwpn, t->vhost_wwpn, sizeof(vs->vs_vhost_wwpn)); - for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { - vq = &vs->vqs[i]; - /* Flushing the vhost_work acts as synchronize_rcu */ - mutex_lock(&vq->mutex); - rcu_assign_pointer(vq->private_data, vs_tpg); - vhost_init_used(vq); - mutex_unlock(&vq->mutex); - } + vs->vs_endpoint = true; ret = 0; } else { ret = -EEXIST; } - /* - * Act as synchronize_rcu to make sure access to - * old vs->vs_tpg is finished. - */ - vhost_scsi_flush(vs); - kfree(vs->vs_tpg); - vs->vs_tpg = vs_tpg; - mutex_unlock(&vs->dev.mutex); return ret; } @@ -903,8 +842,6 @@ static int vhost_scsi_clear_endpoint( { struct tcm_vhost_tport *tv_tport; struct tcm_vhost_tpg *tv_tpg; - struct vhost_virtqueue *vq; - bool match = false; int index, ret, i; u8 target; @@ -913,26 +850,20 @@ static int vhost_scsi_clear_endpoint( for (index = 0; index < vs->dev.nvqs; ++index) { if (!vhost_vq_access_ok(&vs->vqs[index])) { ret = -EFAULT; - goto err_dev; + goto err; } } - - if (!vs->vs_tpg) { - mutex_unlock(&vs->dev.mutex); - return 0; - } - for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) { target = i; + tv_tpg = vs->vs_tpg[target]; if (!tv_tpg) continue; - mutex_lock(&tv_tpg->tv_tpg_mutex); tv_tport = tv_tpg->tport; if (!tv_tport) { ret = -ENODEV; - goto err_tpg; + goto err; } if (strcmp(tv_tport->tport_name, t->vhost_wwpn)) { @@ -941,58 +872,20 @@ static int vhost_scsi_clear_endpoint( tv_tport->tport_name, tv_tpg->tport_tpgt, t->vhost_wwpn, t->vhost_tpgt); ret = -EINVAL; - goto err_tpg; + goto err; } tv_tpg->tv_tpg_vhost_count--; vs->vs_tpg[target] = NULL; - match = true; - mutex_unlock(&tv_tpg->tv_tpg_mutex); + vs->vs_endpoint = false; } - if (match) { - for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { - vq = &vs->vqs[i]; - /* Flushing the vhost_work acts as synchronize_rcu */ - mutex_lock(&vq->mutex); - rcu_assign_pointer(vq->private_data, NULL); - mutex_unlock(&vq->mutex); - } - } - /* - * Act as synchronize_rcu to make sure access to - * old vs->vs_tpg is finished. - */ - vhost_scsi_flush(vs); - kfree(vs->vs_tpg); - vs->vs_tpg = NULL; mutex_unlock(&vs->dev.mutex); - return 0; -err_tpg: - mutex_unlock(&tv_tpg->tv_tpg_mutex); -err_dev: +err: mutex_unlock(&vs->dev.mutex); return ret; } -static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) -{ - if (features & ~VHOST_SCSI_FEATURES) - return -EOPNOTSUPP; - - mutex_lock(&vs->dev.mutex); - if ((features & (1 << VHOST_F_LOG_ALL)) && - !vhost_log_access_ok(&vs->dev)) { - mutex_unlock(&vs->dev.mutex); - return -EFAULT; - } - vs->dev.acked_features = features; - smp_wmb(); - vhost_scsi_flush(vs); - mutex_unlock(&vs->dev.mutex); - return 0; -} - static int vhost_scsi_open(struct inode *inode, struct file *f) { struct vhost_scsi *s; @@ -1033,6 +926,37 @@ static int vhost_scsi_release(struct inode *inode, struct file *f) return 0; } +static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index) +{ + vhost_poll_flush(&vs->dev.vqs[index].poll); +} + +static void vhost_scsi_flush(struct vhost_scsi *vs) +{ + int i; + + for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) + vhost_scsi_flush_vq(vs, i); +} + +static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) +{ + if (features & ~VHOST_FEATURES) + return -EOPNOTSUPP; + + mutex_lock(&vs->dev.mutex); + if ((features & (1 << VHOST_F_LOG_ALL)) && + !vhost_log_access_ok(&vs->dev)) { + mutex_unlock(&vs->dev.mutex); + return -EFAULT; + } + vs->dev.acked_features = features; + smp_wmb(); + vhost_scsi_flush(vs); + mutex_unlock(&vs->dev.mutex); + return 0; +} + static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, unsigned long arg) { @@ -1063,7 +987,7 @@ static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, return -EFAULT; return 0; case VHOST_GET_FEATURES: - features = VHOST_SCSI_FEATURES; + features = VHOST_FEATURES; if (copy_to_user(featurep, &features, sizeof features)) return -EFAULT; return 0; diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 981c1c08c727..4c1546f71d56 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -31,8 +31,26 @@ config VIDEO_OUTPUT_CONTROL This framework adds support for low-level control of the video output switch. -config VIDEOMODE_HELPERS - bool +config DISPLAY_TIMING + bool + +config VIDEOMODE + bool + +config OF_DISPLAY_TIMING + bool "Enable device tree display timing support" + depends on OF + select DISPLAY_TIMING + help + helper to parse display timings from the devicetree + +config OF_VIDEOMODE + bool "Enable device tree videomode support" + depends on OF + select VIDEOMODE + select OF_DISPLAY_TIMING + help + helper to get videomodes from the devicetree config HDMI bool @@ -194,6 +212,14 @@ config FB_SYS_FOPS depends on FB default n +config FB_WMT_GE_ROPS + tristate + depends on FB + default n + ---help--- + Include functions for accelerated rectangle filling and area + copying using WonderMedia Graphics Engine operations. + config FB_DEFERRED_IO bool depends on FB @@ -1771,37 +1797,22 @@ config FB_AU1200 option au1200fb:panel=. config FB_VT8500 - bool "VIA VT8500 framebuffer support" + bool "VT8500 LCD Driver" depends on (FB = y) && ARM && ARCH_VT8500 - select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) - select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) + select FB_WMT_GE_ROPS select FB_SYS_IMAGEBLIT - select FB_MODE_HELPERS - select VIDEOMODE_HELPERS help This is the framebuffer driver for VIA VT8500 integrated LCD controller. config FB_WM8505 - bool "Wondermedia WM8xxx-series frame buffer support" + bool "WM8505 frame buffer support" depends on (FB = y) && ARM && ARCH_VT8500 - select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) - select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) + select FB_WMT_GE_ROPS select FB_SYS_IMAGEBLIT - select FB_MODE_HELPERS - select VIDEOMODE_HELPERS - help - This is the framebuffer driver for WonderMedia WM8xxx-series - integrated LCD controller. This driver covers the WM8505, WM8650 - and WM8850 SoCs. - -config FB_WMT_GE_ROPS - bool "VT8500/WM8xxx accelerated raster ops support" - depends on (FB = y) && (FB_VT8500 || FB_WM8505) - default n help - This adds support for accelerated raster operations on the - VIA VT8500 and Wondermedia 85xx series SoCs. + This is the framebuffer driver for WonderMedia WM8505/WM8650 + integrated LCD controller. source "drivers/video/geode/Kconfig" @@ -2266,7 +2277,7 @@ config XEN_FBDEV_FRONTEND select FB_SYS_IMAGEBLIT select FB_SYS_FOPS select FB_DEFERRED_IO - select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC + select INPUT_XEN_KBDDEV_FRONTEND select XEN_XENBUS_FRONTEND default y help diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index e414378d6a51..9df387334cb7 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -171,7 +171,7 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o #video output switch sysfs driver obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o -obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o -ifeq ($(CONFIG_OF),y) -obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o -endif +obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o +obj-$(CONFIG_OF_DISPLAY_TIMING) += of_display_timing.o +obj-$(CONFIG_VIDEOMODE) += videomode.o +obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o diff --git a/trunk/drivers/video/amifb.c b/trunk/drivers/video/amifb.c index 77cb4ffa1fe4..7fa1bf823729 100644 --- a/trunk/drivers/video/amifb.c +++ b/trunk/drivers/video/amifb.c @@ -3788,7 +3788,19 @@ static struct platform_driver amifb_driver = { }, }; -module_platform_driver_probe(amifb_driver, amifb_probe); +static int __init amifb_init(void) +{ + return platform_driver_probe(&amifb_driver, amifb_probe); +} + +module_init(amifb_init); + +static void __exit amifb_exit(void) +{ + platform_driver_unregister(&amifb_driver); +} + +module_exit(amifb_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:amiga-video"); diff --git a/trunk/drivers/video/atmel_lcdfb.c b/trunk/drivers/video/atmel_lcdfb.c index 98348ec0b3ce..12cf5f31ee8f 100644 --- a/trunk/drivers/video/atmel_lcdfb.c +++ b/trunk/drivers/video/atmel_lcdfb.c @@ -422,22 +422,17 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, = var->bits_per_pixel; break; case 16: - /* Older SOCs use IBGR:555 rather than BGR:565. */ - if (sinfo->have_intensity_bit) - var->green.length = 5; - else - var->green.length = 6; - if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { - /* RGB:5X5 mode */ - var->red.offset = var->green.length + 5; + /* RGB:565 mode */ + var->red.offset = 11; var->blue.offset = 0; } else { - /* BGR:5X5 mode */ + /* BGR:565 mode */ var->red.offset = 0; - var->blue.offset = var->green.length + 5; + var->blue.offset = 11; } var->green.offset = 5; + var->green.length = 6; var->red.length = var->blue.length = 5; break; case 32: @@ -684,7 +679,8 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red, case FB_VISUAL_PSEUDOCOLOR: if (regno < 256) { - if (sinfo->have_intensity_bit) { + if (cpu_is_at91sam9261() || cpu_is_at91sam9263() + || cpu_is_at91sam9rl()) { /* old style I+BGR:555 */ val = ((red >> 11) & 0x001f); val |= ((green >> 6) & 0x03e0); @@ -874,10 +870,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) } sinfo->info = info; sinfo->pdev = pdev; - if (cpu_is_at91sam9261() || cpu_is_at91sam9263() || - cpu_is_at91sam9rl()) { - sinfo->have_intensity_bit = true; - } strcpy(info->fix.id, sinfo->pdev->name); info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; @@ -1158,7 +1150,18 @@ static struct platform_driver atmel_lcdfb_driver = { }, }; -module_platform_driver_probe(atmel_lcdfb_driver, atmel_lcdfb_probe); +static int __init atmel_lcdfb_init(void) +{ + return platform_driver_probe(&atmel_lcdfb_driver, atmel_lcdfb_probe); +} + +static void __exit atmel_lcdfb_exit(void) +{ + platform_driver_unregister(&atmel_lcdfb_driver); +} + +module_init(atmel_lcdfb_init); +module_exit(atmel_lcdfb_exit); MODULE_DESCRIPTION("AT91/AT32 LCD Controller framebuffer driver"); MODULE_AUTHOR("Nicolas Ferre "); diff --git a/trunk/drivers/video/auo_k1900fb.c b/trunk/drivers/video/auo_k1900fb.c index f5b668e77af3..1a9ac6e1f4b3 100644 --- a/trunk/drivers/video/auo_k1900fb.c +++ b/trunk/drivers/video/auo_k1900fb.c @@ -60,12 +60,9 @@ static void auok1900_init(struct auok190xfb_par *par) { - struct device *dev = par->info->device; struct auok190x_board *board = par->board; u16 init_param = 0; - pm_runtime_get_sync(dev); - init_param |= AUOK1900_INIT_TEMP_AVERAGE; init_param |= AUOK1900_INIT_ROTATE(par->rotation); init_param |= AUOK190X_INIT_INVERSE_WHITE; @@ -77,9 +74,6 @@ static void auok1900_init(struct auok190xfb_par *par) /* let the controller finish */ board->wait_for_rdy(par); - - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); } static void auok1900_update_region(struct auok190xfb_par *par, int mode, @@ -88,7 +82,6 @@ static void auok1900_update_region(struct auok190xfb_par *par, int mode, struct device *dev = par->info->device; unsigned char *buf = (unsigned char *)par->info->screen_base; int xres = par->info->var.xres; - int line_length = par->info->fix.line_length; u16 args[4]; pm_runtime_get_sync(dev); @@ -107,9 +100,9 @@ static void auok1900_update_region(struct auok190xfb_par *par, int mode, args[1] = y1 + 1; args[2] = xres; args[3] = y2 - y1; - buf += y1 * line_length; + buf += y1 * xres; auok190x_send_cmdargs_pixels(par, AUOK1900_CMD_PARTIALDISP, 4, args, - ((y2 - y1) * line_length)/2, (u16 *) buf); + ((y2 - y1) * xres)/2, (u16 *) buf); auok190x_send_command(par, AUOK190X_CMD_DATA_STOP); par->update_cnt++; diff --git a/trunk/drivers/video/auo_k1901fb.c b/trunk/drivers/video/auo_k1901fb.c index 12b9adcb75c5..d1db1653cd88 100644 --- a/trunk/drivers/video/auo_k1901fb.c +++ b/trunk/drivers/video/auo_k1901fb.c @@ -101,12 +101,9 @@ static void auok1901_init(struct auok190xfb_par *par) { - struct device *dev = par->info->device; struct auok190x_board *board = par->board; u16 init_param = 0; - pm_runtime_get_sync(dev); - init_param |= AUOK190X_INIT_INVERSE_WHITE; init_param |= AUOK190X_INIT_FORMAT0; init_param |= AUOK1901_INIT_RESOLUTION(par->resolution); @@ -116,9 +113,6 @@ static void auok1901_init(struct auok190xfb_par *par) /* let the controller finish */ board->wait_for_rdy(par); - - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); } static void auok1901_update_region(struct auok190xfb_par *par, int mode, @@ -127,7 +121,6 @@ static void auok1901_update_region(struct auok190xfb_par *par, int mode, struct device *dev = par->info->device; unsigned char *buf = (unsigned char *)par->info->screen_base; int xres = par->info->var.xres; - int line_length = par->info->fix.line_length; u16 args[5]; pm_runtime_get_sync(dev); @@ -146,9 +139,9 @@ static void auok1901_update_region(struct auok190xfb_par *par, int mode, args[1] = y1 + 1; args[2] = xres; args[3] = y2 - y1; - buf += y1 * line_length; + buf += y1 * xres; auok190x_send_cmdargs_pixels_nowait(par, AUOK1901_CMD_DMA_START, 4, - args, ((y2 - y1) * line_length)/2, + args, ((y2 - y1) * xres)/2, (u16 *) buf); auok190x_send_command_nowait(par, AUOK190X_CMD_DATA_STOP); diff --git a/trunk/drivers/video/auo_k190x.c b/trunk/drivers/video/auo_k190x.c index b1f19b266da7..53846cb534d4 100644 --- a/trunk/drivers/video/auo_k190x.c +++ b/trunk/drivers/video/auo_k190x.c @@ -40,14 +40,6 @@ static struct panel_info panel_table[] = { .w = 1024, .h = 768, }, - [AUOK190X_RESOLUTION_600_800] = { - .w = 600, - .h = 800, - }, - [AUOK190X_RESOLUTION_768_1024] = { - .w = 768, - .h = 1024, - }, }; /* @@ -68,48 +60,8 @@ static void auok190x_issue_cmd(struct auok190xfb_par *par, u16 data) par->board->set_ctl(par, AUOK190X_I80_DC, 1); } -/** - * Conversion of 16bit color to 4bit grayscale - * does roughly (0.3 * R + 0.6 G + 0.1 B) / 2 - */ -static inline int rgb565_to_gray4(u16 data, struct fb_var_screeninfo *var) -{ - return ((((data & 0xF800) >> var->red.offset) * 77 + - ((data & 0x07E0) >> (var->green.offset + 1)) * 151 + - ((data & 0x1F) >> var->blue.offset) * 28) >> 8 >> 1); -} - -static int auok190x_issue_pixels_rgb565(struct auok190xfb_par *par, int size, - u16 *data) -{ - struct fb_var_screeninfo *var = &par->info->var; - struct device *dev = par->info->device; - int i; - u16 tmp; - - if (size & 7) { - dev_err(dev, "issue_pixels: size %d must be a multiple of 8\n", - size); - return -EINVAL; - } - - for (i = 0; i < (size >> 2); i++) { - par->board->set_ctl(par, AUOK190X_I80_WR, 0); - - tmp = (rgb565_to_gray4(data[4*i], var) & 0x000F); - tmp |= (rgb565_to_gray4(data[4*i+1], var) << 4) & 0x00F0; - tmp |= (rgb565_to_gray4(data[4*i+2], var) << 8) & 0x0F00; - tmp |= (rgb565_to_gray4(data[4*i+3], var) << 12) & 0xF000; - - par->board->set_hdb(par, tmp); - par->board->set_ctl(par, AUOK190X_I80_WR, 1); - } - - return 0; -} - -static int auok190x_issue_pixels_gray8(struct auok190xfb_par *par, int size, - u16 *data) +static int auok190x_issue_pixels(struct auok190xfb_par *par, int size, + u16 *data) { struct device *dev = par->info->device; int i; @@ -139,23 +91,6 @@ static int auok190x_issue_pixels_gray8(struct auok190xfb_par *par, int size, return 0; } -static int auok190x_issue_pixels(struct auok190xfb_par *par, int size, - u16 *data) -{ - struct fb_info *info = par->info; - struct device *dev = par->info->device; - - if (info->var.bits_per_pixel == 8 && info->var.grayscale) - auok190x_issue_pixels_gray8(par, size, data); - else if (info->var.bits_per_pixel == 16) - auok190x_issue_pixels_rgb565(par, size, data); - else - dev_err(dev, "unsupported color mode (bits: %d, gray: %d)\n", - info->var.bits_per_pixel, info->var.grayscale); - - return 0; -} - static u16 auok190x_read_data(struct auok190xfb_par *par) { u16 data; @@ -289,8 +224,8 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info, { struct fb_deferred_io *fbdefio = info->fbdefio; struct auok190xfb_par *par = info->par; - u16 line_length = info->fix.line_length; u16 yres = info->var.yres; + u16 xres = info->var.xres; u16 y1 = 0, h = 0; int prev_index = -1; struct page *cur; @@ -319,7 +254,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info, } /* height increment is fixed per page */ - h_inc = DIV_ROUND_UP(PAGE_SIZE , line_length); + h_inc = DIV_ROUND_UP(PAGE_SIZE , xres); /* calculate number of pages from pixel height */ threshold = par->consecutive_threshold / h_inc; @@ -330,7 +265,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info, list_for_each_entry(cur, &fbdefio->pagelist, lru) { if (prev_index < 0) { /* just starting so assign first page */ - y1 = (cur->index << PAGE_SHIFT) / line_length; + y1 = (cur->index << PAGE_SHIFT) / xres; h = h_inc; } else if ((cur->index - prev_index) <= threshold) { /* page is within our threshold for single updates */ @@ -340,7 +275,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info, par->update_partial(par, y1, y1 + h); /* start over with our non consecutive page */ - y1 = (cur->index << PAGE_SHIFT) / line_length; + y1 = (cur->index << PAGE_SHIFT) / xres; h = h_inc; } prev_index = cur->index; @@ -441,127 +376,27 @@ static void auok190xfb_imageblit(struct fb_info *info, static int auok190xfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct device *dev = info->device; - struct auok190xfb_par *par = info->par; - struct panel_info *panel = &panel_table[par->resolution]; - int size; - - /* - * Color depth - */ - - if (var->bits_per_pixel == 8 && var->grayscale == 1) { - /* - * For 8-bit grayscale, R, G, and B offset are equal. - */ - var->red.length = 8; - var->red.offset = 0; - var->red.msb_right = 0; - - var->green.length = 8; - var->green.offset = 0; - var->green.msb_right = 0; - - var->blue.length = 8; - var->blue.offset = 0; - var->blue.msb_right = 0; - - var->transp.length = 0; - var->transp.offset = 0; - var->transp.msb_right = 0; - } else if (var->bits_per_pixel == 16) { - var->red.length = 5; - var->red.offset = 11; - var->red.msb_right = 0; - - var->green.length = 6; - var->green.offset = 5; - var->green.msb_right = 0; - - var->blue.length = 5; - var->blue.offset = 0; - var->blue.msb_right = 0; - - var->transp.length = 0; - var->transp.offset = 0; - var->transp.msb_right = 0; - } else { - dev_warn(dev, "unsupported color mode (bits: %d, grayscale: %d)\n", - info->var.bits_per_pixel, info->var.grayscale); + if (info->var.xres != var->xres || info->var.yres != var->yres || + info->var.xres_virtual != var->xres_virtual || + info->var.yres_virtual != var->yres_virtual) { + pr_info("%s: Resolution not supported: X%u x Y%u\n", + __func__, var->xres, var->yres); return -EINVAL; } - /* - * Dimensions - */ - - switch (var->rotate) { - case FB_ROTATE_UR: - case FB_ROTATE_UD: - var->xres = panel->w; - var->yres = panel->h; - break; - case FB_ROTATE_CW: - case FB_ROTATE_CCW: - var->xres = panel->h; - var->yres = panel->w; - break; - default: - dev_dbg(dev, "Invalid rotation request\n"); - return -EINVAL; - } - - var->xres_virtual = var->xres; - var->yres_virtual = var->yres; - /* * Memory limit */ - size = var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8; - if (size > info->fix.smem_len) { - dev_err(dev, "Memory limit exceeded, requested %dK\n", - size >> 10); + if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { + pr_info("%s: Memory Limit requested yres_virtual = %u\n", + __func__, var->yres_virtual); return -ENOMEM; } return 0; } -static int auok190xfb_set_fix(struct fb_info *info) -{ - struct fb_fix_screeninfo *fix = &info->fix; - struct fb_var_screeninfo *var = &info->var; - - fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; - - fix->type = FB_TYPE_PACKED_PIXELS; - fix->accel = FB_ACCEL_NONE; - fix->visual = (var->grayscale) ? FB_VISUAL_STATIC_PSEUDOCOLOR - : FB_VISUAL_TRUECOLOR; - fix->xpanstep = 0; - fix->ypanstep = 0; - fix->ywrapstep = 0; - - return 0; -} - -static int auok190xfb_set_par(struct fb_info *info) -{ - struct auok190xfb_par *par = info->par; - - par->rotation = info->var.rotate; - auok190xfb_set_fix(info); - - /* reinit the controller to honor the rotation */ - par->init(par); - - /* wait for init to complete */ - par->board->wait_for_rdy(par); - - return 0; -} - static struct fb_ops auok190xfb_ops = { .owner = THIS_MODULE, .fb_read = fb_sys_read, @@ -570,7 +405,6 @@ static struct fb_ops auok190xfb_ops = { .fb_copyarea = auok190xfb_copyarea, .fb_imageblit = auok190xfb_imageblit, .fb_check_var = auok190xfb_check_var, - .fb_set_par = auok190xfb_set_par, }; /* @@ -754,16 +588,10 @@ static int auok190x_power(struct auok190xfb_par *par, bool on) static void auok190x_recover(struct auok190xfb_par *par) { - struct device *dev = par->info->device; - auok190x_power(par, 0); msleep(100); auok190x_power(par, 1); - /* after powercycling the device, it's always active */ - pm_runtime_set_active(dev); - par->standby = 0; - par->init(par); /* wait for init to complete */ @@ -1047,17 +875,42 @@ int auok190x_common_probe(struct platform_device *pdev, /* initialise fix, var, resolution and rotation */ strlcpy(info->fix.id, init->id, 16); + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; + info->fix.xpanstep = 0; + info->fix.ypanstep = 0; + info->fix.ywrapstep = 0; + info->fix.accel = FB_ACCEL_NONE; + info->var.bits_per_pixel = 8; info->var.grayscale = 1; + info->var.red.length = 8; + info->var.green.length = 8; + info->var.blue.length = 8; panel = &panel_table[board->resolution]; + /* if 90 degree rotation, switch width and height */ + if (board->rotation & 1) { + info->var.xres = panel->h; + info->var.yres = panel->w; + info->var.xres_virtual = panel->h; + info->var.yres_virtual = panel->w; + info->fix.line_length = panel->h; + } else { + info->var.xres = panel->w; + info->var.yres = panel->h; + info->var.xres_virtual = panel->w; + info->var.yres_virtual = panel->h; + info->fix.line_length = panel->w; + } + par->resolution = board->resolution; - par->rotation = 0; + par->rotation = board->rotation; /* videomemory handling */ - videomemorysize = roundup((panel->w * panel->h) * 2, PAGE_SIZE); + videomemorysize = roundup((panel->w * panel->h), PAGE_SIZE); videomemory = vmalloc(videomemorysize); if (!videomemory) { ret = -ENOMEM; @@ -1071,12 +924,6 @@ int auok190x_common_probe(struct platform_device *pdev, info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; info->fbops = &auok190xfb_ops; - ret = auok190xfb_check_var(&info->var, info); - if (ret) - goto err_defio; - - auok190xfb_set_fix(info); - /* deferred io init */ info->fbdefio = devm_kzalloc(info->device, diff --git a/trunk/drivers/video/controlfb.c b/trunk/drivers/video/controlfb.c index 67b77b40aa7f..0c189b32a4c5 100644 --- a/trunk/drivers/video/controlfb.c +++ b/trunk/drivers/video/controlfb.c @@ -285,26 +285,36 @@ static int controlfb_pan_display(struct fb_var_screeninfo *var, static int controlfb_mmap(struct fb_info *info, struct vm_area_struct *vma) { - unsigned long mmio_pgoff; - unsigned long start; - u32 len; - - start = info->fix.smem_start; - len = info->fix.smem_len; - mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; - if (vma->vm_pgoff >= mmio_pgoff) { - if (info->var.accel_flags) - return -EINVAL; - vma->vm_pgoff -= mmio_pgoff; - start = info->fix.mmio_start; - len = info->fix.mmio_len; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - } else { - /* framebuffer */ - vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot); - } - - return vm_iomap_memory(vma, start, len); + unsigned long off, start; + u32 len; + + off = vma->vm_pgoff << PAGE_SHIFT; + + /* frame buffer memory */ + start = info->fix.smem_start; + len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.smem_len); + if (off >= len) { + /* memory mapped io */ + off -= len; + if (info->var.accel_flags) + return -EINVAL; + start = info->fix.mmio_start; + len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.mmio_len); + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + } else { + /* framebuffer */ + vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot); + } + start &= PAGE_MASK; + if ((vma->vm_end - vma->vm_start + off) > len) + return -EINVAL; + off += start; + vma->vm_pgoff = off >> PAGE_SHIFT; + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; + + return 0; } static int controlfb_blank(int blank_mode, struct fb_info *info) diff --git a/trunk/drivers/video/ep93xx-fb.c b/trunk/drivers/video/ep93xx-fb.c index e06cd5d90c97..3f2519d30715 100644 --- a/trunk/drivers/video/ep93xx-fb.c +++ b/trunk/drivers/video/ep93xx-fb.c @@ -23,7 +23,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/video/exynos/exynos_mipi_dsi.c b/trunk/drivers/video/exynos/exynos_mipi_dsi.c index 3dd43ca2b95f..fac7df6d1aba 100644 --- a/trunk/drivers/video/exynos/exynos_mipi_dsi.c +++ b/trunk/drivers/video/exynos/exynos_mipi_dsi.c @@ -35,6 +35,8 @@ #include